summaryrefslogtreecommitdiff
path: root/source/fitz/load-tiff.c
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2016-09-27 21:58:34 +0800
committerSebastian Rasmussen <sebras@gmail.com>2016-09-28 00:11:23 +0800
commit2738bc06e489a17be6fe6d560b6a70b6c51f6572 (patch)
tree5f74f9d30f4fcf3a54fe50eb8c74502aa5ebb989 /source/fitz/load-tiff.c
parentc8b6591643d341f729de073c468ce1f27e178a9e (diff)
downloadmupdf-2738bc06e489a17be6fe6d560b6a70b6c51f6572.tar.xz
tiff: Do error handling for decoders in a single place.
Diffstat (limited to 'source/fitz/load-tiff.c')
-rw-r--r--source/fitz/load-tiff.c236
1 files changed, 103 insertions, 133 deletions
diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c
index 7bf0d163..8651c2c0 100644
--- a/source/fitz/load-tiff.c
+++ b/source/fitz/load-tiff.c
@@ -147,108 +147,69 @@ static const unsigned char bitrev[256] =
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
-static size_t
-fz_decode_tiff_uncompressed(fz_context *ctx, struct tiff *tiff, fz_stream *stm, unsigned char *wp, int wlen)
+static fz_stream *
+fz_open_tiff_fax(fz_context *ctx, struct tiff *tiff, fz_stream *chain, int comp)
{
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
-}
-
-static size_t
-fz_decode_tiff_packbits(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen)
-{
- fz_stream *stm = fz_open_rld(ctx, chain);
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ int black_is_1 = tiff->photometric == 0;
+ int k = comp == 4 ? -1 : 0;
+ int encoded_byte_align = comp == 2;
+ return fz_open_faxd(ctx, chain,
+ k, 0, encoded_byte_align,
+ tiff->imagewidth, tiff->imagelength, 0, black_is_1);
}
-static size_t
-fz_decode_tiff_sgilog16(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int w)
+static fz_stream *
+fz_open_tiff_lzw(fz_context *ctx, struct tiff *tiff, fz_stream *chain, int old_tiff)
{
- fz_stream *stm = fz_open_sgilog16(ctx, chain, w);
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ return fz_open_lzwd(ctx, chain, old_tiff ? 0 : 1, 9, old_tiff ? 1 : 0, old_tiff);
}
-static size_t
-fz_decode_tiff_sgilog24(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int w)
+static fz_stream *
+fz_open_tiff_jpeg(fz_context *ctx, struct tiff *tiff, fz_stream *chain)
{
- fz_stream *stm = fz_open_sgilog24(ctx, chain, w);
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ fz_stream *jpegtables = NULL;
+ int color_transform = -1; /* unset */
+ if (tiff->jpegtables && (int)tiff->jpegtableslen > 0)
+ jpegtables = fz_open_memory(ctx, tiff->jpegtables, tiff->jpegtableslen);
+ if (tiff->photometric == 2 /* RGB */ || tiff->photometric == 3 /* RGBPal */)
+ color_transform = 0;
+ return fz_open_dctd(ctx, chain, color_transform, 0, jpegtables);
}
-static size_t
-fz_decode_tiff_thunder(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int w)
+static fz_stream *
+fz_open_tiff_flate(fz_context *ctx, struct tiff *tiff, fz_stream *chain)
{
- fz_stream *stm = fz_open_thunder(ctx, chain, w);
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ return fz_open_flated(ctx, chain, 15);
}
-static size_t
-fz_decode_tiff_sgilog32(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int w)
+static fz_stream *
+fz_open_tiff_packbits(fz_context *ctx, struct tiff *tiff, fz_stream *chain)
{
- fz_stream *stm = fz_open_sgilog32(ctx, chain, w);
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ return fz_open_rld(ctx, chain);
}
-static size_t
-fz_decode_tiff_lzw(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int old_tiff)
+static fz_stream *
+fz_open_tiff_sgilog32(fz_context *ctx, struct tiff *tiff, fz_stream *chain, int w)
{
- fz_stream *stm = fz_open_lzwd(ctx, chain, old_tiff ? 0 : 1, 9, old_tiff ? 1 : 0, old_tiff);
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ return fz_open_sgilog32(ctx, chain, w);
}
-static size_t
-fz_decode_tiff_flate(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen)
+static fz_stream *
+fz_open_tiff_sgilog16(fz_context *ctx, struct tiff *tiff, fz_stream *chain, int w)
{
- fz_stream *stm = fz_open_flated(ctx, chain, 15);
- size_t size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ return fz_open_sgilog16(ctx, chain, w);
}
-static size_t
-fz_decode_tiff_fax(fz_context *ctx, struct tiff *tiff, int comp, fz_stream *chain, unsigned char *wp, int wlen)
+static fz_stream *
+fz_open_tiff_sgilog24(fz_context *ctx, struct tiff *tiff, fz_stream *chain, int w)
{
- fz_stream *stm;
- size_t size;
- int black_is_1 = tiff->photometric == 0;
- int k = comp == 4 ? -1 : 0;
- int encoded_byte_align = comp == 2;
- stm = fz_open_faxd(ctx, chain,
- k, 0, encoded_byte_align,
- tiff->imagewidth, tiff->imagelength, 0, black_is_1);
- size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ return fz_open_sgilog24(ctx, chain, w);
}
-static size_t
-fz_decode_tiff_jpeg(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen)
+static fz_stream *
+fz_open_tiff_thunder(fz_context *ctx, struct tiff *tiff, fz_stream *chain, int w)
{
- fz_stream *stm;
- size_t size;
- fz_stream *jpegtables = NULL;
- int color_transform = -1; /* unset */
- if (tiff->jpegtables && (int)tiff->jpegtableslen > 0)
- jpegtables = fz_open_memory(ctx, tiff->jpegtables, tiff->jpegtableslen);
- if (tiff->photometric == 2 /* RGB */ || tiff->photometric == 3 /* RGBPal */)
- color_transform = 0;
- stm = fz_open_dctd(ctx, chain, color_transform, 0, jpegtables);
- size = fz_read(ctx, stm, wp, wlen);
- fz_drop_stream(ctx, stm);
- return size;
+ return fz_open_thunder(ctx, chain, w);
}
static inline int getcomp(unsigned char *line, int x, int bpc)
@@ -401,68 +362,77 @@ fz_decode_tiff_chunk(fz_context *ctx, struct tiff *tiff, unsigned char *rp, unsi
for (i = 0; i < rlen; i++)
rp[i] = bitrev[rp[i]];
- /* each decoder will close this */
- /* FIXME: what if tiff->compression is invalid? what if fz_read() in the strip decoders throws? */
- stm = fz_open_memory(ctx, rp, rlen);
+ fz_try(ctx)
+ {
+ /* each decoder will close this */
+ stm = fz_open_memory(ctx, rp, rlen);
- /* switch on compression to create a filter */
- /* feed each chunk (strip or tile) to the filter */
- /* read out the data into a buffer */
- /* the level above packs the chunk's samples into a pixmap */
+ /* switch on compression to create a filter */
+ /* feed each chunk (strip or tile) to the filter */
+ /* read out the data into a buffer */
+ /* the level above packs the chunk's samples into a pixmap */
- /* type 32773 / packbits -- nothing special (same row-padding as PDF) */
- /* type 2 / ccitt rle -- no EOL, no RTC, rows are byte-aligned */
- /* type 3 and 4 / g3 and g4 -- each strip starts new section */
- /* type 5 / lzw -- each strip is handled separately */
+ /* type 32773 / packbits -- nothing special (same row-padding as PDF) */
+ /* type 2 / ccitt rle -- no EOL, no RTC, rows are byte-aligned */
+ /* type 3 and 4 / g3 and g4 -- each strip starts new section */
+ /* type 5 / lzw -- each strip is handled separately */
+
+ switch (tiff->compression)
+ {
+ case 1:
+ /* stm already open and reading uncompressed data */
+ break;
+ case 2:
+ stm = fz_open_tiff_fax(ctx, tiff, stm, 2);
+ break;
+ case 3:
+ stm = fz_open_tiff_fax(ctx, tiff, stm, 3);
+ break;
+ case 4:
+ stm = fz_open_tiff_fax(ctx, tiff, stm, 4);
+ break;
+ case 5:
+ stm = fz_open_tiff_lzw(ctx, tiff, stm, (rp[0] == 0 && rp[1] & 1));
+ break;
+ case 6:
+ fz_warn(ctx, "deprecated JPEG in TIFF compression not fully supported");
+ /* fall through */
+ case 7:
+ stm = fz_open_tiff_jpeg(ctx, tiff, stm);
+ break;
+ case 8:
+ case 32946:
+ stm = fz_open_tiff_flate(ctx, tiff, stm);
+ break;
+ case 32773:
+ stm = fz_open_tiff_packbits(ctx, tiff, stm);
+ break;
+ case 34676:
+ if (tiff->photometric == 32845)
+ stm = fz_open_tiff_sgilog32(ctx, tiff, stm, tiff->imagewidth);
+ else
+ stm = fz_open_tiff_sgilog16(ctx, tiff, stm, tiff->imagewidth);
+ break;
+ case 34677:
+ stm = fz_open_tiff_sgilog24(ctx, tiff, stm, tiff->imagewidth);
+ break;
+ case 32809:
+ if (tiff->bitspersample != 4)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "invalid bits per pixel in thunder encoding");
+ stm = fz_open_tiff_thunder(ctx, tiff, stm, tiff->imagewidth);
+ break;
+ default:
+ fz_throw(ctx, FZ_ERROR_GENERIC, "unknown TIFF compression: %d", tiff->compression);
+ }
- switch (tiff->compression)
+ size = fz_read(ctx, stm, wp, wlen);
+ }
+ fz_always(ctx)
{
- case 1:
- size = fz_decode_tiff_uncompressed(ctx, tiff, stm, wp, wlen);
- break;
- case 2:
- size = fz_decode_tiff_fax(ctx, tiff, 2, stm, wp, wlen);
- break;
- case 3:
- size = fz_decode_tiff_fax(ctx, tiff, 3, stm, wp, wlen);
- break;
- case 4:
- size = fz_decode_tiff_fax(ctx, tiff, 4, stm, wp, wlen);
- break;
- case 5:
- size = fz_decode_tiff_lzw(ctx, tiff, stm, wp, wlen, (rp[0] == 0 && rp[1] & 1));
- break;
- case 6:
- fz_warn(ctx, "deprecated JPEG in TIFF compression not fully supported");
- /* fall through */
- case 7:
- size = fz_decode_tiff_jpeg(ctx, tiff, stm, wp, wlen);
- break;
- case 8:
- case 32946:
- size = fz_decode_tiff_flate(ctx, tiff, stm, wp, wlen);
- break;
- case 32773:
- size = fz_decode_tiff_packbits(ctx, tiff, stm, wp, wlen);
- break;
- case 34676:
- if (tiff->photometric == 32845)
- size = fz_decode_tiff_sgilog32(ctx, tiff, stm, wp, wlen, tiff->imagewidth);
- else
- size = fz_decode_tiff_sgilog16(ctx, tiff, stm, wp, wlen, tiff->imagewidth);
- break;
- case 34677:
- size = fz_decode_tiff_sgilog24(ctx, tiff, stm, wp, wlen, tiff->imagewidth);
- break;
- case 32809:
- if (tiff->bitspersample != 4)
- fz_throw(ctx, FZ_ERROR_GENERIC, "invalid bits per pixel in thunder encoding");
- size = fz_decode_tiff_thunder(ctx, tiff, stm, wp, wlen, tiff->imagewidth);
- break;
- default:
fz_drop_stream(ctx, stm);
- fz_throw(ctx, FZ_ERROR_GENERIC, "unknown TIFF compression: %d", tiff->compression);
}
+ fz_catch(ctx)
+ fz_rethrow(ctx);
/* scramble the bits back into original order */
if (tiff->fillorder == 2)