Пример #1
0
/* Copy a monochrome bitmap. */
static int
x_copy_mono(gx_device * dev,
            const byte * base, int sourcex, int raster, gx_bitmap_id id,
            int x, int y, int w, int h,
            gx_color_index zero, gx_color_index one)
/*
 * X doesn't directly support the simple operation of writing a color
 * through a mask specified by an image.  The plot is the following:
 *  If neither color is gx_no_color_index ("transparent"),
 *      use XPutImage with the "copy" function as usual.
 *  If the color either bitwise-includes or is bitwise-included-in
 *      every color written to date
 *      (a special optimization for writing black/white on color displays),
 *      use XPutImage with an appropriate Boolean function.
 *  Otherwise, do the following complicated stuff:
 *      Create pixmap of depth 1 if necessary.
 *      If foreground color is "transparent" then
 *        invert the raster data.
 *      Use XPutImage to copy the raster image to the newly
 *        created Pixmap.
 *      Install the Pixmap as the clip_mask in the X GC and
 *        tweak the clip origin.
 *      Do an XFillRectangle, fill style=solid, specifying a
 *        rectangle the same size as the original raster data.
 *      De-install the clip_mask.
 */
{
    gx_device_X *xdev = (gx_device_X *) dev;
    int function = GXcopy;
    unsigned long
        lzero = zero,
        lone = one;
    x_pixel
        bc = lzero,
        fc = lone;

    fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
    flush_text(xdev);

    xdev->image.width = sourcex + w;
    xdev->image.height = h;
    xdev->image.data = (char *)base;
    xdev->image.bytes_per_line = raster;
    X_SET_FILL_STYLE(xdev, FillSolid);

    /* Check for null, easy 1-color, hard 1-color, and 2-color cases. */
    if (zero != gx_no_color_index) {
        if (one != gx_no_color_index) {
            /* 2-color case. */
            /* Simply replace existing bits with what's in the image. */
        } else if (!(~xdev->colors_and & bc)) {
            function = GXand;
            fc = ~(x_pixel) 0;
        } else if (!(~bc & xdev->colors_or)) {
            function = GXor;
            fc = 0;
        } else {
            goto hard;
        }
    } else {
        if (one == gx_no_color_index) {		/* no-op */
            return 0;
        } else if (!(~xdev->colors_and & fc)) {
            function = GXand;
            bc = ~(x_pixel) 0;
        } else if (!(~fc & xdev->colors_or)) {
            function = GXor;
            bc = 0;
        } else {
            goto hard;
        }
    }
    xdev->image.format = XYBitmap;
    X_SET_FUNCTION(xdev, function);
    if (bc != xdev->back_color) {
        XSetBackground(xdev->dpy, xdev->gc, (xdev->back_color = bc));
    }
    if (fc != xdev->fore_color) {
        XSetForeground(xdev->dpy, xdev->gc, (xdev->fore_color = fc));
    }
    if (zero != gx_no_color_index)
        NOTE_COLOR(xdev, lzero);
    if (one != gx_no_color_index)
        NOTE_COLOR(xdev, lone);
    put_image(xdev->dpy, xdev->dest, xdev->gc, &xdev->image,
              sourcex, 0, x, y, w, h);

    goto out;

  hard:			/* Handle the hard 1-color case. */
    if (raster > xdev->cp.raster || h > xdev->cp.height) {
        /* Must allocate a new pixmap and GC. */
        /* Release the old ones first. */
        free_cp(dev);

        /* Create the clipping pixmap, depth must be 1. */
        xdev->cp.pixmap =
            XCreatePixmap(xdev->dpy, xdev->win, raster << 3, h, 1);
        if (xdev->cp.pixmap == (Pixmap) 0) {
            lprintf("x_copy_mono: can't allocate pixmap\n");
            return_error(gs_error_VMerror);
        }
        xdev->cp.gc = XCreateGC(xdev->dpy, xdev->cp.pixmap, 0, 0);
        if (xdev->cp.gc == (GC) 0) {
            lprintf("x_copy_mono: can't allocate GC\n");
            return_error(gs_error_VMerror);
        }
        xdev->cp.raster = raster;
        xdev->cp.height = h;
    }
    /* Initialize static mask image params */
    xdev->image.format = XYBitmap;
    X_SET_FUNCTION(xdev, GXcopy);

    /* Select polarity based on fg/bg transparency. */
    if (one == gx_no_color_index) {	/* invert */
        XSetBackground(xdev->dpy, xdev->cp.gc, (x_pixel) 1);
        XSetForeground(xdev->dpy, xdev->cp.gc, (x_pixel) 0);
        X_SET_FORE_COLOR(xdev, lzero);
    } else {
        XSetBackground(xdev->dpy, xdev->cp.gc, (x_pixel) 0);
        XSetForeground(xdev->dpy, xdev->cp.gc, (x_pixel) 1);
        X_SET_FORE_COLOR(xdev, lone);
    }
    put_image(xdev->dpy, xdev->cp.pixmap, xdev->cp.gc,
              &xdev->image, sourcex, 0, 0, 0, w, h);

    /* Install as clipmask. */
    XSetClipMask(xdev->dpy, xdev->gc, xdev->cp.pixmap);
    XSetClipOrigin(xdev->dpy, xdev->gc, x, y);

    /*
     * Draw a solid rectangle through the raster clip mask.
     * Note fill style is guaranteed to be solid from above.
     */
    XFillRectangle(xdev->dpy, xdev->dest, xdev->gc, x, y, w, h);

    /* Tidy up.  Free the pixmap if it's big. */
    XSetClipMask(xdev->dpy, xdev->gc, None);
    if (raster * h > xdev->MaxTempPixmap)
        free_cp(dev);

  out:if (xdev->bpixmap != (Pixmap) 0) {
        /* We wrote to the pixmap, so update the display now. */
        x_update_add(xdev, x, y, w, h);
    }
    return 0;
}
Пример #2
0
/*
 * Continuation procedure for processing sampled values.
 */
static int
sampled_data_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_sampled_data_enum *penum = senum;
    gs_function_Sd_params_t * params =
            (gs_function_Sd_params_t *)&penum->pfn->params;
    int i, j, num_out = params->n;
    int code = 0;
    byte * data_ptr;
    double sampled_data_value_max = (double)((1 << params->BitsPerSample) - 1);
    int bps = bits2bytes(params->BitsPerSample), stack_depth_adjust = 0;

    /*
     * Check to make sure that the procedure produced the correct number of
     * values.  If not, move the stack back to where it belongs and abort
     */
    if (num_out + O_STACK_PAD + penum->o_stack_depth != ref_stack_count(&o_stack)) {
        stack_depth_adjust = ref_stack_count(&o_stack) - penum->o_stack_depth;

        if (stack_depth_adjust < 0) {
            /*
             * If we get to here then there were major problems.  The function
             * removed too many items off of the stack.  We had placed extra
             * (unused) stack stack space to allow for this but the function
             * exceeded even that.  Data on the stack may have been lost.
             * The only thing that we can do is move the stack pointer back and
             * hope.  (We have not seen real Postscript files that have this
             * problem.)
             */
            push(-stack_depth_adjust);
            ifree_object(penum->pfn, "sampled_data_continue(pfn)");
            ifree_object(penum, "sampled_data_continue((enum)");
            return_error(e_undefinedresult);
        }
    }

    /* Save data from the given function */
    data_ptr = cube_ptr_from_index(params, penum->indexes);
    for (i=0; i < num_out; i++) {
        ulong cv;
        double value;
        double rmin = params->Range[2 * i];
        double rmax = params->Range[2 * i + 1];

        code = real_param(op + i - num_out + 1, &value);
        if (code < 0)
            return code;
        if (value < rmin)
            value = rmin;
        else if (value > rmax)
            value = rmax;
        value = (value - rmin) / (rmax - rmin);		/* Convert to 0 to 1.0 */
        cv = (int) (value * sampled_data_value_max + 0.5);
        for (j = 0; j < bps; j++)
            data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8));	/* MSB first */
    }
    pop(num_out);		    /* Move op to base of result values */

    /* Check if we are done collecting data. */

    if (increment_cube_indexes(params, penum->indexes)) {
        if (stack_depth_adjust == 0)
            pop(O_STACK_PAD);	    /* Remove spare stack space */
        else
            pop(stack_depth_adjust - num_out);
        /* Execute the closing procedure, if given */
        code = 0;
        if (esp_finish_proc != 0)
            code = esp_finish_proc(i_ctx_p);

        return code;
    } else {
        if (stack_depth_adjust) {
            stack_depth_adjust -= num_out;
            push(O_STACK_PAD - stack_depth_adjust);
            for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++)
                make_null(op - i);
        }
    }

    /* Now get the data for the next location */

    return sampled_data_sample(i_ctx_p);
}
Пример #3
0
bool LASzip::setup(U16* num_items, LASitem** items, const U8 point_type, const U16 point_size, const U16 compressor)
{
  BOOL have_point14 = FALSE;
  BOOL have_gps_time = FALSE;
  BOOL have_rgb = FALSE;
  BOOL have_nir = FALSE;
  BOOL have_wavepacket = FALSE;
  I32 extra_bytes_number = 0;

  // switch over the point types we know
  switch (point_type)
  {
  case 0:
    extra_bytes_number = (I32)point_size - 20;
    break;
  case 1:
    have_gps_time = TRUE;
    extra_bytes_number = (I32)point_size - 28;
    break;
  case 2:
    have_rgb = TRUE;
    extra_bytes_number = (I32)point_size - 26;
    break;
  case 3:
    have_gps_time = TRUE;
    have_rgb = TRUE;
    extra_bytes_number = (I32)point_size - 34;
    break;
  case 4:
    have_gps_time = TRUE;
    have_wavepacket = TRUE;
    extra_bytes_number = (I32)point_size - 57;
    break;
  case 5:
    have_gps_time = TRUE;
    have_rgb = TRUE;
    have_wavepacket = TRUE;
    extra_bytes_number = (I32)point_size - 63;
    break;
  case 6:
    have_point14 = TRUE;
    extra_bytes_number = (I32)point_size - 30;
    break;
  case 7:
    have_point14 = TRUE;
    have_rgb = TRUE;
    extra_bytes_number = (I32)point_size - 36;
    break;
  case 8:
    have_point14 = TRUE;
    have_rgb = TRUE;
    have_nir = TRUE;
    extra_bytes_number = (I32)point_size - 38;
    break;
  case 9:
    have_point14 = TRUE;
    have_wavepacket = TRUE;
    extra_bytes_number = (I32)point_size - 59;
    break;
  case 10:
    have_point14 = TRUE;
    have_rgb = TRUE;
    have_nir = TRUE;
    have_wavepacket = TRUE;
    extra_bytes_number = (I32)point_size - 67;
    break;
  default:
    if (1)
    {
      char error[64];
      sprintf(error, "point type %d unknown", point_type);
      return return_error(error);
    }
  }

  if (extra_bytes_number < 0)
  {
//    char error[64];
//    sprintf(error, "point size %d too small for point type %d by %d bytes", point_size, point_type, -extra_bytes_number);
//    return return_error(error);
    fprintf(stderr, "WARNING: point size %d too small by %d bytes for point type %d. assuming point_size of %d\n", point_size, -extra_bytes_number, point_type, point_size-extra_bytes_number);
    extra_bytes_number = 0;
  }

  // create item description

  (*num_items) = 1 + !!(have_gps_time) + !!(have_rgb) + !!(have_wavepacket) + !!(extra_bytes_number);
  (*items) = new LASitem[*num_items];

  U16 i = 1;
  if (have_point14)
  {
    (*items)[0].type = LASitem::POINT14;
    (*items)[0].size = 30;
    (*items)[0].version = 0;
  }
  else
  {
    (*items)[0].type = LASitem::POINT10;
    (*items)[0].size = 20;
    (*items)[0].version = 0;
  }
  if (have_gps_time)
  {
    (*items)[i].type = LASitem::GPSTIME11;
    (*items)[i].size = 8;
    (*items)[i].version = 0;
    i++;
  }
  if (have_rgb)
  {
    if (have_nir)
    {
      (*items)[i].type = LASitem::RGBNIR14;
      (*items)[i].size = 8;
      (*items)[i].version = 0;
    }
    else
    {
      (*items)[i].type = LASitem::RGB12;
      (*items)[i].size = 6;
      (*items)[i].version = 0;
    }
    i++;
  }
  if (have_wavepacket)
  {
    (*items)[i].type = LASitem::WAVEPACKET13;
    (*items)[i].size = 29;
    (*items)[i].version = 0;
    i++;
  }
  if (extra_bytes_number)
  {
    (*items)[i].type = LASitem::BYTE;
    (*items)[i].size = extra_bytes_number;
    (*items)[i].version = 0;
    i++;
  }
  if (compressor) request_version(2);
  assert(i == *num_items);
  return true;
}
Пример #4
0
/*
 * Read generic pixel image parameters.
 */
int
gx_pixel_image_sget(gs_pixel_image_t *pim, stream *s,
		    gs_color_space *pcs)
{
    uint control;
    float decode_default_1 = 1;
    int num_components, num_decode;
    int i;
    int code;
    uint ignore;

    if ((code = sget_variable_uint(s, &control)) < 0 ||
	(code = sget_variable_uint(s, (uint *)&pim->Width)) < 0 ||
	(code = sget_variable_uint(s, (uint *)&pim->Height)) < 0
	)
	return code;
    if_debug3('b', "[b]get control=0x%x, Width=%d, Height=%d\n",
	      control, pim->Width, pim->Height);
    if (control & PI_ImageMatrix) {
	if ((code = sget_matrix(s, &pim->ImageMatrix)) < 0)
	    return code;
	debug_b_print_matrix(pim);
    } else
	gx_image_matrix_set_default((gs_data_image_t *)pim);
    pim->BitsPerComponent = ((control >> PI_BPC_SHIFT) & PI_BPC_MASK) + 1;
    pim->format = (control >> PI_FORMAT_SHIFT) & PI_FORMAT_MASK;
    pim->ColorSpace = pcs;
    num_components = gs_color_space_num_components(pcs);
    num_decode = num_components * 2;
    if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
	decode_default_1 = (float)pcs->params.indexed.hival;
    if (control & PI_Decode) {
	uint dflags = 0x10000;
	float *dp = pim->Decode;

	for (i = 0; i < num_decode; i += 2, dp += 2, dflags <<= 2) {
	    if (dflags >= 0x10000) {
		dflags = sgetc(s) + 0x100;
		if (dflags < 0x100)
		    return_error(gs_error_ioerror);
	    }
	    switch (dflags & 0xc0) {
	    case 0x00:
		dp[0] = 0, dp[1] = DECODE_DEFAULT(i + 1, decode_default_1);
		break;
	    case 0x40:
		dp[0] = DECODE_DEFAULT(i + 1, decode_default_1), dp[1] = 0;
		break;
	    case 0x80:
		dp[0] = 0;
		if (sgets(s, (byte *)(dp + 1), sizeof(float), &ignore) < 0)
		    return_error(gs_error_ioerror);
		break;
	    case 0xc0:
		if (sgets(s, (byte *)dp, sizeof(float) * 2, &ignore) < 0)
		    return_error(gs_error_ioerror);
		break;
	    }
	}
	debug_b_print_decode(pim, num_decode);
    } else {
        for (i = 0; i < num_decode; ++i)
	    pim->Decode[i] = DECODE_DEFAULT(i, decode_default_1);
    }
    pim->Interpolate = (control & PI_Interpolate) != 0;
    pim->CombineWithColor = (control & PI_CombineWithColor) != 0;
    return control >> PI_BITS;
}
Пример #5
0
/* shfill */
int
gs_shfill(gs_state * pgs, const gs_shading_t * psh)
{
    /*
     * shfill is equivalent to filling the current clipping path (or, if
     * clipping, its bounding box) with the shading, disregarding the
     * Background if any.  In order to produce reasonable high-level output,
     * we must implement this by calling gs_fill_path.
     */
    gs_pattern2_template_t pat;
    gs_matrix imat;
    gs_client_color cc;
    gs_color_space *pcs;
    gx_device_color devc;
    int code;

    /* Must install the shading color space
       to allow check_DeviceN_component_names initialize
       the color component map.
     */
    /* Don't bother with saving the old color space, color,
       and cie_joint_caches,
       because .shfill is always called within gsave-grestore -
       see gs/lib . */
    code = gs_setcolorspace(pgs, psh->params.ColorSpace);
    if (code < 0)
        return 0;
    if (psh->params.cie_joint_caches != NULL) {
        pgs->cie_joint_caches = psh->params.cie_joint_caches;
        rc_increment(pgs->cie_joint_caches);
    }
    gs_pattern2_init(&pat);
    pat.Shading = psh;
    gs_make_identity(&imat);
    code = gs_make_pattern(&cc, (gs_pattern_template_t *)&pat, &imat, pgs,
                           pgs->memory);
    if (code < 0)
        return code;
    code = gs_pattern2_set_shfill(&cc);
    if (code < 0)
        return code;
    pcs = gs_cspace_alloc(pgs->memory, &gs_color_space_type_Pattern);
    if (pcs == NULL)
        return_error(gs_error_VMerror);

    pcs->params.pattern.has_base_space = false;
    code = pcs->type->remap_color(&cc, pcs, &devc, (gs_imager_state *)pgs,
                                  pgs->device, gs_color_select_texture);
    if (code >= 0) {
        gx_device *dev = pgs->device;
        bool need_path = !dev_proc(dev, dev_spec_op)(dev,
                             gxdso_pattern_shfill_doesnt_need_path, NULL, 0);

        if (need_path) {
            gx_path cpath;

            gx_path_init_local(&cpath, pgs->memory);
            code = gx_cpath_to_path(pgs->clip_path, &cpath);
            if (code >= 0)
                code = gx_fill_path(&cpath, &devc, pgs, gx_rule_winding_number,
                                    pgs->fill_adjust.x, pgs->fill_adjust.y);
            gx_path_free(&cpath, "gs_shfill");
        } else
            code = gx_fill_path(NULL, &devc, pgs, gx_rule_winding_number,
                                pgs->fill_adjust.x, pgs->fill_adjust.y);
    }
    rc_decrement_cs(pcs, "gs_shfill");
    gs_pattern_reference(&cc, -1);
    return code;
}
Пример #6
0
/* We separate device allocation and initialization at customer request. */
int
gs_initialize_wordimagedevice(gx_device_memory * new_dev, const gs_matrix * pmat,
	      uint width, uint height, const byte * colors, int colors_size,
		    bool word_oriented, bool page_device, gs_memory_t * mem)
{
    const gx_device_memory *proto_dev;
    int palette_count = colors_size;
    int num_components = 1;
    int pcount;
    int bits_per_pixel;
    float x_pixels_per_unit, y_pixels_per_unit;
    byte palette[256 * 3];
    bool has_color;

    switch (colors_size) {
	case 3 * 2:
	    palette_count = 2;
	    num_components = 3;
	case 2:
	    bits_per_pixel = 1;
	    break;
	case 3 * 4:
	    palette_count = 4;
	    num_components = 3;
	case 4:
	    bits_per_pixel = 2;
	    break;
	case 3 * 16:
	    palette_count = 16;
	    num_components = 3;
	case 16:
	    bits_per_pixel = 4;
	    break;
	case 3 * 256:
	    palette_count = 256;
	    num_components = 3;
	case 256:
	    bits_per_pixel = 8;
	    break;
	case -16:
	    bits_per_pixel = 16;
	    palette_count = 0;
	    break;
	case -24:
	    bits_per_pixel = 24;
	    palette_count = 0;
	    break;
	case -32:
	    bits_per_pixel = 32;
	    palette_count = 0;
	    break;
	default:
	    return_error(gs_error_rangecheck);
    }
    proto_dev = (word_oriented ?
		 gdev_mem_word_device_for_bits(bits_per_pixel) :
		 gdev_mem_device_for_bits(bits_per_pixel));
    if (proto_dev == 0)		/* no suitable device */
	return_error(gs_error_rangecheck);
    pcount = palette_count * 3;
    /* Check to make sure the palette contains white and black, */
    /* and, if it has any colors, the six primaries. */
    if (bits_per_pixel <= 8) {
	const byte *p;
	byte *q;
	int primary_mask = 0;
	int i;

	has_color = false;
	for (i = 0, p = colors, q = palette;
	     i < palette_count; i++, q += 3
	    ) {
	    int mask = 1;

	    switch (num_components) {
		case 1:	/* gray */
		    q[0] = q[1] = q[2] = *p++;
		    break;
		default /* case 3 */ :		/* RGB */
		    q[0] = p[0], q[1] = p[1], q[2] = p[2];
		    p += 3;
	    }
#define shift_mask(b,n)\
  switch ( b ) { case 0xff: mask <<= n; case 0: break; default: mask = 0; }
	    shift_mask(q[0], 4);
	    shift_mask(q[1], 2);
	    shift_mask(q[2], 1);
#undef shift_mask
	    primary_mask |= mask;
	    if (q[0] != q[1] || q[0] != q[2])
		has_color = true;
	}
	switch (primary_mask) {
	    case 129:		/* just black and white */
		if (has_color)	/* color but no primaries */
		    return_error(gs_error_rangecheck);
	    case 255:		/* full color */
		break;
	    default:
		return_error(gs_error_rangecheck);
	}
    } else
	has_color = true;
    /*
     * The initial transformation matrix must map 1 user unit to
     * 1/72".  Let W and H be the width and height in pixels, and
     * assume the initial matrix is of the form [A 0 0 B X Y].
     * Then the size of the image in user units is (W/|A|,H/|B|),
     * hence the size in inches is ((W/|A|)/72,(H/|B|)/72), so
     * the number of pixels per inch is
     * (W/((W/|A|)/72),H/((H/|B|)/72)), or (|A|*72,|B|*72).
     * Similarly, if the initial matrix is [0 A B 0 X Y] for a 90
     * or 270 degree rotation, the size of the image in user
     * units is (W/|B|,H/|A|), so the pixels per inch are
     * (|B|*72,|A|*72).  We forbid non-orthogonal transformation
     * matrices.
     */
    if (is_fzero2(pmat->xy, pmat->yx))
	x_pixels_per_unit = pmat->xx, y_pixels_per_unit = pmat->yy;
    else if (is_fzero2(pmat->xx, pmat->yy))
	x_pixels_per_unit = pmat->yx, y_pixels_per_unit = pmat->xy;
    else
	return_error(gs_error_undefinedresult);
    /* All checks done, initialize the device. */
    if (bits_per_pixel == 1) {
	/* Determine the polarity from the palette. */
	gs_make_mem_device(new_dev, proto_dev, mem,
			   (page_device ? 1 : -1), 0);
	/* This is somewhat bogus, but does the right thing */
	/* in the only cases we care about. */
	gdev_mem_mono_set_inverted(new_dev,
			       (palette[0] | palette[1] | palette[2]) != 0);
    } else {
	byte *dev_palette = gs_alloc_string(mem, pcount,
					    "gs_makeimagedevice(palette)");

	if (dev_palette == 0)
	    return_error(gs_error_VMerror);
	gs_make_mem_device(new_dev, proto_dev, mem,
			   (page_device ? 1 : -1), 0);
	new_dev->palette.size = pcount;
	new_dev->palette.data = dev_palette;
	memcpy(dev_palette, palette, pcount);
	if (!has_color) {
	    new_dev->color_info.num_components = 1;
	    new_dev->color_info.max_color = 0;
	    new_dev->color_info.dither_colors = 0;
	    new_dev->color_info.gray_index = 0;
	}
    }
    /* Memory defice is always initialised as an internal device but */
    /* this is an external device */
    new_dev->retained = true;
    rc_init(new_dev, new_dev->memory, 1);

    new_dev->initial_matrix = *pmat;
    new_dev->MarginsHWResolution[0] = new_dev->HWResolution[0] =
	fabs(x_pixels_per_unit) * 72;
    new_dev->MarginsHWResolution[1] = new_dev->HWResolution[1] =
	fabs(y_pixels_per_unit) * 72;
    gx_device_set_width_height((gx_device *) new_dev, width, height);
    /* Set the ImagingBBox so we get a correct clipping region. */
    {
	gs_rect bbox;

	bbox.p.x = 0;
	bbox.p.y = 0;
	bbox.q.x = width;
	bbox.q.y = height;
	gs_bbox_transform_inverse(&bbox, pmat, &bbox);
	new_dev->ImagingBBox[0] = bbox.p.x;
	new_dev->ImagingBBox[1] = bbox.p.y;
	new_dev->ImagingBBox[2] = bbox.q.x;
	new_dev->ImagingBBox[3] = bbox.q.y;
	new_dev->ImagingBBox_set = true;
    }
    /* The bitmap will be allocated when the device is opened. */
    new_dev->is_open = false;
    new_dev->bitmap_memory = mem;
    return 0;
}
Пример #7
0
int
gx_image_no_sget(gs_image_common_t *pic, stream *s,
		 gs_color_space *pcs)
{
    return_error(gs_error_rangecheck);
}
Пример #8
0
static int
mac_open(register gx_device *dev)
{
        gx_device_macos				* mdev = (gx_device_macos *)dev;

        static short picHeader[42] = {	0x0000,									// picture size
                                                                        0x0000, 0x0000, 0x0318, 0x0264,			// bounding rect at 72dpi
                                                                        0x0011, 0x02ff, 0x0c00, 0xfffe, 0x0000,	// version/header opcodes
                                                                        0x0048, 0x0000,							// best x resolution
                                                                        0x0048, 0x0000,							// best y resolution
                                                                        0x0000, 0x0000, 0x0318, 0x0264,			// optimal src rect at 72dpi
                                                                        0x0000,									// reserved

                                                                        0x0000, 0x001e,							// DefHilite
                                                                        0x0008, 0x0048,							// PenMode
                                                                        0x001a, 0x0000, 0x0000, 0x0000,			// RGBFgCol = Black
                                                                        0x001b, 0xFFFF, 0xFFFF, 0xFFFF,			// RGBBkCol = White

                                                                        0x0001, 0x000A,							// set clipping
                                                                        0x0000, 0x0000, 0x0318, 0x0264,			// clipping rect
                                                                        0x0032, 0x0000, 0x0000, 0x0318, 0x0264	// erase rect
                                                                };

        mac_set_colordepth(dev, mdev->color_info.depth);

        mdev->numUsedFonts = 0;
        mdev->lastFontFace = -1;
        mdev->lastFontSize = -1;
        mdev->lastFontID = -1;

        mdev->pic		= (PicHandle) NewHandle(500000);
        if (mdev->pic == 0)	// error, not enough memory
	  return_error(gs_error_VMerror);

        HLockHi((Handle) mdev->pic);	// move handle high and lock it

        mdev->currPicPos	= (short*) *mdev->pic;
        memcpy(mdev->currPicPos, picHeader, 42*2);
        mdev->currPicPos += 42;

        // enter correct dimensions and resolutions
        ((short*)(*mdev->pic))[ 3]	= mdev->MediaSize[1];
        ((short*)(*mdev->pic))[ 4]	= mdev->MediaSize[0];

        ((short*)(*mdev->pic))[16] = ((short*)(*mdev->pic))[35]	= ((short*)(*mdev->pic))[40] = mdev->height;
        ((short*)(*mdev->pic))[17] = ((short*)(*mdev->pic))[36] = ((short*)(*mdev->pic))[41] = mdev->width;

        ((short*)(*mdev->pic))[10]	= (((long) X2Fix( mdev->x_pixels_per_inch )) & 0xFFFF0000) >> 16;
        ((short*)(*mdev->pic))[11]	=  ((long) X2Fix( mdev->x_pixels_per_inch )) & 0x0000FFFF;
        ((short*)(*mdev->pic))[12]	= (((long) X2Fix( mdev->y_pixels_per_inch )) & 0xFFFF0000) >> 16;
        ((short*)(*mdev->pic))[13]	=  ((long) X2Fix( mdev->y_pixels_per_inch )) & 0x0000FFFF;

        // finish picture, but dont increment pointer, we want to go on drawing
        *mdev->currPicPos = 0x00ff;

        // notify the caller that a new device was opened
        if (pgsdll_callback)
                (*pgsdll_callback) (GSDLL_DEVICE, (char *)mdev, 1);

        return 0;
}
Пример #9
0
/* one scan line at a time */
static int
os2prn_print_page(gx_device_printer * pdev, FILE * file)
{
    int raster = gdev_prn_raster(pdev);

    /* BMP scan lines are padded to 32 bits. */
    ulong bmp_raster = (raster + 3) & (~3);
    ulong bmp_raster_multi;
    int height = pdev->height;
    int depth = pdev->color_info.depth;
    byte *row;
    int y;
    int code = 0;		/* return code */
    POINTL apts[4];
    APIRET rc;
    POINTL aptsb[4];
    HBITMAP hbmp, hbmr;
    int i, lines;
    int ystart, yend;
    int yslice;

    struct bmi_s {
        BITMAPINFOHEADER2 h;
        RGB2 pal[256];
    } bmi;

    yslice = 65535 / bmp_raster;
    bmp_raster_multi = bmp_raster * yslice;
    row = (byte *) gs_malloc(pdev->memory, bmp_raster_multi, 1, "bmp file buffer");
    if (row == 0)		/* can't allocate row buffer */
        return_error(gs_error_VMerror);

    if (opdev->newframe)
        DevEscape(opdev->hdc, DEVESC_NEWFRAME, 0L, NULL, NULL, NULL);
    opdev->newframe = 1;

    /* Write the info header. */

    memset(&bmi.h, 0, sizeof(bmi.h));
    bmi.h.cbFix = sizeof(bmi.h);
    bmi.h.cx = pdev->width;	/* opdev->mdev.width; */
    /* bmi.h.cy = height; */
    bmi.h.cy = yslice;		/* size for memory PS */
    bmi.h.cPlanes = 1;
    bmi.h.cBitCount = pdev->color_info.depth;

    /* Write the palette. */

    if (depth <= 8) {
        int i;
        gx_color_value rgb[3];
        PRGB2 pq;

        bmi.h.cclrUsed = 1 << depth;
        bmi.h.cclrImportant = 1 << depth;
        for (i = 0; i != 1 << depth; i++) {
            (*dev_proc(pdev, map_color_rgb)) ((gx_device *) pdev,
                                              (gx_color_index) i, rgb);
            pq = &bmi.pal[i];
            pq->bRed = gx_color_value_to_byte(rgb[0]);
            pq->bGreen = gx_color_value_to_byte(rgb[1]);
            pq->bBlue = gx_color_value_to_byte(rgb[2]);
            pq->fcOptions = 0;
        }
    } else {
        bmi.h.cclrUsed = 0;
        bmi.h.cclrImportant = 0;
    }

    /* for GpiDrawBits */
    /* target is inclusive */
    apts[0].x = 0;
    apts[0].y = 0;		/* filled in later */
    apts[1].x = pdev->width - 1;
    apts[1].y = 0;		/* filled in later */
    /* source is not inclusive of top & right borders */
    apts[2].x = 0;
    apts[2].y = 0;
    apts[3].x = pdev->width;
    apts[3].y = 0;		/* filled in later */

    /* for GpiBitBlt */
    /* target is not inclusive */
    aptsb[0].x = opdev->clipbox[0];
    aptsb[0].y = 0;		/* filled in later */
    aptsb[1].x = opdev->clipbox[2];
    aptsb[1].y = 0;		/* filled in later */
    /* source is not inclusive */
    aptsb[2].x = opdev->clipbox[0];
    aptsb[2].y = 0;
    aptsb[3].x = opdev->clipbox[2];
    aptsb[3].y = 0;		/* filled in later */

    /* write the bits */
    ystart = opdev->clipbox[3];
    yend = opdev->clipbox[1];
    y = ystart;
    while (y > yend) {
        /* create a bitmap for the memory DC */
        hbmp = GpiCreateBitmap(opdev->hpsMem, &bmi.h, 0L, NULL, NULL);
        if (hbmp == GPI_ERROR)
            goto bmp_done;
        hbmr = GpiSetBitmap(opdev->hpsMem, hbmp);

        /* copy slice to memory bitmap */
        if (y > yend + yslice)
            lines = yslice;
        else
            lines = y - yend;
        y -= lines;
        for (i = lines - 1; i >= 0; i--)
            gdev_prn_copy_scan_lines(pdev, ystart - 1 - (y + i), row + (bmp_raster * i), raster);
        apts[0].y = 0;		/* target */
        apts[1].y = lines;
        apts[3].y = lines - 1;	/* source */
        /* copy DIB bitmap to memory bitmap */
        rc = GpiDrawBits(opdev->hpsMem, row, (BITMAPINFO2 *) & bmi, 4, apts,
                         (depth != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, 0);

        /* copy slice to printer */
        aptsb[0].y = y;
        aptsb[1].y = y + lines;
        aptsb[3].y = lines;
        rc = GpiBitBlt(opdev->hps, opdev->hpsMem, 4, aptsb, ROP_SRCCOPY, BBO_IGNORE);

        /* delete bitmap */
        if (hbmr != HBM_ERROR)
            GpiSetBitmap(opdev->hpsMem, (ULONG) 0);
        hbmr = HBM_ERROR;
        if (hbmp != GPI_ERROR)
            GpiDeleteBitmap(hbmp);
        hbmp = GPI_ERROR;
    }

  bmp_done:
    if (row)
        gs_free(pdev->memory, (char *)row, bmp_raster_multi, 1, "bmp file buffer");

    return code;
}
Пример #10
0
/* that's why this will only work on a fully white background!!!! */
static int
mac_copy_alpha(gx_device *dev, const unsigned char *base, int data_x,
                   int raster, gx_bitmap_id id, int x, int y, int w, int h,
                   gx_color_index color, int depth)
{
        gx_device_macos		* mdev = (gx_device_macos *)dev;

        ColorSpec			*colorTable;
        short				copyMode, shade, maxShade = (1 << depth) - 1, byteCount = raster * h;
        gx_color_value		rgb[3];
        colorHSV			colHSV;
        colorRGB			colRGB;
        float				saturation, value;

        fit_copy(dev, base, data_x, raster, id, x, y, w, h);

        CheckMem( byteCount*4 + 200*1024, byteCount*4 + 500*1024 );
        ResetPage();

        colorTable = (ColorSpec*) malloc(sizeof(ColorSpec) * (maxShade+1));
        if (colorTable == NULL)
	  return_error(gs_error_VMerror);

        (*dev_proc(dev, map_color_rgb))(dev, color, rgb);
        colRGB.red = rgb[0];
        colRGB.green = rgb[1];
        colRGB.blue = rgb[2];
        mac_convert_rgb_hsv(&colRGB, &colHSV);
        saturation = colHSV.s;
        value = colHSV.v;

        for (shade=0; shade <= maxShade; shade++) {
                colorTable[shade].value = maxShade -  shade;

                colHSV.s = saturation * (1.0 - (float)shade/(float)maxShade);
                colHSV.v = value + ((1.0 - value) * (float)shade/(float)maxShade);

                mac_convert_hsv_rgb(&colHSV, &colRGB);
                colorTable[shade].rgb.red   = colRGB.red;
                colorTable[shade].rgb.green = colRGB.green;
                colorTable[shade].rgb.blue  = colRGB.blue;
        }
        copyMode = srcCopy + ditherCopy;

        GSSetStdCol(mdev->currPicPos);

        if (raster < 8) {
                PICTWriteOpcode(mdev->currPicPos, 0x0090);
        } else {
                PICTWriteOpcode(mdev->currPicPos, 0x0098);
        }
        PICTWritePixMap(mdev->currPicPos, 0, 0, raster*8/depth, h, raster, 0, 0,
                                        X2Fix(mdev->x_pixels_per_inch), X2Fix(mdev->y_pixels_per_inch), depth);
        PICTWriteColorTable(mdev->currPicPos, 0, maxShade+1, colorTable);
        PICTWriteRect(mdev->currPicPos, data_x, 0, w, h);
        PICTWriteRect(mdev->currPicPos, x, y, w, h);
        PICTWriteInt(mdev->currPicPos, copyMode);
        PICTWriteDataPackBits(mdev->currPicPos, base, raster, h);

        PICT_OpEndPicGoOn(mdev->currPicPos);

        free(colorTable);

        return 0;
}
Пример #11
0
// set color info and procedures according to pixeldepth
static int
mac_set_colordepth(gx_device *dev, int depth)
{
        gx_device_macos				* mdev = (gx_device_macos *)dev;
        gx_device_color_info		* ci = &mdev->color_info;

        if (depth != 1 && depth != 4 && depth != 7 && depth != 8 && depth != 24)
	  return_error(gs_error_rangecheck);

        mdev->color_info.depth = depth;
        switch (depth)
        {
                case 1:		// Black/White
                        ci->num_components	= 1;
                        ci->max_gray		= 1;		ci->max_color		= 0;
                        ci->dither_grays	= 2;		ci->dither_colors	= 0;
                        set_dev_proc(dev, map_rgb_color, gx_default_b_w_map_rgb_color);
                        set_dev_proc(dev, map_color_rgb, gx_default_b_w_map_color_rgb);
                        break;

                case 4:		// 4Bit-Gray
                        ci->num_components	= 1;
                        ci->max_gray		= 15;		ci->max_color		= 0;
                        ci->dither_grays	= 16;		ci->dither_colors	= 0;
                        set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color);
                        set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb);
                        break;

                case 7:		// 8Bit-Gray
                        ci->depth			= 7;
                        ci->num_components	= 1;
                        ci->max_gray		= 255;		ci->max_color		= 0;
                        ci->dither_grays	= 256;		ci->dither_colors	= 0;
                        set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color);
                        set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb);
                        break;

                case 8:		// 8Bit-Color
                        ci->num_components	= 3;
                        ci->max_gray		= 15;		ci->max_color		= 5;
                        ci->dither_grays	= 16;		ci->dither_colors	= 6;
                        set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color);
                        set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb);
                        break;

/*		case 16:	// 16Bit-Color
                        ci->num_components	= 3;
                        ci->max_gray		= 255;		ci->max_color		= 65535;
                        ci->dither_grays	= 256;		ci->dither_colors	= 65536;
                        set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color);
                        set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb);
                        break;
*/
                case 24:	// 24Bit-Color
                        ci->num_components	= 3;
                        ci->max_gray		= 255;		ci->max_color		= 16777215;
                        ci->dither_grays	= 256;		ci->dither_colors	= 16777216;
                        set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color);
                        set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb);
                        break;
        }

        return 0;
}
Пример #12
0
/* The current color space is the alternate space for the DeviceN space. */
static int
zsetdevicenspace(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const ref *pcsa;
    gs_separation_name *names;
    gs_device_n_map *pmap;
    uint num_components;
    gs_color_space *pcs;
    gs_color_space *pacs;
    ref_colorspace cspace_old;
    gs_function_t *pfn;
    int code;

    /* Verify that we have an array as our input parameter */
    check_read_type(*op, t_array);
    if (r_size(op) < 4 || r_size(op) > 5)
	return_error(e_rangecheck);

    /* pcsa is a pointer to the color names array (element 1 in input array) */
    pcsa = op->value.const_refs + 1;
    if (!r_is_array(pcsa))
	return_error(e_typecheck);
    num_components = r_size(pcsa);
    if (num_components == 0)
	return_error(e_rangecheck);
    if (num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
	return_error(e_limitcheck);

    /* Check tint transform procedure.  Note: Cheap trick to get pointer to it.
       The tint transform procedure is element 3 in the input array */
    check_proc(pcsa[2]);
    
    /* The alternate color space has been selected as the current color space */
    pacs = gs_currentcolorspace(igs);

    code = gs_cspace_new_DeviceN(&pcs, num_components, pacs, imemory);
    if (code < 0)
	return code;
    names = pcs->params.device_n.names;
    pmap = pcs->params.device_n.map;
    pcs->params.device_n.get_colorname_string = gs_get_colorname_string;

    /* Pick up the names of the components */
    {
	uint i;
	ref sname;

	for (i = 0; i < num_components; ++i) {
	    array_get(imemory, pcsa, (long)i, &sname);
	    switch (r_type(&sname)) {
		case t_string:
		    code = name_from_string(imemory, &sname, &sname);
		    if (code < 0) {
			rc_decrement(pcs, ".setdevicenspace");
			return code;
		    }
		    /* falls through */
		case t_name:
		    names[i] = name_index(imemory, &sname);
		    break;
		default:
		    rc_decrement(pcs, ".setdevicenspace");
		    return_error(e_typecheck);
	    }
	}
    }

    /* Now set the current color space as DeviceN */

    cspace_old = istate->colorspace;
    /*
     * pcsa is a pointer to element 1 (2nd element)  in the DeviceN
     * description array.  Thus pcsa[2] is element #3 (4th element)
     * which is the tint transform.
     */
    istate->colorspace.procs.special.device_n.layer_names = pcsa[0];
    istate->colorspace.procs.special.device_n.tint_transform = pcsa[2];    
    pfn = ref_function(pcsa + 2);	/* See comment above */
    if (!pfn)
	code = gs_note_error(e_rangecheck);

    if (code < 0) {
	istate->colorspace = cspace_old;
	rc_decrement_only(pcs, "zsetdevicenspace");
	return code;
    }
    gs_cspace_set_devn_function(pcs, pfn);
    code = gs_setcolorspace(igs, pcs);
    /* release reference from construction */
    rc_decrement_only(pcs, "zsetdevicenspace");
    if (code < 0) {
	istate->colorspace = cspace_old;
	return code;
    }
    pop(1);
    return 0;
}
Пример #13
0
/* <string> <numarray|numstring> xyshow - */
static int
moveshow(i_ctx_t *i_ctx_p, bool have_x, bool have_y)
{
    os_ptr op = osp;
    gs_text_enum_t *penum;
    int code = op_show_setup(i_ctx_p, op - 1);
    int format;
    uint i, size, widths_needed;
    float *values;
    bool CPSI_mode = gs_currentcpsimode(imemory);

    if (code != 0)
        return code;
    format = num_array_format(op);
    if (format < 0)
        return format;
    size = num_array_size(op, format);
    values = (float *)ialloc_byte_array(size, sizeof(float), "moveshow");
    if (values == 0)
        return_error(e_VMerror);
    if (CPSI_mode)
        memset(values, 0, size * sizeof(values[0])); /* Safety. */
    if ((code = gs_xyshow_begin(igs, op[-1].value.bytes, r_size(op - 1),
                                (have_x ? values : (float *)0),
                                (have_y ? values : (float *)0),
                                size, imemory, &penum)) < 0) {
        ifree_object(values, "moveshow");
        return code;
    }
    if (CPSI_mode) {
        /* CET 13-29.PS page 2 defines a longer width array
           then the text requires, and CPSI silently ignores extra elements.
           So we need to compute exact number of characters
           to know how many elements to load and type check. */
        code = gs_text_count_chars(igs, gs_get_text_params(penum), imemory);
        if (code < 0)
            return code;
        widths_needed = code;
        if (have_x && have_y)
            widths_needed <<= 1;
    } else
        widths_needed = size;
    for (i = 0; i < widths_needed; ++i) {
        ref value;

        switch (code = num_array_get(imemory, op, format, i, &value)) {
        case t_integer:
            values[i] = (float)value.value.intval; break;
        case t_real:
            values[i] = value.value.realval; break;
        case t_null:
            code = gs_note_error(e_rangecheck);
            /* falls through */
        default:
            ifree_object(values, "moveshow");
            return code;
        }
    }
    if ((code = op_show_finish_setup(i_ctx_p, penum, 2, NULL)) < 0) {
        ifree_object(values, "moveshow");
        return code;
    }
    pop(2);
    return op_show_continue(i_ctx_p);
}
Пример #14
0
/**
* handle_client:  Main application layer thread for each client
* @author ndemarinis (Basic implementation)
*/
void *handle_client(void *data){
    struct client_handler_data *clnt = (struct client_handler_data *)data;
    
    int pipes[2]; // Make a pipe to connect to the layer stack
    uint16_t cur_seq_num = 0;
    
    pid_t clnt_pid; // PID we receive from the client before startup
    struct layer_stack *stack; // Work data for layer stack implementation

    // Grab the client's identifier
    if((recv(clnt->sock, &clnt_pid, sizeof(pid_t), 0) != sizeof(pid_t)))
      die_with_error("Error receiving PID from client!");

    stack = create_layer_stack(clnt->sock, clnt_pid, pipes); // Initialize all of our layer threads

    sleep(1); // Wait a second for the thread creation to settle


    int bytes_read;
    struct packet client_p;
    struct packet response_p;
    while(1){
        //Wait for a packet to come in
        bytes_read = read(pipe_read(pipes), &client_p, sizeof(struct packet));

	if(!bytes_read) // If we read nothing, it's time to terminate.  
	  {
	    dprintf(DID_INFO, "APP:  Read 0 bytes from layer stack.  Terminating!\n");
	    break;
	  }

        int opcode = client_p.opcode;
        //login
        if (opcode == __LOGIN_CODE){
            //payload is just the username for this opcode
            if(login(client_p.payload) == 0){
                //response code for SUCCESS
                response_p.opcode = 0x05;
                response_p.seq_num = cur_seq_num;
                cur_seq_num++;
                //no payload basic success response!
                response_p.length = 0;

                send_packet(pipes, response_p);
            } else {
                //basic response packet signaling invailed login
                response_p.opcode = __NOT_AUTHORIZED_CODE;
                response_p.seq_num = cur_seq_num;
                cur_seq_num++;
                response_p.length = 0;

                send_packet(pipes, response_p);
            }
        //create record
        } else if (opcode == __CREATE_CODE){
            //payload syntax "<firstName>,<lastName>,<location>"
            char *firstName = strtok(client_p.payload, ",");
            char *lastName = strtok(NULL, ",");
            char *location = strtok(NULL, "");

            //replace null with proper response once I determine what its for!
            char *response = malloc(10*sizeof(response));
            int resp = createRecord(firstName, lastName, location, response);
            //if a 0 was not returned an error occured
            if (resp) {
                //send an error back!
                return_error(pipes, resp, &cur_seq_num);
            } else {
                //send back the data
                return_response(pipes, response, &cur_seq_num);
            }
        //query record
        } else if (opcode == __QUERY_CODE){
            //payload syntax "NAME:<firstName>,<lastName>"
            //               "LOCATION:<location>"
            char *queryType = strtok(client_p.payload, ":");

            bodyEntry *responses;
            int resp;
            //two types of query name and location
            if (strcmp(queryType, "NAME") == 0){
                //handle queries by name
                char *firstName = strtok(NULL, ",");
                char *lastName = strtok(NULL, "");
                
		int respCount;
                //get the query response from the database
                resp = queryRecordByName(firstName, lastName, &responses, &respCount);

                //if resp is not 0 then an error occured
                if (resp){
                    //send an error back!
                    return_error(pipes, resp, &cur_seq_num);
                } else {
                    //send the information back to the client!
                    char response[respCount*(16+20+36+3)];
		    memset(response,0,sizeof(response));
                    int i, rID;
		    char recordID[10];
                    for (i = 0; i < respCount; i++){
                        rID = responses[i].id;
                        sprintf(recordID, "%09d", rID);
                        strcat(response, recordID);
                        strcat(response, ",");
                        strcat(response, responses[i].location);
                        strcat(response, ",");
                    }
                    return_response(pipes, response, &cur_seq_num);
                }
            } else if (strcmp(queryType, "LOCATION") == 0){
                //handle queries by location
                char *location = strtok(NULL, "");

		int respCount;
                //get the query response from the database
                resp = queryRecordByLocation(location, &responses, &respCount);

                //if resp is not 0 then an error occured
                if (resp){
                    //send an error back!
                    return_error(pipes, resp, &cur_seq_num);
                } else {
                    //send the information back to the client!
                    char response[respCount*(16+20+36+3)];
		    memset(response,0,sizeof(response));
                    int i, rID;
		    char recordID[10];
                    for (i = 0; i < respCount; i++){
                        rID = responses[i].id;
                        sprintf(recordID, "%09d", rID);
                        strcat(response, recordID);
                        strcat(response, ",");
                        strcat(response, responses[i].firstName);
                        strcat(response, ",");
                        strcat(response, responses[i].lastName);
                        strcat(response, ",");
                    }
                    return_response(pipes, response, &cur_seq_num);
                }
            }
        //update record
        } else if (opcode == __UPDATE_CODE){
            //payload syntax "<recordId>,<firstName>,<lastName>"
            char *recordId = strtok(client_p.payload, ",");
            char *firstName = strtok(NULL, ",");
            char *lastName = strtok(NULL, "");

            //convert recordID into an integer
            int rId = atoi(recordId);
            int resp = updateRecordName(rId, firstName, lastName);

            //if resp is not 0 then an error occured
            if (resp){
                //send an error back!
                return_error(pipes, resp, &cur_seq_num);
            } else {
                //send the information back to the client!
                //basic success packet so an empty string is given for the payload
                return_response(pipes, "", &cur_seq_num);
            }
        //add picture
        } else if (opcode == __ADD_PIC_CODE){
            /*payload syntax 1st   packet:   "<firstName>,<lastName>,<imageSize>"
                             2nd+ packets:   "<pictureData>"
                             These picture data packets will continue until the entirety of the picture has been transmitted
                             The file is complete once the server has recieved a packet ending with an EOF character
            */
            //get the name information from the first packet transmitted
            char *firstName = strtok(client_p.payload, ",");
            char *lastName = strtok(NULL, ",");
            char *imageSize = strtok(NULL, "");

            unsigned long size = atol(imageSize);

            //create an array capable of holding the entire image
            char pictureData[size];
            int i = 0;

	    // DEBUG:  Write out the file as we read it
	    FILE *out = fopen("server_output.png", "w+");

            //start recieving the picture data, continue until this entire picture has been recieved
            while(i < size - 1){
                //read in a new packet of data
                bytes_read = read(pipe_read(pipes), &client_p, sizeof(struct packet));
		dprintf(DID_APP_INFO, "APP:  Received packet of %d bytes with payload of %d bytes.\n", 
		       bytes_read, client_p.length);

                //store the picture data into the array
                memcpy(pictureData + i, client_p.payload, client_p.length);

                //increment i by the length of the payload
                i += client_p.length;
            }

	    // DEBUG:  Write out that whole array to the test file
	    printf("Received picture of %d total bytes.\n", i);
	    write(fileno(out), pictureData, i);

	    // DEBUG:  Close that file
	    fflush(out);
	    fclose(out);	    

            char add_response[10];
            int resp = addPicture(firstName, lastName, pictureData, add_response);

            if (resp){
                //send an error back!
                return_error(pipes, resp, &cur_seq_num);
            } else {
                //send the information back to the client!
                return_response(pipes, add_response, &cur_seq_num);
            }

        //connect picture
        } else if (opcode == __CONNECT_PIC_CODE){
            //payload syntax "<pictureID>,<recordID>"
            char *pictureID = strtok(client_p.payload, ",");
            char *recordID = strtok(NULL, "");

            int pID = atoi(pictureID);
            int rID = atoi(recordID);

            int resp = connectPictureToRecord(pID, rID);

            if (resp){
                //send and error back!
                return_error(pipes, resp, &cur_seq_num);
            } else {
                //send the success packet back!
                return_response(pipes, "", &cur_seq_num);
            }
        //logout!
        } else if (opcode == __LOGOUT_CODE){
            //payload syntax NONE
            //break out of the while loop containin this and allow the thread processing this client to exit
	    logout();
            break;
        //download picture
        } else if (opcode == __QUERY_PIC_CODE){
            //payload syntax "<pictureID>"
            char *pictureID = strtok(client_p.payload, "");
            int pID = atoi(pictureID);

            char pictureData[__MAX_IMAGE_SIZE];
            int resp = queryPicture(pID, pictureData);

            if (resp){
                //send an error back!
                return_error(pipes, resp, &cur_seq_num);
            } else {
                //break the image into packets and send it back to the client!
                //write the data into a tempory file handle for simple reading when breaking into packets
                //base the temporary file off of the pid to ensure uniqueness
                char filename[MAX_FILENAME_SIZE];
                int pid = getpid();
                char cpid[10];
                sprintf(cpid, "%d", pid);
                strcpy(filename, "temp_");
                strcat(filename, cpid);
                strcat(filename, ".jpg");
                //open the temp file for writing
                FILE *picture = fopen(filename, "w");
                //write the entire image to the file!
                fwrite(pictureData, 1, sizeof(pictureData), picture);

                //send a simple packet informing the client of the size of the image that it is going to recieve
                response_p.opcode = 5;
                response_p.seq_num = cur_seq_num;
                cur_seq_num++;
                sprintf(response_p.payload, "%lu", sizeof(pictureData));
                response_p.length = strlen(response_p.payload);
                send_packet(pipes, response_p);

                //read into packets and send them until the end of file is reached
                //note this uses the same packet pointer the entire time so the opcode does not need to be set again
                response_p.opcode = 5;
                while(!feof(picture)){
                    //read at most 251 bytes of the picture into the packets payload
                    int readSize = fread(response_p.payload, 1, MAX_PAYLOAD, picture);
                    //if there was no error then add the sequence number and the length to the packet then send it
                    //DO NOT SET THE SEND FLAG, this will handle it on its own since there could be multiple sends
                    if (!ferror(picture)){
                        response_p.seq_num = cur_seq_num;
                        cur_seq_num++;

                        response_p.length = (uint8_t)readSize;

                        //send this packet down to the data link layer
                        send_packet(pipes, response_p);
                    } else {
                        //an error occured return an error code so that the client can stop processing the image and drop the corrupt data
                        return_error(pipes, 1, &cur_seq_num);
                        break;
                    }
                }
                //close the picture that was being read
                fclose(picture);
                //delete the temporary file
                remove(filename);
            }
        }
    // Send it straight back
    //printf("APP:  Sending string of %d bytes:  %s\n", to_read, read_buffer);
    //write(pipe_write(pipes), read_buffer, to_read);
    }
    
    curr_clients--;
    pthread_exit(NULL);
}
Пример #15
0
/*
 * Create an Indexed color space.  This is a single-use procedure,
 * broken out only for readability.
 */
static int
pdf_indexed_color_space(gx_device_pdf *pdev, cos_value_t *pvalue,
                        const gs_color_space *pcs, cos_array_t *pca)
{
    const gs_indexed_params *pip = &pcs->params.indexed;
    const gs_color_space *base_space = pcs->base_space;
    int num_entries = pip->hival + 1;
    int num_components = gs_color_space_num_components(base_space);
    uint table_size = num_entries * num_components;
    /* Guess at the extra space needed for PS string encoding. */
    uint string_size = 2 + table_size * 4;
    uint string_used;
    byte buf[100];		/* arbitrary */
    stream_AXE_state st;
    stream s, es;
    gs_memory_t *mem = pdev->pdf_memory;
    byte *table;
    byte *palette;
    cos_value_t v;
    int code;

    /* PDF doesn't support Indexed color spaces with more than 256 entries. */
    if (num_entries > 256)
        return_error(gs_error_rangecheck);
    if (pdev->CompatibilityLevel < 1.3 && !pdev->ForOPDFRead) {
        switch (gs_color_space_get_index(pcs)) {
        case gs_color_space_index_Pattern:
        case gs_color_space_index_Separation:
        case gs_color_space_index_Indexed:
        case gs_color_space_index_DeviceN:
            return_error(gs_error_rangecheck);
        default:
            DO_NOTHING;
        }

    }
    table = gs_alloc_string(mem, string_size, "pdf_color_space(table)");
    palette = gs_alloc_string(mem, table_size, "pdf_color_space(palette)");
    if (table == 0 || palette == 0) {
        gs_free_string(mem, palette, table_size,
                       "pdf_color_space(palette)");
        gs_free_string(mem, table, string_size,
                       "pdf_color_space(table)");
        return_error(gs_error_VMerror);
    }
    s_init(&s, mem);
    swrite_string(&s, table, string_size);
    s_init(&es, mem);
    s_init_state((stream_state *)&st, &s_PSSE_template, NULL);
    s_init_filter(&es, (stream_state *)&st, buf, sizeof(buf), &s);
    sputc(&s, '(');
    if (pcs->params.indexed.use_proc) {
        gs_client_color cmin, cmax;
        byte *pnext = palette;
        int i, j;

        /* Find the legal range for the color components. */
        for (j = 0; j < num_components; ++j)
            cmin.paint.values[j] = (float)min_long,
                                   cmax.paint.values[j] = (float)max_long;
        gs_color_space_restrict_color(&cmin, base_space);
        gs_color_space_restrict_color(&cmax, base_space);
        /*
         * Compute the palette values, with the legal range for each
         * one mapped to [0 .. 255].
         */
        for (i = 0; i < num_entries; ++i) {
            gs_client_color cc;

            gs_cspace_indexed_lookup(pcs, i, &cc);
            for (j = 0; j < num_components; ++j) {
                float v = (cc.paint.values[j] - cmin.paint.values[j])
                          * 255 / (cmax.paint.values[j] - cmin.paint.values[j]);

                *pnext++ = (v <= 0 ? 0 : v >= 255 ? 255 : (byte)v);
            }
        }
    } else
        memcpy(palette, pip->lookup.table.data, table_size);
    if (gs_color_space_get_index(base_space) ==
            gs_color_space_index_DeviceRGB
       ) {
        /* Check for an all-gray palette3. */
        int i;

        for (i = table_size; (i -= 3) >= 0; )
            if (palette[i] != palette[i + 1] ||
                    palette[i] != palette[i + 2]
               )
                break;
        if (i < 0) {
            /* Change the color space to DeviceGray. */
            for (i = 0; i < num_entries; ++i)
                palette[i] = palette[i * 3];
            table_size = num_entries;
            base_space = gs_cspace_new_DeviceGray(mem);
        }
    }
    stream_write(&es, palette, table_size);
    gs_free_string(mem, palette, table_size, "pdf_color_space(palette)");
    sclose(&es);
    sflush(&s);
    string_used = (uint)stell(&s);
    table = gs_resize_string(mem, table, string_size, string_used,
                             "pdf_color_space(table)");
    /*
     * Since the array is always referenced by name as a resource
     * rather than being written as a value, even for in-line images,
     * always use the full name for the color space.
     *
     * We don't have to worry about the range of the base space:
     * in PDF, unlike PostScript, the values from the lookup table are
     * scaled automatically.
     */
    if ((code = pdf_color_space_named(pdev, pvalue, NULL, base_space,
                                      &pdf_color_space_names, false, NULL, 0)) < 0 ||
            (code = cos_array_add(pca,
                                  cos_c_string_value(&v,
                                          pdf_color_space_names.Indexed
                                          /*pcsn->Indexed*/))) < 0 ||
            (code = cos_array_add(pca, pvalue)) < 0 ||
            (code = cos_array_add_int(pca, pip->hival)) < 0 ||
            (code = cos_array_add_no_copy(pca,
                                          cos_string_value(&v, table,
                                                  string_used))) < 0
       )
        return code;
    return 0;
}
Пример #16
0
/*
 * Reconstruct a halftone component from its serial representation. The
 * buffer provided is expected to be large enough to hold the entire
 * halftone component.
 *
 * Because halftone components are allocated in arrays (an unfortunate
 * arrangement, as it prevents component sharing), a pointer to an
 * already allocated component structure is passed as an operand, as
 * opposed to the more normal mechanism that would have a read routine
 * allocate the component. The memory pointer is still passed, however,
 * as the levels and bit_data arrays must be allocated.
 *
 * Returns the number of bytes read, or < 0 in the event of an error.
 */
static int
gx_ht_read_component(
    gx_ht_order_component * pcomp,
    const byte *            data,
    uint                    size,
    gs_memory_t *           mem )
{
    gx_ht_order             new_order;
    const byte *            data0 = data;
    const byte *            data_lim = data + size;
    int                     i, code, levels_size, bits_size;
    const gx_dht_proc *     phtrp = gx_device_halftone_list;

    /* check the order type */
    if (size == 0)
        return_error(gs_error_rangecheck);

    /*
     * For performance reasons, the number encoding macros do not
     * support full buffer size verification. The code below verifies
     * that a minimum number of bytes is available, then converts
     * blindly and does not check again until the various integers are
     * read. Obviously this can be hazardous, but should not be a
     * problem in practice, as the calling code should have verified
     * that the data provided holds the entire halftone.
     */
    if (size < 7)
        return_error(gs_error_rangecheck);
    enc_u_getw(new_order.width, data);
    enc_u_getw(new_order.height, data);
    enc_u_getw(new_order.shift, data);
    enc_u_getw(new_order.num_levels, data);
    enc_u_getw(new_order.num_bits, data);
    if (data >= data_lim)
        return_error(gs_error_rangecheck);
    new_order.procs = &ht_order_procs_table[*data++];

    /* calculate the space required for levels and bit data */
    levels_size = new_order.num_levels * sizeof(new_order.levels[0]);
    bits_size = new_order.num_bits * new_order.procs->bit_data_elt_size;

    /* + 1 below is for the minimal transfer function */
    if (data + bits_size + levels_size + 1 > data_lim)
        return_error(gs_error_rangecheck);

    /*
     * Allocate the levels and bit data structures. The gx_ht_alloc_ht_order
     * has a name that is both strange and misleading. The routine does
     * not allocate a halftone order. Rather, it initializes the order,
     * and allocates the levels and bit data arrays. In particular, it
     * sets all of the following fields:
     *
     *    width = operand width
     *    height = operand height
     *    raster = bitmap_raster(operand width)
     *    shift = operand shift
     *    orig_height = operand height
     *    orig_shift = operand strip_shift
     *    num_levels = operand num_levels
     *    num_bits = operand num_bits
     *    procs = operand procs
     *    levels = newly allocated array
     *    bit_data = new allocated array
     *    cache = 0
     *    transfer = 0
     *
     * Since several of the list fields are already set, this call
     * effectively sets them to the values they already have. This is a
     * bit peculiar but not otherwise harmful.
     *
     * For reasons that are not known and are probably historical, the
     * procedure does not initialize the params or screen_params fields.
     * In the unlikely event that these fields are ever contain pointers,
     * we initialize them explicitly here. Wse, params, and scrren_params
     * probably should not occur in the device halftone at all; they are
     * themselves historical artifacts.
     */
    code = gx_ht_alloc_ht_order( &new_order,
                                 new_order.width,
                                 new_order.height,
                                 new_order.num_levels,
                                 new_order.num_bits,
                                 new_order.shift,
                                 new_order.procs,
                                 mem );
    if (code < 0)
        return code;
    memset(&new_order.params, 0, sizeof(new_order.params));
    memset(&new_order.screen_params, 0, sizeof(new_order.screen_params));

    /* fill in the levels and bit_data arrays */
    memcpy(new_order.levels, data, levels_size);
    data += levels_size;
    memcpy(new_order.bit_data, data, bits_size);
    data += bits_size;

    /* process the transfer function */
    code = gx_ht_read_tf(&new_order.transfer, data, data_lim - data, mem);
    if (code < 0) {
        gx_ht_order_release(&new_order, mem, false);
        return code;
    }
    data += code;

    /*
     * Check to see if the order is in ROM. Since it is possible (if not
     * particularly likely) that the command list writer and renderer do
     * not have the same set of ROM-based halftones, the full halftone
     * order is transmitted and compared against the set ROM set provided
     * by the renderer. If there is a match, the transmitted version is
     * discarded and the ROM version used.
     *
     * It is not clear which, if any or the currently used devices
     * provide a ROM-based halftone order set.
     */
    for (i = 0; phtrp[i] != 0; i++) {
        const gx_device_halftone_resource_t *const *    pphtr = phtrp[i]();
        const gx_device_halftone_resource_t *           phtr;

        while ((phtr = *pphtr++) != 0) {
            /*
             * This test does not check for strict equality of the order,
             * nor is strict equality necessary. The ROM data will replace
             * just the levels and bit_data arrays of the transmitted
             * order, so only these must be the same. We don't even care
             * if the ROM's levels and bit_data arrays are larger; we
             * will never check values beyond the range required by the
             * current order.
             */
            if ( phtr->num_levels * sizeof(phtr->levels[0]) >= levels_size &&
                 phtr->Width * phtr->Height * phtr->elt_size >= bits_size  &&
                 memcmp(phtr->levels, new_order.levels, levels_size) == 0  &&
                 memcmp(phtr->bit_data, new_order.bit_data, bits_size) == 0  ) {
                /* the casts below are required to discard const qualifiers */
                gs_free_object(mem, new_order.bit_data, "gx_ht_read_component");
                new_order.bit_data = (void *)phtr->bit_data;
                gs_free_object(mem, new_order.levels, "gx_ht_read_component");
                new_order.levels = (uint *)phtr->levels;
                goto done;
            }
        }
    }

  done:
    /* everything OK, save the order and return the # of bytes read */
    pcomp->corder = new_order;
    pcomp->cname = 0;
    return data - data0;
}
Пример #17
0
/*
 * Create a PDF color space corresponding to a PostScript color space.
 * For parameterless color spaces, set *pvalue to a (literal) string with
 * the color space name; for other color spaces, create a cos_array_t if
 * necessary and set *pvalue to refer to it.  In the latter case, if
 * by_name is true, return a string /Rxxxx rather than a reference to
 * the actual object.
 *
 * If ppranges is not NULL, then if  the domain of the color space had
 * to be scaled (to convert a CIEBased space to ICCBased), store a pointer
 * to the ranges in *ppranges, otherwise set *ppranges to 0.
 */
int
pdf_color_space_named(gx_device_pdf *pdev, cos_value_t *pvalue,
                      const gs_range_t **ppranges,
                      const gs_color_space *pcs_in,
                      const pdf_color_space_names_t *pcsn,
                      bool by_name, const byte *res_name, int name_length)
{
    const gs_color_space *pcs;
    gs_color_space_index csi;
    cos_array_t *pca;
    cos_dict_t *pcd;
    cos_value_t v;
    const gs_cie_common *pciec;
    gs_function_t *pfn;
    const gs_range_t *ranges = 0;
    uint serialized_size;
    byte *serialized = NULL, serialized0[100];
    pdf_resource_t *pres = NULL;
    int code;
#if 0
    bool islab = false;
#endif

    /* If color space is CIE based and we have compatibility then go ahead and use the ICC alternative */
    if ((pdev->CompatibilityLevel < 1.3) || !gs_color_space_is_PSCIE(pcs_in) ) {
        pcs = pcs_in;
    } else {
        pcs = pcs_in;
        /* The snippet below creates an ICC equivalent profile for the PS
           color space.  This is disabled until I add the capability to
           specify the profile version to ensure compatability with
           the PDF versions */
#if 0
        if (pcs_in->icc_equivalent != NULL) {
            pcs = pcs_in->icc_equivalent;
        } else {
            /* Need to create the equivalent object */
            gs_colorspace_set_icc_equivalent((gs_color_space *)pcs_in, &islab, pdev->memory);
            pcs = pcs_in->icc_equivalent;
        }
#endif
    }
    csi = gs_color_space_get_index(pcs);
    /* Note that if csi is ICC, check to see if this was one of
       the default substitutes that we introduced for DeviceGray,
       DeviceRGB or DeviceCMYK.  If it is, then just write
       the default color.  Depending upon the flavor of PDF,
       or other options, we may want to actually have all
       the colors defined by ICC profiles and not do the following
       substituion of the Device space. */
    if (csi == gs_color_space_index_ICC) {
        csi = gsicc_get_default_type(pcs->cmm_icc_profile_data);
    }
    if (ppranges)
        *ppranges = 0;		/* default */
    switch (csi) {
    case gs_color_space_index_DeviceGray:
        cos_c_string_value(pvalue, pcsn->DeviceGray);
        return 0;
    case gs_color_space_index_DeviceRGB:
        cos_c_string_value(pvalue, pcsn->DeviceRGB);
        return 0;
    case gs_color_space_index_DeviceCMYK:
        cos_c_string_value(pvalue, pcsn->DeviceCMYK);
        return 0;
    case gs_color_space_index_Pattern:
        if (!pcs->params.pattern.has_base_space) {
            cos_c_string_value(pvalue, "/Pattern");
            return 0;
        }
        break;
    case gs_color_space_index_ICC:
        /*
         * Take a special early exit for unrecognized ICCBased color spaces,
         * or for PDF 1.2 output (ICCBased color spaces date from PDF 1.3).
         */

        if (pcs->cmm_icc_profile_data == NULL ||
                pdev->CompatibilityLevel < 1.3
           ) {
            if (res_name != NULL)
                return 0; /* Ignore .includecolorspace */
            if (pcs->base_space != NULL) {
                return pdf_color_space_named( pdev, pvalue, ppranges,
                                              pcs->base_space,
                                              pcsn, by_name, NULL, 0);
            } else {
                /* Base space is NULL, use appropriate device space */
                switch( cs_num_components(pcs) )  {
                case 1:
                    cos_c_string_value(pvalue, pcsn->DeviceGray);
                    return 0;
                case 3:
                    cos_c_string_value(pvalue, pcsn->DeviceRGB);
                    return 0;
                case 4:
                    cos_c_string_value(pvalue, pcsn->DeviceCMYK);
                    return 0;
                default:
                    break;
                }
            }
        }

        break;
    default:
        break;
    }
    if (pdev->params.ColorConversionStrategy == ccs_CMYK &&
            csi != gs_color_space_index_DeviceCMYK &&
            csi != gs_color_space_index_DeviceGray &&
            csi != gs_color_space_index_Pattern)
        return_error(gs_error_rangecheck);
    if (pdev->params.ColorConversionStrategy == ccs_sRGB &&
            csi != gs_color_space_index_DeviceRGB &&
            csi != gs_color_space_index_DeviceGray &&
            csi != gs_color_space_index_Pattern)
        return_error(gs_error_rangecheck);
    if (pdev->params.ColorConversionStrategy == ccs_Gray &&
            csi != gs_color_space_index_DeviceGray &&
            csi != gs_color_space_index_Pattern)
        return_error(gs_error_rangecheck);
    /* Check whether we already have a PDF object for this color space. */
    if (pcs->id != gs_no_id)
        pres = pdf_find_resource_by_gs_id(pdev, resourceColorSpace, pcs->id);
    if (pres == NULL) {
        stream s;

        s_init(&s, pdev->memory);
        swrite_position_only(&s);
        code = cs_serialize(pcs, &s);
        if (code < 0)
            return_error(gs_error_unregistered); /* Must not happen. */
        serialized_size = stell(&s);
        sclose(&s);
        if (serialized_size <= sizeof(serialized0))
            serialized = serialized0;
        else {
            serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space");
            if (serialized == NULL)
                return_error(gs_error_VMerror);
        }
        swrite_string(&s, serialized, serialized_size);
        code = cs_serialize(pcs, &s);
        if (code < 0)
            return_error(gs_error_unregistered); /* Must not happen. */
        if (stell(&s) != serialized_size)
            return_error(gs_error_unregistered); /* Must not happen. */
        sclose(&s);
        pres = pdf_find_cspace_resource(pdev, serialized, serialized_size);
        if (pres != NULL) {
            if (serialized != serialized0)
                gs_free_object(pdev->pdf_memory, serialized, "pdf_color_space");
            serialized = NULL;
        }
    }
    if (pres) {
        const pdf_color_space_t *const ppcs =
            (const pdf_color_space_t *)pres;

        if (ppranges != 0 && ppcs->ranges != 0)
            *ppranges = ppcs->ranges;
        pca = (cos_array_t *)pres->object;
        goto ret;
    }

    /* Space has parameters -- create an array. */
    pca = cos_array_alloc(pdev, "pdf_color_space");
    if (pca == 0)
        return_error(gs_error_VMerror);

    switch (csi) {

    case gs_color_space_index_ICC:
        code = pdf_iccbased_color_space(pdev, pvalue, pcs, pca);
        break;

    case gs_color_space_index_CIEA: {
        /* Check that we can represent this as a CalGray space. */
        const gs_cie_a *pcie = pcs->params.a;
        bool unitary = cie_ranges_are_0_1(&pcie->RangeA, 1);
        bool identityA = (pcie->MatrixA.u == 1 && pcie->MatrixA.v == 1 &&
                          pcie->MatrixA.w == 1);
        gs_vector3 expts;

        pciec = (const gs_cie_common *)pcie;
        if (!pcie->common.MatrixLMN.is_identity) {
            code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec,
                                         &pcie->RangeA, ONE_STEP_NOT, NULL,
                                         &ranges);
            break;
        }
        if (unitary && identityA &&
                CIE_CACHE_IS_IDENTITY(&pcie->caches.DecodeA) &&
                CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts) &&
                expts.v == expts.u && expts.w == expts.u
           ) {
            DO_NOTHING;
        } else if (unitary && identityA &&
                   CIE_CACHE3_IS_IDENTITY(pcie->common.caches.DecodeLMN) &&
                   cie_vector_cache_is_exponential(&pcie->caches.DecodeA, &expts.u)
                  ) {
            DO_NOTHING;
        } else {
            code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec,
                                         &pcie->RangeA, ONE_STEP_NOT, NULL,
                                         &ranges);
            break;
        }
        code = cos_array_add(pca, cos_c_string_value(&v, "/CalGray"));
        if (code < 0)
            return code;
        pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
        if (pcd == 0)
            return_error(gs_error_VMerror);
        if (expts.u != 1) {
            code = cos_dict_put_c_key_real(pcd, "/Gamma", expts.u);
            if (code < 0)
                return code;
        }
    }
cal:
        /* Finish handling a CIE-based color space (Calxxx or Lab). */
    if (code < 0)
        return code;
    code = pdf_finish_cie_space(pca, pcd, pciec);
    break;

    case gs_color_space_index_CIEABC: {
        /* Check that we can represent this as a CalRGB space. */
        const gs_cie_abc *pcie = pcs->params.abc;
        bool unitary = cie_ranges_are_0_1(pcie->RangeABC.ranges, 3);
        gs_vector3 expts;
        const gs_matrix3 *pmat = NULL;
        cie_cache_one_step_t one_step =
            cie_cached_abc_is_one_step(pcie, &pmat);

        pciec = (const gs_cie_common *)pcie;
        if (unitary) {
            switch (one_step) {
            case ONE_STEP_ABC:
                if (CIE_VECTOR3_CACHE_IS_EXPONENTIAL(pcie->caches.DecodeABC.caches, expts))
                    goto calrgb;
                break;
            case ONE_STEP_LMN:
                if (CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts))
                    goto calrgb;
            default:
                break;
            }
        }
        if (cie_is_lab(pcie)) {
            /* Represent this as a Lab space. */
            pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
            if (pcd == 0)
                return_error(gs_error_VMerror);
            code = pdf_put_lab_color_space(pca, pcd, pcie->RangeABC.ranges);
            goto cal;
        } else {
            code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ", pciec,
                                         pcie->RangeABC.ranges,
                                         one_step, pmat, &ranges);
            break;
        }
calrgb:
        code = cos_array_add(pca, cos_c_string_value(&v, "/CalRGB"));
        if (code < 0)
            return code;
        pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)");
        if (pcd == 0)
            return_error(gs_error_VMerror);
        if (expts.u != 1 || expts.v != 1 || expts.w != 1) {
            code = cos_dict_put_c_key_vector3(pcd, "/Gamma", &expts);
            if (code < 0)
                return code;
        }
        if (!pmat->is_identity) {
            cos_array_t *pcma =
                cos_array_alloc(pdev, "pdf_color_space(Matrix)");

            if (pcma == 0)
                return_error(gs_error_VMerror);
            if ((code = cos_array_add_vector3(pcma, &pmat->cu)) < 0 ||
                    (code = cos_array_add_vector3(pcma, &pmat->cv)) < 0 ||
                    (code = cos_array_add_vector3(pcma, &pmat->cw)) < 0 ||
                    (code = cos_dict_put(pcd, (const byte *)"/Matrix", 7,
                                         COS_OBJECT_VALUE(&v, pcma))) < 0
               )
                return code;
        }
    }
    goto cal;

    case gs_color_space_index_CIEDEF:
        code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ",
                                     (const gs_cie_common *)pcs->params.def,
                                     pcs->params.def->RangeDEF.ranges,
                                     ONE_STEP_NOT, NULL, &ranges);
        break;

    case gs_color_space_index_CIEDEFG:
        code = pdf_convert_cie_space(pdev, pca, pcs, "CMYK",
                                     (const gs_cie_common *)pcs->params.defg,
                                     pcs->params.defg->RangeDEFG.ranges,
                                     ONE_STEP_NOT, NULL, &ranges);
        break;

    case gs_color_space_index_Indexed:
        code = pdf_indexed_color_space(pdev, pvalue, pcs, pca);
        break;

    case gs_color_space_index_DeviceN:
        if (!pdev->PreserveDeviceN)
            return_error(gs_error_rangecheck);
        if (pdev->CompatibilityLevel < 1.3)
            return_error(gs_error_rangecheck);
        pfn = gs_cspace_get_devn_function(pcs);
        /****** CURRENTLY WE ONLY HANDLE Functions ******/
        if (pfn == 0)
            return_error(gs_error_rangecheck);
        {
            cos_array_t *psna =
                cos_array_alloc(pdev, "pdf_color_space(DeviceN)");
            int i;
            byte *name_string;
            uint name_string_length;
            cos_value_t v_attriburtes, *va = NULL;

            if (psna == 0)
                return_error(gs_error_VMerror);
            for (i = 0; i < pcs->params.device_n.num_components; ++i) {
                if ((code = pcs->params.device_n.get_colorname_string(
                                pdev->memory,
                                pcs->params.device_n.names[i], &name_string,
                                &name_string_length)) < 0 ||
                        (code = pdf_string_to_cos_name(pdev, name_string,
                                                       name_string_length, &v)) < 0 ||
                        (code = cos_array_add_no_copy(psna, &v)) < 0)
                    return code;
            }
            COS_OBJECT_VALUE(&v, psna);
            if (pcs->params.device_n.colorants != NULL) {
                cos_dict_t *colorants  = cos_dict_alloc(pdev, "pdf_color_space(DeviceN)");
                cos_value_t v_colorants, v_separation, v_colorant_name;
                const gs_device_n_attributes *csa;
                pdf_resource_t *pres_attributes;

                if (colorants == NULL)
                    return_error(gs_error_VMerror);
                code = pdf_alloc_resource(pdev, resourceOther, 0, &pres_attributes, -1);
                if (code < 0)
                    return code;
                cos_become(pres_attributes->object, cos_type_dict);
                COS_OBJECT_VALUE(&v_colorants, colorants);
                code = cos_dict_put((cos_dict_t *)pres_attributes->object,
                                    (const byte *)"/Colorants", 10, &v_colorants);
                if (code < 0)
                    return code;
                for (csa = pcs->params.device_n.colorants; csa != NULL; csa = csa->next) {
                    code = pcs->params.device_n.get_colorname_string(pdev->memory,
                            csa->colorant_name, &name_string, &name_string_length);
                    if (code < 0)
                        return code;
                    code = pdf_color_space_named(pdev, &v_separation, NULL, csa->cspace, pcsn, false, NULL, 0);
                    if (code < 0)
                        return code;
                    code = pdf_string_to_cos_name(pdev, name_string, name_string_length, &v_colorant_name);
                    if (code < 0)
                        return code;
                    code = cos_dict_put(colorants, v_colorant_name.contents.chars.data,
                                        v_colorant_name.contents.chars.size, &v_separation);
                    if (code < 0)
                        return code;
                }
                code = pdf_substitute_resource(pdev, &pres_attributes, resourceOther, NULL, true);
                if (code < 0)
                    return code;
                pres_attributes->where_used |= pdev->used_mask;
                va = &v_attriburtes;
                COS_OBJECT_VALUE(va, pres_attributes->object);
            }
            if ((code = pdf_separation_color_space(pdev, pca, "/DeviceN", &v,
                                                   pcs->base_space,
                                                   pfn, &pdf_color_space_names, va)) < 0)
                return code;
        }
        break;

    case gs_color_space_index_Separation:
        if (!pdev->PreserveSeparation)
            return_error(gs_error_rangecheck);
        pfn = gs_cspace_get_sepr_function(pcs);
        /****** CURRENTLY WE ONLY HANDLE Functions ******/
        if (pfn == 0)
            return_error(gs_error_rangecheck);
        {
            byte *name_string;
            uint name_string_length;
            if ((code = pcs->params.separation.get_colorname_string(
                            pdev->memory,
                            pcs->params.separation.sep_name, &name_string,
                            &name_string_length)) < 0 ||
                    (code = pdf_string_to_cos_name(pdev, name_string,
                                                   name_string_length, &v)) < 0 ||
                    (code = pdf_separation_color_space(pdev, pca, "/Separation", &v,
                            pcs->base_space,
                            pfn, &pdf_color_space_names, NULL)) < 0)
                return code;
        }
        break;

    case gs_color_space_index_Pattern:
        if ((code = pdf_color_space_named(pdev, pvalue, ppranges,
                                          pcs->base_space,
                                          &pdf_color_space_names, false, NULL, 0)) < 0 ||
                (code = cos_array_add(pca,
                                      cos_c_string_value(&v, "/Pattern"))) < 0 ||
                (code = cos_array_add(pca, pvalue)) < 0
           )
            return code;
        break;

    default:
        return_error(gs_error_rangecheck);
    }

    /*
     * Register the color space as a resource, since it must be referenced
     * by name rather than directly.
     */
    {
        pdf_color_space_t *ppcs;

        if (code < 0 ||
                (code = pdf_alloc_resource(pdev, resourceColorSpace, pcs->id,
                                           &pres, -1)) < 0
           ) {
            COS_FREE(pca, "pdf_color_space");
            return code;
        }
        pdf_reserve_object_id(pdev, pres, 0);
        if (res_name != NULL) {
            int l = min(name_length, sizeof(pres->rname) - 1);

            memcpy(pres->rname, res_name, l);
            pres->rname[l] = 0;
        }
        ppcs = (pdf_color_space_t *)pres;
        if (serialized == serialized0) {
            serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space");
            if (serialized == NULL)
                return_error(gs_error_VMerror);
            memcpy(serialized, serialized0, serialized_size);
        }
        ppcs->serialized = serialized;
        ppcs->serialized_size = serialized_size;
        if (ranges) {
            int num_comp = gs_color_space_num_components(pcs);
            gs_range_t *copy_ranges = (gs_range_t *)
                                      gs_alloc_byte_array(pdev->pdf_memory, num_comp,
                                              sizeof(gs_range_t), "pdf_color_space");

            if (copy_ranges == 0) {
                COS_FREE(pca, "pdf_color_space");
                return_error(gs_error_VMerror);
            }
            memcpy(copy_ranges, ranges, num_comp * sizeof(gs_range_t));
            ppcs->ranges = copy_ranges;
            if (ppranges)
                *ppranges = copy_ranges;
        } else
            ppcs->ranges = 0;
        pca->id = pres->object->id;
        COS_FREE(pres->object, "pdf_color_space");
        pres->object = (cos_object_t *)pca;
        cos_write_object(COS_OBJECT(pca), pdev, resourceColorSpace);
    }
ret:
    if (by_name) {
        /* Return a resource name rather than an object reference. */
        discard(COS_RESOURCE_VALUE(pvalue, pca));
    } else
        discard(COS_OBJECT_VALUE(pvalue, pca));
    if (pres != NULL) {
        pres->where_used |= pdev->used_mask;
        code = pdf_add_resource(pdev, pdev->substream_Resources, "/ColorSpace", pres);
        if (code < 0)
            return code;
    }
    return 0;
}
Пример #18
0
/*
 * Serialize a halftone. The essential step is the serialization of the
 * halftone orders; beyond this only the halftone type must be
 * transmitted.
 *
 * Returns:
 *
 *    0, with *psize set the the amount of space required, if successful
 *
 *    gs_error_rangecheck, with *psize set to the size required, if the
 *        original *psize was not large enough
 *
 *    some other error code, with *psize unchange, in the event of an
 *        error other than lack of space
 */
int
gx_ht_write(
    const gx_device_halftone *  pdht,
    const gx_device *           dev,
    byte *                      data,
    uint *                      psize )
{
    int                         num_dev_comps;
    int                         i, code;
    uint                        req_size = 2, used_size = 2;
                                /* 1 for halftone type, 1 for num_dev_comps */

    /*
     * With the introduction of color models, there should never be a
     * halftone that includes just one component. Enforce this
     * restriction, even though it is not present in much of the rest
     * of the code.
     *
     * NB: the pdht->order field is ignored by this code.
     */
    if (pdht == 0 || pdht->components == 0)
        return_error(gs_error_unregistered); /* Must not happen. */
    num_dev_comps = pdht->num_dev_comp;

    /*
     * The following fields do not need to be transmitted:
     *
     *  order       Ignored by this code (see above).
     *
     *  rc, id      Recreated by the allocation code on the renderer.
     *
     *  lcm_width,  Can be recreated by the de-serialization code on the
     *  lcm_height  the renderer. Since halftones are transmitted
     *              infrequently (for normal jobs), the time required
     *              for re-calculation is not significant.
     *
     * Hence, the only fields that must be serialized are the type,and
     * the number of components.  (The number of components for the halftone
     * may not match the device's if we are compositing with a process color
     * model which does not match the output device.
     *
     * Several halftone components may be identical, but there is
     * currently no simple way to determine this. Halftones are normally
     * transmitted only once per page, so it is not clear that use of
     * such information would significantly reduce command list size.
     */

    /* calculate the required data space */
    for ( i = 0, code = gs_error_rangecheck;
          i < num_dev_comps && code == gs_error_rangecheck;
          i++) {
        uint     tmp_size = 0;

        /* sanity check */
        if (i != pdht->components[i].comp_number)
            return_error(gs_error_unregistered); /* Must not happen. */

        code = gx_ht_write_component( &pdht->components[i],
                                      data,
                                      &tmp_size );
        req_size += tmp_size;
    }
    if (code < 0 && code != gs_error_rangecheck)
        return code;
    else if (*psize < req_size) {
        *psize = req_size;
        return 0;
    }
    req_size = *psize;

    /* the halftone type is known to fit in a byte */
    *data++ = (byte)pdht->type;
    /* the number of components is known to fit in a byte */
    *data++ = (byte)num_dev_comps;

    /* serialize the halftone components */
    for (i = 0, code = 0; i < num_dev_comps && code == 0; i++) {
        uint    tmp_size = req_size - used_size;

        code = gx_ht_write_component( &pdht->components[i],
                                      data,
                                      &tmp_size );
        used_size += tmp_size;
        data += tmp_size;
    }

    if (code < 0) {
        if (code == gs_error_rangecheck)
            code = gs_error_unknownerror;
        return code;
    }

    *psize = used_size;
    return 0;
}
Пример #19
0
int
gx_image_no_sput(const gs_image_common_t *pic, stream *s,
		 const gs_color_space **ppcs)
{
    return_error(gs_error_rangecheck);
}
Пример #20
0
/*
 * Reconstruct a halftone from its serial representation, and install it
 * as the current halftone. The buffer provided is expected to be large
 * enough to hold the entire halftone.
 *
 * The reading and installation phases are combined in this routine so as
 * to avoid unnecessarily allocating a device halftone and its component
 * array, just to release them immediately after installation is complete.
 * There is also not much reason to reconstuct a halftone except to make
 * it the current halftone.
 *
 * Returns the number of bytes read, or <0 in the event of an error.
 */
int
gx_ht_read_and_install(
    gs_imager_state *       pis,
    const gx_device *       dev,
    const byte *            data,
    uint                    size,
    gs_memory_t *           mem )
{
    gx_ht_order_component   components[GX_DEVICE_COLOR_MAX_COMPONENTS];
    gx_ht_order_component   components_save[GX_DEVICE_COLOR_MAX_COMPONENTS];
    const byte *            data0 = data;
    gx_device_halftone      dht;
    int                     num_dev_comps;
    int                     i, code;

    /* fill in some fixed fields */
    memset(&dht.order, 0, sizeof(dht.order));
    memset(&dht.rc, 0, sizeof(dht.rc));
    dht.id = gs_no_id;      /* updated during installation */
    dht.components = components;
    dht.lcm_width = 1;      /* recalculated during installation */
    dht.lcm_height = 1;

    /* clear pointers in the components array in case we need to abort */
    memset(components, 0, sizeof(components));

    /* get the halftone type */
    if (size < 2)
        return_error(gs_error_rangecheck);
    dht.type = (gs_halftone_type)(*data++);
    num_dev_comps = dht.num_dev_comp = dht.num_comp = *data++;
    size -= 2;

    /* process the component orders */
    for (i = 0, code = 0; i < num_dev_comps && code >= 0; i++) {
        components[i].comp_number = i;
        code = gx_ht_read_component(&components[i], data, size, mem);
        if (code >= 0) {
            size -= code;
            data += code;
        }
    }

    /* if everything is OK, install the halftone */
    if (code >= 0) {
        /* save since the 'install' copies the order, but then clears the source order	*/
        for (i = 0; i < num_dev_comps; i++)
            components_save[i] = components[i];
        code = gx_imager_dev_ht_install(pis, &dht, dht.type, dev);
        for (i = 0; i < num_dev_comps; i++)
            gx_ht_order_release(&components_save[i].corder, mem, false);
    }

    /*
     * If installation failed, discard the allocated elements. We can't
     * use the gx_device_halftone_release procedure, as the components
     * array is on the stack rather than in the heap.
     */
    if (code < 0) {
        for (i = 0; i < num_dev_comps; i++)
            gx_ht_order_release(&components[i].corder, mem, false);
    }

    return code < 0 ? code : data - data0;
}
Пример #21
0
/*
 *	Width, encoded as a variable-length uint
 *	Height, encoded ditto
 *	ImageMatrix (if A = 1), per gs_matrix_store/fetch
 *	Decode (if D = 1): blocks of up to 4 components
 *	    aabbccdd, where each xx is decoded as:
 *		00 = default, 01 = swapped default,
 *		10 = (0,V), 11 = (U,V)
 *	    non-defaulted components (up to 8 floats)
 */
int
gx_pixel_image_sput(const gs_pixel_image_t *pim, stream *s,
		    const gs_color_space **ppcs, int extra)
{
    const gs_color_space *pcs = pim->ColorSpace;
    int bpc = pim->BitsPerComponent;
    int num_components = gs_color_space_num_components(pcs);
    int num_decode;
    uint control = extra << PI_BITS;
    float decode_default_1 = 1;
    int i;
    uint ignore;

    /* Construct the control word. */

    if (!gx_image_matrix_is_default((const gs_data_image_t *)pim))
	control |= PI_ImageMatrix;
    switch (pim->format) {
    case gs_image_format_chunky:
    case gs_image_format_component_planar:
	switch (bpc) {
	case 1: case 2: case 4: case 8: case 12: break;
	default: return_error(gs_error_rangecheck);
	}
	break;
    case gs_image_format_bit_planar:
	if (bpc < 1 || bpc > 8)
	    return_error(gs_error_rangecheck);
    }
    control |= (bpc - 1) << PI_BPC_SHIFT;
    control |= pim->format << PI_FORMAT_SHIFT;
    num_decode = num_components * 2;
    if (gs_color_space_get_index(pcs) == gs_color_space_index_Indexed)
	decode_default_1 = (float)pcs->params.indexed.hival;
    for (i = 0; i < num_decode; ++i)
	if (pim->Decode[i] != DECODE_DEFAULT(i, decode_default_1)) {
	    control |= PI_Decode;
	    break;
	}
    if (pim->Interpolate)
	control |= PI_Interpolate;
    if (pim->CombineWithColor)
	control |= PI_CombineWithColor;

    /* Write the encoding on the stream. */

    if_debug3('b', "[b]put control=0x%x, Width=%d, Height=%d\n",
	      control, pim->Width, pim->Height);
    sput_variable_uint(s, control);
    sput_variable_uint(s, (uint)pim->Width);
    sput_variable_uint(s, (uint)pim->Height);
    if (control & PI_ImageMatrix) {
	debug_b_print_matrix(pim);
	sput_matrix(s, &pim->ImageMatrix);
    }
    if (control & PI_Decode) {
	int i;
	uint dflags = 1;
	float decode[8];
	int di = 0;

	debug_b_print_decode(pim, num_decode);
	for (i = 0; i < num_decode; i += 2) {
	    float u = pim->Decode[i], v = pim->Decode[i + 1];
	    float dv = DECODE_DEFAULT(i + 1, decode_default_1);

	    if (dflags >= 0x100) {
		sputc(s, (byte)(dflags & 0xff));
		sputs(s, (const byte *)decode, di * sizeof(float), &ignore);
		dflags = 1;
		di = 0;
	    }
	    dflags <<= 2;
	    if (u == 0 && v == dv)
		DO_NOTHING;
	    else if (u == dv && v == 0)
		dflags += 1;
	    else {
		if (u != 0) {
		    dflags++;
		    decode[di++] = u;
		}
		dflags += 2;
		decode[di++] = v;
	    }
	}
	sputc(s, (byte)((dflags << (8 - num_decode)) & 0xff));
	sputs(s, (const byte *)decode, di * sizeof(float), &ignore);
    }
    *ppcs = pcs;
    return 0;
}
Пример #22
0
/*
 * If a Type 1 character is defined with 'seac', store the character codes
 * in chars[0] and chars[1] and return 1; otherwise, return 0 or <0.
 * This is exported only for the benefit of font copying.
 */
int
gs_type1_piece_codes(/*const*/ gs_font_type1 *pfont,
		     const gs_glyph_data_t *pgd, gs_char *chars)
{
    gs_type1_data *const pdata = &pfont->data;
    /*
     * Decode the CharString looking for seac.  We have to process
     * callsubr, callothersubr, and return operators, but if we see
     * any other operators other than [h]sbw, pop, hint operators,
     * or endchar, we can return immediately.  We have to include
     * endchar because it is an (undocumented) equivalent for seac
     * in Type 2 CharStrings: see the cx_endchar case in
     * gs_type2_interpret in gstype2.c.
     *
     * It's really unfortunate that we have to duplicate so much parsing
     * code, but factoring out the parser from the interpreter would
     * involve more restructuring than we're prepared to do right now.
     */
    bool encrypted = pdata->lenIV >= 0;
    fixed cstack[ostack_size];
    fixed *csp;
    ip_state_t ipstack[ipstack_size + 1];
    ip_state_t *ipsp = &ipstack[0];
    const byte *cip;
    crypt_state state;
    int c;
    int code;
    
    CLEAR_CSTACK(cstack, csp);
    cip = pgd->bits.data;
 call:
    state = crypt_charstring_seed;
    if (encrypted) {
	int skip = pdata->lenIV;

	/* Skip initial random bytes */
	for (; skip > 0; ++cip, --skip)
	    decrypt_skip_next(*cip, state);
    }
 top:
    for (;;) {
	uint c0 = *cip++;

	charstring_next(c0, state, c, encrypted);
	if (c >= c_num1) {
	    /* This is a number, decode it and push it on the stack. */
	    if (c < c_pos2_0) {	/* 1-byte number */
		decode_push_num1(csp, cstack, c);
	    } else if (c < cx_num4) {	/* 2-byte number */
		decode_push_num2(csp, cstack, c, cip, state, encrypted);
	    } else if (c == cx_num4) {	/* 4-byte number */
		long lw;

		decode_num4(lw, cip, state, encrypted);
		CS_CHECK_PUSH(csp, cstack);
		*++csp = int2fixed(lw);
	    } else		/* not possible */
		return_error(gs_error_invalidfont);
	    continue;
	}
#define cnext CLEAR_CSTACK(cstack, csp); goto top
	switch ((char_command) c) {
	default:
	    goto out;
	case c_callsubr:
	    c = fixed2int_var(*csp) + pdata->subroutineNumberBias;
	    code = pdata->procs.subr_data
		(pfont, c, false, &ipsp[1].cs_data);
	    if (code < 0)
		return_error(code);
	    --csp;
	    ipsp->ip = cip, ipsp->dstate = state;
	    ++ipsp;
	    cip = ipsp->cs_data.bits.data;
	    goto call;
	case c_return:
	    gs_glyph_data_free(&ipsp->cs_data, "gs_type1_piece_codes");
	    --ipsp;
	    cip = ipsp->ip, state = ipsp->dstate;
	    goto top;
	case cx_hstem:
	case cx_vstem:
	case c1_hsbw:
	    cnext;
	case cx_endchar:
	    if (csp < cstack + 3)
		goto out;	/* not seac */
	do_seac:
	    /* This is the payoff for all this code! */
	    chars[0] = fixed2int(csp[-1]);
	    chars[1] = fixed2int(csp[0]);
	    return 1;
	case cx_escape:
	    charstring_next(*cip, state, c, encrypted);
	    ++cip;
	    switch ((char1_extended_command) c) {
	    default:
		goto out;
	    case ce1_vstem3:
	    case ce1_hstem3:
	    case ce1_sbw:
		cnext;
	    case ce1_pop:
		/*
		 * pop must do nothing, since it is used after
		 * subr# 1 3 callothersubr.
		 */
		goto top;
	    case ce1_seac:
		goto do_seac;
	    case ce1_callothersubr:
		switch (fixed2int_var(*csp)) {
		default:
		    goto out;
		case 3:
		    csp -= 2;
		    goto top;
		case 12:
		case 13:
		case 14:
		case 15:
		case 16:
		case 17:
		case 18:
		    cnext;
		}
	    }
	}
#undef cnext
    }
 out:
    return 0;
}
Пример #23
0
void Impl::ParseResponse( Response * response )
{
    // This function uses return defines for readability and maintainability.
#   define return_error(error_type, error_message)                             \
    {                                                                          \
        SetError(response, error_type, error_message);                         \
        return;                                                                \
    }

    // create_content_parse_single required
    if ( ! GetIfExists(
            response->pt,
            "response.folder_key",
            &response->folderkey ) )
        return_error(
            mf::api::api_code::ContentInvalidData,
            "missing \"response.folder_key\"");

    // create_content_parse_single required
    if ( ! GetIfExists(
            response->pt,
            "response.upload_key",
            &response->uploadkey ) )
        return_error(
            mf::api::api_code::ContentInvalidData,
            "missing \"response.upload_key\"");

    // create_content_parse_single required
    if ( ! GetIfExists(
            response->pt,
            "response.name",
            &response->name ) )
        return_error(
            mf::api::api_code::ContentInvalidData,
            "missing \"response.name\"");

    // create_content_parse_single required
    if ( ! GetIfExists(
            response->pt,
            "response.created",
            &response->created_datetime ) )
        return_error(
            mf::api::api_code::ContentInvalidData,
            "missing \"response.created\"");

    {
        std::string optval;
        // create_content_enum_parse TSingle
        if ( GetIfExists(
                response->pt,
                "response.privacy",
                &optval) )
        {
            if ( optval == "public" )
                response->privacy = Privacy::Public;
            else if ( optval == "private" )
                response->privacy = Privacy::Private;
            else
                return_error(
                    mf::api::api_code::ContentInvalidData,
                    "invalid value in response.privacy");
        }
        else
            return_error(
                mf::api::api_code::ContentInvalidData,
                "no value in response.privacy");
    }

    // create_content_parse_single required
    if ( ! GetIfExists(
            response->pt,
            "response.revision",
            &response->revision ) )
        return_error(
            mf::api::api_code::ContentInvalidData,
            "missing \"response.revision\"");

#   undef return_error
}
Пример #24
0
int
gs_type1_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
		    int members, gs_glyph_info_t *info)
{
    gs_font_type1 *const pfont = (gs_font_type1 *)font;
    gs_type1_data *const pdata = &pfont->data;
    int wmode = ((members & GLYPH_INFO_WIDTH1) != 0);
    int piece_members = members & (GLYPH_INFO_NUM_PIECES | GLYPH_INFO_PIECES);
    int width_members = (members & ((GLYPH_INFO_WIDTH0 << wmode) | (GLYPH_INFO_VVECTOR0 << wmode)));
    int default_members = members & ~(piece_members | GLYPH_INFO_WIDTHS |
				     GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1 |
				     GLYPH_INFO_OUTLINE_WIDTHS);
    int code = 0;
    gs_glyph_data_t gdata;

    if (default_members) {
	code = gs_default_glyph_info(font, glyph, pmat, default_members, info);

	if (code < 0)
	    return code;
    } else
	info->members = 0;

    if (default_members == members)
	return code;		/* all done */

    gdata.memory = pfont->memory;
    if ((code = pdata->procs.glyph_data(pfont, glyph, &gdata)) < 0)
	return code;		/* non-existent glyph */

    if (piece_members) {
	code = gs_type1_glyph_pieces(pfont, &gdata, members, info);
	if (code < 0)
	    return code;
	info->members |= piece_members;
    }

    if (width_members) {
	gx_path path;
	/*
	 * Interpret the CharString until we get to the [h]sbw.
	 */
	gs_imager_state gis;
	gs_type1_state cis;
	int value;

	/* Initialize just enough of the imager state. */
	if (pmat)
	    gs_matrix_fixed_from_matrix(&gis.ctm, pmat);
	else {
	    gs_matrix imat;

	    gs_make_identity(&imat);
	    gs_matrix_fixed_from_matrix(&gis.ctm, &imat);
	}
	gis.flatness = 0;
	code = gs_type1_interp_init(&cis, &gis, NULL /* no path needed */,
				    NULL, NULL, true, 0, pfont);
	if (code < 0)
	    return code;
	cis.no_grid_fitting = true;
	gx_path_init_bbox_accumulator(&path);
	cis.path = &path;
	code = pdata->interpret(&cis, &gdata, &value);
	switch (code) {
	case 0:		/* done with no [h]sbw, error */
	    code = gs_note_error(gs_error_invalidfont);
	default:		/* code < 0, error */
	    return code;
	case type1_result_callothersubr:	/* unknown OtherSubr */
	    return_error(gs_error_rangecheck); /* can't handle it */
	case type1_result_sbw:
	    info->width[wmode].x = fixed2float(cis.width.x);
	    info->width[wmode].y = fixed2float(cis.width.y);
	    info->v.x = fixed2float(cis.lsb.x);
	    info->v.y = fixed2float(cis.lsb.y);
	    break;
	}
	info->members |= width_members | (GLYPH_INFO_VVECTOR0 << wmode);
    }

    gs_glyph_data_free(&gdata, "gs_type1_glyph_info");
    return code;
}
Пример #25
0
/* Send the page to the printer. */
static int
coslw_print_page(gx_device_printer * pdev, FILE * prn_stream)
{
    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
    int line_size_words = (line_size + W - 1) / W;
    uint storage_size_words = line_size_words * 8;	/* data, out_row, out_row_alt, prev_row */
    word *storage = (ulong *) gs_malloc(pdev->memory, storage_size_words, W,
                                        "coslw_print_page");

    word *data_words;
#define data ((byte *)data_words)

    byte *out_data;
    int num_rows = dev_print_scan_lines(pdev);
    int bytes_per_line = 0;
    int out_count;
    int code = 0;

    if (storage == 0)		/* can't allocate working area */
        return_error(gs_error_VMerror);
    data_words = storage;

    /* Clear temp storage */
    memset(data, 0, storage_size_words * W);

    /* Initialize printer. */
    if (pdev->PageCount == 0) {
    }

    /* Put out per-page initialization. */

    /* End raster graphics, position cursor at top. */

    /* Send each scan line in turn */
    {
        int lnum;
        int num_blank_lines = 0;
        word rmask = ~(word) 0 << (-pdev->width & (W * 8 - 1));

        /* Transfer raster graphics. */
        for (lnum = 0; lnum < num_rows; lnum++) {
            register word *end_data =
            data_words + line_size_words;

            code = gdev_prn_copy_scan_lines(pdev, lnum,
                                            (byte *) data, line_size);
            if (code < 0)
                break;
            /* Mask off 1-bits beyond the line width. */
            end_data[-1] &= rmask;
            /* Remove trailing 0s. */
            while (end_data > data_words && end_data[-1] == 0)
                end_data--;
            if (end_data == data_words) {	/* Blank line */
                num_blank_lines++;
                continue;
            }

            /* We've reached a non-blank line. */
            /* Put out a spacing command if necessary. */
            while (num_blank_lines > 0)
            {
                int this_blank = 255;
                if (num_blank_lines < this_blank)
                    this_blank = num_blank_lines;
                fprintf(prn_stream, "\033f\001%c", this_blank);
                num_blank_lines -= this_blank;
            }

            /* Perhaps add compression here later? */
            out_data = data;
            out_count = (byte *) end_data - data;

            /* For 2 inch model, max width is 56 bytes */
            if (out_count > 56)
                out_count = 56;
            /* Possible change the bytes per line */
            if (bytes_per_line != out_count)
            {
                fprintf(prn_stream, "\033D%c", out_count);
                bytes_per_line = out_count;
            }

            /* Transfer the data */
            fputs("\026", prn_stream);
            fwrite(out_data, sizeof(byte), out_count, prn_stream);
        }
    }

    /* eject page */
    fputs("\033E", prn_stream);

    /* free temporary storage */
    gs_free(pdev->memory, (char *)storage, storage_size_words, W, "coslw_print_page");

    return code;
}
Пример #26
0
/* Send the page to the printer.  */
static int
fmlbp_print_page(gx_device_printer *pdev, FILE *prn_stream)
{
  int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
#ifdef	FMLBP_NOPAPERSIZE
  char data[LINE_SIZE*2];
#else
  byte *data = (byte *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), 1, line_size, "fmlpr_print_page(data)");
  if(data == NULL) return_error(gs_error_VMerror);
#endif/*FMLBP_NOPAPERSIZE*/

  /* initialize */
  fwrite(can_inits, sizeof(can_inits), 1, prn_stream);
  fprintf(prn_stream, "%c%c%d!I", PU1, 0);	/* 100% */
#ifndef	OLD_FMLBP_400DPI
  fprintf(prn_stream, "%c%c%d!A", PU1,
          (int)(pdev->x_pixels_per_inch));	/* 240dpi or 400dpi */
#endif/*!OLD_FMLBP_400DPI*/
#ifndef	FMLBP_NOPAPERSIZE
  fprintf(prn_stream, "%c%c%s!F", PU1,
          gdev_fmlbp_paper_size(pdev));		/* Paper size */
#endif/*!FMLBP_NOPAPERSIZE*/

  /* Send each scan line in turn */
  {	int lnum;
        byte rmask = (byte)(0xff << (-pdev->width & 7));

        for ( lnum = 0; lnum < pdev->height; lnum++ )
          {	byte *end_data = data + line_size;
                int s = gdev_prn_copy_scan_lines(pdev, lnum,
                                                (byte *)data, line_size);
                if(s < 0) return_error(s);
                /* Mask off 1-bits beyond the line width. */
                end_data[-1] &= rmask;
                /* Remove trailing 0s. */
                while ( end_data > data && end_data[-1] == 0 )
                  end_data--;
                if ( end_data != data ) {
                  int num_cols = 0;
                  int out_count = 0;
                  byte *out_data = data;

                  while(out_data < end_data && *out_data == 0) {
                    num_cols += 8;
                    out_data++;
                  }
                  out_count = end_data - out_data;

                  /* move down */ /* move across */
                  goto_xy(prn_stream, num_cols, lnum);

                  /* transfer raster graphics */
                  fprintf(prn_stream, "%c%c%d;%d;0!a",
                          PU1, out_count, out_count*8 );

                  /* send the row */
                  fwrite(out_data, sizeof(byte), out_count, prn_stream);
                }
              }
      }
  /* eject page */
  fputc(0x0c,prn_stream);
  fflush(prn_stream);
#ifndef	FMLBP_NOPAPERSIZE
  gs_free(gs_lib_ctx_get_non_gc_memory_t(), (char *)data, line_size, sizeof(byte), "fmlbp_print_page(data)");
#endif/*!FMLBP_NOPAPERSIZE*/

  return 0;
}
Пример #27
0
bool LASzip::check_item(const LASitem* item)
{
  switch (item->type)
  {
  case LASitem::POINT10:
    if (item->size != 20) return return_error("POINT10 has size != 20");
    if (item->version > 2) return return_error("POINT10 has version > 2");
    break;
  case LASitem::GPSTIME11:
    if (item->size != 8) return return_error("GPSTIME11 has size != 8");
    if (item->version > 2) return return_error("GPSTIME11 has version > 2");
    break;
  case LASitem::RGB12:
    if (item->size != 6) return return_error("RGB12 has size != 6");
    if (item->version > 2) return return_error("RGB12 has version > 2");
    break;
  case LASitem::WAVEPACKET13:
    if (item->size != 29) return return_error("WAVEPACKET13 has size != 29");
    if (item->version > 1) return return_error("WAVEPACKET13 has version > 1");
    break;
  case LASitem::BYTE:
    if (item->size < 1) return return_error("BYTE has size < 1");
    if (item->version > 2) return return_error("BYTE has version > 2");
    break;
  case LASitem::POINT14:
    if (item->size != 30) return return_error("POINT14 has size != 30");
    if (item->version > 0) return return_error("POINT14 has version > 0");
    break;
  case LASitem::RGBNIR14:
    if (item->size != 8) return return_error("RGBNIR14 has size != 8");
    if (item->version > 0) return return_error("RGBNIR14 has version > 0");
    break;
  default:
    if (1)
    {
      char error[64];
      sprintf(error, "item unknown (%d,%d,%d)", item->type, item->size, item->version);
      return return_error(error);
    }
  }
  return true;
}
Пример #28
0
bool LASunzipper::seek(const unsigned int position)
{
  if (!reader->seek(count, position)) return return_error("seek() of LASreadPoint failed");
  count = position;
  return true;
}
Пример #29
0
bool LASzip::is_standard(const U16 num_items, const LASitem* items, U8* point_type, U16* record_length)
{
  if (items == 0) return return_error("LASitem array is zero");

  // this is always true
  if (point_type) *point_type = 127;
  if (record_length)
  {
    U16 i;
    *record_length = 0;
    for (i = 0; i < num_items; i++)
    {
      *record_length += items[i].size;
    }
  }

  // the minimal number of items is 1
  if (num_items < 1) return return_error("less than one LASitem entries");
  // the maximal number of items is 5
  if (num_items > 5) return return_error("more than five LASitem entries");

  if (items[0].is_type(LASitem::POINT10))
  {
    // consider all the POINT10 combinations
    if (num_items == 1)
    {
      if (point_type) *point_type = 0;
      if (record_length) assert(*record_length == 20);
      return true;
    }
    else
    {
      if (items[1].is_type(LASitem::GPSTIME11))
      {
        if (num_items == 2)
        {
          if (point_type) *point_type = 1;
          if (record_length) assert(*record_length == 28);
          return true;
        }
        else
        {
          if (items[2].is_type(LASitem::RGB12))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 3;
              if (record_length) assert(*record_length == 34);
              return true;
            }
            else
            {
              if (items[3].is_type(LASitem::WAVEPACKET13))
              {
                if (num_items == 4)
                {
                  if (point_type) *point_type = 5;
                  if (record_length) assert(*record_length == 63);
                  return true;
                }
                else
                {
                  if (items[4].is_type(LASitem::BYTE))
                  {
                    if (num_items == 5)
                    {
                      if (point_type) *point_type = 5;
                      if (record_length) assert(*record_length == (63 + items[4].size));
                      return true;
                    }
                  }
                }
              }
              else if (items[3].is_type(LASitem::BYTE))
              {
                if (num_items == 4)
                {
                  if (point_type) *point_type = 3;
                  if (record_length) assert(*record_length == (34 + items[3].size));
                  return true;
                }
              }
            }
          }
          else if (items[2].is_type(LASitem::WAVEPACKET13))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 4;
              if (record_length) assert(*record_length == 57);
              return true;
            }
            else 
            {
              if (items[3].is_type(LASitem::BYTE))
              {
                if (num_items == 4)
                {
                  if (point_type) *point_type = 4;
                  if (record_length) assert(*record_length == (57 + items[3].size));
                  return true;
                }
              }
            }
          }
          else if (items[2].is_type(LASitem::BYTE))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 1;
              if (record_length) assert(*record_length == (28 + items[2].size));
              return true;
            }
          }
        }
      }
      else if (items[1].is_type(LASitem::RGB12))
      {
        if (num_items == 2)
        {
          if (point_type) *point_type = 2;
          if (record_length) assert(*record_length == 26);
          return true;
        }
        else
        {
          if (items[2].is_type(LASitem::BYTE))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 2;
              if (record_length) assert(*record_length == (26 + items[2].size));
              return true;
            }
          }
        }
      }
      else if (items[1].is_type(LASitem::BYTE))
      {
        if (num_items == 2)
        {
          if (point_type) *point_type = 0;
          if (record_length) assert(*record_length == (20 + items[1].size));
          return true;
        }
      }
    }
  }
  else if (items[0].is_type(LASitem::POINT14))
  {
    // consider all the POINT14 combinations
    if (num_items == 1)
    {
      if (point_type) *point_type = 6;
      if (record_length) assert(*record_length == 30);
      return true;
    }
    else
    {
      if (items[1].is_type(LASitem::RGB12))
      {
        if (num_items == 2)
        {
          if (point_type) *point_type = 7;
          if (record_length) assert(*record_length == 36);
          return true;
        }
        else
        {
          if (items[2].is_type(LASitem::BYTE))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 7;
              if (record_length) assert(*record_length == (36 + items[2].size));
              return true;
            }
          }
        }
      }
      else if (items[1].is_type(LASitem::RGBNIR14))
      {
        if (num_items == 2)
        {
          if (point_type) *point_type = 8;
          if (record_length) assert(*record_length == 38);
          return true;
        }
        else
        {
          if (items[2].is_type(LASitem::WAVEPACKET13))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 10;
              if (record_length) assert(*record_length == 67);
              return true;
            }
            else 
            {
              if (items[3].is_type(LASitem::BYTE))
              {
                if (num_items == 4)
                {
                  if (point_type) *point_type = 10;
                  if (record_length) assert(*record_length == (67 + items[3].size));
                  return true;
                }
              }
            }
          }
          else if (items[2].is_type(LASitem::BYTE))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 8;
              if (record_length) assert(*record_length == (38 + items[2].size));
              return true;
            }
          }
        }
      }
      else if (items[1].is_type(LASitem::WAVEPACKET13))
      {
        if (num_items == 2)
        {
          if (point_type) *point_type = 9;
          if (record_length) assert(*record_length == 59);
          return true;
        }
        else
        {
          if (items[2].is_type(LASitem::BYTE))
          {
            if (num_items == 3)
            {
              if (point_type) *point_type = 9;
              if (record_length) assert(*record_length == (59 + items[2].size));
              return true;
            }
          }
        }
      }
      else if (items[1].is_type(LASitem::BYTE))
      {
        if (num_items == 2)
        {
          if (point_type) *point_type = 6;
          if (record_length) assert(*record_length == (30 + items[1].size));
          return true;
        }
      }
    }
  }
  else
  {
    return_error("first LASitem is neither POINT10 nor POINT14");
  }
  return return_error("LASitem array does not match LAS specification 1.4");
}
Пример #30
0
/* Send the page to the printer. */
#define DD 0x40				/* double density flag */
static int
eps_print_page(gx_device_printer *pdev, FILE *prn_stream, int y_9pin_high,
  const char *init_string, int init_length, const char *end_string,
  int archaic, int tab_hiccup)
{	
	static const char graphics_modes_9[5] =
	{	
	-1, 0 /*60*/, 1	/*120*/, 7 /*180*/, DD+3 /*240*/
	};

	static const char graphics_modes_24[7] =
	{	
    	-1, 32 /*60*/, 33 /*120*/, 39 /*180*/,
	DD+35 /*240*/, -1, DD+40 /*360*/
	};

	int y_24pin = (y_9pin_high ? 0 : pdev->y_pixels_per_inch > 72);
	int in_y_mult = ((y_24pin | y_9pin_high) ? 3 : 1);
	int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
	/* Note that in_size is a multiple of 8. */
	int in_size = line_size * (8 * in_y_mult);
	byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf1)");
	byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "eps_print_page(buf2)");
	byte *in = buf1;
	byte *out = buf2;
	int out_y_mult = (y_24pin ? 3 : 1);
	int x_dpi = (int)pdev->x_pixels_per_inch;
	char start_graphics =
		(y_24pin ? graphics_modes_24 : graphics_modes_9)[x_dpi / 60];
	int first_pass = (start_graphics & DD ? 1 : 0);
	int last_pass = first_pass * (y_9pin_high == 2 ? 1 : 2); 
	int y_passes = (y_9pin_high ? 3 : 1);
	int dots_per_space = x_dpi / 10;	/* pica space = 1/10" */
	int bytes_per_space = dots_per_space * out_y_mult;
	int tab_min_pixels = x_dpi * MIN_TAB_10THS / 10;
	int skip = 0, lnum = 0, pass, ypass;

	/* Check allocations */
	if ( buf1 == 0 || buf2 == 0 )
	{	if ( buf1 ) 
		  gs_free(pdev->memory, (char *)buf1, in_size, 1, "eps_print_page(buf1)");
		if ( buf2 ) 
		  gs_free(pdev->memory, (char *)buf2, in_size, 1, "eps_print_page(buf2)");
		return_error(gs_error_VMerror);
	}

	/* Initialize the printer and reset the margins. */
	fwrite(init_string, 1, init_length, prn_stream);
	if ( init_string[init_length - 1] == 'Q' )
		fputc((int)(pdev->width / pdev->x_pixels_per_inch * 10) + 2,
		      prn_stream);

	/* Calculate the minimum tab distance. */
	if ( tab_min_pixels < max(MIN_TAB_PIXELS, 3) )
		tab_min_pixels = max(MIN_TAB_PIXELS, 3);
	tab_min_pixels -= tab_min_pixels % 3;	/* simplify life */

	/* Print lines of graphics */
	while ( lnum < pdev->height )
	{	
		byte *in_data;
		byte *inp;
		byte *in_end;
		byte *out_end;
		byte *out_blk;
		register byte *outp;
		int lcnt;

		/* Copy 1 scan line and test for all zero. */
		gdev_prn_get_bits(pdev, lnum, in, &in_data);
		if ( in_data[0] == 0 &&
		     !memcmp((char *)in_data, (char *)in_data + 1, line_size - 1)
		   )
	    	{	
			lnum++;
			skip += 3 / in_y_mult;
			continue;
		}

		/* Vertical tab to the appropriate position. */
		while ( skip > 255 )
		{	
			fputs("\033J\377", prn_stream);
			skip -= 255;
		}
		if ( skip )
		{
			fprintf(prn_stream, "\033J%c", skip);
		}

		/* Copy the the scan lines. */
	    	lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
		if ( lcnt < 8 * in_y_mult )
		{	/* Pad with lines of zeros. */
			memset(in + lcnt * line_size, 0,
			       in_size - lcnt * line_size);
		}

		if ( y_9pin_high == 2 ) 
		{	/* Force printing of every dot in one pass */
			/* by reducing vertical resolution */
		        /* (ORing with the next line of data). */
		        /* This is necessary because some Epson compatibles */
			/* can't print neighboring dots. */
			int i;
			for ( i = 0; i < line_size * in_y_mult; ++i )
				in_data[i] |= in_data[i + line_size];
		}

		if ( y_9pin_high )
		{	/* Shuffle the scan lines */
			byte *p;
			int i;
			static const char index[] =
			{  0,  8, 16,  1,  9, 17,  
			   2, 10, 18,  3, 11, 19,
			   4, 12, 20,  5, 13, 21,
			   6, 14, 22,  7, 15, 23
			};

			for ( i = 0; i < 24; i++ )
			{
				memcpy(out+(index[i]*line_size),
				       in+(i*line_size), line_size);
			}
			p = in;
			in = out;
			out = p;
		}

	for ( ypass = 0; ypass < y_passes; ypass++ )
	{
	    for ( pass = first_pass; pass <= last_pass; pass++ )
	    {
		/* We have to 'transpose' blocks of 8 pixels x 8 lines, */
		/* because that's how the printer wants the data. */
		/* If we are in a 24-pin mode, we have to transpose */
		/* groups of 3 lines at a time. */

		if ( pass == first_pass )
		{
		    out_end = out;
		    inp = in;
		    in_end = inp + line_size;
    
		    if ( y_24pin )
    	            { 
    			for ( ; inp < in_end; inp++, out_end += 24 )
    			{ 
    	    	            gdev_prn_transpose_8x8(inp, line_size, out_end, 3);
    	                    gdev_prn_transpose_8x8(inp + line_size * 8, 
					           line_size, out_end + 1, 3);
    	                    gdev_prn_transpose_8x8(inp + line_size * 16, 
					           line_size, out_end + 2, 3);
			}
			/* Remove trailing 0s. */
			while ( out_end > out && out_end[-1] == 0 &&
    	   			out_end[-2] == 0 && out_end[-3] == 0)
			{
		             out_end -= 3;
			}
    	            }
		    else
    	            { 
    			for ( ; inp < in_end; inp++, out_end += 8 )
    			{ 
    		            gdev_prn_transpose_8x8(inp + (ypass * 8*line_size), 
					           line_size, out_end, 1);
		    	}
			/* Remove trailing 0s. */
			while ( out_end > out && out_end[-1] == 0 )
	        	{
		       	    out_end--;
			}
    	    	    }
		}

		for ( out_blk = outp = out; outp < out_end; )
    		{ 
    	 	    /* Skip a run of leading 0s.  At least */
    	            /* tab_min_pixels are needed to make tabbing */
    		    /* worth it.  We do everything by 3's to */
    		    /* avoid having to make different cases */
    		    /* for 9- and 24-pin. */
		   if ( !archaic &&
			*outp == 0 && out_end - outp >= tab_min_pixels &&
			(outp[1] | outp[2]) == 0 &&
			!memcmp((char *)outp, (char *)outp + 3,
				tab_min_pixels - 3)
		      )
    	    	    {
    			byte *zp = outp;
			int tpos;
			byte *newp;
           
			outp += tab_min_pixels;
    			while ( outp + 3 <= out_end && 
    		     		*outp == 0 &&
    				outp[1] == 0 && outp[2] == 0 )
    			{
			    outp += 3;
    			}
			tpos = (outp - out) / bytes_per_space;
			newp = out + tpos * bytes_per_space;
			if ( newp > zp + 10 )
    			{ 
    			    /* Output preceding bit data.*/
    		   	    if ( zp > out_blk )	
    			    {
    				/* only false at beginning of line */
			     	eps_output_run(out_blk, (int)(zp - out_blk),
    				    	       out_y_mult, start_graphics, 
					       prn_stream,
					       (y_9pin_high == 2 ?
					        (1 + ypass) & 1 : pass));
			    }
			    /* Tab over to the appropriate position. */
			    if ( tab_hiccup )
			      fputs("\010 ", prn_stream); /* bksp, space */
			    /* The following statement is broken up */
			    /* to work around a bug in emx/gcc. */
			    fprintf(prn_stream, "\033D%c", tpos);
			    fputc(0, prn_stream);
			    fputc('\t', prn_stream);
			    out_blk = outp = newp;
			}
		    }
		    else
		    {
    			outp += out_y_mult;
		    }
    		}
		if ( outp > out_blk )
		{
		    eps_output_run(out_blk, (int)(outp - out_blk),
			           out_y_mult, start_graphics,
				   prn_stream,
				   (y_9pin_high == 2 ? (1 + ypass) & 1 : pass));
		}

		fputc('\r', prn_stream);
	    }
	    if ( ypass < y_passes - 1 )
		fputs("\033J\001", prn_stream);
	}
	skip = 24 - y_passes + 1;		/* no skip on last Y pass */
	lnum += 8 * in_y_mult;
	}

	/* Eject the page and reinitialize the printer */
	fputs(end_string, prn_stream);
	fflush(prn_stream);

	gs_free(pdev->memory, (char *)buf2, in_size, 1, "eps_print_page(buf2)");
	gs_free(pdev->memory, (char *)buf1, in_size, 1, "eps_print_page(buf1)");
	return 0;
}