static fz_error pdf_readstartxref(pdf_xref *xref) { unsigned char buf[1024]; int t, n; int i; fz_seek(xref->file, 0, 2); xref->filesize = fz_tell(xref->file); t = MAX(0, xref->filesize - (int)sizeof buf); fz_seek(xref->file, t, 0); n = fz_read(xref->file, buf, sizeof buf); if (n < 0) return fz_rethrow(n, "cannot read from file"); for (i = n - 9; i >= 0; i--) { if (memcmp(buf + i, "startxref", 9) == 0) { i += 9; while (iswhite(buf[i]) && i < n) i ++; xref->startxref = atoi((char*)(buf + i)); pdf_logxref("startxref %d\n", xref->startxref); return fz_okay; } } return fz_throw("cannot find startxref"); }
static void fz_decode_tiff_flate(struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen) { fz_stream *stm = fz_open_flated(chain); fz_read(stm, wp, wlen); fz_close(stm); }
static void showstream(int num, int gen) { fz_error error; fz_stream *stm; unsigned char buf[2048]; int n; showcolumn = 0; if (showdecode) error = pdf_openstream(&stm, xref, num, gen); else error = pdf_openrawstream(&stm, xref, num, gen); if (error) die(error); while (1) { error = fz_read(&n, stm, buf, sizeof buf); if (error) die(error); if (n == 0) break; if (showbinary) fwrite(buf, 1, n, stdout); else showsafe(buf, n); } fz_dropstream(stm); }
static fz_error readstartxref(pdf_xref *xref) { fz_error error; unsigned char buf[1024]; int t, n; int i; error = fz_seek(xref->file, 0, 2); if (error) return fz_rethrow(error, "cannot seek to end of file"); t = MAX(0, fz_tell(xref->file) - ((int)sizeof buf)); error = fz_seek(xref->file, t, 0); if (error) return fz_rethrow(error, "cannot seek to offset %d", t); error = fz_read(&n, xref->file, buf, sizeof buf); if (error) return fz_rethrow(error, "cannot read from file"); for (i = n - 9; i >= 0; i--) { if (memcmp(buf + i, "startxref", 9) == 0) { i += 9; while (iswhite(buf[i]) && i < n) i ++; xref->startxref = atoi((char*)(buf + i)); return fz_okay; } } return fz_throw("cannot find startxref"); }
static void fz_decode_tiff_flate(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen) { fz_stream *stm = fz_open_flated(ctx, chain, 15); fz_read(ctx, stm, wp, wlen); fz_drop_stream(ctx, stm); }
static int xps_find_and_read_zip_dir(xps_context *ctx) { unsigned char buf[512]; int file_size, back, maxback; int i, n; fz_seek(ctx->file, 0, SEEK_END); file_size = fz_tell(ctx->file); maxback = MIN(file_size, 0xFFFF + sizeof buf); back = MIN(maxback, sizeof buf); while (back < maxback) { fz_seek(ctx->file, file_size - back, 0); n = fz_read(ctx->file, buf, sizeof buf); if (n < 0) return fz_error_make(ctx->ctx, "cannot read end of central directory"); for (i = n - 4; i > 0; i--) if (!memcmp(buf + i, "PK\5\6", 4)) return xps_read_zip_dir(ctx, file_size - back + i); back += sizeof buf - 4; } return fz_error_make(ctx->ctx, "cannot find end of central directory"); }
static fz_colorspace * load_indexed(pdf_document *doc, pdf_obj *array) { fz_context *ctx = doc->ctx; pdf_obj *baseobj = pdf_array_get(array, 1); pdf_obj *highobj = pdf_array_get(array, 2); pdf_obj *lookupobj = pdf_array_get(array, 3); fz_colorspace *base = NULL; fz_colorspace *cs; int i, n, high; unsigned char *lookup = NULL; fz_var(base); fz_var(lookup); fz_try(ctx) { base = pdf_load_colorspace(doc, baseobj); high = pdf_to_int(highobj); high = fz_clampi(high, 0, 255); n = base->n * (high + 1); lookup = fz_malloc_array(ctx, 1, n); if (pdf_is_string(lookupobj) && pdf_to_str_len(lookupobj) >= n) { unsigned char *buf = (unsigned char *) pdf_to_str_buf(lookupobj); for (i = 0; i < n; i++) lookup[i] = buf[i]; } else if (pdf_is_indirect(lookupobj)) { fz_stream *file = NULL; fz_var(file); fz_try(ctx) { file = pdf_open_stream(doc, pdf_to_num(lookupobj), pdf_to_gen(lookupobj)); i = fz_read(file, lookup, n); if (i < n) memset(lookup+i, 0, n-i); } fz_always(ctx) { fz_close(file); } fz_catch(ctx) { fz_rethrow_message(ctx, "cannot open colorspace lookup table (%d 0 R)", pdf_to_num(lookupobj)); } } else { fz_rethrow_message(ctx, "cannot parse colorspace lookup table"); } cs = fz_new_indexed_colorspace(ctx, base, high, lookup); }
static fz_error safe_read(fz_stream *file, char *buf, int size) { int n = fz_read(file, buf, size); if (n != size) /* covers n < 0 case */ return fz_error_make(file->ctx, "ioerror"); return fz_okay; }
static int read_null(fz_stream *stm, unsigned char *buf, int len) { struct null_filter *state = stm->state; int amount = MIN(len, state->remain); int n = fz_read(state->chain, buf, amount); state->remain -= n; return n; }
static int xps_decode_tiff_uncompressed(struct tiff *tiff, fz_stream *stm, byte *wp, int wlen) { int n = fz_read(stm, wp, wlen); fz_close(stm); if (n < 0) return fz_error_note(tiff->ctx, n, "cannot read uncompressed strip"); return fz_okay; }
fz_buffer * fz_read_best(fz_stream *stm, int initial, int *truncated) { fz_buffer *buf = NULL; int n; fz_context *ctx = stm->ctx; fz_var(buf); if (truncated) *truncated = 0; fz_try(ctx) { if (initial < 1024) initial = 1024; buf = fz_new_buffer(ctx, initial+1); while (1) { if (buf->len == buf->cap) fz_grow_buffer(ctx, buf); if (buf->len >= MIN_BOMB && buf->len / 200 > initial) { fz_throw(ctx, FZ_ERROR_GENERIC, "compression bomb detected"); } n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len); if (n == 0) break; buf->len += n; } } fz_catch(ctx) { if (fz_caught(ctx) == FZ_ERROR_TRYLATER) { fz_drop_buffer(ctx, buf); fz_rethrow(ctx); } if (truncated) { *truncated = 1; } else { fz_drop_buffer(ctx, buf); fz_rethrow(ctx); } } return buf; }
static int xps_decode_tiff_jpeg(struct tiff *tiff, fz_stream *chain, byte *wp, int wlen) { fz_stream *stm = fz_open_dctd(chain, NULL); int n = fz_read(stm, wp, wlen); fz_close(stm); if (n < 0) return fz_error_note(chain->ctx, n, "cannot read jpeg strip"); return fz_okay; }
void dump_stream(int i, FILE *fout) { fz_stream *stm = pdf_open_stream(doc, i, 0); static unsigned char buf[8192]; while (1) { int n = fz_read(stm, buf, sizeof buf); if (n == 0) break; fwrite(buf, 1, n, fout); } fz_close(stm); }
static int readnull(fz_stream *stm, unsigned char *buf, int len) { struct nullfilter *state = stm->state; int amount = MIN(len, state->remain); int n = fz_read(state->chain, buf, amount); if (n < 0) return fz_rethrow(n, "read error in null filter"); state->remain -= n; return n; }
static void fz_decode_tiff_jpeg(struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen) { fz_stream *stm; fz_stream *jpegtables = NULL; if (tiff->jpegtables && (int)tiff->jpegtableslen > 0) jpegtables = fz_open_memory(tiff->ctx, tiff->jpegtables, (int)tiff->jpegtableslen); /* cf. https://code.google.com/p/sumatrapdf/issues/detail?id=2370 */ stm = fz_open_dctd(chain, tiff->photometric != 2 && tiff->photometric != 3 ? -1 : 0, 0, jpegtables); fz_read(stm, wp, wlen); fz_close(stm); }
static void fz_decode_tiff_fax(struct tiff *tiff, int comp, fz_stream *chain, unsigned char *wp, int wlen) { fz_stream *stm; int black_is_1 = tiff->photometric == 0; int k = comp == 4 ? -1 : 0; int encoded_byte_align = comp == 2; stm = fz_open_faxd(chain, k, 0, encoded_byte_align, tiff->imagewidth, tiff->imagelength, 0, black_is_1); fz_read(stm, wp, wlen); fz_close(stm); }
static int read_null(fz_stream *stm, unsigned char *buf, int len) { struct null_filter *state = stm->state; int amount = fz_mini(len, state->remain); int n; fz_seek(state->chain, state->pos, 0); n = fz_read(state->chain, buf, amount); state->remain -= n; state->pos += n; return n; }
static void fz_decode_tiff_jpeg(struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen) { fz_stream *stm; fz_stream *jpegtables = NULL; int color_transform = -1; /* unset */ if (tiff->jpegtables && (int)tiff->jpegtableslen > 0) jpegtables = fz_open_memory(tiff->ctx, tiff->jpegtables, (int)tiff->jpegtableslen); if (tiff->photometric == 2 /* RGB */ || tiff->photometric == 3 /* RGBPal */) color_transform = 0; stm = fz_open_dctd(chain, color_transform, 0, jpegtables); fz_read(stm, wp, wlen); fz_close(stm); }
int fz_skip(fz_context *ctx, fz_stream *stm, int len) { int count, l, total = 0; while (len) { l = len; if (l > sizeof(skip_buf)) l = sizeof(skip_buf); count = fz_read(ctx, stm, skip_buf, l); total += count; if (count < l) break; len -= count; } return total; }
int read_jbig2d(fz_stream *stm, unsigned char *buf, int len) { fz_jbig2d *state = (fz_jbig2d *)stm->state; unsigned char tmp[4096]; unsigned char *p = buf; unsigned char *ep = buf + len; unsigned char *s; int x, w, n; //try{ if (!state->page) { while (1) { n = fz_read(state->chain, tmp, sizeof tmp); if (n == 0) break; jbig2_data_in(state->ctx, tmp, n); } jbig2_complete_page(state->ctx); state->page = jbig2_page_out(state->ctx); if (!state->page) return 0; //throw("jbig2_page_out failed"); } s = state->page->data; w = state->page->height * state->page->stride; x = state->idx; while (p < ep && x < w) *p++ = s[x++] ^ 0xff; state->idx = x; return p - buf; /*} catch(...){ return -1; }*/ }
fz_buffer * fz_read_all(fz_stream *stm, int initial) { fz_buffer *buf = NULL; int n; fz_context *ctx = stm->ctx; try { if (initial < 1024) initial = 1024; buf = fz_new_buffer(ctx, initial+1); while (1) { if (buf->len == buf->cap) fz_grow_buffer(ctx, buf); if (buf->len >= MIN_BOMB && buf->len / 200 > initial) { throw("compression bomb detected"); } n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len); if (n == 0) break; buf->len += n; } } catch(...) { fz_drop_buffer(ctx, buf); throw(""); } fz_trim_buffer(ctx, buf); return buf; }
static int read_concat(fz_stream *stm, unsigned char *buf, int len) { struct concat_filter *state = (struct concat_filter *)stm->state; int n; int read = 0; if (len <= 0) return 0; while (state->current != state->count && len > 0) { /* If we need to send a whitespace char, do that */ if (state->ws) { *buf++ = 32; read++; len--; state->ws = 0; continue; } /* Otherwise, read as much data as will fit in the buffer */ n = fz_read(state->chain[state->current], buf, len); read += n; buf += n; len -= n; /* If we didn't read any, then we must have hit the end of * our buffer space. Move to the next stream, and remember to * pad. */ if (n == 0) { fz_close(state->chain[state->current]); state->current++; state->ws = state->pad; } } return read; }
static int read_jbig2d(fz_stream *stm, unsigned char *buf, int len) { fz_jbig2d *state = stm->state; unsigned char tmp[4096]; unsigned char *p = buf; unsigned char *ep = buf + len; unsigned char *s; int x, w, n; if (!state->page) { while (1) { n = fz_read(state->chain, tmp, sizeof tmp); if (n < 0) return fz_rethrow(n, "read error in jbig2 filter"); if (n == 0) break; jbig2_data_in(state->ctx, tmp, n); } jbig2_complete_page(state->ctx); state->page = jbig2_page_out(state->ctx); if (!state->page) return fz_throw("jbig2_page_out failed"); } s = state->page->data; w = state->page->height * state->page->stride; x = state->idx; while (p < ep && x < w) *p++ = s[x++] ^ 0xff; state->idx = x; return p - buf; }
static int xps_decode_tiff_fax(struct tiff *tiff, int comp, fz_stream *chain, byte *wp, int wlen) { fz_stream *stm; fz_obj *params; fz_obj *columns, *rows, *black_is_1, *k, *encoded_byte_align; int n; fz_context *ctx = tiff->ctx; columns = fz_new_int(ctx, tiff->imagewidth); rows = fz_new_int(ctx, tiff->imagelength); black_is_1 = fz_new_bool(ctx, tiff->photometric == 0); k = fz_new_int(ctx, comp == 4 ? -1 : 0); encoded_byte_align = fz_new_bool(ctx, comp == 2); params = fz_new_dict(ctx, 5); fz_dict_puts(ctx, params, "Columns", columns); fz_dict_puts(ctx, params, "Rows", rows); fz_dict_puts(ctx, params, "BlackIs1", black_is_1); fz_dict_puts(ctx, params, "K", k); fz_dict_puts(ctx, params, "EncodedByteAlign", encoded_byte_align); fz_drop_obj(ctx, columns); fz_drop_obj(ctx, rows); fz_drop_obj(ctx, black_is_1); fz_drop_obj(ctx, k); fz_drop_obj(ctx, encoded_byte_align); stm = fz_open_faxd(chain, params); n = fz_read(stm, wp, wlen); fz_close(stm); fz_drop_obj(ctx, params); if (n < 0) return fz_error_note(ctx, n, "cannot read fax strip"); return fz_okay; }
static fz_pixmap * decomp_image_from_stream(fz_context *ctx, fz_stream *stm, pdf_image *image, int in_line, int indexed, int l2factor, int native_l2factor, int cache) { fz_pixmap *tile = NULL; fz_pixmap *existing_tile; int stride, len, i; unsigned char *samples = NULL; int f = 1<<native_l2factor; int w = (image->base.w + f-1) >> native_l2factor; int h = (image->base.h + f-1) >> native_l2factor; pdf_image_key *key = NULL; fz_var(tile); fz_var(samples); fz_var(key); fz_try(ctx) { tile = fz_new_pixmap(ctx, image->base.colorspace, w, h); tile->interpolate = image->interpolate; stride = (w * image->n * image->base.bpc + 7) / 8; samples = fz_malloc_array(ctx, h, stride); len = fz_read(stm, samples, h * stride); if (len < 0) { fz_throw(ctx, "cannot read image data"); } /* Make sure we read the EOF marker (for inline images only) */ if (in_line) { unsigned char tbuf[512]; fz_try(ctx) { int tlen = fz_read(stm, tbuf, sizeof tbuf); if (tlen > 0) fz_warn(ctx, "ignoring garbage at end of image"); } fz_catch(ctx) { fz_warn(ctx, "ignoring error at end of image"); } } /* Pad truncated images */ if (len < stride * h) { fz_warn(ctx, "padding truncated image"); memset(samples + len, 0, stride * h - len); } /* Invert 1-bit image masks */ if (image->imagemask) { /* 0=opaque and 1=transparent so we need to invert */ unsigned char *p = samples; len = h * stride; for (i = 0; i < len; i++) p[i] = ~p[i]; } fz_unpack_tile(tile, samples, image->n, image->base.bpc, stride, indexed); fz_free(ctx, samples); samples = NULL; if (image->usecolorkey) pdf_mask_color_key(tile, image->n, image->colorkey); if (indexed) { fz_pixmap *conv; fz_decode_indexed_tile(tile, image->decode, (1 << image->base.bpc) - 1); conv = pdf_expand_indexed_pixmap(ctx, tile); fz_drop_pixmap(ctx, tile); tile = conv; } else { fz_decode_tile(tile, image->decode); } } fz_always(ctx) { fz_close(stm); } fz_catch(ctx) { if (tile) fz_drop_pixmap(ctx, tile); fz_free(ctx, samples); fz_rethrow(ctx); } /* Now apply any extra subsampling required */ if (l2factor - native_l2factor > 0) { if (l2factor - native_l2factor > 8) l2factor = native_l2factor + 8; fz_subsample_pixmap(ctx, tile, l2factor - native_l2factor); } if (!cache) return tile; /* Now we try to cache the pixmap. Any failure here will just result * in us not caching. */ fz_try(ctx) { key = fz_malloc_struct(ctx, pdf_image_key); key->refs = 1; key->image = fz_keep_image(ctx, &image->base); key->l2factor = l2factor; existing_tile = fz_store_item(ctx, key, tile, fz_pixmap_size(ctx, tile), &pdf_image_store_type); if (existing_tile) { /* We already have a tile. This must have been produced by a * racing thread. We'll throw away ours and use that one. */ fz_drop_pixmap(ctx, tile); tile = existing_tile; } } fz_always(ctx) { pdf_drop_image_key(ctx, key); } fz_catch(ctx) { /* Do nothing */ } return tile; }
static fz_pixmap * decomp_image_from_stream(fz_context *ctx, fz_stream *stm, pdf_image *image, int in_line, int indexed, int l2factor, int native_l2factor, int cache) { fz_pixmap *tile = NULL; fz_pixmap *existing_tile; int stride, len, i; unsigned char *samples = NULL; int f = 1<<native_l2factor; int w = (image->base.w + f-1) >> native_l2factor; int h = (image->base.h + f-1) >> native_l2factor; pdf_image_key *key = NULL; fz_var(tile); fz_var(samples); fz_var(key); fz_try(ctx) { tile = fz_new_pixmap(ctx, image->base.colorspace, w, h); tile->interpolate = image->interpolate; stride = (w * image->n * image->bpc + 7) / 8; samples = fz_malloc_array(ctx, h, stride); len = fz_read(stm, samples, h * stride); if (len < 0) { fz_throw(ctx, "cannot read image data"); } /* Make sure we read the EOF marker (for inline images only) */ /* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1980 */ if (in_line && 0) { unsigned char tbuf[512]; fz_try(ctx) { int tlen = fz_read(stm, tbuf, sizeof tbuf); if (tlen > 0) fz_warn(ctx, "ignoring garbage at end of image"); } fz_catch(ctx) { fz_warn(ctx, "ignoring error at end of image"); } } /* Pad truncated images */ if (len < stride * h) { fz_warn(ctx, "padding truncated image"); memset(samples + len, 0, stride * h - len); } /* Invert 1-bit image masks */ if (image->imagemask) { /* 0=opaque and 1=transparent so we need to invert */ unsigned char *p = samples; len = h * stride; for (i = 0; i < len; i++) p[i] = ~p[i]; } fz_unpack_tile(tile, samples, image->n, image->bpc, stride, indexed); fz_free(ctx, samples); samples = NULL; if (image->usecolorkey) pdf_mask_color_key(tile, image->n, image->colorkey); if (indexed) { fz_pixmap *conv; fz_decode_indexed_tile(tile, image->decode, (1 << image->bpc) - 1); conv = pdf_expand_indexed_pixmap(ctx, tile); fz_drop_pixmap(ctx, tile); tile = conv; } else { fz_decode_tile(tile, image->decode); } }
static fz_colorspace * load_indexed(pdf_document *xref, pdf_obj *array) { struct indexed *idx = NULL; fz_context *ctx = xref->ctx; pdf_obj *baseobj = pdf_array_get(array, 1); pdf_obj *highobj = pdf_array_get(array, 2); pdf_obj *lookup = pdf_array_get(array, 3); fz_colorspace *base = NULL; fz_colorspace *cs = NULL; int i, n; fz_var(idx); fz_var(base); fz_var(cs); fz_try(ctx) { base = pdf_load_colorspace(xref, baseobj); /* "cannot load base colorspace (%d %d R)", pdf_to_num(baseobj), pdf_to_gen(baseobj) */ idx = fz_malloc_struct(ctx, struct indexed); idx->lookup = NULL; idx->base = base; idx->high = pdf_to_int(highobj); idx->high = CLAMP(idx->high, 0, 255); n = base->n * (idx->high + 1); idx->lookup = fz_malloc_array(ctx, 1, n); cs = fz_new_colorspace(ctx, "Indexed", 1); cs->to_rgb = indexed_to_rgb; cs->free_data = free_indexed; cs->data = idx; cs->size += sizeof(*idx) + n + (base ? base->size : 0); if (pdf_is_string(lookup) && pdf_to_str_len(lookup) == n) { unsigned char *buf = (unsigned char *) pdf_to_str_buf(lookup); for (i = 0; i < n; i++) idx->lookup[i] = buf[i]; } else if (pdf_is_indirect(lookup)) { fz_stream *file = NULL; fz_try(ctx) { file = pdf_open_stream(xref, pdf_to_num(lookup), pdf_to_gen(lookup)); } fz_catch(ctx) { fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", pdf_to_num(lookup)); } i = fz_read(file, idx->lookup, n); if (i < 0) { fz_close(file); fz_throw(ctx, "cannot read colorspace lookup table (%d 0 R)", pdf_to_num(lookup)); } fz_close(file); } else { fz_throw(ctx, "cannot parse colorspace lookup table"); } }
fz_pixmap * fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor) { fz_pixmap *tile = NULL; int stride, len, i; unsigned char *samples = NULL; int f = 1<<l2factor; int w = (image->w + f-1) >> l2factor; int h = (image->h + f-1) >> l2factor; fz_var(tile); fz_var(samples); fz_try(ctx) { tile = fz_new_pixmap(ctx, image->colorspace, w, h); tile->interpolate = image->interpolate; stride = (w * image->n * image->bpc + 7) / 8; samples = fz_malloc_array(ctx, h, stride); len = fz_read(ctx, stm, samples, h * stride); /* Pad truncated images */ if (len < stride * h) { fz_warn(ctx, "padding truncated image"); memset(samples + len, 0, stride * h - len); } /* Invert 1-bit image masks */ if (image->imagemask) { /* 0=opaque and 1=transparent so we need to invert */ unsigned char *p = samples; len = h * stride; for (i = 0; i < len; i++) p[i] = ~p[i]; } fz_unpack_tile(ctx, tile, samples, image->n, image->bpc, stride, indexed); fz_free(ctx, samples); samples = NULL; /* color keyed transparency */ if (image->usecolorkey && !image->mask) fz_mask_color_key(tile, image->n, image->colorkey); if (indexed) { fz_pixmap *conv; fz_decode_indexed_tile(ctx, tile, image->decode, (1 << image->bpc) - 1); conv = fz_expand_indexed_pixmap(ctx, tile); fz_drop_pixmap(ctx, tile); tile = conv; } else { fz_decode_tile(ctx, tile, image->decode); } /* pre-blended matte color */ if (image->usecolorkey && image->mask) fz_unblend_masked_tile(ctx, tile, image); } fz_always(ctx) { fz_drop_stream(ctx, stm); } fz_catch(ctx) { if (tile) fz_drop_pixmap(ctx, tile); fz_free(ctx, samples); fz_rethrow(ctx); } return tile; }
static unsigned char * cbz_read_zip_entry(cbz_document *doc, int offset, int *sizep) { fz_context *ctx = doc->ctx; fz_stream *file = doc->file; int sig, method, namelength, extralength; unsigned long csize, usize; unsigned char *cdata; int code; fz_seek(file, offset, 0); sig = getlong(doc->file); if (sig != ZIP_LOCAL_FILE_SIG) fz_throw(ctx, "wrong zip local file signature (0x%x)", sig); (void) getshort(doc->file); /* version */ (void) getshort(doc->file); /* general */ method = getshort(doc->file); (void) getshort(doc->file); /* file time */ (void) getshort(doc->file); /* file date */ (void) getlong(doc->file); /* crc-32 */ csize = getlong(doc->file); /* csize */ usize = getlong(doc->file); /* usize */ namelength = getshort(doc->file); extralength = getshort(doc->file); fz_seek(file, namelength + extralength, 1); cdata = fz_malloc(ctx, csize); fz_try(ctx) { fz_read(file, cdata, csize); } fz_catch(ctx) { fz_free(ctx, cdata); fz_rethrow(ctx); } if (method == 0) { *sizep = usize; return cdata; } if (method == 8) { unsigned char *udata = fz_malloc(ctx, usize); z_stream stream; memset(&stream, 0, sizeof stream); stream.zalloc = cbz_zip_alloc_items; stream.zfree = cbz_zip_free; stream.opaque = ctx; stream.next_in = cdata; stream.avail_in = csize; stream.next_out = udata; stream.avail_out = usize; fz_try(ctx) { code = inflateInit2(&stream, -15); if (code != Z_OK) fz_throw(ctx, "zlib inflateInit2 error: %s", stream.msg); code = inflate(&stream, Z_FINISH); if (code != Z_STREAM_END) { inflateEnd(&stream); fz_throw(ctx, "zlib inflate error: %s", stream.msg); } code = inflateEnd(&stream); if (code != Z_OK) fz_throw(ctx, "zlib inflateEnd error: %s", stream.msg); } fz_always(ctx) { fz_free(ctx, cdata); } fz_catch(ctx) { fz_free(ctx, udata); fz_rethrow(ctx); } *sizep = usize; return udata; }
static fz_error pdf_readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap) { fz_error error; int ofs, len; char *s; int n; pdf_token_e tok; int i; int c; pdf_logxref("load old xref format\n"); fz_readline(xref->file, buf, cap); if (strncmp(buf, "xref", 4) != 0) return fz_throw("cannot find xref marker"); while (1) { c = fz_peekbyte(xref->file); if (!(c >= '0' && c <= '9')) break; fz_readline(xref->file, buf, cap); s = buf; ofs = atoi(fz_strsep(&s, " ")); len = atoi(fz_strsep(&s, " ")); /* broken pdfs where the section is not on a separate line */ if (s && *s != '\0') { fz_warn("broken xref section. proceeding anyway."); fz_seek(xref->file, -(2 + (int)strlen(s)), 1); } /* broken pdfs where size in trailer undershoots entries in xref sections */ if (ofs + len > xref->cap) { fz_warn("broken xref section, proceeding anyway."); xref->cap = ofs + len; xref->table = fz_realloc(xref->table, xref->cap * sizeof(pdf_xrefentry)); } if ((ofs + len) > xref->len) { for (i = xref->len; i < (ofs + len); i++) { xref->table[i].ofs = 0; xref->table[i].gen = 0; xref->table[i].stmofs = 0; xref->table[i].obj = nil; xref->table[i].type = 0; } xref->len = ofs + len; } for (i = ofs; i < ofs + len; i++) { n = fz_read(xref->file, (unsigned char *) buf, 20); if (n < 0) return fz_rethrow(n, "cannot read xref table"); if (!xref->table[i].type) { s = buf; /* broken pdfs where line start with white space */ while (*s != '\0' && iswhite(*s)) s++; xref->table[i].ofs = atoi(s); xref->table[i].gen = atoi(s + 11); xref->table[i].type = s[17]; } } } error = pdf_lex(&tok, xref->file, buf, cap, &n); if (error) return fz_rethrow(error, "cannot parse trailer"); if (tok != PDF_TTRAILER) return fz_throw("expected trailer marker"); error = pdf_lex(&tok, xref->file, buf, cap, &n); if (error) return fz_rethrow(error, "cannot parse trailer"); if (tok != PDF_TODICT) return fz_throw("expected trailer dictionary"); error = pdf_parsedict(trailerp, xref, xref->file, buf, cap); if (error) return fz_rethrow(error, "cannot parse trailer"); return fz_okay; }