示例#1
0
/*
 * Convert a CIEBasedA color into device color.
 */
static int
client_remap_CIEBasedA(client_custom_color_params_t * pparams,
    const gs_client_color * pc, const gs_color_space * pcs,
    gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
    gs_color_select_t select)
{
    demo_color_space_data_t * pdata =
	(demo_color_space_data_t *)(pcs->pclient_color_space_data);
    frac gray = convert2frac(pc->paint.values[0], pcs->params.a->RangeA);

    /*** Demonstrate method to convert to XYZ ***/
    if (pdata->CIEtoXYZ_pis) {
	frac xyz[3];

	cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pis);
	/* We don't really do anything with these values, but this */
	/* is where a real client could convert to a device color  */
	if_debug4('|', "[c]client_remap CIEA [%g] -> XYZ [%g, %g, %g]\n",
		  pc->paint.values[0],
		  frac2float(xyz[0]), frac2float(xyz[1]), frac2float(xyz[2]));

    }
    /*
     * For demo and debug purposes, make our colors a function of the
     * intensity of the given color value and the object type.
     */
    return client_remap_DeviceGray(pparams, &gray, pcs, pdc, pis, dev, select);
}
示例#2
0
/* Render a CIEBasedDEFG color. */
int
gx_concretize_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs_in,
                      frac * pconc, const gs_imager_state * pis, gx_device *dev)
{
    int code;
    gs_color_space *pcs_icc;
    gs_client_color scale_pc;
    gs_color_space *pcs = (gs_color_space *) pcs_in;

    if_debug4('c', "[c]concretize DEFG [%g %g %g %g]\n",
              pc->paint.values[0], pc->paint.values[1],
              pc->paint.values[2], pc->paint.values[3]);
    /* If we are comming in here then we have not completed
       the conversion of the DEFG space to an ICC type.  We
       will finish that process now. */
    if (pcs->icc_equivalent == NULL) {
        code = gx_ciedefg_to_icc(&pcs_icc, pcs, pis->memory->stable_memory);
    } else {
        pcs_icc = pcs->icc_equivalent;
    }
    /* Rescale the input based upon the input range since profile is
       created to remap this range from 0 to 1 */
    if (check_range(&(pcs->params.defg->RangeDEFG.ranges[0]), 4)) {
        return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev));
    }
    /* Do the rescale from 0 to 1 */
    rescale_input_color(&(pcs->params.defg->RangeDEFG.ranges[0]), 4, pc, &scale_pc);
    /* Now the icc remap */
    return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev));
}
示例#3
0
/* Used for when we have to mash entire transform to CIEXYZ */
int
gx_psconcretize_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs,
                      frac * pconc, const gs_imager_state * pis)
{
    const gs_cie_defg *pcie = pcs->params.defg;
    int i;
    fixed hijk[4];
    frac abc[3];
    cie_cached_vector3 vec3;
    int code;

    if_debug4('c', "[c]concretize DEFG [%g %g %g %g]\n",
              pc->paint.values[0], pc->paint.values[1],
              pc->paint.values[2], pc->paint.values[3]);
    code = gx_cie_check_rendering_inline(pcs, pconc, pis);
    if (code < 0)
        return code;
    if (code == 1)
        return 0;
    /*
     * Apply DecodeDEFG, including restriction to RangeHIJK and scaling to
     * the Table dimensions.
     */
    for (i = 0; i < 4; ++i) {
        int tdim = pcie->Table.dims[i] - 1;
        double factor = pcie->caches_defg.DecodeDEFG[i].floats.params.factor;
        double v0 = pc->paint.values[i];
        const gs_range *const rangeDEFG = &pcie->RangeDEFG.ranges[i];
        double value =
            (v0 < rangeDEFG->rmin ? 0.0 : factor *
            (v0 > rangeDEFG->rmax ? rangeDEFG->rmax - rangeDEFG->rmin :
             v0 - rangeDEFG->rmin ));
        int vi = (int)value;
        double vf = value - vi;
        double v = pcie->caches_defg.DecodeDEFG[i].floats.values[vi];

        if (vf != 0 && vi < factor)
            v += vf *
                (pcie->caches_defg.DecodeDEFG[i].floats.values[vi + 1] - v);
        v = (v < 0 ? 0 : v > tdim ? tdim : v);
        hijk[i] = float2fixed(v);
    }
    /* Apply Table. */
    gx_color_interpolate_linear(hijk, &pcie->Table, abc);

#define SCALE_TO_RANGE(range, frac) ( \
       float2cie_cached(((range).rmax - (range).rmin) * frac2float(frac) + \
            (range).rmin) \
    )
    /* Scale the abc[] frac values to RangeABC cie_cached result */
    vec3.u = SCALE_TO_RANGE(pcie->RangeABC.ranges[0], abc[0]);
    vec3.v = SCALE_TO_RANGE(pcie->RangeABC.ranges[1], abc[1]);
    vec3.w = SCALE_TO_RANGE(pcie->RangeABC.ranges[2], abc[2]);
    /* Apply DecodeABC and MatrixABC. */
    if (!pis->cie_joint_caches->skipDecodeABC)
        cie_lookup_map3(&vec3 /* ABC => LMN */, &pcie->caches.DecodeABC,
                        "Decode/MatrixABC");
    GX_CIE_REMAP_FINISH(vec3, pconc, pis, pcs);
    return 0;
}
示例#4
0
static inline int get_run(stream_CFD_state *ss, stream_cursor_read *pr, const cfd_node decode[],
           int initial_bits, int min_bits, int *runlen, const char *str)
{
    cfd_declare_state;
    const cfd_node *np;
    int clen;
    cfd_load_state();

    HCD_ENSURE_BITS_ELSE(initial_bits) {
        /* We might still have enough bits for the specific code. */
        if (bits_left < min_bits)
            goto outl;
        np = &decode[hcd_peek_bits_left() << (initial_bits - bits_left)];
        if ((clen = np->code_length) > bits_left)
            goto outl;
        goto locl;
    }
    np = &decode[peek_bits(initial_bits)];
    if ((clen = np->code_length) > initial_bits) {
            IF_DEBUG(uint init_bits = peek_bits(initial_bits));
            if (!avail_bits(clen)) goto outl;
            clen -= initial_bits;
            skip_bits(initial_bits);
            ensure_bits(clen, outl);                /* can't goto outl */
            np = &decode[np->run_length + peek_var_bits(clen)];
            if_debug4('W', "%s xcode=0x%x,%d rlen=%d\n", str,
                      (init_bits << np->code_length) +
                        peek_var_bits(np->code_length),
                      initial_bits + np->code_length,
                      np->run_length);
            skip_bits(np->code_length);
    } else {
locl:
       if_debug4('W', "%s code=0x%x,%d rlen=%d\n", str,
                      peek_var_bits(clen), clen, np->run_length);
       skip_bits(clen);
    }
    *runlen = np->run_length;

    cfd_store_state();
    return(0);
outl:
    cfd_store_state();
    return(-1);
}
示例#5
0
文件: pxvendor.c 项目: hackqiang/gs
static int
vu_tag_dispatch(px_args_t * par, px_state_t * pxs)
{
    px_vendor_state_t *v_state = pxs->vendor_state;

    if (v_state->state == vu_blank) {
	if (par->source.available < 6)
	    return pxNeedData;
	v_state->tag.tag_id
	    = uint16at(par->source.data, pxs->data_source_big_endian);
	v_state->tag.bytes_expected
	    = uint32at(par->source.data + 2, pxs->data_source_big_endian);
	v_state->tag.bytes_so_far = 0;
	v_state->state = vu_tagged;
	memset(v_state->row, 0xff, v_state->data_per_row);
	par->source.data += 6;
	par->source.available -= 6;
	par->source.position += 6;
	if_debug2('I', "Signature %04X expect=%d\n",
		  v_state->tag.tag_id, v_state->tag.bytes_expected);
    };
    if (v_state->state != vu_blank) {
	if_debug4('I', "tag %04X bytes=%d/%d avail=%d\n",
		  v_state->tag.tag_id,
		  v_state->tag.bytes_so_far,
		  v_state->tag.bytes_expected, par->source.available);
	switch (v_state->tag.tag_id) {
	    case 0x9031:
		/* CLJ3600 specific; 3550 returns IllegalTag */
	    case 0x9011:
	    case 0x9021:
		return tag_dispatch_90X1(par, pxs);
		break;
	    case 0x1001:
		/* do nothing */
		if (v_state->tag.bytes_expected == 0) {
		    v_state->state = vu_blank;
		    return 0;
		}
		/* probably should return error */
		return tag_dispatch_generic(par, pxs);
		break;
	    case 0x8000:
		return tag_dispatch_8000(par, pxs);
		break;
	    case 0x8001:
		return tag_dispatch_generic(par, pxs);
		break;
	    default:
		return_error(errorIllegalTag);
		break;
	}
    }
    /* unreachable */
    return pxNeedData;
}
示例#6
0
/* Record the side bearing and character width. */
int
gs_type1_sbw(gs_type1_state * pcis, fixed lsbx, fixed lsby, fixed wx, fixed wy)
{
    if (!pcis->sb_set)
	pcis->lsb.x = lsbx, pcis->lsb.y = lsby,
	    pcis->sb_set = true;	/* needed for accented chars */
    if (!pcis->width_set)
	pcis->width.x = wx, pcis->width.y = wy,
	    pcis->width_set = true;
    if_debug4('1', "[1]sb=(%g,%g) w=(%g,%g)\n",
	      fixed2float(pcis->lsb.x), fixed2float(pcis->lsb.y),
	      fixed2float(pcis->width.x), fixed2float(pcis->width.y));
    return 0;
}
示例#7
0
gx_color_index eprn_map_cmyk_color_max(gx_device *device,
  const gx_color_value cv[])
{
  gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3];
  gx_color_index value;

#ifdef EPRN_TRACE
  if_debug4(EPRN_TRACE_CHAR,
    "! eprn_map_cmyk_color_max() called for CMYK = (%hu, %hu, %hu, %hu),\n",
      cyan, magenta, yellow, black);
#endif

  value = dominant_8bits(black);
  value |= dominant_8bits(cyan)    <<  8;
  value |= dominant_8bits(magenta) << 16;
  value |= dominant_8bits(yellow)  << 24;

#ifdef EPRN_TRACE
  if_debug1(EPRN_TRACE_CHAR, "  returning 0x%08lX.\n", (unsigned long)value);
#endif
  return value;
}
示例#8
0
gx_color_index eprn_map_cmyk_color(gx_device *device,
  const gx_color_value cv[])
{
  gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3];
  gx_color_index value = 0;
  static const gx_color_value threshold = gx_max_color_value/2;

#ifdef EPRN_TRACE
  if_debug4(EPRN_TRACE_CHAR,
    "! eprn_map_cmyk_color() called for CMYK = (%hu, %hu, %hu, %hu),\n",
      cyan, magenta, yellow, black);
#endif

  if (cyan    > threshold) value |= CYAN_BIT;
  if (magenta > threshold) value |= MAGENTA_BIT;
  if (yellow  > threshold) value |= YELLOW_BIT;
  if (black   > threshold) value |= BLACK_BIT;

#ifdef EPRN_TRACE
  if_debug1(EPRN_TRACE_CHAR, "  returning 0x%lX.\n", (unsigned long)value);
#endif
  return value;
}
示例#9
0
static int
svg_lineto(gx_device_vector *vdev, floatp x0, floatp y0,
           floatp x, floatp y, gx_path_type_t type)
{
    gx_device_svg *svg = (gx_device_svg *)vdev;
    char line[SVG_LINESIZE];

    /* hack single-page output */
    if (svg->page_count)
      return 0;

    /* skip non-drawing paths for now */
    if (!(type & gx_path_type_fill) && !(type & gx_path_type_stroke))
      return 0;

    if_debug4('_', "svg_lineto(%lf,%lf,%lf,%lf) ", x0,y0, x,y);
    svg_print_path_type(svg, type);
    if_debug0('_', "\n");

    sprintf(line, " L%lf,%lf", x, y);
    svg_write(svg, line);

    return 0;
}
示例#10
0
int
gx_remap_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs_in,
        gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
                gs_color_select_t select)
{
    gs_color_space *pcs_icc;
    int code, i;
    gs_client_color scale_pc;
    gs_color_space *pcs = (gs_color_space *) pcs_in;

    if_debug4('c', "[c]remap CIEDEFG [%g %g %g %g]\n",
              pc->paint.values[0], pc->paint.values[1],
              pc->paint.values[2], pc->paint.values[3]);
    /* If we are comming in here then we have not completed
       the conversion of the DEFG space to an ICC type.  We
       will finish that process now. */
    if (pcs->icc_equivalent == NULL) {
        code = gx_ciedefg_to_icc(&pcs_icc, pcs, pis->memory->stable_memory);
    } else {
        pcs_icc = pcs->icc_equivalent;
    }
    /* Rescale the input based upon the input range since profile is
       created to remap this range from 0 to 1 */
    if (check_range(&(pcs->params.defg->RangeDEFG.ranges[0]), 4)) {
        return((pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pis,dev,select));
    }
    /* Do the rescale from 0 to 1 */
    rescale_input_color(&(pcs->params.defg->RangeDEFG.ranges[0]), 4, pc, &scale_pc);
    /* Now the icc remap */
    code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pis,dev,select);
    /* Save unscaled data for high level device (e.g. pdfwrite) */
    for (i = 0; i < 4; i++)
        pdc->ccolor.paint.values[i] = pc->paint.values[i];
    pdc->ccolor_valid = true;
    return(code);
}
示例#11
0
gx_color_index eprn_map_cmyk_color_flex(gx_device *device,
  const gx_color_value cv[])
{
  gx_color_value cyan = cv[0], magenta = cv[1], yellow = cv[2], black = cv[3];
  gx_color_index value = 0;
  gx_color_value step;
  unsigned int level;
  const eprn_Eprn *eprn = &((eprn_Device *)device)->eprn;

#ifdef EPRN_TRACE
  if_debug4(EPRN_TRACE_CHAR,
    "! eprn_map_cmyk_color_flex() called for CMYK = (%hu, %hu, %hu, %hu),\n",
      cyan, magenta, yellow, black);
#endif

  /*  I can think of three linear methods to extract discrete values from a
      continuous intensity in the range [0, 1]:
      (a) multiply by the number of levels minus 1 and truncate,
      (b) multiply by the number of levels minus 1 and round, and
      (c) multiply by the number of levels and truncate, except for an
	  intensity of 1 in which case one returns the number of levels minus 1.
      For intensity values which can be represented exactly, i.e.,

	intensity = i/(levels-1)	for some non-negative i < levels,

      these three methods are identical. (a) is however inappropriate here
      because for less than 32 levels ghostscript already provides intensity
      values which have been adjusted to a representable level. A rounding
      error could now result in a level which is too small by one. I prefer (c)
      because it gives equal shares to all levels.

      I'm using integer arithmetic here although floating point numbers would
      be more accurate. This routine may, however, be called quite frequently,
      and the loss in accuray is acceptable as long as the values determined
      for 'step' are large compared to the number of levels. If you consider
      "large" as meaning "10 times as large", the critical boundary is at about
      81 levels. The highest number of intensity levels at present supported by
      HP DeskJets is apparently 4.

      A more accurate implementation would determine 'step' as a floating point
      value, divide the intensity by it, and take the floor (entier) of the
      result as the component intensity.
  */

  /* The order has to be (YMC)(K) from left to right */
  if (eprn->colour_model != eprn_DeviceGray) {
    step = gx_max_color_value/eprn->non_black_levels;

    level = yellow/step;
    if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1;
    value = level << eprn->bits_per_colorant;
    level = magenta/step;
    if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1;
    value = (value | level) << eprn->bits_per_colorant;
    level = cyan/step;
    if (level >= eprn->non_black_levels) level = eprn->non_black_levels - 1;
    value = (value | level) << eprn->bits_per_colorant;
  }
  if (eprn->colour_model != eprn_DeviceCMY) {
    step = gx_max_color_value/eprn->black_levels;
    level = black/step;
    if (level >= eprn->black_levels) level = eprn->black_levels - 1;
    value |= level;
  }

#ifdef EPRN_TRACE
  if_debug1(EPRN_TRACE_CHAR, "  returning 0x%lX.\n", (unsigned long)value);
#endif
  return value;
}
示例#12
0
/*
 * This is somewhat a clone of the tile_by_steps function but one
 * that performs filling from and to pdf14dev (transparency) buffers.
 * At some point it may be desirable to do some optimization here.
 */
static int
tile_by_steps_trans(tile_fill_trans_state_t * ptfs, int x0, int y0, int w0, int h0,
              gx_pattern_trans_t *fill_trans_buffer, const gx_color_tile * ptile)
{
    int x1 = x0 + w0, y1 = y0 + h0;
    int i0, i1, j0, j1, i, j;
    gs_matrix step_matrix;      /* translated by phase */
    gx_pattern_trans_t *ptrans_pat = ptile->ttrans;

    ptfs->x0 = x0, ptfs->w0 = w0;
    ptfs->y0 = y0, ptfs->h0 = h0;
    step_matrix = ptile->step_matrix;
    step_matrix.tx -= ptfs->phase.x;
    step_matrix.ty -= ptfs->phase.y;
    {
        gs_rect bbox;           /* bounding box in device space */
        gs_rect ibbox;          /* bounding box in stepping space */
        double bbw = ptile->bbox.q.x - ptile->bbox.p.x;
        double bbh = ptile->bbox.q.y - ptile->bbox.p.y;
        double u0, v0, u1, v1;

        bbox.p.x = x0, bbox.p.y = y0;
        bbox.q.x = x1, bbox.q.y = y1;
        gs_bbox_transform_inverse(&bbox, &step_matrix, &ibbox);
        if_debug10('T',
          "[T]x,y=(%d,%d) w,h=(%d,%d) => (%g,%g),(%g,%g), offset=(%g,%g)\n",
                   x0, y0, w0, h0,
                   ibbox.p.x, ibbox.p.y, ibbox.q.x, ibbox.q.y,
                   step_matrix.tx, step_matrix.ty);
        /*
         * If the pattern is partly transparent and XStep/YStep is smaller
         * than the device space BBox, we need to ensure that we cover
         * each pixel of the rectangle being filled with *every* pattern
         * that overlaps it, not just *some* pattern copy.
         */
        u0 = ibbox.p.x - max(ptile->bbox.p.x, 0) - 0.000001;
        v0 = ibbox.p.y - max(ptile->bbox.p.y, 0) - 0.000001;
        u1 = ibbox.q.x - min(ptile->bbox.q.x, 0) + 0.000001;
        v1 = ibbox.q.y - min(ptile->bbox.q.y, 0) + 0.000001;
        if (!ptile->is_simple)
            u0 -= bbw, v0 -= bbh, u1 += bbw, v1 += bbh;
        i0 = (int)fastfloor(u0);
        j0 = (int)fastfloor(v0);
        i1 = (int)ceil(u1);
        j1 = (int)ceil(v1);
    }
    if_debug4('T', "[T]i=(%d,%d) j=(%d,%d)\n", i0, i1, j0, j1);
    for (i = i0; i < i1; i++)
        for (j = j0; j < j1; j++) {
            int x = (int)fastfloor(step_matrix.xx * i +
                          step_matrix.yx * j + step_matrix.tx);
            int y = (int)fastfloor(step_matrix.xy * i +
                          step_matrix.yy * j + step_matrix.ty);
            int w = ptrans_pat->width;
            int h = ptrans_pat->height;
            int xoff, yoff;
            int px, py;

            if_debug4('T', "[T]i=%d j=%d x,y=(%d,%d)", i, j, x, y);
            if (x < x0)
                xoff = x0 - x, x = x0, w -= xoff;
            else
                xoff = 0;
            if (y < y0)
                yoff = y0 - y, y = y0, h -= yoff;
            else
                yoff = 0;
            if (x + w > x1)
                w = x1 - x;
            if (y + h > y1)
                h = y1 - y;
            if_debug6('T', "=>(%d,%d) w,h=(%d,%d) x/yoff=(%d,%d)\n",
                      x, y, w, h, xoff, yoff);
            if (w > 0 && h > 0) {

                px = imod(xoff - x, ptile->ttrans->width);
                py = imod(yoff - y, ptile->ttrans->height);

                /* Set the offsets for colored pattern fills */
                ptfs->xoff = xoff;
                ptfs->yoff = yoff;

                /* We only go through blending during tiling, if
                   there was overlap as defined by the step matrix
                   and the bounding box */

                ptile->ttrans->pat_trans_fill(x, y, x+w, y+h, px, py, ptile,
                        fill_trans_buffer);
            }
        }
    return 0;
}
示例#13
0
/*
 * Fill with non-standard X and Y stepping.
 * ptile is pdevc->colors.pattern.{m,p}_tile.
 * tbits_or_tmask is whichever of tbits and tmask is supplying
 * the tile size.
 * This implementation could be sped up considerably!
 */
static int
tile_by_steps(tile_fill_state_t * ptfs, int x0, int y0, int w0, int h0,
              const gx_color_tile * ptile,
              const gx_strip_bitmap * tbits_or_tmask,
              int (*fill_proc) (const tile_fill_state_t * ptfs,
                                int x, int y, int w, int h))
{
    int x1 = x0 + w0, y1 = y0 + h0;
    int i0, i1, j0, j1, i, j;
    gs_matrix step_matrix;      /* translated by phase */
    int code;

    ptfs->x0 = x0, ptfs->w0 = w0;
    ptfs->y0 = y0, ptfs->h0 = h0;
    step_matrix = ptile->step_matrix;
    step_matrix.tx -= ptfs->phase.x;
    step_matrix.ty -= ptfs->phase.y;
    {
        gs_rect bbox;           /* bounding box in device space */
        gs_rect ibbox;          /* bounding box in stepping space */
        double bbw = ptile->bbox.q.x - ptile->bbox.p.x;
        double bbh = ptile->bbox.q.y - ptile->bbox.p.y;
        double u0, v0, u1, v1;

        bbox.p.x = x0, bbox.p.y = y0;
        bbox.q.x = x1, bbox.q.y = y1;
        gs_bbox_transform_inverse(&bbox, &step_matrix, &ibbox);
        if_debug10('T',
          "[T]x,y=(%d,%d) w,h=(%d,%d) => (%g,%g),(%g,%g), offset=(%g,%g)\n",
                   x0, y0, w0, h0,
                   ibbox.p.x, ibbox.p.y, ibbox.q.x, ibbox.q.y,
                   step_matrix.tx, step_matrix.ty);
        /*
         * If the pattern is partly transparent and XStep/YStep is smaller
         * than the device space BBox, we need to ensure that we cover
         * each pixel of the rectangle being filled with *every* pattern
         * that overlaps it, not just *some* pattern copy.
         */
        u0 = ibbox.p.x - max(ptile->bbox.p.x, 0) - 0.000001;
        v0 = ibbox.p.y - max(ptile->bbox.p.y, 0) - 0.000001;
        u1 = ibbox.q.x - min(ptile->bbox.q.x, 0) + 0.000001;
        v1 = ibbox.q.y - min(ptile->bbox.q.y, 0) + 0.000001;
        if (!ptile->is_simple)
            u0 -= bbw, v0 -= bbh, u1 += bbw, v1 += bbh;
        i0 = (int)fastfloor(u0);
        j0 = (int)fastfloor(v0);
        i1 = (int)ceil(u1);
        j1 = (int)ceil(v1);
    }
    if_debug4('T', "[T]i=(%d,%d) j=(%d,%d)\n", i0, i1, j0, j1);
    for (i = i0; i < i1; i++)
        for (j = j0; j < j1; j++) {
            int x = (int)fastfloor(step_matrix.xx * i +
                          step_matrix.yx * j + step_matrix.tx);
            int y = (int)fastfloor(step_matrix.xy * i +
                          step_matrix.yy * j + step_matrix.ty);
            int w = tbits_or_tmask->size.x;
            int h = tbits_or_tmask->size.y;
            int xoff, yoff;

            if_debug4('T', "[T]i=%d j=%d x,y=(%d,%d)", i, j, x, y);
            if (x < x0)
                xoff = x0 - x, x = x0, w -= xoff;
            else
                xoff = 0;
            if (y < y0)
                yoff = y0 - y, y = y0, h -= yoff;
            else
                yoff = 0;
            if (x + w > x1)
                w = x1 - x;
            if (y + h > y1)
                h = y1 - y;
            if_debug6('T', "=>(%d,%d) w,h=(%d,%d) x/yoff=(%d,%d)\n",
                      x, y, w, h, xoff, yoff);
            if (w > 0 && h > 0) {
                if (ptfs->pcdev == (gx_device *) & ptfs->cdev)
                    tile_clip_set_phase(&ptfs->cdev,
                                imod(xoff - x, ptfs->tmask->rep_width),
                                imod(yoff - y, ptfs->tmask->rep_height));
                /* Set the offsets for colored pattern fills */
                ptfs->xoff = xoff;
                ptfs->yoff = yoff;
                code = (*fill_proc) (ptfs, x, y, w, h);
                if (code < 0)
                    return code;
            }
        }
    return 0;
}
示例#14
0
文件: pxvendor.c 项目: hackqiang/gs
/* TODO: consider using source.position and source.count (and possibly also phase) */
static int
read_mode10_bitmap_data(byte ** pdata, px_args_t * par, px_state_t * pxs,
			bool mode9031)
{
    px_vendor_state_t *v_state = pxs->vendor_state;
    mode10_state_t *mode10_state = &v_state->mode10_state;
    uint avail = min(par->source.available,
		     (v_state->tag.bytes_expected -
		      v_state->tag.bytes_so_far));
    const byte *pin = par->source.data;
    byte *pout;
    bool end_of_row = false;
    uint32_t pixel;
    int i;

    update_pout(pout);

    if ((v_state->state == vu_body)
	&& v_state->rowwritten == v_state->BlockHeight) {
	int code = pl_end_image(pxs->pgs, v_state->info, true);

	if (code < 0)
	    return code;

	v_state->state = vu_blank;
	v_state->rowwritten = 0;
	return 0;
    }

    /* initialize at begin of image */
    if (v_state->state == vu_tagged) {
	int code = vu_begin_image(pxs);

	if (code < 0)
	    return code;

	mode10_state->state = next_is_cmd;
	mode10_state->cursor = 0;
	v_state->rowwritten = 0;
	v_state->state = vu_body;
    }

    /* one byte at a time until end of input or end of row */
    while ((avail || mode10_state->state == process_rle)	/* process_rle does not consume */
	   &&(!end_of_row)) {
	switch (mode10_state->state) {
	    case next_is_cmd:{
		    mode10_state->cmd = *pin++;
		    --avail;
		    if_debug4('w',
			      "command:%02X row written:%d cursor:%d cached=%08X\n",
			      mode10_state->cmd,
			      v_state->rowwritten,
			      mode10_state->cursor,
			      mode10_state->cached_pixel);
		    mode10_state->offset = (mode10_state->cmd >> 3) & 0x03;
		    mode10_state->count = mode10_state->cmd & 0x07;
		    mode10_state->cursor += mode10_state->offset;	/* may be partial */
		    if ((mode10_state->offset < 3)
			&& (mode10_state->count < 7)
			&& (!srcNEW(mode10_state->cmd))
			) {
			/* completed command */
			if (mode10_state->cmd & eRLE) {
			    mode10_state->state = process_rle;
			} else {
			    /* literal, non-new */
			    update_pout(pout);
			    pixel =
				get_pixel(pout, &mode10_state->cached_pixel,
					  mode10_state->cmd,
					  v_state->color_space);

			    copy_pixel(pout, pixel);
			    mode10_state->cursor += 1;
			    if (mode10_state->count > 0) {
				mode10_state->count--;
				mode10_state->state = next_is_pixel;
			    } else
				mode10_state->state = next_is_cmd;
			}
		    } else if (mode10_state->offset == 3)
			mode10_state->state = partial_offset;
		    else if (srcNEW(mode10_state->cmd)) {
			if ((mode10_state->cmd & eRLE)
			    && (mode10_state->cursor >= v_state->SourceWidth)) {
			    /* special case */
			    if_debug0('w', "special\n");
			    mode10_state->cursor = 0;
			    end_of_row = 1;
			    mode10_state->state = next_is_cmd;
			} else
			    mode10_state->state = next_is_pixel;
		    } else if (mode10_state->count == 7)
			mode10_state->state = partial_count;
		    else
			mode10_state->state = next_is_cmd;	/* does not happen */
		    break;
		}

	    case partial_offset:{
		    uint offset = *pin++;

		    avail--;
		    mode10_state->offset += offset;
		    mode10_state->cursor += offset;
		    if (offset == 0xff)
			mode10_state->state = partial_offset;
		    else {
			/* completed offset */
			if_debug5('w',
				  "%02X row=%d offset=%d cursor=%d/%d\n",
				  mode10_state->cmd,
				  v_state->rowwritten,
				  mode10_state->offset, mode10_state->cursor,
				  v_state->SourceWidth);
			if (srcNEW(mode10_state->cmd)) {
			    if ((mode10_state->cmd & eRLE)
				&& (mode10_state->cursor >=
				    v_state->SourceWidth)) {
				/* special case */
				if_debug0('w', "special\n");
				mode10_state->cursor = 0;
				end_of_row = 1;
				mode10_state->state = next_is_cmd;
			    } else
				mode10_state->state = next_is_pixel;
			} else if (mode10_state->count == 7) {
			    mode10_state->state = partial_count;
			} else {
			    /* not new pixels, counts under 7, so we need to process there */
			    if (mode10_state->cmd & eRLE) {
				mode10_state->state = process_rle;
			    } else {
				/* literal non-new */
				update_pout(pout);
				pixel = get_pixel(pout,
						  &mode10_state->cached_pixel,
						  mode10_state->cmd,
						  v_state->color_space);
				copy_pixel(pout, pixel);
				mode10_state->cursor += 1;
				if (mode10_state->count > 0) {
				    mode10_state->count--;
				    mode10_state->state = next_is_pixel;
				} else
				    mode10_state->state = next_is_cmd;
			    }
			}
		    }
		    break;
		}

	    case partial_count:{
		    uint count = *pin++;

		    avail--;
		    mode10_state->count += count;
		    if (count == 0xff)
			mode10_state->state = partial_count;
		    else {
			/* finished count - partial count only happens on RLE */
			if_debug1('w', "count=%d\n", mode10_state->count);
			mode10_state->state = process_rle;
		    }
		    break;
		}

	    case next_is_pixel:{
		    if (!mode9031 && (avail < 3)) {
			/* get to outer loop to get more data */
			avail = 0;
			break;
		    }
		    if_debug3('w', "pixel:%02X%02X%02X\n", pin[0], pin[1],
			      pin[2]);
		    if (v_state->color_space == eGraySub) {
			/* bug in recent hpijs */
			mode10_state->cached_pixel =
			    (pin[0] << 16 | pin[0] << 8 | pin[0]) ^
			    0x00ffffff;
		    } else if (mode9031) {
			mode10_state->cached_pixel =
			    (pin[0] << 16 | pin[0] << 8 | pin[0]);
		    } else
			mode10_state->cached_pixel =
			    (pin[0] << 16 | pin[1] << 8 | pin[2]);
		    update_pout(pout);
		    update_advance_pixel(pout, pin, mode9031);
		    if (mode9031) {
			pin += 1;
			avail -= 1;
		    } else {
			pin += 3;
			avail -= 3;
		    }
		    mode10_state->cursor++;
		    if ((mode10_state->cmd & eRLE)
			&& (mode10_state->count == 7))
			mode10_state->state = partial_count;
		    else if (mode10_state->cmd & eRLE) {
			mode10_state->state = process_rle;
		    } else if (mode10_state->count > 0) {
			/* literal */
			mode10_state->count--;
			mode10_state->state = next_is_pixel;
		    } else
			mode10_state->state = next_is_cmd;
		    break;
		}

	    case process_rle:{
		    update_pout(pout);
		    pixel =
			get_pixel(pout, &mode10_state->cached_pixel,
				  mode10_state->cmd, v_state->color_space);

		    mode10_state->cursor += mode10_state->count + 2;
		    i = mode10_state->count + 2;

		    if (srcNEW(mode10_state->cmd)) {
			i--;	/* already moved cursor in the case of new pixel */
			mode10_state->cursor--;
		    }
		    while (i > 0) {
			copy_pixel(pout, pixel);
			i--;
		    }
		    mode10_state->state = next_is_cmd;
		    break;
		}

	}			/* end switch */

	/* conditional on state may not be necessary */
	if ((mode10_state->state == next_is_cmd) &&
	    (mode10_state->cursor >= v_state->SourceWidth)) {
	    mode10_state->cursor = 0;
	    end_of_row = 1;
	}
    }				/* end of while */

    par->source.available -= pin - par->source.data;	/* subtract compressed data used */
    par->source.position += pin - par->source.data;
    par->source.data = pin;	/* new compressed data position */

    if (end_of_row) {
	v_state->rowwritten++;
	return 1;
    }
    return pxNeedData;		/* not end of row so request more data */
}
示例#15
0
/* Process a buffer */
static int
s_DCTE_process(stream_state * st, stream_cursor_read * pr,
               stream_cursor_write * pw, bool last)
{
    stream_DCT_state *const ss = (stream_DCT_state *) st;
    jpeg_compress_data *jcdp = ss->data.compress;
    struct jpeg_destination_mgr *dest = jcdp->cinfo.dest;

    if_debug2('w', "[wde]process avail=%u, last=%d\n",
              (uint) (pr->limit - pr->ptr), last);
    dest->next_output_byte = pw->ptr + 1;
    dest->free_in_buffer = pw->limit - pw->ptr;
    switch (ss->phase) {
        case 0:		/* not initialized yet */
            if (gs_jpeg_start_compress(ss, TRUE) < 0)
                return ERRC;
            if_debug4('w', "[wde]width=%u, height=%u, components=%d, scan_line_size=%u\n",
                      jcdp->cinfo.image_width,
                      jcdp->cinfo.image_height,
                      jcdp->cinfo.input_components,
                      ss->scan_line_size);
            pw->ptr = dest->next_output_byte - 1;
            ss->phase = 1;
            /* falls through */
        case 1:		/* initialized, Markers not written */
            if (pw->limit - pw->ptr < ss->Markers.size)
                return 1;
            memcpy(pw->ptr + 1, ss->Markers.data, ss->Markers.size);
            pw->ptr += ss->Markers.size;
            ss->phase = 2;
            /* falls through */
        case 2:		/* still need to write Adobe marker */
            if (!ss->NoMarker) {
                static const byte Adobe[] =
                {
                    0xFF, JPEG_APP0 + 14, 0, 14,	/* parameter length */
                    'A', 'd', 'o', 'b', 'e',
                    0, 100,	/* Version */
                    0, 0,	/* Flags0 */
                    0, 0,	/* Flags1 */
                    0		/* ColorTransform */
                };

#define ADOBE_MARKER_LEN sizeof(Adobe)
                if (pw->limit - pw->ptr < ADOBE_MARKER_LEN)
                    return 1;
                memcpy(pw->ptr + 1, Adobe, ADOBE_MARKER_LEN);
                pw->ptr += ADOBE_MARKER_LEN;
                *pw->ptr = ss->ColorTransform;
#undef ADOBE_MARKER_LEN
            }
            dest->next_output_byte = pw->ptr + 1;
            dest->free_in_buffer = pw->limit - pw->ptr;
            ss->phase = 3;
            /* falls through */
        case  3:     
            /* If we have it, then write out the ICC profile */
            /* Due to size limitations allowed in APP0 markers, the profile 
               may have to be written in mutiple markers */
	        if (ss->icc_profile != NULL) {
		        static const char marker[2] = {0xFF, 0xE2};  /* JPEG_APP0 + 2 */
                byte num_mark;

                /* Number of markers */
                num_mark = ss->icc_profile->buffer_size / MAX_MARKER_DATA_SIZE;
                if (num_mark * MAX_MARKER_DATA_SIZE < ss->icc_profile->buffer_size) {
                    num_mark++;
                }
		        while (ss->icc_marker < num_mark) {
		            ulong offset = ss->icc_marker * MAX_MARKER_DATA_SIZE;
		            ulong size;

                    size = ss->icc_profile->buffer_size - offset;
                    if (size > MAX_MARKER_DATA_SIZE)
                      size = MAX_MARKER_DATA_SIZE;

                    /* In this case we are just getting started with the 
                       header of the marker.  Write that portion out */
		            if (ss->icc_position == -1) {
			            byte length_byte[2];
			            byte curr_mark = ss->icc_marker + 1;
			            ulong total_length;

			            if ((uint) (pw->limit - pw->ptr) < (sizeof(marker) + ICC_OVERHEAD))
		   	                return 1;
			            total_length = size + ICC_OVERHEAD;
			            memcpy(pw->ptr + 1, marker, sizeof(marker));
			            length_byte[0] = total_length >> 8;
			            length_byte[1] = total_length & 0xFF;
			            memcpy(pw->ptr + 3, length_byte, sizeof(length_byte));
			            memcpy(pw->ptr + 5, "ICC_PROFILE", 12); /* Null included */
			            memcpy(pw->ptr + 17, &curr_mark, 1);
			            memcpy(pw->ptr + 18, &num_mark, 1);
			            pw->ptr += sizeof(marker) + ICC_OVERHEAD;
			            ss->icc_position = 0;
		            }
                    /* Now write out the actual profile data */
		            while (ss->icc_position < size) {
			            ulong avail_bytes, num_bytes;

			            avail_bytes = (ulong) (pw->limit - pw->ptr);
			            if (avail_bytes == 0)
			                return 1;
			            num_bytes = (size - ss->icc_position);
			            if (num_bytes > avail_bytes)
			                num_bytes = avail_bytes;
			            memcpy(pw->ptr + 1,  ss->icc_profile->buffer + offset + ss->icc_position, num_bytes);
			            ss->icc_position += num_bytes;
			            pw->ptr += num_bytes;
		            }
                    /* Move on to the next marker */
		            ++ss->icc_marker;
		            ss->icc_position = -1;
	    	    }
	            dest->next_output_byte = pw->ptr + 1;
	            dest->free_in_buffer = pw->limit - pw->ptr;
	        }
	        ss->phase = 4;
	        /* falls through */
        case 4:		/* markers written, processing data */
            while (jcdp->cinfo.image_height > jcdp->cinfo.next_scanline) {
                int written;

                /*
                 * The data argument for jpeg_write_scanlines is
                 * declared as a JSAMPARRAY.  There is no corresponding
                 * const type, so we must remove const from the
                 * argument that we are passing here.  (Tom Lane of IJG
                 * judges that providing const analogues of the
                 * interface types wouldn't be worth the trouble.)
                 */
                /*const */ byte *samples = (byte *) (pr->ptr + 1);

                if_debug1('w', "[wde]next_scanline=%u\n",
                          jcdp->cinfo.next_scanline);
                if ((uint) (pr->limit - pr->ptr) < ss->scan_line_size) {
                    if (last)
                        return ERRC;	/* premature EOD */
                    return 0;	/* need more data */
                }
                written = gs_jpeg_write_scanlines(ss, &samples, 1);
                if (written < 0)
                    return ERRC;
                if_debug3('w', "[wde]write returns %d, used=%u, written=%u\n",
                          written,
                          (uint) (samples - 1 - pr->ptr),
                          (uint) (dest->next_output_byte - 1 - pw->ptr));
                pw->ptr = dest->next_output_byte - 1;
                if (!written)
                    return 1;	/* output full */
                pr->ptr += ss->scan_line_size;
            }
            ss->phase = 5;
            /* falls through */
        case 5:		/* all data processed, finishing */
            /* jpeg_finish_compress can't suspend, so write its output
             * to a fixed-size internal buffer.
             */
            dest->next_output_byte = jcdp->finish_compress_buf;
            dest->free_in_buffer = sizeof(jcdp->finish_compress_buf);
            if (gs_jpeg_finish_compress(ss) < 0)
                return ERRC;
            jcdp->fcb_size =
                dest->next_output_byte - jcdp->finish_compress_buf;
            jcdp->fcb_pos = 0;
            ss->phase = 6;
            /* falls through */
        case 6:		/* copy the final data to the output */
            if (jcdp->fcb_pos < jcdp->fcb_size) {
                int count = min(jcdp->fcb_size - jcdp->fcb_pos,
                                pw->limit - pw->ptr);

                if_debug1('w', "[wde]copying final %d\n", count);
                memcpy(pw->ptr + 1, jcdp->finish_compress_buf + jcdp->fcb_pos,
                       count);
                jcdp->fcb_pos += count;
                pw->ptr += count;
                if (jcdp->fcb_pos < jcdp->fcb_size)
                    return 1;
            }
            return EOFC;
    }