summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cloos <cloos@jhcloos.com>2012-05-25 06:06:06 -0400
committerJames Cloos <cloos@jhcloos.com>2012-05-25 19:18:01 -0400
commit675005781d36848a10b1fba80d6ff2488e44747a (patch)
treed7dcfd3311b046a78d21606802edc3cd1062ee13
parentfad17657f6f583dbdef5a634d0f11dd79e446ffe (diff)
Add 16 bit/component psd devices.psd16
• psdrgb16 creates 48-bit rgb files. • psdcmyk16 creates 64+ bit cmyk (plus spot, as applicable) files. Given that the downscaler can only handle eight bit planes, a rangecheck error is generated when combining psdrgb16 or psdcmyk16 with a DownScaleFactor other than unity. This fixes Bug #688210. Signed-off-by: James Cloos <cloos@jhcloos.com>
-rw-r--r--gs/base/configure.ac2
-rw-r--r--gs/base/devs.mak6
-rw-r--r--gs/base/gdevpsd.c125
-rw-r--r--gs/base/unix-gcc.mak2
-rw-r--r--gs/base/unixansi.mak2
5 files changed, 97 insertions, 40 deletions
diff --git a/gs/base/configure.ac b/gs/base/configure.ac
index caaac4cc9..84f024918 100644
--- a/gs/base/configure.ac
+++ b/gs/base/configure.ac
@@ -1387,7 +1387,7 @@ JPEG_DEVS='jpeg jpeggray jpegcmyk'
TIFF_DEVS='tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled tiffscaled8 tiffscaled24'
PCX_DEVS='pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk pcx2up'
PBM_DEVS='pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw pam pamcmyk4 pamcmyk32 plan plang planm planc plank'
-PS_DEVS='psdf psdcmyk psdrgb pdfwrite pswrite ps2write epswrite psgray psmono psrgb bbox txtwrite inkcov'
+PS_DEVS='psdf psdcmyk psdrgb psdcmyk16 psdrgb16 pdfwrite pswrite ps2write epswrite psgray psmono psrgb bbox txtwrite inkcov'
MISC_FDEVS='ccr cif inferno mag16 mag256 mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm sgirgb sunhmono bit bitrgb bitrgbtags bitcmyk devicen spotcmyk xcf'
SVGDEV='svgwrite'
diff --git a/gs/base/devs.mak b/gs/base/devs.mak
index 82b82aa74..d67696062 100644
--- a/gs/base/devs.mak
+++ b/gs/base/devs.mak
@@ -1284,9 +1284,15 @@ psd_=$(GLOBJ)gdevpsd.$(OBJ) $(GLOBJ)gdevdevn.$(OBJ) $(GLOBJ)gsequivc.$(OBJ)
$(DD)psdrgb.dev : $(DEVS_MAK) $(psd_) $(GLD)page.dev $(GDEV)
$(SETDEV) $(DD)psdrgb $(psd_)
+$(DD)psdrgb16.dev : $(DEVS_MAK) $(psd_) $(GLD)page.dev $(GDEV)
+ $(SETDEV) $(DD)psdrgb16 $(psd_)
+
$(DD)psdcmyk.dev : $(DEVS_MAK) $(psd_) $(GLD)page.dev $(GDEV)
$(SETDEV) $(DD)psdcmyk $(psd_)
+$(DD)psdcmyk16.dev : $(DEVS_MAK) $(psd_) $(GLD)page.dev $(GDEV)
+ $(SETDEV) $(DD)psdcmyk16 $(psd_)
+
$(GLOBJ)gdevpsd.$(OBJ) : $(GLSRC)gdevpsd.c $(PDEVH) $(math__h)\
$(gdevdcrd_h) $(gscrd_h) $(gscrdp_h) $(gsparam_h) $(gxlum_h)\
$(gstypes_h) $(gxdcconv_h) $(gdevdevn_h) $(gsequivc_h)\
diff --git a/gs/base/gdevpsd.c b/gs/base/gdevpsd.c
index 5a640e7ca..417f97014 100644
--- a/gs/base/gdevpsd.c
+++ b/gs/base/gdevpsd.c
@@ -270,6 +270,19 @@ static fixed_colorant_name DeviceRGBComponents[] = {
prn_device_body_rest_(psd_print_page)
/*
+ * Select the default number of components based upon the number of bits
+ * that we have in a gx_color_index. If we have 64 bits then we can compress
+ * the colorant data. This allows us to handle more colorants. However the
+ * compressed encoding is not separable. If we do not have 64 bits then we
+ * use a simple non-compressable encoding.
+ */
+#define NC ARCH_SIZEOF_GX_COLOR_INDEX
+#define SL GX_CINFO_SEP_LIN
+#define ENCODE_COLOR psd_encode_color
+#define DECODE_COLOR psd_decode_color
+#define GCIB (ARCH_SIZEOF_GX_COLOR_INDEX * 8)
+
+/*
* PSD device with RGB process color model.
*/
static const gx_device_procs spot_rgb_procs =
@@ -277,7 +290,7 @@ static const gx_device_procs spot_rgb_procs =
const psd_device gs_psdrgb_device =
{
- psd_device_body(spot_rgb_procs, "psdrgb", 3, GX_CINFO_POLARITY_ADDITIVE, 24, 255, 255, GX_CINFO_SEP_LIN, "DeviceRGB"),
+ psd_device_body(spot_rgb_procs, "psdrgb", NC, GX_CINFO_POLARITY_ADDITIVE, GCIB, 255, 255, GX_CINFO_SEP_LIN, "DeviceRGB"),
/* devn_params specific parameters */
{ 8, /* Bits per color - must match ncomp, depth, etc. above */
DeviceRGBComponents, /* Names of color model colorants */
@@ -294,18 +307,24 @@ const psd_device gs_psdrgb_device =
1 /* downscale_factor */
};
-/*
- * Select the default number of components based upon the number of bits
- * that we have in a gx_color_index. If we have 64 bits then we can compress
- * the colorant data. This allows us to handle more colorants. However the
- * compressed encoding is not separable. If we do not have 64 bits then we
- * use a simple non-compressable encoding.
- */
-#define NC ARCH_SIZEOF_GX_COLOR_INDEX
-#define SL GX_CINFO_SEP_LIN
-#define ENCODE_COLOR psd_encode_color
-#define DECODE_COLOR psd_decode_color
-#define GCIB (ARCH_SIZEOF_GX_COLOR_INDEX * 8)
+const psd_device gs_psdrgb16_device =
+{
+ psd_device_body(spot_rgb_procs, "psdrgb16", NC, GX_CINFO_POLARITY_ADDITIVE, (GCIB << 1), 65535, 65535, GX_CINFO_SEP_LIN, "DeviceRGB"),
+ /* devn_params specific parameters */
+ { 16, /* Bits per color - must match ncomp, depth, etc. above */
+ DeviceRGBComponents, /* Names of color model colorants */
+ 3, /* Number colorants for RGB */
+ 0, /* MaxSeparations has not been specified */
+ -1, /* PageSpotColors has not been specified */
+ {0}, /* SeparationNames */
+ 0, /* SeparationOrder names */
+ {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
+ },
+ { true }, /* equivalent CMYK colors for spot colors */
+ /* PSD device specific parameters */
+ psd_DEVICE_RGB, /* Color model */
+ 1 /* downscale_factor */
+};
/*
* PSD device with CMYK process color model and spot color support.
@@ -332,6 +351,25 @@ const psd_device gs_psdcmyk_device =
1 /* downscale_factor */
};
+const psd_device gs_psdcmyk16_device =
+{
+ psd_device_body(spot_cmyk_procs, "psdcmyk16", NC, GX_CINFO_POLARITY_SUBTRACTIVE, (GCIB << 1), 65535, 65535, SL, "DeviceCMYK"),
+ /* devn_params specific parameters */
+ { 16, /* Bits per color - must match ncomp, depth, etc. above */
+ DeviceCMYKComponents, /* Names of color model colorants */
+ 4, /* Number colorants for CMYK */
+ 0, /* MaxSeparations has not been specified */
+ -1, /* PageSpotColors has not been specified */
+ {0}, /* SeparationNames */
+ 0, /* SeparationOrder names */
+ {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
+ },
+ { true }, /* equivalent CMYK colors for spot colors */
+ /* PSD device specific parameters */
+ psd_DEVICE_CMYK, /* Color model */
+ 1 /* downscale_factor */
+};
+
#undef NC
#undef SL
#undef ENCODE_COLOR
@@ -1009,9 +1047,9 @@ typedef struct {
int width;
int height;
- int base_bytes_pp; /* almost always 3 (rgb) or 4 (CMYK) */
+ int base_num_channels; /* almost always 3 (rgb) or 4 (CMYK) */
int n_extra_channels;
- int num_channels; /* base_bytes_pp + any spot colors that are imaged */
+ int num_channels; /* base_num_channels + any spot colors that are imaged */
/* Map output channel number to original separation number. */
int chnl_to_orig_sep[GX_DEVICE_COLOR_MAX_COMPONENTS];
/* Map output channel number to gx_color_index position. */
@@ -1028,8 +1066,8 @@ psd_setup(psd_write_ctx *xc, psd_device *dev)
int spot_count;
#define NUM_CMYK_COMPONENTS 4
- xc->base_bytes_pp = dev->devn_params.num_std_colorant_names;
- xc->num_channels = xc->base_bytes_pp;
+ xc->base_num_channels = dev->devn_params.num_std_colorant_names;
+ xc->num_channels = xc->base_num_channels;
if (dev->devn_params.num_separation_order_names == 0) {
xc->n_extra_channels = dev->devn_params.separations.num_separations;
} else {
@@ -1053,7 +1091,7 @@ psd_setup(psd_write_ctx *xc, psd_device *dev)
* model channels are simply filled with white. For spot colors we only
* image the requested channels.
*/
- for (i = 0; i < xc->base_bytes_pp + xc->n_extra_channels; i++) {
+ for (i = 0; i < xc->base_num_channels + xc->n_extra_channels; i++) {
xc->chnl_to_position[i] = i;
xc->chnl_to_orig_sep[i] = i;
}
@@ -1110,7 +1148,8 @@ static int
psd_write_header(psd_write_ctx *xc, psd_device *pdev)
{
int code = 0;
- int bytes_pp = xc->num_channels;
+ int num_channels = xc->num_channels;
+ int bpc = pdev->devn_params.bitspercomponent;
int chan_idx;
int chan_names_len = 0;
int sep_num;
@@ -1121,11 +1160,11 @@ psd_write_header(psd_write_ctx *xc, psd_device *pdev)
/* Reserved 6 Bytes - Must be zero */
psd_write_32(xc, 0);
psd_write_16(xc, 0);
- psd_write_16(xc, (bits16) bytes_pp); /* Channels (2 Bytes) - Supported range is 1 to 24 */
+ psd_write_16(xc, (bits16) num_channels); /* Channels (2 Bytes) - Supported range is 1 to 56 */
psd_write_32(xc, xc->height); /* Rows */
psd_write_32(xc, xc->width); /* Columns */
- psd_write_16(xc, 8); /* Depth - 1, 8 and 16 */
- psd_write_16(xc, (bits16) xc->base_bytes_pp); /* Mode - RGB=3, CMYK=4 */
+ psd_write_16(xc, bpc); /* Depth - 1, 8, 16 or 32*/
+ psd_write_16(xc, (bits16) xc->base_num_channels); /* Mode - Bitmap=0, Grayscale=1, RGB=3, CMYK=4 MultiChannel=7 Lab=9 */
/* Color Mode Data */
psd_write_32(xc, 0); /* No color mode data */
@@ -1139,7 +1178,7 @@ psd_write_header(psd_write_ctx *xc, psd_device *pdev)
chan_names_len += (separation_name->size + 1);
}
psd_write_32(xc, 12 + (chan_names_len + (chan_names_len % 2))
- + (12 + (14 * (xc->num_channels - xc->base_bytes_pp)))
+ + (12 + (14 * (xc->num_channels - xc->base_num_channels)))
+ 28);
psd_write(xc, (const byte *)"8BIM", 4);
psd_write_16(xc, 1006); /* 0x03EE */
@@ -1158,7 +1197,7 @@ psd_write_header(psd_write_ctx *xc, psd_device *pdev)
psd_write(xc, (const byte *)"8BIM", 4);
psd_write_16(xc, 1007); /* 0x03EF */
psd_write_16(xc, 0); /* PString */
- psd_write_32(xc, 14 * (xc->num_channels - xc->base_bytes_pp)); /* Length */
+ psd_write_32(xc, 14 * (xc->num_channels - xc->base_num_channels)); /* Length */
for (chan_idx = NUM_CMYK_COMPONENTS; chan_idx < xc->num_channels; chan_idx++) {
sep_num = xc->chnl_to_orig_sep[chan_idx] - NUM_CMYK_COMPONENTS;
psd_write_16(xc, 02); /* CMYK */
@@ -1251,12 +1290,14 @@ psd_prn_close(gx_device *dev)
static int
psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev)
{
- int raster_plane = bitmap_raster(pdev->width * 8);
+ psd_device *psd_dev = (psd_device *)pdev;
+ int bpc = psd_dev->devn_params.bitspercomponent;
+ int raster_plane = bitmap_raster(pdev->width * bpc);
byte *planes[GS_CLIENT_COLOR_MAX_COMPONENTS];
int code = 0;
int i, j;
byte *sep_line;
- int base_bytes_pp = xc->base_bytes_pp;
+ int base_num_channels = xc->base_num_channels;
int chan_idx;
/* psd_device *xdev = (psd_device *)pdev;
gcmmhlink_t link = xdev->output_icc_link; */
@@ -1265,7 +1306,9 @@ psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev)
gs_int_rect rect;
gs_get_bits_params_t params;
gx_downscaler_t ds = { NULL };
- psd_device *psd_dev = (psd_device *)pdev;
+ int val;
+ int octets_per_component = bpc >> 3;
+ int octets_per_line = xc->width * octets_per_component;
rect.q.x = pdev->width;
rect.p.x = 0;
@@ -1275,9 +1318,9 @@ psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev)
GB_PACKING_PLANAR | GB_COLORS_NATIVE | GB_ALPHA_NONE);
params.x_offset = 0;
params.raster = bitmap_raster(pdev->width * pdev->color_info.depth);
- psd_write_16(xc, 0); /* Compression */
+ psd_write_16(xc, 0); /* Compression - 0=None, 1=RLE/PackBits, 2=Deflate 3=Defalte+Prediction */
- sep_line = gs_alloc_bytes(pdev->memory, xc->width, "psd_write_sep_line");
+ sep_line = gs_alloc_bytes(pdev->memory, octets_per_line , "psd_write_sep_line");
for (chan_idx = 0; chan_idx < num_comp; chan_idx++) {
planes[chan_idx] = gs_alloc_bytes(pdev->memory, raster_plane,
@@ -1291,7 +1334,7 @@ psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev)
return_error(gs_error_VMerror);
code = gx_downscaler_init_planar(&ds, (gx_device *)pdev, &params, num_comp,
- psd_dev->downscale_factor, 0, 8);
+ psd_dev->downscale_factor, 0, bpc);
if (code < 0)
goto cleanup;
@@ -1309,13 +1352,18 @@ psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev)
unpacked = params.data[data_pos];
/* To do, get ICC stuff in place for planar device */
// if (link == NULL) {
- if (base_bytes_pp == 3) {
+ if (base_num_channels == 3) {
/* RGB */
- memcpy(sep_line, unpacked, xc->width);
+ memcpy(sep_line, unpacked, xc->width * octets_per_component);
} else {
- for (i = 0; i < xc->width; ++i) {
+ for (i = 0; i < xc->width; ++i) {
/* CMYK + spots*/
- sep_line[i] = 255 - unpacked[i];
+ if (octets_per_component == 1) {
+ sep_line[i] = pdev->color_info.max_color - unpacked[i];
+ } else if (octets_per_component == 2) {
+ val = pdev->color_info.max_color - ((short *)unpacked)[i];
+ ((short *)sep_line)[i] = val;
+ }
}
}
/* } else {
@@ -1323,13 +1371,13 @@ psd_write_image_data(psd_write_ctx *xc, gx_device_printer *pdev)
link, xdev->output_profile->num_comps,
xdev->output_profile->num_comps_out);
} */
- psd_write(xc, sep_line, xc->width);
+ psd_write(xc, sep_line, octets_per_line);
}
} else {
if (chan_idx < NUM_CMYK_COMPONENTS) {
/* Write empty process color in the area */
- memset(sep_line,255,xc->width);
- psd_write(xc, sep_line, xc->width);
+ memset(sep_line, 255, octets_per_line);
+ psd_write(xc, sep_line, octets_per_line);
}
}
}
@@ -1352,6 +1400,9 @@ psd_print_page(gx_device_printer *pdev, FILE *file)
xc.f = file;
+ if (psd_dev->devn_params.bitspercomponent > 8 && psd_dev->downscale_factor != 1)
+ return_error(gs_error_rangecheck);
+
psd_setup(&xc, psd_dev);
psd_write_header(&xc, psd_dev);
psd_write_image_data(&xc, pdev);
diff --git a/gs/base/unix-gcc.mak b/gs/base/unix-gcc.mak
index a3a9d2d33..f303f5eb0 100644
--- a/gs/base/unix-gcc.mak
+++ b/gs/base/unix-gcc.mak
@@ -416,7 +416,7 @@ DEVICE_DEVS17=$(DD)plan.dev $(DD)planm.dev $(DD)plang.dev $(DD)planc.dev $(DD)pl
DEVICE_DEVS18=
DEVICE_DEVS19=
DEVICE_DEVS20=$(DD)cljet5.dev $(DD)cljet5c.dev $(DD)pamcmyk32.dev $(DD)pamcmyk4.dev
-DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev
+DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)psdcmyk16.dev $(DD)psdrgb16.dev
# Shared library target to build.
# Note that the two vga devices are Linux specific, and requires svgalib
diff --git a/gs/base/unixansi.mak b/gs/base/unixansi.mak
index bdeab04b0..7f553c3d4 100644
--- a/gs/base/unixansi.mak
+++ b/gs/base/unixansi.mak
@@ -362,7 +362,7 @@ DEVICE_DEVS17=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm
DEVICE_DEVS18=
DEVICE_DEVS19=
DEVICE_DEVS20=
-DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)pamcmyk32.dev
+DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)psdcmyk16.dev $(DD)psdrgb16.dev $(DD)pamcmyk32.dev
# ---------------------------- End of options --------------------------- #