Coverage Report

Created: 2023-06-07 06:20

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