Esempio n. 1
0
/*
 * Continuation for procedure data source.  We use the topmost aliasing slot
 * to remember whether we've just called the procedure (1) or whether we're
 * returning from a RemapColor callout (0).
 */
static int
image_proc_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_image_enum *penum = r_ptr(esp, gs_image_enum);
    int px = ETOP_PLANE_INDEX(esp)->value.intval;
    int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
    uint size, used[gs_image_max_planes];
    gs_const_string plane_data[gs_image_max_planes];
    const byte *wanted;
    int i, code;

    if (!r_has_type_attrs(op, t_string, a_read)) {
	check_op(1);
	/* Procedure didn't return a (readable) string.  Quit. */
	esp = zimage_pop_estack(esp);
	image_cleanup(i_ctx_p);
	return_error(!r_has_type(op, t_string) ? e_typecheck : e_invalidaccess);
    }
    size = r_size(op);
    if (size == 0 && ETOP_SOURCE(esp, 0)[1].value.intval == 0)
	code = 1;
    else {
	for (i = 0; i < num_sources; i++)
	    plane_data[i].size = 0;
	plane_data[px].data = op->value.bytes;
	plane_data[px].size = size;
	code = gs_image_next_planes(penum, plane_data, used);
	if (code == e_RemapColor) {
	    op->value.bytes += used[px]; /* skip used data */
	    r_dec_size(op, used[px]);
	    ETOP_SOURCE(esp, 0)[1].value.intval = 0; /* RemapColor callout */
	    return code;
	}
    }
    if (code) {			/* Stop now. */
	esp = zimage_pop_estack(esp);
	pop(1);
	image_cleanup(i_ctx_p);
	return (code < 0 ? code : o_pop_estack);
    }
    pop(1);
    wanted = gs_image_planes_wanted(penum);
    do {
	if (++px == num_sources)
	    px = 0;
    } while (!wanted[px]);
    ETOP_PLANE_INDEX(esp)->value.intval = px;
    return image_proc_process(i_ctx_p);
}
Esempio n. 2
0
/* Process the next piece of an image. */
int
gs_image_next(gs_image_enum * penum, const byte * dbytes, uint dsize,
	      uint * pused)
{
    int px = penum->plane_index;
    int num_planes = penum->num_planes;
    int i, code;
    uint used[GS_IMAGE_MAX_COMPONENTS];
    gs_const_string plane_data[GS_IMAGE_MAX_COMPONENTS];

    if (penum->planes[px].source.size != 0)
	return_error(gs_error_rangecheck);
    for (i = 0; i < num_planes; i++)
	plane_data[i].size = 0;
    plane_data[px].data = dbytes;
    plane_data[px].size = dsize;
    penum->error = false;
    code = gs_image_next_planes(penum, plane_data, used);
    *pused = used[px];
    if (code >= 0)
	next_plane(penum);
    return code;
}
Esempio n. 3
0
/* This may still encounter a RemapColor callback. */
static int
image_string_continue(i_ctx_t *i_ctx_p)
{
    gs_image_enum *penum = r_ptr(esp, gs_image_enum);
    int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
    gs_const_string sources[gs_image_max_planes];
    uint used[gs_image_max_planes];

    /* Pass no data initially, to find out how much is retained. */
    memset(sources, 0, sizeof(sources[0]) * num_sources);
    for (;;) {
	int px;
	int code = gs_image_next_planes(penum, sources, used);

	if (code == e_RemapColor)
	    return code;
    stop_now:
	if (code) {		/* Stop now. */
	    esp -= NUM_PUSH(num_sources);
	    image_cleanup(i_ctx_p);
	    return (code < 0 ? code : o_pop_estack);
	}
	for (px = 0; px < num_sources; ++px)
	    if (sources[px].size == 0) {
		const ref *psrc = ETOP_SOURCE(esp, px);
		uint size = r_size(psrc);

		if (size == 0) {	    /* empty source */
		    code = 1;
		    goto stop_now;
                }
		sources[px].data = psrc->value.bytes;
		sources[px].size = size;
	    }
    }
}
Esempio n. 4
0
/* Continue processing data from an image with file data sources. */
static int
image_file_continue(i_ctx_t *i_ctx_p)
{
    gs_image_enum *penum = r_ptr(esp, gs_image_enum);
    int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;

    for (;;) {
	uint min_avail = max_int;
	gs_const_string plane_data[gs_image_max_planes];
	int code;
	int px;
	const ref *pp;
	bool at_eof = false;

	/*
	 * Do a first pass through the files to ensure that at least
	 * one has data available in its buffer.
	 */

	for (px = 0, pp = ETOP_SOURCE(esp, 0); px < num_sources;
	     ++px, pp -= 2
	    ) {
	    int num_aliases = pp[1].value.intval;
	    stream *s = pp->value.pfile;
	    int min_left;
	    uint avail;

	    if (num_aliases <= 0)
		num_aliases = ETOP_SOURCE(esp, -num_aliases)[1].value.intval;
	    while ((avail = sbufavailable(s)) <=
		   (min_left = sbuf_min_left(s)) + num_aliases - 1) {
		int next = s->end_status;

		switch (next) {
		case 0:
		    s_process_read_buf(s);
		    continue;
		case EOFC:
		    at_eof = true;
		    break;	/* with no data available */
		case INTC:
		case CALLC:
		    return
			s_handle_read_exception(i_ctx_p, next, pp,
						NULL, 0, image_file_continue);
		default:
		    /* case ERRC: */
		    return_error(e_ioerror);
		}
		break;		/* for EOFC */
	    }
	    /*
	     * Note that in the EOF case, we can get here with no data
	     * available.
	     */
	    if (avail >= min_left)
		avail = (avail - min_left) / num_aliases; /* may be 0 */
	    if (avail < min_avail)
		min_avail = avail;
	    plane_data[px].data = sbufptr(s);
	    plane_data[px].size = avail;
	}

	/*
	 * Now pass the available buffered data to the image processor.
	 * Even if there is no available data, we must call
	 * gs_image_next_planes one more time to finish processing any
	 * retained data.
	 */

	{
	    int pi;
	    uint used[gs_image_max_planes];

	    code = gs_image_next_planes(penum, plane_data, used);
	    /* Now that used has been set, update the streams. */
	    for (pi = 0, pp = ETOP_SOURCE(esp, 0); pi < num_sources;
		 ++pi, pp -= 2
		 )
		sbufskip(pp->value.pfile, used[pi]);
	    if (code == e_RemapColor)
		return code;
	}
	if (at_eof)
	    code = 1;
	if (code) {
	    int code1;

	    esp = zimage_pop_estack(esp);
	    code1 = image_cleanup(i_ctx_p);
	    return (code < 0 ? code : code1 < 0 ? code1 : o_pop_estack);
	}
    }
}