コード例 #1
0
/* Process the next piece of an ImageType 1 image. */
int
gx_image1_plane_data(gx_image_enum_common_t * info,
		     const gx_image_plane_t * planes, int height,
		     int *rows_used)
{
    gx_image_enum *penum = (gx_image_enum *) info;
    gx_device *dev;
    const int y = penum->y;
    int y_end = min(y + height, penum->rect.h);
    int width_spp = penum->rect.w * penum->spp;
    int num_planes = penum->num_planes;
    int num_components_per_plane = 1;

#define BCOUNT(plane)		/* bytes per data row */\
  (((penum->rect.w + (plane).data_x) * penum->spp * penum->bps / num_planes\
    + 7) >> 3)

    fixed adjust = penum->adjust;
    ulong offsets[gs_image_max_planes];
    int ignore_data_x;
    bool bit_planar = penum->num_planes > penum->spp;
    int code;

    if (height == 0) {
	*rows_used = 0;
	return 0;
    }
    dev = setup_image_device(penum);

    /* Now render complete rows. */

    if (penum->used.y) {
	/*
	 * Processing was interrupted by an error.  Skip over rows
	 * already processed.
	 */
	int px;

	for (px = 0; px < num_planes; ++px)
	    offsets[px] = planes[px].raster * penum->used.y;
	penum->used.y = 0;
    } else
	memset(offsets, 0, num_planes * sizeof(offsets[0]));
    if (num_planes == 1 && penum->plane_depths[0] != penum->bps) {
	/* A single plane with multiple components. */
	num_components_per_plane = penum->plane_depths[0] / penum->bps;
    }
    for (; penum->y < y_end; penum->y++) {
	int px;
	const byte *buffer;
	int sourcex;
	int x_used = penum->used.x;

	if (bit_planar) {
	    /* Repack the bit planes into byte-wide samples. */
	    
	    buffer = penum->buffer;
	    sourcex = 0;
	    for (px = 0; px < num_planes; px += penum->bps)
		repack_bit_planes(planes, offsets, penum->bps, penum->buffer,
				  penum->rect.w, &penum->map[px].table,
				  penum->spread);
	    for (px = 0; px < num_planes; ++px)
		offsets[px] += planes[px].raster;
	} else {
	    /*
	     * Normally, we unpack the data into the buffer, but if
	     * there is only one plane and we don't need to expand the
	     * input samples, we may use the data directly.
	     */
	    sourcex = planes[0].data_x;
	    buffer =
		(*penum->unpack)(penum->buffer, &sourcex,
				 planes[0].data + offsets[0],
				 planes[0].data_x, BCOUNT(planes[0]),
				 &penum->map[0], penum->spread, num_components_per_plane);

	    offsets[0] += planes[0].raster;
	    for (px = 1; px < num_planes; ++px) {
		(*penum->unpack)(penum->buffer + (px << penum->log2_xbytes),
				 &ignore_data_x,
				 planes[px].data + offsets[px],
				 planes[px].data_x, BCOUNT(planes[px]),
				 &penum->map[px], penum->spread, 1);
		offsets[px] += planes[px].raster;
	    }
	}
#ifdef DEBUG
	if (gs_debug_c('b'))
	    dprintf1("[b]image1 y=%d\n", y);
	if (gs_debug_c('B')) {
	    int i, n = width_spp;

	    if (penum->bps > 8)
		n *= 2;
	    else if (penum->bps == 1 && penum->unpack_bps == 8)
		n = (n + 7) / 8;
	    dlputs("[B]row:");
	    for (i = 0; i < n; i++)
		dprintf1(" %02x", buffer[i]);
	    dputs("\n");
	}
#endif
	penum->cur.x = dda_current(penum->dda.row.x);
	dda_next(penum->dda.row.x);
	penum->cur.y = dda_current(penum->dda.row.y);
	dda_next(penum->dda.row.y);
	if (!penum->interpolate)
	    switch (penum->posture) {
		case image_portrait:
		    {		/* Precompute integer y and height, */
			/* and check for clipping. */
			fixed yc = penum->cur.y,
			    yn = dda_current(penum->dda.row.y);

			if (yn < yc) {
			    fixed temp = yn;

			    yn = yc;
			    yc = temp;
			}
			yc -= adjust;
			if (yc >= penum->clip_outer.q.y)
			    goto mt;
			yn += adjust;
			if (yn <= penum->clip_outer.p.y)
			    goto mt;
			penum->yci = fixed2int_pixround(yc);
			penum->hci = fixed2int_pixround(yn) - penum->yci;
			if (penum->hci == 0)
			    goto mt;
			if_debug2('b', "[b]yci=%d, hci=%d\n",
				  penum->yci, penum->hci);
		    }
		    break;
		case image_landscape:
		    {		/* Check for no pixel centers in x. */
			fixed xc = penum->cur.x,
			    xn = dda_current(penum->dda.row.x);

			if (xn < xc) {
			    fixed temp = xn;

			    xn = xc;
			    xc = temp;
			}
			xc -= adjust;
			if (xc >= penum->clip_outer.q.x)
			    goto mt;
			xn += adjust;
			if (xn <= penum->clip_outer.p.x)
			    goto mt;
			penum->xci = fixed2int_pixround(xc);
			penum->wci = fixed2int_pixround(xn) - penum->xci;
			if (penum->wci == 0)
			    goto mt;
			if_debug2('b', "[b]xci=%d, wci=%d\n",
				  penum->xci, penum->wci);
		    }
		    break;
		case image_skewed:
		    ;
	    }
	update_strip(penum);
	if (x_used) {
	    /*
	     * Processing was interrupted by an error.  Skip over pixels
	     * already processed.
	     */
	    dda_advance(penum->dda.pixel0.x, x_used);
	    dda_advance(penum->dda.pixel0.y, x_used);
	    penum->used.x = 0;
	}
	if_debug2('b', "[b]pixel0 x=%g, y=%g\n",
		  fixed2float(dda_current(penum->dda.pixel0.x)),
		  fixed2float(dda_current(penum->dda.pixel0.y)));
	code = (*penum->render)(penum, buffer, sourcex + x_used,
				width_spp - x_used * penum->spp, 1, dev);
	if (code < 0) {
	    /* Error or interrupt, restore original state. */
	    penum->used.x += x_used;
	    if (!penum->used.y) {
		dda_previous(penum->dda.row.x);
		dda_previous(penum->dda.row.y);
		dda_translate(penum->dda.strip.x,
			      penum->prev.x - penum->cur.x);
		dda_translate(penum->dda.strip.y,
			      penum->prev.y - penum->cur.y);
	    }
	    goto out;
	}
	penum->prev = penum->cur;
      mt:;
    }
    if (penum->y < penum->rect.h) {
	code = 0;
    } else {
	/* End of input data.  Render any left-over buffered data. */
	code = gx_image1_flush(info);
	if (code >= 0)
	    code = 1;
    }
out:
    /* Note that caller must call end_image */
    /* for both error and normal termination. */
    *rows_used = penum->y - y;
    return code;
}
コード例 #2
0
ファイル: gximage0.c プロジェクト: BoxianLai/moxiedev
/* Process the next piece of an image */
int
gx_default_image_data(gx_device *dev,
  void *info, const byte **planes, int data_x, uint raster, int height)
{	gx_image_enum *penum = info;
	int y = penum->y;
	int y_end = min(y + height, penum->rect.h);
	int width_spp = penum->rect.w * penum->spp;
	int nplanes = penum->num_planes;
	uint bcount =			/* bytes per data row */
	  (width_spp / penum->num_planes * penum->bps + 7) >> 3;
	fixed adjust = penum->adjust;
	gx_dda_fixed_point pixel0;
	ulong offset = 0;
	int ignore_data_x;
	int code;

	if ( height == 0 )
	  return 0;

	/* Set up the clipping and/or RasterOp device if needed. */

	if ( penum->clip_dev )
	   {	gx_device_clip *cdev = penum->clip_dev;
		cdev->target = dev;
		dev = (gx_device *)cdev;
	   }
	if ( penum->rop_dev )
	  {	gx_device_rop_texture *rtdev = penum->rop_dev;
		((gx_device_forward *)rtdev)->target = dev;
		dev = (gx_device *)rtdev;
	  }
	pixel0 = penum->dda.pixel0;

	/* Now render complete rows. */

	for ( ; penum->y < y_end; offset += raster, penum->y++ )
	   {	int px;
		/*
		 * Normally, we unpack the data into the buffer, but if
		 * there is only one plane and we don't need to expand the
		 * input samples, we may use the data directly.
		 */
	        int sourcex = data_x;
		const byte *buffer =
		  (*penum->unpack)(penum->buffer, &sourcex,
				   planes[0] + offset, data_x, bcount,
				   &penum->map[0].table, penum->spread);

		for ( px = 1; px < nplanes; ++px )
		  (*penum->unpack)(penum->buffer + (px << penum->log2_xbytes),
				   &ignore_data_x, planes[px] + offset,
				   data_x, bcount,
				   &penum->map[px].table, penum->spread);
#ifdef DEBUG
		if ( gs_debug_c('B') )
		  { int i, n = width_spp;
		    dputs("[B]row:");
		    for ( i = 0; i < n; i++ )
		      dprintf1(" %02x", buffer[i]);
		    dputs("\n");
		  }
#endif
		penum->cur.x = dda_current(penum->dda.row.x);
		dda_next(penum->dda.row.x);
		penum->cur.y = dda_current(penum->dda.row.y);
		dda_next(penum->dda.row.y);
		if ( !penum->interpolate )
		  switch ( penum->posture )
		    {
		    case image_portrait:
		      { /* Precompute integer y and height, */
			/* and check for clipping. */
			fixed yc = penum->cur.y,
			  yn = dda_current(penum->dda.row.y);

			if ( yn < yc )
			  { fixed temp = yn; yn = yc; yc = temp; }
			yc -= adjust;
			if ( yc >= penum->clip_outer.q.y ) goto mt;
			yn += adjust;
			if ( yn <= penum->clip_outer.p.y ) goto mt;
			penum->yci = fixed2int_pixround(yc);
			penum->hci = fixed2int_pixround(yn) - penum->yci;
			if ( penum->hci == 0 ) goto mt;
		      }	break;
		    case image_landscape:
		      { /* Check for no pixel centers in x. */
			fixed xc = penum->cur.x,
			  xn = dda_current(penum->dda.row.x);

			if ( xn < xc )
			  { fixed temp = xn; xn = xc; xc = temp; }
			xc -= adjust;
			if ( xc >= penum->clip_outer.q.x ) goto mt;
			xn += adjust;
			if ( xn <= penum->clip_outer.p.x ) goto mt;
			penum->xci = fixed2int_pixround(xc);
			penum->wci = fixed2int_pixround(xn) - penum->xci;
			if ( penum->wci == 0 ) goto mt;
		      }	break;
		    case image_skewed:
		      ;
		    }
		dda_translate(penum->dda.pixel0.x,
			      penum->cur.x - penum->prev.x);
		dda_translate(penum->dda.pixel0.y,
			      penum->cur.y - penum->prev.y);
		penum->prev = penum->cur;
		code = (*penum->render)(penum, buffer, sourcex, width_spp, 1,
					dev);
		if ( code < 0 )
		  goto err;
mt:		;
	   }
	if ( penum->y < penum->rect.h )
	  { code = 0;
	    goto out;
	  }
	/* End of data.  Render any left-over buffered data. */
	switch ( penum->posture )
	  {
	  case image_portrait:
	    {	fixed yc = dda_current(penum->dda.row.y);
		penum->yci = fixed2int_rounded(yc - adjust);
		penum->hci = fixed2int_rounded(yc + adjust) - penum->yci;
	    }	break;
	  case image_landscape:
	    {	fixed xc = dda_current(penum->dda.row.x);
		penum->xci = fixed2int_rounded(xc - adjust);
		penum->wci = fixed2int_rounded(xc + adjust) - penum->xci;
	    }	break;
	  case image_skewed:		/* pacify compilers */
	    ;
	  }
	dda_translate(penum->dda.pixel0.x, penum->cur.x - penum->prev.x);
	dda_translate(penum->dda.pixel0.y, penum->cur.y - penum->prev.y);
	code = (*penum->render)(penum, NULL, 0, width_spp, 0, dev);
	if ( code < 0 )
	  { penum->y--;
	    goto err;
	  }
	code = 1;
	goto out;
err:	/* Error or interrupt, restore original state. */
	while ( penum->y > y )
	  { dda_previous(penum->dda.row.x);
	    dda_previous(penum->dda.row.y);
	    --(penum->y);
	  }
	/* Note that caller must call end_image */
	/* for both error and normal termination. */
out:	return code;
}
コード例 #3
0
ファイル: gsdps1.c プロジェクト: 99years/plan9
/* We take the trouble to do this efficiently in the simple cases. */
int
gs_rectfill(gs_state * pgs, const gs_rect * pr, uint count)
{
    const gs_rect *rlist = pr;
    gx_clip_path *pcpath;
    uint rcount = count;
    int code;
    gx_device * pdev = pgs->device;
    gx_device_color *pdc = pgs->dev_color;
    const gs_imager_state *pis = (const gs_imager_state *)pgs;
    bool hl_color_available = gx_hld_is_hl_color_available(pis, pdc);
    gs_fixed_rect empty = {{0, 0}, {0, 0}};
    bool hl_color = (hl_color_available && 
		dev_proc(pdev, fill_rectangle_hl_color)(pdev, 
		    	    &empty, pis, pdc, NULL) == 0);

    gx_set_dev_color(pgs);
    if ((is_fzero2(pgs->ctm.xy, pgs->ctm.yx) ||
	 is_fzero2(pgs->ctm.xx, pgs->ctm.yy)) &&
	gx_effective_clip_path(pgs, &pcpath) >= 0 &&
	clip_list_is_rectangle(gx_cpath_list(pcpath)) &&
	(hl_color ||
	 pdc->type == gx_dc_type_pure ||
	 pdc->type == gx_dc_type_ht_binary ||
	 pdc->type == gx_dc_type_ht_colored
	 /* DeviceN todo: add wts case */) &&
	gs_state_color_load(pgs) >= 0 &&
	(*dev_proc(pdev, get_alpha_bits)) (pdev, go_graphics)
	<= 1 &&
        (!pgs->overprint || !pgs->effective_overprint_mode)
	) {
	uint i;
	gs_fixed_rect clip_rect;

	gx_cpath_inner_box(pcpath, &clip_rect);
	for (i = 0; i < count; ++i) {
	    gs_fixed_point p, q;
	    gs_fixed_rect draw_rect;
	    
	    if (gs_point_transform2fixed(&pgs->ctm, pr[i].p.x, pr[i].p.y, &p) < 0 ||
		gs_point_transform2fixed(&pgs->ctm, pr[i].q.x, pr[i].q.y, &q) < 0
		) {		/* Switch to the slow algorithm. */
		goto slow;
	    }
	    draw_rect.p.x = min(p.x, q.x);
	    draw_rect.p.y = min(p.y, q.y);
	    draw_rect.q.x = max(p.x, q.x);
	    draw_rect.q.y = max(p.y, q.y);
	    if (hl_color) {
		rect_intersect(draw_rect, clip_rect);
		if (draw_rect.p.x < draw_rect.q.x &&
		    draw_rect.p.y < draw_rect.q.y) {
		    code = dev_proc(pdev, fill_rectangle_hl_color)(pdev,
			     &draw_rect, pis, pdc, pcpath);
		    if (code < 0)
			return code;
		}
	    } else {
		int x, y, w, h;

		draw_rect.p.x -= pgs->fill_adjust.x;
		draw_rect.p.y -= pgs->fill_adjust.x;
		draw_rect.q.x += pgs->fill_adjust.x;
		draw_rect.q.y += pgs->fill_adjust.x;
		rect_intersect(draw_rect, clip_rect);
		x = fixed2int_pixround(draw_rect.p.x);
		y = fixed2int_pixround(draw_rect.p.y);
		w = fixed2int_pixround(draw_rect.q.x) - x;
		h = fixed2int_pixround(draw_rect.q.y) - y;
		if (w > 0 && h > 0)
    		    if (gx_fill_rectangle(x, y, w, h, pdc, pgs) < 0)
			goto slow;
	    }
	}
	return 0;
      slow:rlist = pr + i;
	rcount = count - i;
    } {
	bool do_save = !gx_path_is_null(pgs->path);

	if (do_save) {
	    if ((code = gs_gsave(pgs)) < 0)
		return code;
	    gs_newpath(pgs);
	}
	if ((code = gs_rectappend(pgs, rlist, rcount)) < 0 ||
	    (code = gs_fill(pgs)) < 0
	    )
	    DO_NOTHING;
	if (do_save)
	    gs_grestore(pgs);
	else if (code < 0)
	    gs_newpath(pgs);
    }
    return code;
}