Coverage Report

Created: 2024-05-20 06:23

/src/mupdf/source/fitz/image.c
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2004-2023 Artifex Software, Inc.
2
//
3
// This file is part of MuPDF.
4
//
5
// MuPDF is free software: you can redistribute it and/or modify it under the
6
// terms of the GNU Affero General Public License as published by the Free
7
// Software Foundation, either version 3 of the License, or (at your option)
8
// any later version.
9
//
10
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
// details.
14
//
15
// You should have received a copy of the GNU Affero General Public License
16
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17
//
18
// Alternative licensing terms are available from the licensor.
19
// For commercial licensing, see <https://www.artifex.com/> or contact
20
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21
// CA 94129, USA, for further information.
22
23
#include "mupdf/fitz.h"
24
25
#include "context-imp.h"
26
#include "image-imp.h"
27
#include "pixmap-imp.h"
28
29
#include <string.h>
30
#include <math.h>
31
#include <assert.h>
32
33
/* TODO: here or public? */
34
static int
35
fz_key_storable_needs_reaping(fz_context *ctx, const fz_key_storable *ks)
36
51.3k
{
37
51.3k
  return ks == NULL ? 0 : (ks->store_key_refs == ks->storable.refs);
38
51.3k
}
39
40
18.7k
#define SANE_DPI 72.0f
41
12.3k
#define INSANE_DPI 4800.0f
42
43
0
#define SCALABLE_IMAGE_DPI 96
44
45
struct fz_compressed_image
46
{
47
  fz_image super;
48
  fz_compressed_buffer *buffer;
49
};
50
51
struct fz_pixmap_image
52
{
53
  fz_image super;
54
  fz_pixmap *tile;
55
};
56
57
typedef struct
58
{
59
  int refs;
60
  fz_image *image;
61
  int l2factor;
62
  fz_irect rect;
63
} fz_image_key;
64
65
fz_image *
66
fz_keep_image(fz_context *ctx, fz_image *image)
67
42.9k
{
68
42.9k
  return fz_keep_key_storable(ctx, &image->key_storable);
69
42.9k
}
70
71
fz_image *
72
fz_keep_image_store_key(fz_context *ctx, fz_image *image)
73
26.7k
{
74
26.7k
  return fz_keep_key_storable_key(ctx, &image->key_storable);
75
26.7k
}
76
77
void
78
fz_drop_image_store_key(fz_context *ctx, fz_image *image)
79
26.7k
{
80
26.7k
  fz_drop_key_storable_key(ctx, &image->key_storable);
81
26.7k
}
82
83
static int
84
fz_make_hash_image_key(fz_context *ctx, fz_store_hash *hash, void *key_)
85
150k
{
86
150k
  fz_image_key *key = (fz_image_key *)key_;
87
150k
  hash->u.pir.ptr = key->image;
88
150k
  hash->u.pir.i = key->l2factor;
89
150k
  hash->u.pir.r = key->rect;
90
150k
  return 1;
91
150k
}
92
93
static void *
94
fz_keep_image_key(fz_context *ctx, void *key_)
95
26.7k
{
96
26.7k
  fz_image_key *key = (fz_image_key *)key_;
97
26.7k
  return fz_keep_imp(ctx, key, &key->refs);
98
26.7k
}
99
100
static void
101
fz_drop_image_key(fz_context *ctx, void *key_)
102
53.4k
{
103
53.4k
  fz_image_key *key = (fz_image_key *)key_;
104
53.4k
  if (fz_drop_imp(ctx, key, &key->refs))
105
26.7k
  {
106
26.7k
    fz_drop_image_store_key(ctx, key->image);
107
26.7k
    fz_free(ctx, key);
108
26.7k
  }
109
53.4k
}
110
111
static int
112
fz_cmp_image_key(fz_context *ctx, void *k0_, void *k1_)
113
0
{
114
0
  fz_image_key *k0 = (fz_image_key *)k0_;
115
0
  fz_image_key *k1 = (fz_image_key *)k1_;
116
0
  return k0->image == k1->image && k0->l2factor == k1->l2factor && k0->rect.x0 == k1->rect.x0 && k0->rect.y0 == k1->rect.y0 && k0->rect.x1 == k1->rect.x1 && k0->rect.y1 == k1->rect.y1;
117
0
}
118
119
static void
120
fz_format_image_key(fz_context *ctx, char *s, size_t n, void *key_)
121
0
{
122
0
  fz_image_key *key = (fz_image_key *)key_;
123
0
  fz_snprintf(s, n, "(image %d x %d sf=%d)", key->image->w, key->image->h, key->l2factor);
124
0
}
125
126
static int
127
fz_needs_reap_image_key(fz_context *ctx, void *key_)
128
51.3k
{
129
51.3k
  fz_image_key *key = (fz_image_key *)key_;
130
131
51.3k
  return fz_key_storable_needs_reaping(ctx, &key->image->key_storable);
132
51.3k
}
133
134
static const fz_store_type fz_image_store_type =
135
{
136
  "fz_image",
137
  fz_make_hash_image_key,
138
  fz_keep_image_key,
139
  fz_drop_image_key,
140
  fz_cmp_image_key,
141
  fz_format_image_key,
142
  fz_needs_reap_image_key
143
};
144
145
void
146
fz_drop_image(fz_context *ctx, fz_image *image)
147
144k
{
148
144k
  fz_drop_key_storable(ctx, &image->key_storable);
149
144k
}
150
151
static void
152
fz_mask_color_key(fz_context *ctx, fz_pixmap *pix, int n, int bpc, const int *colorkey_in, int indexed)
153
17
{
154
17
  unsigned char *p = pix->samples;
155
17
  int w;
156
17
  int k, t;
157
17
  int h = pix->h;
158
17
  size_t stride = pix->stride - pix->w * (size_t)pix->n;
159
17
  int colorkey[FZ_MAX_COLORS * 2];
160
17
  int scale, shift, max;
161
162
17
  if (pix->w == 0)
163
0
    return;
164
165
17
  if (indexed)
166
3
  {
167
    /* no upscaling or downshifting needed for indexed images */
168
3
    scale = 1;
169
3
    shift = 0;
170
3
  }
171
14
  else
172
14
  {
173
14
    switch (bpc)
174
14
    {
175
0
    case 1: scale = 255; shift = 0; break;
176
0
    case 2: scale = 85; shift = 0; break;
177
0
    case 4: scale = 17; shift = 0; break;
178
0
    default:
179
14
    case 8: scale = 1; shift = 0; break;
180
0
    case 16: scale = 1; shift = 8; break;
181
0
    case 24: scale = 1; shift = 16; break;
182
0
    case 32: scale = 1; shift = 24; break;
183
14
    }
184
14
  }
185
186
17
  switch (bpc)
187
17
  {
188
0
  case 1: max = 1; break;
189
0
  case 2: max = 3; break;
190
0
  case 4: max = 15; break;
191
0
  default:
192
17
  case 8: max = 0xff; break;
193
0
  case 16: max = 0xffff; break;
194
0
  case 24: max = 0xffffff; break;
195
0
  case 32: max = 0xffffffff; break;
196
17
  }
197
198
83
  for (k = 0; k < 2 * n; k++)
199
66
  {
200
66
    colorkey[k] = colorkey_in[k];
201
202
66
    if (colorkey[k] > max)
203
0
    {
204
0
      if (indexed && bpc == 1)
205
0
      {
206
0
        if (k == 0)
207
0
        {
208
0
          fz_warn(ctx, "first color key masking value out of range in 1bpc indexed image, ignoring color key masking");
209
0
          return;
210
0
        }
211
0
        fz_warn(ctx, "later color key masking value out of range in 1bpc indexed image, assumed to be 1");
212
0
        colorkey[k] = 1;
213
0
      }
214
0
      else if (bpc != 1)
215
0
      {
216
0
        fz_warn(ctx, "color key masking value out of range, masking to valid range");
217
0
        colorkey[k] &= max;
218
0
      }
219
0
    }
220
221
66
    if (colorkey[k] < 0 || colorkey[k] > max)
222
0
    {
223
0
      fz_warn(ctx, "color key masking value out of range, clamping to valid range");
224
0
      colorkey[k] = fz_clampi(colorkey[k], 0, max);
225
0
    }
226
227
66
    if (scale > 1)
228
0
    {
229
      /* scale up color key masking value so it can be compared with samples. */
230
0
      colorkey[k] *= scale;
231
0
    }
232
66
    else if (shift > 0)
233
0
    {
234
      /* shifting down color key masking value so it can be compared with samples. */
235
0
      colorkey[k] >>= shift;
236
0
    }
237
66
  }
238
239
4.45k
  while (h--)
240
4.44k
  {
241
4.44k
    w = pix->w;
242
4.44k
    do
243
1.04M
    {
244
1.04M
      t = 1;
245
2.94M
      for (k = 0; k < n; k++)
246
1.90M
        if (p[k] < colorkey[k * 2] || p[k] > colorkey[k * 2 + 1])
247
705k
          t = 0;
248
1.04M
      if (t)
249
1.20M
        for (k = 0; k < pix->n; k++)
250
863k
          p[k] = 0;
251
1.04M
      p += pix->n;
252
1.04M
    }
253
1.04M
    while (--w);
254
4.44k
    p += stride;
255
4.44k
  }
256
17
}
257
258
static void
259
fz_unblend_masked_tile(fz_context *ctx, fz_pixmap *tile, fz_image *image, const fz_irect *isa)
260
7
{
261
7
  fz_pixmap *mask;
262
7
  unsigned char *s, *d = tile->samples;
263
7
  int n = tile->n;
264
7
  int k;
265
7
  size_t sstride, dstride = tile->stride - tile->w * (size_t)tile->n;
266
7
  int h;
267
7
  fz_irect subarea;
268
269
  /* We need at least as much of the mask as there was of the tile. */
270
7
  if (isa)
271
0
    subarea = *isa;
272
7
  else
273
7
  {
274
7
    subarea.x0 = 0;
275
7
    subarea.y0 = 0;
276
7
    subarea.x1 = tile->w;
277
7
    subarea.y1 = tile->h;
278
7
  }
279
280
7
  mask = fz_get_pixmap_from_image(ctx, image->mask, &subarea, NULL, NULL, NULL);
281
7
  s = mask->samples;
282
  /* RJW: Urgh, bit of nastiness here. fz_pixmap_from_image will either return
283
   * an exact match for the subarea we asked for, or the full image, and the
284
   * normal way to know is that the matrix will be updated. That doesn't help
285
   * us here. */
286
7
  if (image->mask->w == mask->w && image->mask->h == mask->h) {
287
7
    subarea.x0 = 0;
288
7
    subarea.y0 = 0;
289
7
  }
290
7
  if (isa)
291
0
    s += (isa->x0 - subarea.x0) * (size_t)mask->n + (isa->y0 - subarea.y0) * (size_t)mask->stride;
292
7
  sstride = mask->stride - tile->w * (size_t)mask->n;
293
7
  h = tile->h;
294
295
7
  if (tile->w != 0)
296
7
  {
297
29.7k
    while (h--)
298
29.7k
    {
299
29.7k
      int w = tile->w;
300
29.7k
      do
301
89.2M
      {
302
89.2M
        if (*s == 0)
303
336M
          for (k = 0; k < image->n; k++)
304
252M
            d[k] = image->colorkey[k];
305
5.13M
        else
306
20.5M
          for (k = 0; k < image->n; k++)
307
15.4M
            d[k] = fz_clampi(image->colorkey[k] + (d[k] - image->colorkey[k]) * 255 / *s, 0, 255);
308
89.2M
        s++;
309
89.2M
        d += n;
310
89.2M
      }
311
89.2M
      while (--w);
312
29.7k
      s += sstride;
313
29.7k
      d += dstride;
314
29.7k
    }
315
7
  }
316
317
7
  fz_drop_pixmap(ctx, mask);
318
7
}
319
320
static void fz_adjust_image_subarea(fz_context *ctx, fz_image *image, fz_irect *subarea, int l2factor)
321
78.3k
{
322
78.3k
  int f = 1<<l2factor;
323
78.3k
  int bpp = image->bpc * image->n;
324
78.3k
  int mask;
325
326
78.3k
  switch (bpp)
327
78.3k
  {
328
42.1k
  case 1: mask = 8*f; break;
329
1.92k
  case 2: mask = 4*f; break;
330
18
  case 4: mask = 2*f; break;
331
34.2k
  default: mask = (bpp & 7) == 0 ? f : 0; break;
332
78.3k
  }
333
334
78.3k
  if (mask != 0)
335
78.3k
  {
336
78.3k
    subarea->x0 &= ~(mask - 1);
337
78.3k
    subarea->x1 = (subarea->x1 + mask - 1) & ~(mask - 1);
338
78.3k
  }
339
7
  else
340
7
  {
341
    /* Awkward case - mask cannot be a power of 2. */
342
7
    mask = bpp*f;
343
7
    switch (bpp)
344
7
    {
345
0
    case 3:
346
0
    case 5:
347
0
    case 7:
348
0
    case 9:
349
0
    case 11:
350
0
    case 13:
351
0
    case 15:
352
5
    default:
353
5
      mask *= 8;
354
5
      break;
355
2
    case 6:
356
2
    case 10:
357
2
    case 14:
358
2
      mask *= 4;
359
2
      break;
360
0
    case 12:
361
0
      mask *= 2;
362
0
      break;
363
7
    }
364
7
    subarea->x0 = (subarea->x0 / mask) * mask;
365
7
    subarea->x1 = ((subarea->x1 + mask - 1) / mask) * mask;
366
7
  }
367
368
78.3k
  subarea->y0 &= ~(f - 1);
369
78.3k
  if (subarea->x1 > image->w)
370
44.5k
    subarea->x1 = image->w;
371
78.3k
  subarea->y1 = (subarea->y1 + f - 1) & ~(f - 1);
372
78.3k
  if (subarea->y1 > image->h)
373
7.34k
    subarea->y1 = image->h;
374
78.3k
}
375
376
static void fz_compute_image_key(fz_context *ctx, fz_image *image, fz_matrix *ctm,
377
  fz_image_key *key, const fz_irect *subarea, int l2factor, int *w, int *h, int *dw, int *dh)
378
103k
{
379
103k
  key->refs = 1;
380
103k
  key->image = image;
381
103k
  key->l2factor = l2factor;
382
383
103k
  if (subarea == NULL)
384
27.1k
  {
385
27.1k
    key->rect.x0 = 0;
386
27.1k
    key->rect.y0 = 0;
387
27.1k
    key->rect.x1 = image->w;
388
27.1k
    key->rect.y1 = image->h;
389
27.1k
  }
390
76.4k
  else
391
76.4k
  {
392
76.4k
    key->rect = *subarea;
393
76.4k
    ctx->tuning->image_decode(ctx->tuning->image_decode_arg, image->w, image->h, key->l2factor, &key->rect);
394
76.4k
    fz_adjust_image_subarea(ctx, image, &key->rect, key->l2factor);
395
76.4k
  }
396
397
  /* Based on that subarea, recalculate the extents */
398
103k
  if (ctm)
399
103k
  {
400
103k
    float frac_w = (float) (key->rect.x1 - key->rect.x0) / image->w;
401
103k
    float frac_h = (float) (key->rect.y1 - key->rect.y0) / image->h;
402
103k
    float a = ctm->a * frac_w;
403
103k
    float b = ctm->b * frac_w;
404
103k
    float c = ctm->c * frac_h;
405
103k
    float d = ctm->d * frac_h;
406
103k
    *w = sqrtf(a * a + b * b);
407
103k
    *h = sqrtf(c * c + d * d);
408
103k
  }
409
21
  else
410
21
  {
411
21
    *w = image->w;
412
21
    *h = image->h;
413
21
  }
414
415
  /* Return the true sizes to the caller */
416
103k
  if (dw)
417
103k
    *dw = *w;
418
103k
  if (dh)
419
103k
    *dh = *h;
420
103k
  if (*w > image->w)
421
18.2k
    *w = image->w;
422
103k
  if (*h > image->h)
423
11.2k
    *h = image->h;
424
425
103k
  if (*w == 0 || *h == 0)
426
24.9k
    key->l2factor = 0;
427
103k
}
428
429
typedef struct {
430
  fz_stream *src;
431
  size_t l_skip; /* Number of bytes to skip on the left. */
432
  size_t r_skip; /* Number of bytes to skip on the right. */
433
  size_t b_skip; /* Number of bytes to skip on the bottom. */
434
  int lines; /* Number of lines left to copy. */
435
  size_t stride; /* Number of bytes to read in the image. */
436
  size_t nskip; /* Number of bytes left to skip on this line. */
437
  size_t nread; /* Number of bytes left to read on this line. */
438
} subarea_state;
439
440
static int
441
subarea_next(fz_context *ctx, fz_stream *stm, size_t len)
442
72.6k
{
443
72.6k
  subarea_state *state = stm->state;
444
72.6k
  size_t n;
445
446
72.6k
  stm->wp = stm->rp = NULL;
447
448
108k
  while (state->nskip > 0)
449
36.3k
  {
450
36.3k
    n = fz_skip(ctx, state->src, state->nskip);
451
36.3k
    if (n == 0)
452
285
      return EOF;
453
36.0k
    state->nskip -= n;
454
36.0k
  }
455
72.3k
  if (state->lines == 0)
456
0
    return EOF;
457
72.3k
  n = fz_available(ctx, state->src, state->nread);
458
72.3k
  if (n > state->nread)
459
19.3k
    n = state->nread;
460
72.3k
  if (n == 0)
461
121
    return EOF;
462
72.2k
  stm->rp = state->src->rp;
463
72.2k
  stm->wp = stm->rp + n;
464
72.2k
  stm->pos += n;
465
72.2k
  state->src->rp = stm->wp;
466
72.2k
  state->nread -= n;
467
72.2k
  if (state->nread == 0)
468
58.5k
  {
469
58.5k
    state->lines--;
470
58.5k
    if (state->lines == 0)
471
1.55k
      state->nskip = state->r_skip + state->b_skip;
472
56.9k
    else
473
56.9k
      state->nskip = state->l_skip + state->r_skip;
474
58.5k
    state->nread = state->stride;
475
58.5k
  }
476
72.2k
  return *stm->rp++;
477
72.3k
}
478
479
static void
480
subarea_drop(fz_context *ctx, void *state)
481
1.96k
{
482
1.96k
  fz_free(ctx, state);
483
1.96k
}
484
485
static fz_stream *
486
subarea_stream(fz_context *ctx, fz_stream *stm, fz_image *image, const fz_irect *subarea, int l2factor)
487
1.96k
{
488
1.96k
  subarea_state *state;
489
1.96k
  int f = 1<<l2factor;
490
1.96k
  int stream_w = (image->w + f - 1)>>l2factor;
491
1.96k
  size_t stream_stride = (stream_w * (size_t)image->n * image->bpc + 7) / 8;
492
1.96k
  int l_margin = subarea->x0 >> l2factor;
493
1.96k
  int t_margin = subarea->y0 >> l2factor;
494
1.96k
  int r_margin = (image->w + f - 1 - subarea->x1) >> l2factor;
495
1.96k
  int b_margin = (image->h + f - 1 - subarea->y1) >> l2factor;
496
1.96k
  size_t l_skip = (l_margin * (size_t)image->n * image->bpc)/8;
497
1.96k
  size_t r_skip = (r_margin * (size_t)image->n * image->bpc + 7)/8;
498
1.96k
  size_t t_skip = t_margin * stream_stride;
499
1.96k
  size_t b_skip = b_margin * stream_stride;
500
1.96k
  int h = (subarea->y1 - subarea->y0 + f - 1) >> l2factor;
501
1.96k
  int w = (subarea->x1 - subarea->x0 + f - 1) >> l2factor;
502
1.96k
  size_t stride = (w * (size_t)image->n * image->bpc + 7) / 8;
503
504
1.96k
  state = fz_malloc_struct(ctx, subarea_state);
505
1.96k
  state->src = stm;
506
1.96k
  state->l_skip = l_skip;
507
1.96k
  state->r_skip = r_skip;
508
1.96k
  state->b_skip = b_skip;
509
1.96k
  state->lines = h;
510
1.96k
  state->nskip = l_skip+t_skip;
511
1.96k
  state->stride = stride;
512
1.96k
  state->nread = stride;
513
514
1.96k
  return fz_new_stream(ctx, state, subarea_next, subarea_drop);
515
1.96k
}
516
517
typedef struct
518
{
519
  fz_stream *src;
520
  int w; /* Width in source pixels. */
521
  int h; /* Height (remaining) in scanlines. */
522
  int n; /* Number of components. */
523
  int f; /* Fill level (how many scanlines we've copied in). */
524
  size_t r; /* How many samples Remain to be filled in this line. */
525
  int l2; /* The amount of subsampling we're doing. */
526
  unsigned char data[1];
527
} l2sub_state;
528
529
static void
530
subsample_drop(fz_context *ctx, void *state)
531
4.83k
{
532
4.83k
  fz_free(ctx, state);
533
4.83k
}
534
535
static int
536
subsample_next(fz_context *ctx, fz_stream *stm, size_t len)
537
191k
{
538
191k
  l2sub_state *state = (l2sub_state *)stm->state;
539
191k
  size_t fill;
540
541
191k
  stm->rp = stm->wp = &state->data[0];
542
191k
  if (state->h == 0)
543
0
    return EOF;
544
545
  /* Copy in data */
546
191k
  do
547
538k
  {
548
538k
    if (state->r == 0)
549
538k
      state->r = state->w * (size_t)state->n;
550
551
1.10M
    while (state->r > 0)
552
563k
    {
553
563k
      size_t a;
554
563k
      a = fz_available(ctx, state->src, state->r);
555
563k
      if (a == 0)
556
901
        return EOF;
557
562k
      if (a > state->r)
558
245k
        a = state->r;
559
562k
      memcpy(&state->data[state->w * (size_t)state->n * (state->f+1) - state->r],
560
562k
        state->src->rp, a);
561
562k
      state->src->rp += a;
562
562k
      state->r -= a;
563
562k
    }
564
537k
    state->f++;
565
537k
    state->h--;
566
537k
  }
567
537k
  while (state->h > 0 && state->f != (1<<state->l2));
568
569
  /* Perform the subsample */
570
190k
  fz_subsample_pixblock(state->data, state->w, state->f, state->n, state->l2, state->w * (size_t)state->n);
571
190k
  state->f = 0;
572
573
  /* Update data pointers. */
574
190k
  fill = ((state->w + (1<<state->l2) - 1)>>state->l2) * (size_t)state->n;
575
190k
  stm->pos += fill;
576
190k
  stm->rp = &state->data[0];
577
190k
  stm->wp = &state->data[fill];
578
579
190k
  return *stm->rp++;
580
191k
}
581
582
static fz_stream *
583
subsample_stream(fz_context *ctx, fz_stream *src, int w, int h, int n, int l2extra)
584
4.83k
{
585
4.83k
  l2sub_state *state = fz_malloc(ctx, sizeof(l2sub_state) + w*(size_t)(n<<l2extra));
586
587
4.83k
  state->src = src;
588
4.83k
  state->w = w;
589
4.83k
  state->h = h;
590
4.83k
  state->n = n;
591
4.83k
  state->f = 0;
592
4.83k
  state->r = 0;
593
4.83k
  state->l2 = l2extra;
594
595
4.83k
  return fz_new_stream(ctx, state, subsample_next, subsample_drop);
596
4.83k
}
597
598
/* l2factor is the amount of subsampling that the decoder is going to be
599
 * doing for us already. (So for JPEG 0,1,2,3 corresponding to 1, 2, 4,
600
 * 8. For other formats, probably 0.). l2extra is the additional amount
601
 * of subsampling we should perform here. */
602
fz_pixmap *
603
fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image *cimg, fz_irect *subarea, int indexed, int l2factor, int *l2extra)
604
56.7k
{
605
56.7k
  fz_image *image = &cimg->super;
606
56.7k
  fz_pixmap *tile = NULL;
607
56.7k
  size_t stride, len, i;
608
56.7k
  unsigned char *samples = NULL;
609
56.7k
  int f = 1<<l2factor;
610
56.7k
  int w = image->w;
611
56.7k
  int h = image->h;
612
56.7k
  int matte = image->use_colorkey && image->mask;
613
56.7k
  fz_stream *read_stream = stm;
614
56.7k
  fz_stream *sstream = NULL;
615
56.7k
  fz_stream *l2stream = NULL;
616
56.7k
  fz_stream *unpstream = NULL;
617
618
56.7k
  if (matte)
619
7
  {
620
    /* Can't do l2factor decoding */
621
7
    if (image->w != image->mask->w || image->h != image->mask->h)
622
0
    {
623
0
      fz_warn(ctx, "mask must be of same size as image for /Matte");
624
0
      matte = 0;
625
0
    }
626
7
    assert(l2factor == 0);
627
7
  }
628
56.7k
  if (subarea)
629
26.0k
  {
630
26.0k
    if (subarea->x0 == 0 && subarea->x1 == image->w &&
631
26.0k
      subarea->y0 == 0 && subarea->y1 == image->h)
632
24.1k
      subarea = NULL;
633
1.96k
    else
634
1.96k
    {
635
1.96k
      fz_adjust_image_subarea(ctx, image, subarea, l2factor);
636
1.96k
      w = (subarea->x1 - subarea->x0);
637
1.96k
      h = (subarea->y1 - subarea->y0);
638
1.96k
    }
639
26.0k
  }
640
56.7k
  w = (w + f - 1) >> l2factor;
641
56.7k
  h = (h + f - 1) >> l2factor;
642
643
56.7k
  fz_var(tile);
644
56.7k
  fz_var(samples);
645
56.7k
  fz_var(sstream);
646
56.7k
  fz_var(unpstream);
647
56.7k
  fz_var(l2stream);
648
649
113k
  fz_try(ctx)
650
113k
  {
651
56.7k
    int alpha = (image->colorspace == NULL);
652
56.7k
    if (image->use_colorkey)
653
24
      alpha = 1;
654
655
56.7k
    if (subarea)
656
1.96k
      read_stream = sstream = subarea_stream(ctx, stm, image, subarea, l2factor);
657
56.7k
    if (image->bpc != 8 || image->use_colorkey)
658
49.0k
      read_stream = unpstream = fz_unpack_stream(ctx, read_stream, image->bpc, w, h, image->n, indexed, image->use_colorkey, 0);
659
56.7k
    if (l2extra && *l2extra && !indexed)
660
4.83k
    {
661
4.83k
      read_stream = l2stream = subsample_stream(ctx, read_stream, w, h, image->n + image->use_colorkey, *l2extra);
662
4.83k
      w = (w + (1<<*l2extra) - 1)>>*l2extra;
663
4.83k
      h = (h + (1<<*l2extra) - 1)>>*l2extra;
664
4.83k
      *l2extra = 0;
665
4.83k
    }
666
667
56.7k
    tile = fz_new_pixmap(ctx, image->colorspace, w, h, NULL, alpha);
668
56.7k
    if (image->interpolate & FZ_PIXMAP_FLAG_INTERPOLATE)
669
1.58k
      tile->flags |= FZ_PIXMAP_FLAG_INTERPOLATE;
670
55.1k
    else
671
55.1k
      tile->flags &= ~FZ_PIXMAP_FLAG_INTERPOLATE;
672
673
56.7k
    samples = tile->samples;
674
56.7k
    stride = tile->stride;
675
676
56.7k
    len = fz_read(ctx, read_stream, samples, h * stride);
677
678
    /* Pad truncated images */
679
56.7k
    if (len < stride * h)
680
9.50k
    {
681
9.50k
      fz_warn(ctx, "padding truncated image");
682
9.50k
      memset(samples + len, 0, stride * h - len);
683
9.50k
    }
684
685
    /* Invert 1-bit image masks */
686
56.7k
    if (image->imagemask)
687
42.4k
    {
688
      /* 0=opaque and 1=transparent so we need to invert */
689
42.4k
      unsigned char *p = samples;
690
42.4k
      len = h * stride;
691
111M
      for (i = 0; i < len; i++)
692
111M
        p[i] = ~p[i];
693
42.4k
    }
694
695
    /* color keyed transparency */
696
56.7k
    if (image->use_colorkey && !image->mask)
697
17
      fz_mask_color_key(ctx, tile, image->n, image->bpc, image->colorkey, indexed);
698
699
56.7k
    if (indexed)
700
247
    {
701
247
      fz_pixmap *conv;
702
247
      fz_decode_indexed_tile(ctx, tile, image->decode, (1 << image->bpc) - 1);
703
247
      conv = fz_convert_indexed_pixmap_to_base(ctx, tile);
704
247
      fz_drop_pixmap(ctx, tile);
705
247
      tile = conv;
706
247
    }
707
56.4k
    else if (image->use_decode)
708
33.4k
    {
709
33.4k
      fz_decode_tile(ctx, tile, image->decode);
710
33.4k
    }
711
712
    /* pre-blended matte color */
713
56.7k
    if (matte)
714
7
      fz_unblend_masked_tile(ctx, tile, image, subarea);
715
56.7k
  }
716
113k
  fz_always(ctx)
717
56.7k
  {
718
56.7k
    fz_drop_stream(ctx, sstream);
719
56.7k
    fz_drop_stream(ctx, unpstream);
720
56.7k
    fz_drop_stream(ctx, l2stream);
721
56.7k
  }
722
56.7k
  fz_catch(ctx)
723
11
  {
724
11
    fz_drop_pixmap(ctx, tile);
725
11
    fz_rethrow(ctx);
726
11
  }
727
728
56.7k
  return tile;
729
56.7k
}
730
731
void
732
fz_drop_image_base(fz_context *ctx, fz_image *image)
733
36.7k
{
734
36.7k
  fz_drop_colorspace(ctx, image->colorspace);
735
36.7k
  fz_drop_image(ctx, image->mask);
736
36.7k
  fz_free(ctx, image);
737
36.7k
}
738
739
void
740
fz_drop_image_imp(fz_context *ctx, fz_storable *image_)
741
36.7k
{
742
36.7k
  fz_image *image = (fz_image *)image_;
743
744
36.7k
  image->drop_image(ctx, image);
745
36.7k
  fz_drop_image_base(ctx, image);
746
36.7k
}
747
748
static void
749
drop_compressed_image(fz_context *ctx, fz_image *image_)
750
36.3k
{
751
36.3k
  fz_compressed_image *image = (fz_compressed_image *)image_;
752
753
36.3k
  fz_drop_compressed_buffer(ctx, image->buffer);
754
36.3k
}
755
756
static void
757
drop_pixmap_image(fz_context *ctx, fz_image *image_)
758
401
{
759
401
  fz_pixmap_image *image = (fz_pixmap_image *)image_;
760
761
401
  fz_drop_pixmap(ctx, image->tile);
762
401
}
763
764
static fz_pixmap *
765
compressed_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea, int w, int h, int *l2factor)
766
26.8k
{
767
26.8k
  fz_compressed_image *image = (fz_compressed_image *)image_;
768
26.8k
  int native_l2factor;
769
26.8k
  fz_stream *stm;
770
26.8k
  int indexed;
771
26.8k
  fz_pixmap *tile;
772
26.8k
  int can_sub = 0;
773
26.8k
  int local_l2factor;
774
775
  /* If we are using matte, then the decode code requires both image and tile sizes
776
   * to match. The simplest way to ensure this is to do no native l2factor decoding.
777
   */
778
26.8k
  if (image->super.use_colorkey && image->super.mask)
779
7
  {
780
7
    local_l2factor = 0;
781
7
    l2factor = &local_l2factor;
782
7
  }
783
784
  /* We need to make a new one. */
785
  /* First check for ones that we can't decode using streams */
786
26.8k
  switch (image->buffer->params.type)
787
26.8k
  {
788
108
  case FZ_IMAGE_PNG:
789
108
    tile = fz_load_png(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
790
108
    break;
791
60
  case FZ_IMAGE_GIF:
792
60
    tile = fz_load_gif(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
793
60
    break;
794
0
  case FZ_IMAGE_BMP:
795
0
    tile = fz_load_bmp(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
796
0
    break;
797
0
  case FZ_IMAGE_TIFF:
798
0
    tile = fz_load_tiff(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
799
0
    break;
800
0
  case FZ_IMAGE_PNM:
801
0
    tile = fz_load_pnm(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
802
0
    break;
803
0
  case FZ_IMAGE_JXR:
804
0
    tile = fz_load_jxr(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
805
0
    break;
806
568
  case FZ_IMAGE_JPX:
807
568
    tile = fz_load_jpx(ctx, image->buffer->buffer->data, image->buffer->buffer->len, image->super.colorspace);
808
568
    break;
809
32
  case FZ_IMAGE_PSD:
810
32
    tile = fz_load_psd(ctx, image->buffer->buffer->data, image->buffer->buffer->len);
811
32
    break;
812
1.84k
  case FZ_IMAGE_JPEG:
813
    /* Scan JPEG stream and patch missing height values in header */
814
1.84k
    {
815
1.84k
      unsigned char *s = image->buffer->buffer->data;
816
1.84k
      unsigned char *e = s + image->buffer->buffer->len;
817
1.84k
      unsigned char *d;
818
7.16k
      for (d = s + 2; s < d && d + 9 < e && d[0] == 0xFF; d += (d[2] << 8 | d[3]) + 2)
819
5.32k
      {
820
5.32k
        if (d[1] < 0xC0 || (0xC3 < d[1] && d[1] < 0xC9) || 0xCB < d[1])
821
4.11k
          continue;
822
1.20k
        if ((d[5] == 0 && d[6] == 0) || ((d[5] << 8) | d[6]) > image->super.h)
823
180
        {
824
180
          d[5] = (image->super.h >> 8) & 0xFF;
825
180
          d[6] = image->super.h & 0xFF;
826
180
        }
827
1.20k
      }
828
1.84k
    }
829
    /* fall through */
830
831
26.0k
  default:
832
26.0k
    native_l2factor = l2factor ? *l2factor : 0;
833
26.0k
    stm = fz_open_image_decomp_stream_from_buffer(ctx, image->buffer, l2factor);
834
52.1k
    fz_try(ctx)
835
52.1k
    {
836
26.0k
      if (l2factor)
837
26.0k
        native_l2factor -= *l2factor;
838
26.0k
      indexed = fz_colorspace_is_indexed(ctx, image->super.colorspace);
839
26.0k
      can_sub = 1;
840
26.0k
      tile = fz_decomp_image_from_stream(ctx, stm, image, subarea, indexed, native_l2factor, l2factor);
841
26.0k
    }
842
52.1k
    fz_always(ctx)
843
26.0k
      fz_drop_stream(ctx, stm);
844
26.0k
    fz_catch(ctx)
845
6
      fz_rethrow(ctx);
846
847
26.0k
    break;
848
26.8k
  }
849
850
26.7k
  if (can_sub == 0 && subarea != NULL)
851
662
  {
852
662
    subarea->x0 = 0;
853
662
    subarea->y0 = 0;
854
662
    subarea->x1 = image->super.w;
855
662
    subarea->y1 = image->super.h;
856
662
  }
857
858
26.7k
  return tile;
859
26.8k
}
860
861
static fz_pixmap *
862
pixmap_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea, int w, int h, int *l2factor)
863
401
{
864
401
  fz_pixmap_image *image = (fz_pixmap_image *)image_;
865
866
  /* 'Simple' images created direct from pixmaps will have no buffer
867
   * of compressed data. We cannot do any better than just returning
868
   * a pointer to the original 'tile'.
869
   */
870
401
  return fz_keep_pixmap(ctx, image->tile); /* That's all we can give you! */
871
401
}
872
873
static void
874
update_ctm_for_subarea(fz_matrix *ctm, const fz_irect *subarea, int w, int h)
875
49.4k
{
876
49.4k
  fz_matrix m;
877
878
49.4k
  if (ctm == NULL || (subarea->x0 == 0 && subarea->y0 == 0 && subarea->x1 == w && subarea->y1 == h))
879
47.2k
    return;
880
881
2.25k
  m.a = (float) (subarea->x1 - subarea->x0) / w;
882
2.25k
  m.b = 0;
883
2.25k
  m.c = 0;
884
2.25k
  m.d = (float) (subarea->y1 - subarea->y0) / h;
885
2.25k
  m.e = (float) subarea->x0 / w;
886
2.25k
  m.f = (float) subarea->y0 / h;
887
2.25k
  *ctm = fz_concat(m, *ctm);
888
2.25k
}
889
890
void fz_default_image_decode(void *arg, int w, int h, int l2factor, fz_irect *subarea)
891
76.4k
{
892
76.4k
  (void)arg;
893
894
76.4k
  if ((subarea->x1-subarea->x0)*(subarea->y1-subarea->y0) >= (w*h/10)*9)
895
71.7k
  {
896
    /* Either no subarea specified, or a subarea 90% or more of the
897
     * whole area specified. Use the whole image. */
898
71.7k
    subarea->x0 = 0;
899
71.7k
    subarea->y0 = 0;
900
71.7k
    subarea->x1 = w;
901
71.7k
    subarea->y1 = h;
902
71.7k
  }
903
4.69k
  else
904
4.69k
  {
905
    /* Clip to the edges if they are within 1% */
906
4.69k
    if (subarea->x0 <= w/100)
907
4.45k
      subarea->x0 = 0;
908
4.69k
    if (subarea->y0 <= h/100)
909
1.43k
      subarea->y0 = 0;
910
4.69k
    if (subarea->x1 >= w*99/100)
911
1.75k
      subarea->x1 = w;
912
4.69k
    if (subarea->y1 >= h*99/100)
913
4.03k
      subarea->y1 = h;
914
4.69k
  }
915
76.4k
}
916
917
static fz_pixmap *
918
fz_find_image_tile(fz_context *ctx, fz_image *image, fz_image_key *key, fz_matrix *ctm)
919
76.7k
{
920
76.7k
  fz_pixmap *tile;
921
76.7k
  do
922
97.3k
  {
923
97.3k
    tile = fz_find_item(ctx, fz_drop_pixmap_imp, key, &fz_image_store_type);
924
97.3k
    if (tile)
925
22.7k
    {
926
22.7k
      update_ctm_for_subarea(ctm, &key->rect, image->w, image->h);
927
22.7k
      return tile;
928
22.7k
    }
929
74.6k
    key->l2factor--;
930
74.6k
  }
931
76.7k
  while (key->l2factor >= 0);
932
53.9k
  return NULL;
933
76.7k
}
934
935
fz_pixmap *
936
fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subarea, fz_matrix *ctm, int *dw, int *dh)
937
49.9k
{
938
49.9k
  fz_pixmap *tile;
939
49.9k
  int l2factor, l2factor_remaining;
940
49.9k
  fz_image_key key;
941
49.9k
  fz_image_key *keyp = NULL;
942
49.9k
  int w;
943
49.9k
  int h;
944
945
49.9k
  fz_var(keyp);
946
947
49.9k
  if (!image)
948
0
    return NULL;
949
950
  /* Figure out the extent. */
951
49.9k
  if (ctm)
952
49.9k
  {
953
49.9k
    w = sqrtf(ctm->a * ctm->a + ctm->b * ctm->b);
954
49.9k
    h = sqrtf(ctm->c * ctm->c + ctm->d * ctm->d);
955
49.9k
  }
956
7
  else
957
7
  {
958
7
    w = image->w;
959
7
    h = image->h;
960
7
  }
961
962
49.9k
  if (image->scalable)
963
0
  {
964
    /* If the image is scalable, we always want to re-render and never cache. */
965
0
    fz_irect subarea_copy;
966
0
    if (subarea)
967
0
      subarea_copy = *subarea;
968
0
    l2factor_remaining = 0;
969
0
    if (dw) *dw = w;
970
0
    if (dh) *dh = h;
971
0
    return image->get_pixmap(ctx, image, subarea ? &subarea_copy : NULL, image->w, image->h, &l2factor_remaining);
972
0
  }
973
974
  /* Clamp requested image size, since we never want to magnify images here. */
975
49.9k
  if (w > image->w)
976
8.69k
    w = image->w;
977
49.9k
  if (h > image->h)
978
5.31k
    h = image->h;
979
980
49.9k
  if (image->decoded)
981
401
  {
982
    /* If the image is already decoded, then we can't offer a subarea,
983
     * or l2factor, and we don't want to cache. */
984
401
    l2factor_remaining = 0;
985
401
    if (dw) *dw = w;
986
401
    if (dh) *dh = h;
987
401
    return image->get_pixmap(ctx, image, NULL, image->w, image->h, &l2factor_remaining);
988
401
  }
989
990
  /* What is our ideal factor? We search for the largest factor where
991
   * we can subdivide and stay larger than the required size. We add
992
   * a fudge factor of +2 here to allow for the possibility of
993
   * expansion due to grid fitting. */
994
49.5k
  l2factor = 0;
995
49.5k
  if (w > 0 && h > 0)
996
36.5k
  {
997
56.9k
    while (image->w>>(l2factor+1) >= w+2 && image->h>>(l2factor+1) >= h+2 && l2factor < 6)
998
20.3k
      l2factor++;
999
36.5k
  }
1000
1001
  /* First, look through the store for existing tiles */
1002
49.5k
  if (subarea)
1003
49.5k
  {
1004
49.5k
    fz_compute_image_key(ctx, image, ctm, &key, subarea, l2factor, &w, &h, dw, dh);
1005
49.5k
    tile = fz_find_image_tile(ctx, image, &key, ctm);
1006
49.5k
    if (tile)
1007
22.4k
      return tile;
1008
49.5k
  }
1009
1010
  /* No subarea given, or no tile for subarea found; try entire image */
1011
27.1k
  fz_compute_image_key(ctx, image, ctm, &key, NULL, l2factor, &w, &h, dw, dh);
1012
27.1k
  tile = fz_find_image_tile(ctx, image, &key, ctm);
1013
27.1k
  if (tile)
1014
327
    return tile;
1015
1016
  /* Neither subarea nor full image tile found; prepare the subarea key again */
1017
26.8k
  if (subarea)
1018
26.8k
    fz_compute_image_key(ctx, image, ctm, &key, subarea, l2factor, &w, &h, dw, dh);
1019
1020
  /* We'll have to decode the image; request the correct amount of downscaling. */
1021
26.8k
  l2factor_remaining = l2factor;
1022
26.8k
  tile = image->get_pixmap(ctx, image, &key.rect, w, h, &l2factor_remaining);
1023
1024
  /* Update the ctm to allow for subareas. */
1025
26.8k
  update_ctm_for_subarea(ctm, &key.rect, image->w, image->h);
1026
1027
  /* l2factor_remaining is updated to the amount of subscaling left to do */
1028
26.8k
  assert(l2factor_remaining >= 0 && l2factor_remaining <= 6);
1029
26.7k
  if (l2factor_remaining)
1030
42
  {
1031
84
    fz_try(ctx)
1032
84
      fz_subsample_pixmap(ctx, tile, l2factor_remaining);
1033
84
    fz_catch(ctx)
1034
0
    {
1035
0
      fz_drop_pixmap(ctx, tile);
1036
0
      fz_rethrow(ctx);
1037
0
    }
1038
42
  }
1039
1040
53.4k
  fz_try(ctx)
1041
53.4k
  {
1042
26.7k
    fz_pixmap *existing_tile;
1043
1044
    /* Now we try to cache the pixmap. Any failure here will just result
1045
     * in us not caching. */
1046
26.7k
    keyp = fz_malloc_struct(ctx, fz_image_key);
1047
26.7k
    keyp->refs = 1;
1048
26.7k
    keyp->image = fz_keep_image_store_key(ctx, image);
1049
26.7k
    keyp->l2factor = l2factor;
1050
26.7k
    keyp->rect = key.rect;
1051
1052
26.7k
    existing_tile = fz_store_item(ctx, keyp, tile, fz_pixmap_size(ctx, tile), &fz_image_store_type);
1053
26.7k
    if (existing_tile)
1054
0
    {
1055
      /* We already have a tile. This must have been produced by a
1056
       * racing thread. We'll throw away ours and use that one. */
1057
0
      fz_drop_pixmap(ctx, tile);
1058
0
      tile = existing_tile;
1059
0
    }
1060
26.7k
  }
1061
53.4k
  fz_always(ctx)
1062
26.7k
  {
1063
26.7k
    fz_drop_image_key(ctx, keyp);
1064
26.7k
  }
1065
26.7k
  fz_catch(ctx)
1066
0
  {
1067
    /* Do nothing */
1068
0
    fz_rethrow_if(ctx, FZ_ERROR_SYSTEM);
1069
0
    fz_report_error(ctx);
1070
0
  }
1071
1072
26.7k
  return tile;
1073
26.7k
}
1074
1075
fz_pixmap *
1076
fz_get_unscaled_pixmap_from_image(fz_context *ctx, fz_image *image)
1077
0
{
1078
0
  return fz_get_pixmap_from_image(ctx, image, NULL /*subarea*/, NULL /*ctm*/, NULL /*dw*/, NULL /*dh*/);
1079
0
}
1080
1081
static size_t
1082
pixmap_image_get_size(fz_context *ctx, fz_image *image)
1083
25
{
1084
25
  fz_pixmap_image *im = (fz_pixmap_image *)image;
1085
1086
25
  if (image == NULL)
1087
0
    return 0;
1088
1089
25
  return sizeof(fz_pixmap_image) + fz_pixmap_size(ctx, im->tile);
1090
25
}
1091
1092
size_t fz_image_size(fz_context *ctx, fz_image *im)
1093
2.90k
{
1094
2.90k
  if (im == NULL)
1095
0
    return 0;
1096
1097
2.90k
  return im->get_size(ctx, im);
1098
2.90k
}
1099
1100
fz_image *
1101
fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask)
1102
401
{
1103
401
  fz_pixmap_image *image;
1104
1105
401
  image = fz_new_derived_image(ctx, pixmap->w, pixmap->h, 8, pixmap->colorspace,
1106
401
        pixmap->xres, pixmap->yres, 0, 0,
1107
401
        NULL, NULL, mask, fz_pixmap_image,
1108
401
        pixmap_image_get_pixmap,
1109
401
        pixmap_image_get_size,
1110
401
        drop_pixmap_image);
1111
401
  image->tile = fz_keep_pixmap(ctx, pixmap);
1112
401
  image->super.decoded = 1;
1113
1114
401
  return &image->super;
1115
401
}
1116
1117
fz_image *
1118
fz_new_image_of_size(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace,
1119
    int xres, int yres, int interpolate, int imagemask, const float *decode,
1120
    const int *colorkey, fz_image *mask, size_t size,
1121
    fz_image_get_pixmap_fn *get_pixmap,
1122
    fz_image_get_size_fn *get_size,
1123
    fz_drop_image_fn *drop)
1124
36.7k
{
1125
36.7k
  fz_image *image;
1126
36.7k
  int i;
1127
1128
36.7k
  assert(mask == NULL || mask->mask == NULL);
1129
36.7k
  assert(size >= sizeof(fz_image));
1130
1131
36.7k
  image = Memento_label(fz_calloc(ctx, 1, size), "fz_image");
1132
36.7k
  FZ_INIT_KEY_STORABLE(image, 1, fz_drop_image_imp);
1133
36.7k
  image->drop_image = drop;
1134
36.7k
  image->get_pixmap = get_pixmap;
1135
36.7k
  image->get_size = get_size;
1136
36.7k
  image->w = w;
1137
36.7k
  image->h = h;
1138
36.7k
  image->xres = xres;
1139
36.7k
  image->yres = yres;
1140
36.7k
  image->bpc = bpc;
1141
36.7k
  image->n = (colorspace ? fz_colorspace_n(ctx, colorspace) : 1);
1142
36.7k
  image->colorspace = fz_keep_colorspace(ctx, colorspace);
1143
36.7k
  image->interpolate = interpolate;
1144
36.7k
  image->imagemask = imagemask;
1145
36.7k
  image->use_colorkey = (colorkey != NULL);
1146
36.7k
  if (colorkey)
1147
24
    memcpy(image->colorkey, colorkey, sizeof(int)*image->n*2);
1148
36.7k
  image->use_decode = 0;
1149
36.7k
  if (decode)
1150
34.7k
  {
1151
34.7k
    memcpy(image->decode, decode, sizeof(float)*image->n*2);
1152
34.7k
  }
1153
1.99k
  else
1154
1.99k
  {
1155
1.99k
    float maxval = fz_colorspace_is_indexed(ctx, colorspace) ? (1 << bpc) - 1 : 1;
1156
5.95k
    for (i = 0; i < image->n; i++)
1157
3.95k
    {
1158
3.95k
      image->decode[2*i] = 0;
1159
3.95k
      image->decode[2*i+1] = maxval;
1160
3.95k
    }
1161
1.99k
  }
1162
  /* ICC spaces have the default decode arrays pickled into them.
1163
   * For most spaces this is fine, because [ 0 1 0 1 0 1 ] is
1164
   * idempotent. For Lab, however, we need to adjust it. */
1165
36.7k
  if (fz_colorspace_is_lab_icc(ctx, colorspace))
1166
8
  {
1167
    /* Undo the default decode array of [0 100 -128 127 -128 127] */
1168
8
    image->decode[0] = image->decode[0]/100.0f;
1169
8
    image->decode[1] = image->decode[1]/100.0f;
1170
8
    image->decode[2] = (image->decode[2]+128)/255.0f;
1171
8
    image->decode[3] = (image->decode[3]+128)/255.0f;
1172
8
    image->decode[4] = (image->decode[4]+128)/255.0f;
1173
8
    image->decode[5] = (image->decode[5]+128)/255.0f;
1174
8
  }
1175
62.2k
  for (i = 0; i < image->n; i++)
1176
44.5k
  {
1177
44.5k
    if (image->decode[i * 2] != 0 || image->decode[i * 2 + 1] != 1)
1178
19.0k
      break;
1179
44.5k
  }
1180
36.7k
  if (i != image->n)
1181
19.0k
    image->use_decode = 1;
1182
36.7k
  image->mask = fz_keep_image(ctx, mask);
1183
1184
36.7k
  return image;
1185
36.7k
}
1186
1187
static size_t
1188
compressed_image_get_size(fz_context *ctx, fz_image *image)
1189
2.88k
{
1190
2.88k
  fz_compressed_image *im = (fz_compressed_image *)image;
1191
1192
2.88k
  if (image == NULL)
1193
0
    return 0;
1194
1195
2.88k
  return sizeof(fz_pixmap_image) + (im->buffer && im->buffer->buffer ? im->buffer->buffer->cap : 0);
1196
2.88k
}
1197
1198
fz_image *
1199
fz_new_image_from_compressed_buffer(fz_context *ctx, int w, int h,
1200
  int bpc, fz_colorspace *colorspace,
1201
  int xres, int yres, int interpolate, int imagemask, const float *decode,
1202
  const int *colorkey, fz_compressed_buffer *buffer, fz_image *mask)
1203
36.3k
{
1204
36.3k
  fz_compressed_image *image;
1205
1206
72.7k
  fz_try(ctx)
1207
72.7k
  {
1208
36.3k
    image = fz_new_derived_image(ctx, w, h, bpc,
1209
36.3k
          colorspace, xres, yres,
1210
36.3k
          interpolate, imagemask, decode,
1211
36.3k
          colorkey, mask, fz_compressed_image,
1212
36.3k
          compressed_image_get_pixmap,
1213
36.3k
          compressed_image_get_size,
1214
36.3k
          drop_compressed_image);
1215
36.3k
    image->buffer = buffer;
1216
36.3k
  }
1217
72.7k
  fz_catch(ctx)
1218
0
  {
1219
0
    fz_drop_compressed_buffer(ctx, buffer);
1220
0
    fz_rethrow(ctx);
1221
0
  }
1222
1223
36.3k
  return &image->super;
1224
36.3k
}
1225
1226
fz_compressed_buffer *fz_compressed_image_buffer(fz_context *ctx, fz_image *image)
1227
0
{
1228
0
  if (image == NULL || image->get_pixmap != compressed_image_get_pixmap)
1229
0
    return NULL;
1230
0
  return ((fz_compressed_image *)image)->buffer;
1231
0
}
1232
1233
void fz_set_compressed_image_buffer(fz_context *ctx, fz_compressed_image *image, fz_compressed_buffer *buf)
1234
30.6k
{
1235
30.6k
  assert(image != NULL && image->super.get_pixmap == compressed_image_get_pixmap);
1236
30.6k
  ((fz_compressed_image *)image)->buffer = buf; /* Note: compressed buffers are not reference counted */
1237
30.6k
}
1238
1239
fz_pixmap *fz_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *image)
1240
13
{
1241
13
  if (image == NULL || image->super.get_pixmap != pixmap_image_get_pixmap)
1242
0
    return NULL;
1243
13
  return ((fz_pixmap_image *)image)->tile;
1244
13
}
1245
1246
void fz_set_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *image, fz_pixmap *pix)
1247
13
{
1248
13
  assert(image != NULL && image->super.get_pixmap == pixmap_image_get_pixmap);
1249
13
  ((fz_pixmap_image *)image)->tile = pix;
1250
13
}
1251
1252
const char *
1253
fz_image_type_name(int type)
1254
0
{
1255
0
  switch (type)
1256
0
  {
1257
0
  default:
1258
0
  case FZ_IMAGE_UNKNOWN: return "unknown";
1259
0
  case FZ_IMAGE_RAW: return "raw";
1260
0
  case FZ_IMAGE_FAX: return "fax";
1261
0
  case FZ_IMAGE_FLATE: return "flate";
1262
0
  case FZ_IMAGE_LZW: return "lzw";
1263
0
  case FZ_IMAGE_RLD: return "rld";
1264
0
  case FZ_IMAGE_BMP: return "bmp";
1265
0
  case FZ_IMAGE_GIF: return "gif";
1266
0
  case FZ_IMAGE_JBIG2: return "jbig2";
1267
0
  case FZ_IMAGE_JPEG: return "jpeg";
1268
0
  case FZ_IMAGE_JPX: return "jpx";
1269
0
  case FZ_IMAGE_JXR: return "jxr";
1270
0
  case FZ_IMAGE_PNG: return "png";
1271
0
  case FZ_IMAGE_PNM: return "pnm";
1272
0
  case FZ_IMAGE_TIFF: return "tiff";
1273
0
  }
1274
0
}
1275
1276
int
1277
fz_lookup_image_type(const char *type)
1278
0
{
1279
0
  if (type == NULL) return FZ_IMAGE_UNKNOWN;
1280
0
  if (!strcmp(type, "raw")) return FZ_IMAGE_RAW;
1281
0
  if (!strcmp(type, "fax")) return FZ_IMAGE_FAX;
1282
0
  if (!strcmp(type, "flate")) return FZ_IMAGE_FLATE;
1283
0
  if (!strcmp(type, "lzw")) return FZ_IMAGE_LZW;
1284
0
  if (!strcmp(type, "rld")) return FZ_IMAGE_RLD;
1285
0
  if (!strcmp(type, "bmp")) return FZ_IMAGE_BMP;
1286
0
  if (!strcmp(type, "gif")) return FZ_IMAGE_GIF;
1287
0
  if (!strcmp(type, "jbig2")) return FZ_IMAGE_JBIG2;
1288
0
  if (!strcmp(type, "jpeg")) return FZ_IMAGE_JPEG;
1289
0
  if (!strcmp(type, "jpx")) return FZ_IMAGE_JPX;
1290
0
  if (!strcmp(type, "jxr")) return FZ_IMAGE_JXR;
1291
0
  if (!strcmp(type, "png")) return FZ_IMAGE_PNG;
1292
0
  if (!strcmp(type, "pnm")) return FZ_IMAGE_PNM;
1293
0
  if (!strcmp(type, "tiff")) return FZ_IMAGE_TIFF;
1294
0
  return FZ_IMAGE_UNKNOWN;
1295
0
}
1296
1297
int
1298
fz_recognize_image_format(fz_context *ctx, unsigned char p[8])
1299
21.3k
{
1300
21.3k
  if (p[0] == 'P' && p[1] >= '1' && p[1] <= '7')
1301
809
    return FZ_IMAGE_PNM;
1302
20.5k
  if (p[0] == 'P' && (p[1] == 'F' || p[1] == 'f'))
1303
10
    return FZ_IMAGE_PNM;
1304
20.5k
  if (p[0] == 0xff && p[1] == 0x4f)
1305
3.95k
    return FZ_IMAGE_JPX;
1306
16.5k
  if (p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x0c &&
1307
16.5k
      p[4] == 0x6a && p[5] == 0x50 && p[6] == 0x20 && p[7] == 0x20)
1308
236
    return FZ_IMAGE_JPX;
1309
16.3k
  if (p[0] == 0xff && p[1] == 0xd8)
1310
3.50k
    return FZ_IMAGE_JPEG;
1311
12.8k
  if (p[0] == 137 && p[1] == 80 && p[2] == 78 && p[3] == 71 &&
1312
12.8k
      p[4] == 13 && p[5] == 10 && p[6] == 26 && p[7] == 10)
1313
1.02k
    return FZ_IMAGE_PNG;
1314
11.8k
  if (p[0] == 'I' && p[1] == 'I' && p[2] == 0xBC)
1315
0
    return FZ_IMAGE_JXR;
1316
11.8k
  if (p[0] == 'I' && p[1] == 'I' && p[2] == 42 && p[3] == 0)
1317
651
    return FZ_IMAGE_TIFF;
1318
11.1k
  if (p[0] == 'M' && p[1] == 'M' && p[2] == 0 && p[3] == 42)
1319
90
    return FZ_IMAGE_TIFF;
1320
11.0k
  if (p[0] == 'G' && p[1] == 'I' && p[2] == 'F')
1321
686
    return FZ_IMAGE_GIF;
1322
10.4k
  if (p[0] == 'B' && p[1] == 'M')
1323
724
    return FZ_IMAGE_BMP;
1324
9.67k
  if (p[0] == 'B' && p[1] == 'A')
1325
18
    return FZ_IMAGE_BMP;
1326
9.65k
  if (p[0] == 0x97 && p[1] == 'J' && p[2] == 'B' && p[3] == '2' &&
1327
9.65k
    p[4] == '\r' && p[5] == '\n'  && p[6] == 0x1a && p[7] == '\n')
1328
59
    return FZ_IMAGE_JBIG2;
1329
9.59k
  if (p[0] == '8' && p[1] == 'B' && p[2] == 'P' && p[3] == 'S')
1330
162
    return FZ_IMAGE_PSD;
1331
9.43k
  return FZ_IMAGE_UNKNOWN;
1332
9.59k
}
1333
1334
fz_image *
1335
fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer)
1336
2.55k
{
1337
2.55k
  fz_compressed_buffer *bc;
1338
2.55k
  int w, h, xres, yres;
1339
2.55k
  fz_colorspace *cspace;
1340
2.55k
  size_t len = buffer->len;
1341
2.55k
  unsigned char *buf = buffer->data;
1342
2.55k
  fz_image *image = NULL;
1343
2.55k
  int type;
1344
2.55k
  int bpc;
1345
2.55k
  uint8_t orientation = 0;
1346
1347
2.55k
  if (len < 8)
1348
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unknown image file format");
1349
1350
2.55k
  type = fz_recognize_image_format(ctx, buf);
1351
2.55k
  bpc = 8;
1352
2.55k
  switch (type)
1353
2.55k
  {
1354
0
  case FZ_IMAGE_PNM:
1355
0
    fz_load_pnm_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1356
0
    break;
1357
1.23k
  case FZ_IMAGE_JPX:
1358
1.23k
    fz_load_jpx_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1359
1.23k
    break;
1360
1.01k
  case FZ_IMAGE_JPEG:
1361
1.01k
    fz_load_jpeg_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace, &orientation);
1362
1.01k
    break;
1363
198
  case FZ_IMAGE_PNG:
1364
198
    fz_load_png_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1365
198
    break;
1366
43
  case FZ_IMAGE_PSD:
1367
43
    fz_load_psd_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1368
43
    break;
1369
0
  case FZ_IMAGE_JXR:
1370
0
    fz_load_jxr_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1371
0
    break;
1372
0
  case FZ_IMAGE_TIFF:
1373
0
    fz_load_tiff_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1374
0
    break;
1375
60
  case FZ_IMAGE_GIF:
1376
60
    fz_load_gif_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1377
60
    break;
1378
0
  case FZ_IMAGE_BMP:
1379
0
    fz_load_bmp_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1380
0
    break;
1381
0
  case FZ_IMAGE_JBIG2:
1382
0
    fz_load_jbig2_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace);
1383
0
    bpc = 1;
1384
0
    break;
1385
0
  default:
1386
0
    fz_throw(ctx, FZ_ERROR_FORMAT, "unknown image file format");
1387
2.55k
  }
1388
1389
3.19k
  fz_try(ctx)
1390
3.19k
  {
1391
1.59k
    bc = fz_new_compressed_buffer(ctx);
1392
1.59k
    bc->buffer = fz_keep_buffer(ctx, buffer);
1393
1.59k
    bc->params.type = type;
1394
1.59k
    if (type == FZ_IMAGE_JPEG)
1395
819
    {
1396
819
      bc->params.u.jpeg.color_transform = -1;
1397
819
      bc->params.u.jpeg.invert_cmyk = 1;
1398
819
    }
1399
1.59k
    image = fz_new_image_from_compressed_buffer(ctx, w, h, bpc, cspace, xres, yres, 0, 0, NULL, NULL, bc, NULL);
1400
1.59k
    image->orientation = orientation;
1401
1.59k
  }
1402
3.19k
  fz_always(ctx)
1403
1.59k
    fz_drop_colorspace(ctx, cspace);
1404
1.59k
  fz_catch(ctx)
1405
0
    fz_rethrow(ctx);
1406
1407
1.59k
  return image;
1408
1.59k
}
1409
1410
int
1411
fz_compressed_image_type(fz_context *ctx, fz_image *image)
1412
0
{
1413
0
  fz_compressed_image *cim;
1414
1415
0
  if (image == NULL || image->drop_image != drop_compressed_image)
1416
0
    return FZ_IMAGE_UNKNOWN;
1417
1418
0
  cim = (fz_compressed_image *)image;
1419
1420
0
  return cim->buffer->params.type;
1421
0
}
1422
1423
fz_image *
1424
fz_new_image_from_file(fz_context *ctx, const char *path)
1425
0
{
1426
0
  fz_buffer *buffer;
1427
0
  fz_image *image = NULL;
1428
1429
0
  buffer = fz_read_file(ctx, path);
1430
0
  fz_try(ctx)
1431
0
    image = fz_new_image_from_buffer(ctx, buffer);
1432
0
  fz_always(ctx)
1433
0
    fz_drop_buffer(ctx, buffer);
1434
0
  fz_catch(ctx)
1435
0
    fz_rethrow(ctx);
1436
1437
0
  return image;
1438
0
}
1439
1440
void
1441
fz_image_resolution(fz_image *image, int *xres, int *yres)
1442
3.90k
{
1443
3.90k
  *xres = image->xres;
1444
3.90k
  *yres = image->yres;
1445
3.90k
  if (*xres < 0 || *yres < 0 || (*xres == 0 && *yres == 0))
1446
42
  {
1447
    /* If neither xres or yres is sane, pick a sane value */
1448
42
    *xres = SANE_DPI; *yres = SANE_DPI;
1449
42
  }
1450
3.86k
  else if (*xres == 0)
1451
20
  {
1452
20
    *xres = *yres;
1453
20
  }
1454
3.84k
  else if (*yres == 0)
1455
16
  {
1456
16
    *yres = *xres;
1457
16
  }
1458
1459
  /* Scale xres and yres up until we get believable values */
1460
3.90k
  if (*xres < SANE_DPI || *yres < SANE_DPI || *xres > INSANE_DPI || *yres > INSANE_DPI)
1461
458
  {
1462
458
    if (*xres < *yres)
1463
116
    {
1464
116
      *yres = *yres * SANE_DPI / *xres;
1465
116
      *xres = SANE_DPI;
1466
116
    }
1467
342
    else
1468
342
    {
1469
342
      *xres = *xres * SANE_DPI / *yres;
1470
342
      *yres = SANE_DPI;
1471
342
    }
1472
1473
458
    if (*xres == *yres || *xres < SANE_DPI || *yres < SANE_DPI || *xres > INSANE_DPI || *yres > INSANE_DPI)
1474
196
    {
1475
196
      *xres = SANE_DPI;
1476
196
      *yres = SANE_DPI;
1477
196
    }
1478
458
  }
1479
3.90k
}
1480
1481
uint8_t fz_image_orientation(fz_context *ctx, fz_image *image)
1482
3.90k
{
1483
3.90k
  return image ? image->orientation : 0;
1484
3.90k
}
1485
1486
fz_matrix fz_image_orientation_matrix(fz_context *ctx, fz_image *image)
1487
1.94k
{
1488
1.94k
  fz_matrix m;
1489
1490
1.94k
  switch (image ? image->orientation : 0)
1491
1.94k
  {
1492
1.93k
  case 0:
1493
1.94k
  case 1: /* 0 degree rotation */
1494
1.94k
    m.a =  1; m.b =  0;
1495
1.94k
    m.c =  0; m.d =  1;
1496
1.94k
    m.e =  0; m.f =  0;
1497
1.94k
    break;
1498
1
  case 2: /* 90 degree ccw */
1499
1
    m.a =  0; m.b = -1;
1500
1
    m.c =  1; m.d =  0;
1501
1
    m.e =  0; m.f =  1;
1502
1
    break;
1503
1
  case 3: /* 180 degree ccw */
1504
1
    m.a = -1; m.b =  0;
1505
1
    m.c =  0; m.d = -1;
1506
1
    m.e =  1; m.f =  1;
1507
1
    break;
1508
0
  case 4: /* 270 degree ccw */
1509
0
    m.a =  0; m.b =  1;
1510
0
    m.c = -1; m.d =  0;
1511
0
    m.e =  1; m.f =  0;
1512
0
    break;
1513
0
  case 5: /* flip on X */
1514
0
    m.a = -1; m.b = 0;
1515
0
    m.c =  0; m.d = 1;
1516
0
    m.e =  1; m.f = 0;
1517
0
    break;
1518
0
  case 6: /* flip on X, then rotate ccw by 90 degrees */
1519
0
    m.a =  0; m.b =  1;
1520
0
    m.c =  1; m.d =  0;
1521
0
    m.e =  0; m.f =  0;
1522
0
    break;
1523
0
  case 7: /* flip on X, then rotate ccw by 180 degrees */
1524
0
    m.a =  1; m.b =  0;
1525
0
    m.c =  0; m.d = -1;
1526
0
    m.e =  0; m.f =  1;
1527
0
    break;
1528
0
  case 8: /* flip on X, then rotate ccw by 270 degrees */
1529
0
    m.a =  0; m.b = -1;
1530
0
    m.c = -1; m.d =  0;
1531
0
    m.e =  1; m.f =  1;
1532
0
    break;
1533
1.94k
  }
1534
1535
1.94k
  return m;
1536
1.94k
}
1537
1538
typedef struct fz_display_list_image_s
1539
{
1540
  fz_image super;
1541
  fz_matrix transform;
1542
  fz_display_list *list;
1543
} fz_display_list_image;
1544
1545
static fz_pixmap *
1546
display_list_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea, int w, int h, int *l2factor)
1547
0
{
1548
0
  fz_display_list_image *image = (fz_display_list_image *)image_;
1549
0
  fz_matrix ctm;
1550
0
  fz_device *dev;
1551
0
  fz_pixmap *pix;
1552
1553
0
  fz_var(dev);
1554
1555
0
  if (subarea)
1556
0
  {
1557
    /* So, the whole image should be scaled to w * h, but we only want the
1558
     * given subarea of it. */
1559
0
    int l = (subarea->x0 * w) / image->super.w;
1560
0
    int t = (subarea->y0 * h) / image->super.h;
1561
0
    int r = (subarea->x1 * w + image->super.w - 1) / image->super.w;
1562
0
    int b = (subarea->y1 * h + image->super.h - 1) / image->super.h;
1563
1564
0
    pix = fz_new_pixmap(ctx, image->super.colorspace, r-l, b-t, NULL, 0);
1565
0
    pix->x = l;
1566
0
    pix->y = t;
1567
0
  }
1568
0
  else
1569
0
  {
1570
0
    pix = fz_new_pixmap(ctx, image->super.colorspace, w, h, NULL, 0);
1571
0
  }
1572
1573
  /* If we render the display list into pix with the image matrix, we'll get a unit
1574
   * square result. Therefore scale by w, h. */
1575
0
  ctm = fz_pre_scale(image->transform, w, h);
1576
1577
0
  fz_clear_pixmap(ctx, pix); /* clear to transparent */
1578
0
  fz_try(ctx)
1579
0
  {
1580
0
    dev = fz_new_draw_device(ctx, ctm, pix);
1581
0
    fz_run_display_list(ctx, image->list, dev, fz_identity, fz_infinite_rect, NULL);
1582
0
    fz_close_device(ctx, dev);
1583
0
  }
1584
0
  fz_always(ctx)
1585
0
    fz_drop_device(ctx, dev);
1586
0
  fz_catch(ctx)
1587
0
  {
1588
0
    fz_drop_pixmap(ctx, pix);
1589
0
    fz_rethrow(ctx);
1590
0
  }
1591
1592
  /* Never do more subsampling, cos we've already given them the right size */
1593
0
  if (l2factor)
1594
0
    *l2factor = 0;
1595
1596
0
  return pix;
1597
0
}
1598
1599
static void drop_display_list_image(fz_context *ctx, fz_image *image_)
1600
0
{
1601
0
  fz_display_list_image *image = (fz_display_list_image *)image_;
1602
1603
0
  if (image == NULL)
1604
0
    return;
1605
0
  fz_drop_display_list(ctx, image->list);
1606
0
}
1607
1608
static size_t
1609
display_list_image_get_size(fz_context *ctx, fz_image *image_)
1610
0
{
1611
0
  fz_display_list_image *image = (fz_display_list_image *)image_;
1612
1613
0
  if (image == NULL)
1614
0
    return 0;
1615
1616
0
  return sizeof(fz_display_list_image) + 4096; /* FIXME */
1617
0
}
1618
1619
fz_image *fz_new_image_from_display_list(fz_context *ctx, float w, float h, fz_display_list *list)
1620
0
{
1621
0
  fz_display_list_image *image;
1622
0
  int iw, ih;
1623
1624
0
  iw = w * SCALABLE_IMAGE_DPI / 72;
1625
0
  ih = h * SCALABLE_IMAGE_DPI / 72;
1626
1627
0
  image = fz_new_derived_image(ctx, iw, ih, 8, fz_device_rgb(ctx),
1628
0
        SCALABLE_IMAGE_DPI, SCALABLE_IMAGE_DPI, 0, 0,
1629
0
        NULL, NULL, NULL, fz_display_list_image,
1630
0
        display_list_image_get_pixmap,
1631
0
        display_list_image_get_size,
1632
0
        drop_display_list_image);
1633
0
  image->super.scalable = 1;
1634
0
  image->transform = fz_scale(1 / w, 1 / h);
1635
0
  image->list = fz_keep_display_list(ctx, list);
1636
1637
0
  return &image->super;
1638
0
}