diff options
author | James Cloos <cloos@jhcloos.com> | 2012-05-25 06:06:06 -0400 |
---|---|---|
committer | James Cloos <cloos@jhcloos.com> | 2012-05-25 19:18:01 -0400 |
commit | 675005781d36848a10b1fba80d6ff2488e44747a (patch) | |
tree | d7dcfd3311b046a78d21606802edc3cd1062ee13 | |
parent | fad17657f6f583dbdef5a634d0f11dd79e446ffe (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.ac | 2 | ||||
-rw-r--r-- | gs/base/devs.mak | 6 | ||||
-rw-r--r-- | gs/base/gdevpsd.c | 125 | ||||
-rw-r--r-- | gs/base/unix-gcc.mak | 2 | ||||
-rw-r--r-- | gs/base/unixansi.mak | 2 |
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, ¶ms, 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 --------------------------- # |