/* Free the image enumerator. */
void
gx_image_free_enum(gx_image_enum_common_t **ppenum)
{
    gx_image_enum_common_t  * penum = *ppenum;
    gs_memory_t *mem = penum->memory;

     /* Bug 688845 comment #38 :
        Adobe Illustrator creates a Postscript document, 
	in which an image data procedure executes 'save',
	and the corresponding 'restore' appears after the image end.
	It causes this procedure is called at a higher save level than
	at which the enumerator was allocated, so that gs_free_object below
	works idle. Nevertheless we can't leave pointers in the structure,
	because they may point to blocks already released
	by the client's subclass method for end_image.
	Leaving them uncleaned caused a real crash in the garbager - see bug 688845.
	So we clean the entire subclassed enumerator here,
	rather this is a generic function for base class.
	Note the cleaning is neccessaryfor Postscript only,
	because other languaged don't implement save-restore.
     */
    memset(penum, 0, gs_object_size(mem, penum));
    gs_free_object(mem, penum, "gx_image_free_enum");
    *ppenum = NULL;
}
Exemple #2
0
/* <array|dict|name|packedarray|string> length <int> */
static int
zlength(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    switch (r_type(op)) {
	case t_array:
	case t_string:
	case t_mixedarray:
	case t_shortarray:
	    check_read(*op);
	    make_int(op, r_size(op));
	    return 0;
	case t_dictionary:
	    check_dict_read(*op);
	    make_int(op, dict_length(op));
	    return 0;
	case t_name: {
	    ref str;

	    name_string_ref(imemory, op, &str);
	    make_int(op, r_size(&str));
	    return 0;
	}
	case t_astruct:
	    if (gs_object_type(imemory, op->value.pstruct) != &st_bytes)
		return_error(e_typecheck);
	    check_read(*op);
	    make_int(op, gs_object_size(imemory, op->value.pstruct));
	    return 0;
	default:
	    return_op_typecheck(op);
    }
}
/* we call this from ps code to instantiate a jbig2_global_context
   object which the JBIG2Decode filter uses if available. The
   pointer to the global context is stored in an astruct object
   and returned that way since it lives outside the interpreters
   memory management */
static int
z_jbig2makeglobalctx(i_ctx_t * i_ctx_p)
{
        void *global = NULL;
        s_jbig2_global_data_t *st;
        os_ptr op = osp;
        byte *data;
        int size;
        int code = 0;

        check_type(*op, t_astruct);
        size = gs_object_size(imemory, op->value.pstruct);
        data = r_ptr(op, byte);

        code = s_jbig2decode_make_global_data(data, size,
                        &global);
        if (size > 0 && global == NULL) {
            dlprintf("failed to create parsed JBIG2GLOBALS object.");
            return_error(e_unknownerror);
        }

        st = ialloc_struct(s_jbig2_global_data_t,
                &st_jbig2_global_data_t,
                "jbig2decode parsed global context");
        if (st == NULL) return_error(e_VMerror);

        st->data = global;
        make_astruct(op, a_readonly | icurrent_space, (byte*)st);

        return code;
}
Exemple #4
0
/* Add a command to the DL table - pen up or pen down coordinates.
   Resizing the table as appropriate. */
static int
hpgl_add_dl_char_data(hpgl_state_t * pgls, hpgl_dl_cdata_t * pcdata,
                      short cc_data)
{
    /* characters stored as short */
    int csz = sizeof(short);

    if (pcdata->index == -1) {
        /* first element - allocate a small array which will be resized as needed */
        pcdata->data =
            (short *)gs_alloc_bytes(pgls->memory, 2 * csz, "DL data");
        if (pcdata->data == 0)
            return e_Memory;
    } else if (gs_object_size(pgls->memory, pcdata->data) ==
               (pcdata->index + 1) * csz) {
        /* new character doesn't fit - double the size of the array */
        short *new_cdata =
            (short *)gs_resize_object(pgls->memory, pcdata->data,
                                      (pcdata->index + 1) * csz * 2,
                                      "DL data resize");

        if (new_cdata == 0) {
            return e_Memory;
        }
        pcdata->data = new_cdata;
    }
    pcdata->data[++pcdata->index] = cc_data;
    return 0;
}
Exemple #5
0
/* <string> <index> <int> put - */
static int
zput(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    os_ptr op2 = op1 - 1;
    byte *sdata;
    uint ssize;

    switch (r_type(op2)) {
	case t_dictionary:
	    if (i_ctx_p->in_superexec == 0)
		check_dict_write(*op2);
	    {
		int code = idict_put(op2, op1, op);

		if (code < 0)
		    return code;	/* error */
	    }
	    break;
	case t_array:
	    check_write(*op2);
	    check_int_ltu(*op1, r_size(op2));
	    store_check_dest(op2, op);
	    {
		ref *eltp = op2->value.refs + (uint) op1->value.intval;

		ref_assign_old(op2, eltp, op, "put");
	    }
	    break;
	case t_mixedarray:	/* packed arrays are read-only */
	case t_shortarray:
	    return_error(e_invalidaccess);
	case t_string:
	    sdata = op2->value.bytes;
	    ssize = r_size(op2);
str:	    check_write(*op2);
	    check_int_ltu(*op1, ssize);
	    check_int_leu(*op, 0xff);
	    sdata[(uint)op1->value.intval] = (byte)op->value.intval;
	    break;
	case t_astruct:
	    if (gs_object_type(imemory, op2->value.pstruct) != &st_bytes)
		return_error(e_typecheck);
	    sdata = r_ptr(op2, byte);
	    ssize = gs_object_size(imemory, op2->value.pstruct);
	    goto str;
	default:
	    return_op_typecheck(op2);
    }
    pop(3);
    return 0;
}
Exemple #6
0
/* BitsPerSample. */
static int
dict_threshold2_params(const ref * pdict, gs_threshold2_halftone * ptp,
		       ref * ptproc, gs_memory_t *mem)
{
    ref *tstring;
    int code =
	dict_threshold_common_params(pdict,
				     (gs_threshold_halftone_common *)ptp,
				     &tstring, ptproc);
    int bps;
    uint size;
    int cw2, ch2;

    if (code < 0 ||
	(code = cw2 = dict_int_param(pdict, "Width2", 0, 0x7fff, 0,
				     &ptp->width2)) < 0 ||
	(code = ch2 = dict_int_param(pdict, "Height2", 0, 0x7fff, 0,
				     &ptp->height2)) < 0 ||
	(code = dict_int_param(pdict, "BitsPerSample", 8, 16, -1, &bps)) < 0
	)
	return code;
    if ((bps != 8 && bps != 16) || cw2 != ch2 ||
	(!cw2 && (ptp->width2 == 0 || ptp->height2 == 0))
	)
	return_error(e_rangecheck);
    ptp->bytes_per_sample = bps / 8;
    switch (r_type(tstring)) {
    case t_string:
	size = r_size(tstring);
	gs_bytestring_from_string(&ptp->thresholds, tstring->value.const_bytes,
				  size);
	break;
    case t_astruct:
	if (gs_object_type(mem, tstring->value.pstruct) != &st_bytes)
	    return_error(e_typecheck);
	size = gs_object_size(mem, tstring->value.pstruct);
	gs_bytestring_from_bytes(&ptp->thresholds, r_ptr(tstring, byte),
				 0, size);
	break;
    default:
	return_error(e_typecheck);
    }
    check_read(*tstring);
    if (size != (ptp->width * ptp->height + ptp->width2 * ptp->height2) *
	ptp->bytes_per_sample)
	return_error(e_rangecheck);
    return 0;
}
Exemple #7
0
/* <bytestring1> <index> <string2> putinterval - */
static int
zputinterval(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr opindex = op - 1;
    os_ptr opto = opindex - 1;
    int code;

    switch (r_type(opto)) {
	default:
            return_error(e_typecheck);
        case t__invalid:
            if (r_type(op) != t_array && r_type(op) != t_string && r_type(op) != t__invalid)
                return_error(e_typecheck); /* to match Distiller */
            else
                return_error(e_stackunderflow);
	case t_mixedarray:
	case t_shortarray:
	    return_error(e_invalidaccess);
	case t_array:
	case t_string:
	    check_write(*opto);
	    check_int_leu(*opindex, r_size(opto));
	    code = copy_interval(i_ctx_p, opto, (uint)(opindex->value.intval),
				 op, "putinterval");
	    break;
	case t_astruct: {
	    uint dsize, ssize, index;

	    check_write(*opto);
	    if (gs_object_type(imemory, opto->value.pstruct) != &st_bytes)
		return_error(e_typecheck);
	    dsize = gs_object_size(imemory, opto->value.pstruct);
	    check_int_leu(*opindex, dsize);
	    index = (uint)opindex->value.intval;
	    check_read_type(*op, t_string);
	    ssize = r_size(op);
	    if (ssize > dsize - index)
		return_error(e_rangecheck);
	    memcpy(r_ptr(opto, byte) + index, op->value.const_bytes, ssize);
	    code = 0;
	    break;
	}
    }
    if (code >= 0)
	pop(3);
    return code;
}
Exemple #8
0
/* Read a string value. */
static int
ref_param_read_string_value(gs_memory_t *mem, const iparam_loc * ploc, gs_param_string * pvalue)
{
    const ref *pref = ploc->pvalue;

    switch (r_type(pref)) {
	case t_name: {
	    ref nref;

	    name_string_ref(mem, pref, &nref);
	    pvalue->data = nref.value.const_bytes;
	    pvalue->size = r_size(&nref);
	    pvalue->persistent = true;
	}
	    break;
	case t_string:
	    iparam_check_read(*ploc);
	    pvalue->data = pref->value.const_bytes;
	    pvalue->size = r_size(pref);
	    pvalue->persistent = false;
	    break;
	case t_astruct:
	    /* Note: technically, instead of the "mem" argument, we
	       should be using the plists's ref_memory. However, in a
	       simple call to .putdeviceparams, they are identical. */
	    iparam_check_read(*ploc);
	    if (gs_object_type(mem, pref->value.pstruct) != &st_bytes) 
		return iparam_note_error(*ploc, e_typecheck);
	    pvalue->data = r_ptr(pref, byte);
	    pvalue->size = gs_object_size(mem, pref->value.pstruct);
	    pvalue->persistent = false;
	    break;
	default:
	    return iparam_note_error(*ploc, e_typecheck);
    }
    return 0;
}
Exemple #9
0
static void *
gs_heap_resize_object(gs_memory_t * mem, void *obj, uint new_num_elements,
		      client_name_t cname)
{
    gs_malloc_memory_t *mmem = (gs_malloc_memory_t *) mem;
    gs_malloc_block_t *ptr = (gs_malloc_block_t *) obj - 1;
    gs_memory_type_ptr_t pstype = ptr->type;
    uint old_size = gs_object_size(mem, obj) + sizeof(gs_malloc_block_t);
    uint new_size =
	gs_struct_type_size(pstype) * new_num_elements +
	sizeof(gs_malloc_block_t);
    gs_malloc_block_t *new_ptr;

    if (new_size == old_size)
        return obj;
    if (mmem->monitor)
	gx_monitor_enter(mmem->monitor);	/* Exclusive access */
    new_ptr = (gs_malloc_block_t *) gs_realloc(ptr, old_size, new_size);
    if (new_ptr == 0)
	return 0;
    if (new_ptr->prev)
	new_ptr->prev->next = new_ptr;
    else
	mmem->allocated = new_ptr;
    if (new_ptr->next)
	new_ptr->next->prev = new_ptr;
    new_ptr->size = new_size - sizeof(gs_malloc_block_t);
    mmem->used -= old_size;
    mmem->used += new_size;
    if (mmem->monitor)
	gx_monitor_leave(mmem->monitor);	/* Done with exclusive access */
    if (new_size > old_size)
	gs_alloc_fill((byte *) new_ptr + old_size,
		      gs_alloc_fill_alloc, new_size - old_size);
    return new_ptr + 1;
}
Exemple #10
0
static int
zreusablestream(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr source_op = op - 1;
    long length = max_long;
    bool close_source;
    int code;

    check_type(*op, t_boolean);
    close_source = op->value.boolval;
    if (r_has_type(source_op, t_string)) {
        uint size = r_size(source_op);

        check_read(*source_op);
        code = make_rss(i_ctx_p, source_op, source_op->value.const_bytes,
                        size, r_space(source_op), 0L, size, false);
    } else if (r_has_type(source_op, t_astruct)) {
        uint size = gs_object_size(imemory, source_op->value.pstruct);

        if (gs_object_type(imemory, source_op->value.pstruct) != &st_bytes)
            return_error(e_rangecheck);
        check_read(*source_op);
        code = make_rss(i_ctx_p, source_op,
                        (const byte *)source_op->value.pstruct, size,
                        r_space(source_op), 0L, size, true);
    } else if (r_has_type(source_op, t_array)) {  /* no packedarrays */
        int i, blk_cnt, blk_sz;
        ref *blk_ref;
        ulong filelen = 0;

        check_read(*source_op);
        blk_cnt = r_size(source_op);
        blk_ref = source_op->value.refs;
        if (blk_cnt > 0) {
            blk_sz = r_size(blk_ref);
            for (i = 0; i < blk_cnt; i++) {
                int len;

                check_read_type(blk_ref[i], t_string);
                len = r_size(&blk_ref[i]);
                if (len > blk_sz || (len < blk_sz && i < blk_cnt - 1))
                   return_error(e_rangecheck); /* last block can be smaller */
                filelen += len;
            }
        }
        if (filelen == 0) {
           code = make_rss(i_ctx_p, source_op, (unsigned char *)"", 0,
               r_space(source_op), 0, 0, false);
        } else {
           code = make_aos(i_ctx_p, source_op, blk_sz, r_size(&blk_ref[blk_cnt - 1]), filelen);
        }
    } else {
        long offset = 0;
        stream *source;
        stream *s;

        check_read_file(i_ctx_p, source, source_op);
        s = source;
rs:
        if (s->cbuf_string.data != 0) {	/* string stream */
            long pos = stell(s);
            long avail = sbufavailable(s) + pos;

            offset += pos;
            code = make_rss(i_ctx_p, source_op, s->cbuf_string.data,
                            s->cbuf_string.size,
                            imemory_space((const gs_ref_memory_t *)s->memory),
                            offset, min(avail, length), false);
        } else if (s->file != 0) { /* file stream */
            if (~s->modes & (s_mode_read | s_mode_seek))
                return_error(e_ioerror);
            code = make_rfs(i_ctx_p, source_op, s, offset + stell(s), length);
        } else if (s->state->templat == &s_SFD_template) {
            /* SubFileDecode filter */
            const stream_SFD_state *const sfd_state =
                (const stream_SFD_state *)s->state;

            if (sfd_state->eod.size != 0)
                return_error(e_rangecheck);
            offset += sfd_state->skip_count - sbufavailable(s);
            if (sfd_state->count != 0) {
                long left = max(sfd_state->count, 0) + sbufavailable(s);

                if (left < length)
                    length = left;
            }
            s = s->strm;
            goto rs;
        }
        else			/* some other kind of stream */
            return_error(e_rangecheck);
        if (close_source) {
            stream *rs = fptr(source_op);

            rs->strm = source;	/* only for close_source */
            rs->close_strm = true;
        }
    }
    if (code >= 0)
        pop(1);
    return code;
}