コード例 #1
0
ファイル: zfdctd.c プロジェクト: hackqiang/gs
/* <source> DCTDecode/filter <file> */
static int
zDCTD(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_memory_t *mem;
    stream_DCT_state state;
    dict_param_list list;
    jpeg_decompress_data *jddp;
    int code;
    const ref *dop;
    uint dspace;

    if (r_has_type(op, t_dictionary))
        dop = op, dspace = r_space(op);
    else
        dop = 0, dspace = 0;
    mem = (gs_memory_t *)find_stream_memory(i_ctx_p, 0, &dspace);
    state.memory = mem;
    /* First allocate space for IJG parameters. */
    jddp = gs_alloc_struct_immovable(mem,jpeg_decompress_data,
      &st_jpeg_decompress_data, "zDCTD");
    if (jddp == 0)
        return_error(e_VMerror);
    if (s_DCTD_template.set_defaults)
        (*s_DCTD_template.set_defaults) ((stream_state *) & state);
    state.data.decompress = jddp;
    jddp->memory = state.jpeg_memory = mem;	/* set now for allocation */
    jddp->scanline_buffer = NULL;	/* set this early for safe error exit */
    state.report_error = filter_report_error;	/* in case create fails */
    if ((code = gs_jpeg_create_decompress(&state)) < 0)
        goto fail;		/* correct to do jpeg_destroy here */
    /* Read parameters from dictionary */
    if ((code = dict_param_list_read(&list, dop, NULL, false, iimemory)) < 0)
        goto fail;
    if ((code = s_DCTD_put_params((gs_param_list *) & list, &state)) < 0)
        goto rel;
    /* Create the filter. */
    jddp->templat = s_DCTD_template;
    code = filter_read(i_ctx_p, 0, &jddp->templat,
                       (stream_state *) & state, dspace);
    if (code >= 0)		/* Success! */
        return code;
    /*
     * We assume that if filter_read fails, the stream has not been
     * registered for closing, so s_DCTD_release will never be called.
     * Therefore we free the allocated memory before failing.
     */
rel:
    iparam_list_release(&list);
fail:
    gs_jpeg_destroy(&state);
    gs_free_object(mem, jddp, "zDCTD fail");
    return code;
}
コード例 #2
0
ファイル: xpsjpeg.c プロジェクト: computersforpeace/ghostpdl
int
xps_decode_jpeg(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
{
    jpeg_decompress_data jddp;
    stream_DCT_state state;
    stream_cursor_read rp;
    stream_cursor_write wp;
    int code;
    int wlen;
    byte *wbuf;
    jpeg_saved_marker_ptr curr_marker;

    s_init_state((stream_state*)&state, &s_DCTD_template, ctx->memory);
    state.report_error = xps_report_error;

    s_DCTD_template.set_defaults((stream_state*)&state);

    state.jpeg_memory = ctx->memory;
    state.data.decompress = &jddp;

    jddp.templat = s_DCTD_template;
    jddp.memory = ctx->memory;
    jddp.scanline_buffer = NULL;

    if ((code = gs_jpeg_create_decompress(&state)) < 0)
        return gs_throw(-1, "cannot gs_jpeg_create_decompress");

    s_DCTD_template.init((stream_state*)&state);

    rp.ptr = rbuf - 1;
    rp.limit = rbuf + rlen - 1;

    /* read the header only by not having a write buffer */
    wp.ptr = 0;
    wp.limit = 0;

    /* Set up to save the ICC marker APP2.
     * According to the spec we should be getting APP1 APP2 and APP13.
     * Library gets APP0 and APP14. */
    jpeg_save_markers(&(jddp.dinfo), 0xe2, 0xFFFF);

    code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
    if (code != 1)
        return gs_throw(-1, "premature EOF or error in jpeg");

    /* Check if we had an ICC profile */
    curr_marker = jddp.dinfo.marker_list;
    while (curr_marker != NULL)
    {
        if (curr_marker->marker == 0xe2)
        {
            /* Found ICC profile. Create a buffer and copy over now.
             * Strip JPEG APP2 14 byte header */
            image->profilesize = curr_marker->data_length - 14;
            image->profile = xps_alloc(ctx, image->profilesize);
            if (image->profile)
            {
                /* If we can't create it, just ignore */
                memcpy(image->profile, &(curr_marker->data[14]), image->profilesize);
            }
            break;
        }
        curr_marker = curr_marker->next;
    }

    image->width = jddp.dinfo.output_width;
    image->height = jddp.dinfo.output_height;
    image->comps = jddp.dinfo.output_components;
    image->bits = 8;
    image->stride = image->width * image->comps;

    if (image->comps == 1)
        image->colorspace = ctx->gray;
    if (image->comps == 3)
        image->colorspace = ctx->srgb;
    if (image->comps == 4)
        image->colorspace = ctx->cmyk;

    if (jddp.dinfo.density_unit == 1)
    {
        image->xres = jddp.dinfo.X_density;
        image->yres = jddp.dinfo.Y_density;
    }
    else if (jddp.dinfo.density_unit == 2)
    {
        image->xres = (int)(jddp.dinfo.X_density * 2.54 + 0.5);
        image->yres = (int)(jddp.dinfo.Y_density * 2.54 + 0.5);
    }
    else
    {
        image->xres = 96;
        image->yres = 96;
    }

    wlen = image->stride * image->height;
    wbuf = xps_alloc(ctx, wlen);
    if (!wbuf)
        return gs_throw1(gs_error_VMerror, "out of memory allocating samples: %d", wlen);

    image->samples = wbuf;

    wp.ptr = wbuf - 1;
    wp.limit = wbuf + wlen - 1;

    code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
    if (code != EOFC)
        return gs_throw1(-1, "error in jpeg (code = %d)", code);

    gs_jpeg_destroy(&state);

    return gs_okay;
}
コード例 #3
0
ファイル: pxvendor.c プロジェクト: hackqiang/gs
/* TODO: consider using source.count (and possibly also phase) */
static int
read_headless_jpeg_bitmap_data(byte ** pdata,
			       px_args_t * par, px_state_t * pxs)
{
    px_vendor_state_t *v_state = pxs->vendor_state;
    uint data_per_row = v_state->data_per_row;	/* jpeg doesn't pad */
    uint avail = par->source.available;

    uint pos_in_row = par->source.position % data_per_row;
    const byte *data = par->source.data;
    stream_DCT_state *ss = (&v_state->dct_stream_state);
    stream_cursor_read r;
    stream_cursor_write w;
    uint used;
    int code = -1;

    if_debug3('w', "jpeg begin pos=%d row=%d/%d\n",
	      pos_in_row, v_state->rowwritten, v_state->BlockHeight);

    /* consumed all of the data */
    if ((v_state->state == vu_body)
	&& v_state->rowwritten == v_state->BlockHeight) {
	if (par->source.available == 2) {
	    /* the data includes EOI; the filter may or may not consume it */
	    par->source.data += 2;
	    par->source.available -= 2;
	}
	gs_jpeg_destroy((&v_state->dct_stream_state));
	v_state->state = vu_blank;
	v_state->rowwritten = 0;
	code = pl_end_image(pxs->pgs, v_state->info, true);

	if (code < 0)
	    return code;
	return 0;
    }

    if (v_state->state == vu_tagged) {
	jpeg_decompress_data *jddp = &(v_state->jdd);

	v_state->rowwritten = 0;
	code = vu_begin_image(pxs);
	if (code < 0)
	    return code;

	/* use the graphics library support for DCT streams */
	ss->memory = pxs->memory;
	ss->templat = &s_DCTD_template;
	s_DCTD_template.set_defaults((stream_state *) ss);
	ss->report_error = vu_stream_error;
	ss->data.decompress = jddp;
	/* set now for allocation */
	jddp->memory = ss->jpeg_memory = pxs->memory;
	/* set this early for safe error exit */
	jddp->scanline_buffer = NULL;
	if (gs_jpeg_create_decompress(ss) < 0)
	    return_error(errorInsufficientMemory);
	(*s_DCTD_template.init) ((stream_state *) ss);
	jddp->templat = s_DCTD_template;
	fastforward_jpeg_stream_state(jddp, ss, pxs);
	v_state->state = vu_body;
    }

    r.ptr = data - 1;
    r.limit = r.ptr + avail;
    if (pos_in_row < data_per_row) {
	/* Read more of the current row. */
	byte *data = *pdata;

	w.ptr = data + pos_in_row - 1;
	w.limit = data + data_per_row - 1;
	code =
	    (*s_DCTD_template.process) ((stream_state *) ss, &r, &w, false);
	/* code = num scanlines processed (0=need more data, -ve=error) */
	if_debug1('w', "s_DCTD_template.process returns %d\n", code);
	used = w.ptr + 1 - data - pos_in_row;
	if ((code == EOFC) && (used > 0))
	    code = 1;
	if_debug2('w', "data generated: %d/%d\n", used, data_per_row);
	/* pos_in_row += used; */
	par->source.position += used;
    }
    used = r.ptr + 1 - data;
    par->source.data = r.ptr + 1;
    par->source.available = avail - used;
    if_debug2('w', "scanlines %d used %d\n", code, used);
    if (code == 0)
	return pxNeedData;
    if (code == EOFC)		/* used = 0 is possible, and earlier than end */
	return 0;
    if (code > 0) {
	v_state->rowwritten++;
	if_debug1('w', "row written:%d\n", v_state->rowwritten);
	jpeg_custom_color_fixup(v_state->row,
				v_state->color_space, v_state->data_per_row);
	return 1;
    }
    return code;
}