コード例 #1
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;
}
コード例 #2
0
ファイル: gxidata.c プロジェクト: SynEmira/ruby-ghostscript
/* 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_COMPONENTS];
    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_perfect(yc);
                        penum->hci = fixed2int_pixround_perfect(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_perfect(xc);
                        penum->wci = fixed2int_pixround_perfect(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;
}