/* parse a globals stream packed into a gs_bytestring for us by the postscript layer and stuff the resulting context into a pointer for use in later decoding */ int s_jbig2decode_make_global_data(byte *data, uint length, void **result) { Jbig2Ctx *ctx = NULL; int code; /* the cvision encoder likes to include empty global streams */ if (length == 0) { if_debug0('w', "[w] ignoring zero-length jbig2 global stream.\n"); *result = NULL; return 0; } /* allocate a context with which to parse our global segments */ ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, s_jbig2decode_error, NULL); if (ctx == NULL) return 0; /* parse the global bitstream */ code = jbig2_data_in(ctx, data, length); if (code) { /* error parsing the global stream */ *result = NULL; return code; } /* canonize and store our global state */ *result = jbig2_make_global_ctx(ctx); return 0; /* todo: check for allocation failure */ }
fz_error * fz_setjbig2dglobalstream(fz_filter *filter, unsigned char *buf, int len) { fz_jbig2d *d = (fz_jbig2d*)filter; jbig2_data_in(d->ctx, buf, len); d->gctx = jbig2_make_global_ctx(d->ctx); d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, d->gctx, nil, nil); return fz_okay; }
fz_error * fz_newjbig2d(fz_filter **fp, fz_obj *params) { FZ_NEWFILTER(fz_jbig2d, d, jbig2d); d->ctx = jbig2_ctx_new(nil, JBIG2_OPTIONS_EMBEDDED, nil, nil, nil); d->page = nil; d->idx = 0; return fz_okay; }
fz_stream * fz_open_jbig2d(fz_stream *chain, fz_buffer *globals) { fz_jbig2d *state = NULL; fz_context *ctx = chain->ctx; //fz_var(state); try { state = (fz_jbig2d*)fz_malloc_struct(chain->ctx, fz_jbig2d); state->ctx = NULL; state->gctx = NULL; state->chain = chain; state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, NULL, NULL); state->page = NULL; state->idx = 0; if (globals) { jbig2_data_in(state->ctx, globals->data, globals->len); state->gctx = jbig2_make_global_ctx(state->ctx); state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, state->gctx, NULL, NULL); } } catch(...) { if (state) { if (state->gctx) jbig2_global_ctx_free(state->gctx); if (state->ctx) jbig2_ctx_free(state->ctx); } fz_drop_buffer(ctx, globals); fz_free(ctx, state); fz_close(chain); throw("error"); } fz_drop_buffer(ctx, globals); return fz_new_stream(ctx, state, read_jbig2d, close_jbig2d); }
fz_stream * fz_open_jbig2d(fz_stream *chain, fz_buffer *globals) { fz_jbig2d *state; state = fz_malloc(sizeof(fz_jbig2d)); state->chain = chain; state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, NULL, NULL); state->gctx = NULL; state->page = NULL; state->idx = 0; if (globals) { jbig2_data_in(state->ctx, globals->data, globals->len); state->gctx = jbig2_make_global_ctx(state->ctx); state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, state->gctx, NULL, NULL); } return fz_new_stream(state, read_jbig2d, close_jbig2d); }
/* initialize the steam. this involves allocating the context structures, and initializing the global context from the /JBIG2Globals object reference */ static int s_jbig2decode_init(stream_state * ss) { stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss; Jbig2GlobalCtx *global_ctx = state->global_ctx; /* may be NULL */ state->error = 0; /* initialize the decoder with the parsed global context if any */ state->decode_ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, global_ctx, s_jbig2decode_error, ss); state->image = 0; return (state->error); }
int main (int argc, char **argv) { FILE *f = NULL, *f_page = NULL; Jbig2Ctx *ctx; uint8_t buf[4096]; jbig2dec_params_t params; int filearg; /* set defaults */ params.mode = render; params.verbose = 1; params.hash = 0; params.output_file = NULL; params.output_format = jbig2dec_format_none; filearg = parse_options(argc, argv, ¶ms); if (params.hash) hash_init(¶ms); switch (params.mode) { case usage: print_usage(); exit (0); break; case dump: fprintf(stderr, "Sorry, segment dump not yet implemented\n"); break; case render: if ((argc - filearg) == 1) /* only one argument--open as a jbig2 file */ { char *fn = argv[filearg]; f = fopen(fn, "rb"); if (f == NULL) { fprintf(stderr, "error opening %s\n", fn); return 1; } } else if ((argc - filearg) == 2) /* two arguments open as separate global and page streams */ { char *fn = argv[filearg]; char *fn_page = argv[filearg+1]; f = fopen(fn, "rb"); if (f == NULL) { fprintf(stderr, "error opening %s\n", fn); return 1; } f_page = fopen(fn_page, "rb"); if (f_page == NULL) { fprintf(stderr, "error opening %s\n", fn_page); return 1; } } else /* any other number of arguments */ return print_usage(); ctx = jbig2_ctx_new(NULL, f_page != NULL ? JBIG2_OPTIONS_EMBEDDED : 0, NULL, error_callback, ¶ms); /* pull the whole file/global stream into memory */ for (;;) { int n_bytes = fread(buf, 1, sizeof(buf), f); if (n_bytes <= 0) break; jbig2_data_in(ctx, buf, n_bytes); } fclose(f); /* if there's a local page stream read that in its entirety */ if (f_page != NULL) { Jbig2GlobalCtx *global_ctx = jbig2_make_global_ctx(ctx); ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, global_ctx, error_callback, ¶ms); for (;;) { int n_bytes = fread(buf, 1, sizeof(buf), f_page); if (n_bytes <= 0) break; jbig2_data_in(ctx, buf, n_bytes); } fclose(f_page); jbig2_global_ctx_free(global_ctx); } /* retrieve and output the returned pages */ { Jbig2Image *image; /* work around broken CVision embedded streams */ if (f_page != NULL) jbig2_complete_page(ctx); if (params.output_file == NULL) { #ifdef HAVE_LIBPNG params.output_file = make_output_filename(argv[filearg], ".png"); params.output_format = jbig2dec_format_png; #else params.output_file = make_output_filename(argv[filearg], ".pbm"); params.output_format = jbig2dec_format_pbm; #endif } else { int len = strlen(params.output_file); if ((len >= 3) && (params.output_format == jbig2dec_format_none)) /* try to set the output type by the given extension */ set_output_format(¶ms, params.output_file + len - 3); } /* retrieve and write out all the completed pages */ while ((image = jbig2_page_out(ctx)) != NULL) { write_page_image(¶ms, image); if (params.hash) hash_image(¶ms, image); jbig2_release_page(ctx, image); } if (params.hash) write_document_hash(¶ms); } jbig2_ctx_free(ctx); } /* end params.mode switch */ if (params.output_file) free(params.output_file); if (params.hash) hash_free(¶ms); /* fin */ return 0; }