1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Raster file routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * This file is part of the CUPS Imaging library.
8*5e7646d2SAndroid Build Coastguard Worker *
9*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
10*5e7646d2SAndroid Build Coastguard Worker * information.
11*5e7646d2SAndroid Build Coastguard Worker */
12*5e7646d2SAndroid Build Coastguard Worker
13*5e7646d2SAndroid Build Coastguard Worker /*
14*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
15*5e7646d2SAndroid Build Coastguard Worker */
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker #include "raster-private.h"
18*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
19*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_STDINT_H
20*5e7646d2SAndroid Build Coastguard Worker # include <stdint.h>
21*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_STDINT_H */
22*5e7646d2SAndroid Build Coastguard Worker
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker /*
25*5e7646d2SAndroid Build Coastguard Worker * Private structures...
26*5e7646d2SAndroid Build Coastguard Worker */
27*5e7646d2SAndroid Build Coastguard Worker
28*5e7646d2SAndroid Build Coastguard Worker typedef void (*_cups_copyfunc_t)(void *dst, const void *src, size_t bytes);
29*5e7646d2SAndroid Build Coastguard Worker
30*5e7646d2SAndroid Build Coastguard Worker
31*5e7646d2SAndroid Build Coastguard Worker /*
32*5e7646d2SAndroid Build Coastguard Worker * Local globals...
33*5e7646d2SAndroid Build Coastguard Worker */
34*5e7646d2SAndroid Build Coastguard Worker
35*5e7646d2SAndroid Build Coastguard Worker static const char * const apple_media_types[] =
36*5e7646d2SAndroid Build Coastguard Worker { /* media-type values for Apple Raster */
37*5e7646d2SAndroid Build Coastguard Worker "auto",
38*5e7646d2SAndroid Build Coastguard Worker "stationery",
39*5e7646d2SAndroid Build Coastguard Worker "transparency",
40*5e7646d2SAndroid Build Coastguard Worker "envelope",
41*5e7646d2SAndroid Build Coastguard Worker "cardstock",
42*5e7646d2SAndroid Build Coastguard Worker "labels",
43*5e7646d2SAndroid Build Coastguard Worker "stationery-letterhead",
44*5e7646d2SAndroid Build Coastguard Worker "disc",
45*5e7646d2SAndroid Build Coastguard Worker "photographic-matte",
46*5e7646d2SAndroid Build Coastguard Worker "photographic-satin",
47*5e7646d2SAndroid Build Coastguard Worker "photographic-semi-gloss",
48*5e7646d2SAndroid Build Coastguard Worker "photographic-glossy",
49*5e7646d2SAndroid Build Coastguard Worker "photographic-high-gloss",
50*5e7646d2SAndroid Build Coastguard Worker "other"
51*5e7646d2SAndroid Build Coastguard Worker };
52*5e7646d2SAndroid Build Coastguard Worker
53*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
54*5e7646d2SAndroid Build Coastguard Worker static const char * const cups_modes[] =
55*5e7646d2SAndroid Build Coastguard Worker { /* Open modes */
56*5e7646d2SAndroid Build Coastguard Worker "CUPS_RASTER_READ",
57*5e7646d2SAndroid Build Coastguard Worker "CUPS_RASTER_WRITE",
58*5e7646d2SAndroid Build Coastguard Worker "CUPS_RASTER_WRITE_COMPRESSED",
59*5e7646d2SAndroid Build Coastguard Worker "CUPS_RASTER_WRITE_PWG",
60*5e7646d2SAndroid Build Coastguard Worker "CUPS_RASTER_WRITE_APPLE"
61*5e7646d2SAndroid Build Coastguard Worker };
62*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker
65*5e7646d2SAndroid Build Coastguard Worker /*
66*5e7646d2SAndroid Build Coastguard Worker * Local functions...
67*5e7646d2SAndroid Build Coastguard Worker */
68*5e7646d2SAndroid Build Coastguard Worker
69*5e7646d2SAndroid Build Coastguard Worker static ssize_t cups_raster_io(cups_raster_t *r, unsigned char *buf, size_t bytes);
70*5e7646d2SAndroid Build Coastguard Worker static ssize_t cups_raster_read(cups_raster_t *r, unsigned char *buf, size_t bytes);
71*5e7646d2SAndroid Build Coastguard Worker static int cups_raster_update(cups_raster_t *r);
72*5e7646d2SAndroid Build Coastguard Worker static ssize_t cups_raster_write(cups_raster_t *r, const unsigned char *pixels);
73*5e7646d2SAndroid Build Coastguard Worker static void cups_swap(unsigned char *buf, size_t bytes);
74*5e7646d2SAndroid Build Coastguard Worker static void cups_swap_copy(unsigned char *dst, const unsigned char *src, size_t bytes);
75*5e7646d2SAndroid Build Coastguard Worker
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker /*
78*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterColorSpaceString()' - Return the colorspace name for a
79*5e7646d2SAndroid Build Coastguard Worker * cupsColorSpace value.
80*5e7646d2SAndroid Build Coastguard Worker */
81*5e7646d2SAndroid Build Coastguard Worker
82*5e7646d2SAndroid Build Coastguard Worker const char *
_cupsRasterColorSpaceString(cups_cspace_t cspace)83*5e7646d2SAndroid Build Coastguard Worker _cupsRasterColorSpaceString(
84*5e7646d2SAndroid Build Coastguard Worker cups_cspace_t cspace) /* I - cupsColorSpace value */
85*5e7646d2SAndroid Build Coastguard Worker {
86*5e7646d2SAndroid Build Coastguard Worker static const char * const cups_color_spaces[] =
87*5e7646d2SAndroid Build Coastguard Worker { /* Color spaces */
88*5e7646d2SAndroid Build Coastguard Worker "W",
89*5e7646d2SAndroid Build Coastguard Worker "RGB",
90*5e7646d2SAndroid Build Coastguard Worker "RGBA",
91*5e7646d2SAndroid Build Coastguard Worker "K",
92*5e7646d2SAndroid Build Coastguard Worker "CMY",
93*5e7646d2SAndroid Build Coastguard Worker "YMC",
94*5e7646d2SAndroid Build Coastguard Worker "CMYK",
95*5e7646d2SAndroid Build Coastguard Worker "YMCK",
96*5e7646d2SAndroid Build Coastguard Worker "KCMY",
97*5e7646d2SAndroid Build Coastguard Worker "KCMYcm",
98*5e7646d2SAndroid Build Coastguard Worker "GMCK",
99*5e7646d2SAndroid Build Coastguard Worker "GMCS",
100*5e7646d2SAndroid Build Coastguard Worker "WHITE",
101*5e7646d2SAndroid Build Coastguard Worker "GOLD",
102*5e7646d2SAndroid Build Coastguard Worker "SILVER",
103*5e7646d2SAndroid Build Coastguard Worker "CIEXYZ",
104*5e7646d2SAndroid Build Coastguard Worker "CIELab",
105*5e7646d2SAndroid Build Coastguard Worker "RGBW",
106*5e7646d2SAndroid Build Coastguard Worker "SW",
107*5e7646d2SAndroid Build Coastguard Worker "SRGB",
108*5e7646d2SAndroid Build Coastguard Worker "ADOBERGB",
109*5e7646d2SAndroid Build Coastguard Worker "21",
110*5e7646d2SAndroid Build Coastguard Worker "22",
111*5e7646d2SAndroid Build Coastguard Worker "23",
112*5e7646d2SAndroid Build Coastguard Worker "24",
113*5e7646d2SAndroid Build Coastguard Worker "25",
114*5e7646d2SAndroid Build Coastguard Worker "26",
115*5e7646d2SAndroid Build Coastguard Worker "27",
116*5e7646d2SAndroid Build Coastguard Worker "28",
117*5e7646d2SAndroid Build Coastguard Worker "29",
118*5e7646d2SAndroid Build Coastguard Worker "30",
119*5e7646d2SAndroid Build Coastguard Worker "31",
120*5e7646d2SAndroid Build Coastguard Worker "ICC1",
121*5e7646d2SAndroid Build Coastguard Worker "ICC2",
122*5e7646d2SAndroid Build Coastguard Worker "ICC3",
123*5e7646d2SAndroid Build Coastguard Worker "ICC4",
124*5e7646d2SAndroid Build Coastguard Worker "ICC5",
125*5e7646d2SAndroid Build Coastguard Worker "ICC6",
126*5e7646d2SAndroid Build Coastguard Worker "ICC7",
127*5e7646d2SAndroid Build Coastguard Worker "ICC8",
128*5e7646d2SAndroid Build Coastguard Worker "ICC9",
129*5e7646d2SAndroid Build Coastguard Worker "ICCA",
130*5e7646d2SAndroid Build Coastguard Worker "ICCB",
131*5e7646d2SAndroid Build Coastguard Worker "ICCC",
132*5e7646d2SAndroid Build Coastguard Worker "ICCD",
133*5e7646d2SAndroid Build Coastguard Worker "ICCE",
134*5e7646d2SAndroid Build Coastguard Worker "ICCF",
135*5e7646d2SAndroid Build Coastguard Worker "47",
136*5e7646d2SAndroid Build Coastguard Worker "DEVICE1",
137*5e7646d2SAndroid Build Coastguard Worker "DEVICE2",
138*5e7646d2SAndroid Build Coastguard Worker "DEVICE3",
139*5e7646d2SAndroid Build Coastguard Worker "DEVICE4",
140*5e7646d2SAndroid Build Coastguard Worker "DEVICE5",
141*5e7646d2SAndroid Build Coastguard Worker "DEVICE6",
142*5e7646d2SAndroid Build Coastguard Worker "DEVICE7",
143*5e7646d2SAndroid Build Coastguard Worker "DEVICE8",
144*5e7646d2SAndroid Build Coastguard Worker "DEVICE9",
145*5e7646d2SAndroid Build Coastguard Worker "DEVICEA",
146*5e7646d2SAndroid Build Coastguard Worker "DEVICEB",
147*5e7646d2SAndroid Build Coastguard Worker "DEVICEC",
148*5e7646d2SAndroid Build Coastguard Worker "DEVICED",
149*5e7646d2SAndroid Build Coastguard Worker "DEVICEE",
150*5e7646d2SAndroid Build Coastguard Worker "DEVICEF"
151*5e7646d2SAndroid Build Coastguard Worker };
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker if (cspace < CUPS_CSPACE_W || cspace > CUPS_CSPACE_DEVICEF)
154*5e7646d2SAndroid Build Coastguard Worker return ("Unknown");
155*5e7646d2SAndroid Build Coastguard Worker else
156*5e7646d2SAndroid Build Coastguard Worker return (cups_color_spaces[cspace]);
157*5e7646d2SAndroid Build Coastguard Worker }
158*5e7646d2SAndroid Build Coastguard Worker
159*5e7646d2SAndroid Build Coastguard Worker
160*5e7646d2SAndroid Build Coastguard Worker /*
161*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterDelete()' - Free a raster stream.
162*5e7646d2SAndroid Build Coastguard Worker *
163*5e7646d2SAndroid Build Coastguard Worker * The file descriptor associated with the raster stream must be closed
164*5e7646d2SAndroid Build Coastguard Worker * separately as needed.
165*5e7646d2SAndroid Build Coastguard Worker */
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker void
_cupsRasterDelete(cups_raster_t * r)168*5e7646d2SAndroid Build Coastguard Worker _cupsRasterDelete(cups_raster_t *r) /* I - Stream to free */
169*5e7646d2SAndroid Build Coastguard Worker {
170*5e7646d2SAndroid Build Coastguard Worker if (r != NULL)
171*5e7646d2SAndroid Build Coastguard Worker {
172*5e7646d2SAndroid Build Coastguard Worker if (r->buffer)
173*5e7646d2SAndroid Build Coastguard Worker free(r->buffer);
174*5e7646d2SAndroid Build Coastguard Worker
175*5e7646d2SAndroid Build Coastguard Worker if (r->pixels)
176*5e7646d2SAndroid Build Coastguard Worker free(r->pixels);
177*5e7646d2SAndroid Build Coastguard Worker
178*5e7646d2SAndroid Build Coastguard Worker free(r);
179*5e7646d2SAndroid Build Coastguard Worker }
180*5e7646d2SAndroid Build Coastguard Worker }
181*5e7646d2SAndroid Build Coastguard Worker
182*5e7646d2SAndroid Build Coastguard Worker
183*5e7646d2SAndroid Build Coastguard Worker /*
184*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterInitPWGHeader()' - Initialize a page header for PWG Raster output.
185*5e7646d2SAndroid Build Coastguard Worker *
186*5e7646d2SAndroid Build Coastguard Worker * The "media" argument specifies the media to use.
187*5e7646d2SAndroid Build Coastguard Worker *
188*5e7646d2SAndroid Build Coastguard Worker * The "type" argument specifies a "pwg-raster-document-type-supported" value
189*5e7646d2SAndroid Build Coastguard Worker * that controls the color space and bit depth of the raster data.
190*5e7646d2SAndroid Build Coastguard Worker *
191*5e7646d2SAndroid Build Coastguard Worker * The "xres" and "yres" arguments specify the raster resolution in dots per
192*5e7646d2SAndroid Build Coastguard Worker * inch.
193*5e7646d2SAndroid Build Coastguard Worker *
194*5e7646d2SAndroid Build Coastguard Worker * The "sheet_back" argument specifies a "pwg-raster-document-sheet-back" value
195*5e7646d2SAndroid Build Coastguard Worker * to apply for the back side of a page. Pass @code NULL@ for the front side.
196*5e7646d2SAndroid Build Coastguard Worker *
197*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 2.2/macOS 10.12@
198*5e7646d2SAndroid Build Coastguard Worker */
199*5e7646d2SAndroid Build Coastguard Worker
200*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on success, 0 on failure */
_cupsRasterInitPWGHeader(cups_page_header2_t * h,pwg_media_t * media,const char * type,int xdpi,int ydpi,const char * sides,const char * sheet_back)201*5e7646d2SAndroid Build Coastguard Worker _cupsRasterInitPWGHeader(
202*5e7646d2SAndroid Build Coastguard Worker cups_page_header2_t *h, /* I - Page header */
203*5e7646d2SAndroid Build Coastguard Worker pwg_media_t *media, /* I - PWG media information */
204*5e7646d2SAndroid Build Coastguard Worker const char *type, /* I - PWG raster type string */
205*5e7646d2SAndroid Build Coastguard Worker int xdpi, /* I - Cross-feed direction (horizontal) resolution */
206*5e7646d2SAndroid Build Coastguard Worker int ydpi, /* I - Feed direction (vertical) resolution */
207*5e7646d2SAndroid Build Coastguard Worker const char *sides, /* I - IPP "sides" option value */
208*5e7646d2SAndroid Build Coastguard Worker const char *sheet_back) /* I - Transform for back side or @code NULL@ for none */
209*5e7646d2SAndroid Build Coastguard Worker {
210*5e7646d2SAndroid Build Coastguard Worker if (!h || !media || !type || xdpi <= 0 || ydpi <= 0)
211*5e7646d2SAndroid Build Coastguard Worker {
212*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("%s", strerror(EINVAL));
213*5e7646d2SAndroid Build Coastguard Worker return (0);
214*5e7646d2SAndroid Build Coastguard Worker }
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker /*
217*5e7646d2SAndroid Build Coastguard Worker * Initialize the page header...
218*5e7646d2SAndroid Build Coastguard Worker */
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker memset(h, 0, sizeof(cups_page_header2_t));
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker strlcpy(h->cupsPageSizeName, media->pwg, sizeof(h->cupsPageSizeName));
223*5e7646d2SAndroid Build Coastguard Worker
224*5e7646d2SAndroid Build Coastguard Worker h->PageSize[0] = (unsigned)(72 * media->width / 2540);
225*5e7646d2SAndroid Build Coastguard Worker h->PageSize[1] = (unsigned)(72 * media->length / 2540);
226*5e7646d2SAndroid Build Coastguard Worker
227*5e7646d2SAndroid Build Coastguard Worker /* This never gets written but is needed for some applications */
228*5e7646d2SAndroid Build Coastguard Worker h->cupsPageSize[0] = 72.0f * media->width / 2540.0f;
229*5e7646d2SAndroid Build Coastguard Worker h->cupsPageSize[1] = 72.0f * media->length / 2540.0f;
230*5e7646d2SAndroid Build Coastguard Worker
231*5e7646d2SAndroid Build Coastguard Worker h->ImagingBoundingBox[2] = h->PageSize[0];
232*5e7646d2SAndroid Build Coastguard Worker h->ImagingBoundingBox[3] = h->PageSize[1];
233*5e7646d2SAndroid Build Coastguard Worker
234*5e7646d2SAndroid Build Coastguard Worker h->HWResolution[0] = (unsigned)xdpi;
235*5e7646d2SAndroid Build Coastguard Worker h->HWResolution[1] = (unsigned)ydpi;
236*5e7646d2SAndroid Build Coastguard Worker
237*5e7646d2SAndroid Build Coastguard Worker h->cupsWidth = (unsigned)(media->width * xdpi / 2540);
238*5e7646d2SAndroid Build Coastguard Worker h->cupsHeight = (unsigned)(media->length * ydpi / 2540);
239*5e7646d2SAndroid Build Coastguard Worker
240*5e7646d2SAndroid Build Coastguard Worker if (h->cupsWidth > 0x00ffffff || h->cupsHeight > 0x00ffffff)
241*5e7646d2SAndroid Build Coastguard Worker {
242*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Raster dimensions too large.");
243*5e7646d2SAndroid Build Coastguard Worker return (0);
244*5e7646d2SAndroid Build Coastguard Worker }
245*5e7646d2SAndroid Build Coastguard Worker
246*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_ImageBoxRight] = h->cupsWidth;
247*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_ImageBoxBottom] = h->cupsHeight;
248*5e7646d2SAndroid Build Coastguard Worker
249*5e7646d2SAndroid Build Coastguard Worker /*
250*5e7646d2SAndroid Build Coastguard Worker * Colorspace and bytes per line...
251*5e7646d2SAndroid Build Coastguard Worker */
252*5e7646d2SAndroid Build Coastguard Worker
253*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(type, "adobe-rgb_8"))
254*5e7646d2SAndroid Build Coastguard Worker {
255*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 8;
256*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 24;
257*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_ADOBERGB;
258*5e7646d2SAndroid Build Coastguard Worker }
259*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "adobe-rgb_16"))
260*5e7646d2SAndroid Build Coastguard Worker {
261*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 16;
262*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 48;
263*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_ADOBERGB;
264*5e7646d2SAndroid Build Coastguard Worker }
265*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "black_1"))
266*5e7646d2SAndroid Build Coastguard Worker {
267*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 1;
268*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 1;
269*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_K;
270*5e7646d2SAndroid Build Coastguard Worker }
271*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "black_8"))
272*5e7646d2SAndroid Build Coastguard Worker {
273*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 8;
274*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 8;
275*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_K;
276*5e7646d2SAndroid Build Coastguard Worker }
277*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "black_16"))
278*5e7646d2SAndroid Build Coastguard Worker {
279*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 16;
280*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 16;
281*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_K;
282*5e7646d2SAndroid Build Coastguard Worker }
283*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "cmyk_8"))
284*5e7646d2SAndroid Build Coastguard Worker {
285*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 8;
286*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 32;
287*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_CMYK;
288*5e7646d2SAndroid Build Coastguard Worker }
289*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "cmyk_16"))
290*5e7646d2SAndroid Build Coastguard Worker {
291*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 16;
292*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 64;
293*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_CMYK;
294*5e7646d2SAndroid Build Coastguard Worker }
295*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(type, "device", 6) && type[6] >= '1' && type[6] <= '9')
296*5e7646d2SAndroid Build Coastguard Worker {
297*5e7646d2SAndroid Build Coastguard Worker int ncolors, bits; /* Number of colors and bits */
298*5e7646d2SAndroid Build Coastguard Worker
299*5e7646d2SAndroid Build Coastguard Worker
300*5e7646d2SAndroid Build Coastguard Worker if (sscanf(type, "device%d_%d", &ncolors, &bits) != 2 || ncolors > 15 || (bits != 8 && bits != 16))
301*5e7646d2SAndroid Build Coastguard Worker {
302*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unsupported raster type \'%s\'.", type);
303*5e7646d2SAndroid Build Coastguard Worker return (0);
304*5e7646d2SAndroid Build Coastguard Worker }
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = (unsigned)bits;
307*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = (unsigned)(ncolors * bits);
308*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = (cups_cspace_t)(CUPS_CSPACE_DEVICE1 + ncolors - 1);
309*5e7646d2SAndroid Build Coastguard Worker }
310*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "rgb_8"))
311*5e7646d2SAndroid Build Coastguard Worker {
312*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 8;
313*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 24;
314*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_RGB;
315*5e7646d2SAndroid Build Coastguard Worker }
316*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "rgb_16"))
317*5e7646d2SAndroid Build Coastguard Worker {
318*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 16;
319*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 48;
320*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_RGB;
321*5e7646d2SAndroid Build Coastguard Worker }
322*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "sgray_1"))
323*5e7646d2SAndroid Build Coastguard Worker {
324*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 1;
325*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 1;
326*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_SW;
327*5e7646d2SAndroid Build Coastguard Worker }
328*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "sgray_8"))
329*5e7646d2SAndroid Build Coastguard Worker {
330*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 8;
331*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 8;
332*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_SW;
333*5e7646d2SAndroid Build Coastguard Worker }
334*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "sgray_16"))
335*5e7646d2SAndroid Build Coastguard Worker {
336*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 16;
337*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 16;
338*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_SW;
339*5e7646d2SAndroid Build Coastguard Worker }
340*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "srgb_8"))
341*5e7646d2SAndroid Build Coastguard Worker {
342*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 8;
343*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 24;
344*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_SRGB;
345*5e7646d2SAndroid Build Coastguard Worker }
346*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(type, "srgb_16"))
347*5e7646d2SAndroid Build Coastguard Worker {
348*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerColor = 16;
349*5e7646d2SAndroid Build Coastguard Worker h->cupsBitsPerPixel = 48;
350*5e7646d2SAndroid Build Coastguard Worker h->cupsColorSpace = CUPS_CSPACE_SRGB;
351*5e7646d2SAndroid Build Coastguard Worker }
352*5e7646d2SAndroid Build Coastguard Worker else
353*5e7646d2SAndroid Build Coastguard Worker {
354*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unsupported raster type \'%s\'.", type);
355*5e7646d2SAndroid Build Coastguard Worker return (0);
356*5e7646d2SAndroid Build Coastguard Worker }
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker h->cupsColorOrder = CUPS_ORDER_CHUNKED;
359*5e7646d2SAndroid Build Coastguard Worker h->cupsNumColors = h->cupsBitsPerPixel / h->cupsBitsPerColor;
360*5e7646d2SAndroid Build Coastguard Worker h->cupsBytesPerLine = (h->cupsWidth * h->cupsBitsPerPixel + 7) / 8;
361*5e7646d2SAndroid Build Coastguard Worker
362*5e7646d2SAndroid Build Coastguard Worker /*
363*5e7646d2SAndroid Build Coastguard Worker * Duplex support...
364*5e7646d2SAndroid Build Coastguard Worker */
365*5e7646d2SAndroid Build Coastguard Worker
366*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 1;
367*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_FeedTransform] = 1;
368*5e7646d2SAndroid Build Coastguard Worker
369*5e7646d2SAndroid Build Coastguard Worker if (sides)
370*5e7646d2SAndroid Build Coastguard Worker {
371*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(sides, "two-sided-long-edge"))
372*5e7646d2SAndroid Build Coastguard Worker {
373*5e7646d2SAndroid Build Coastguard Worker h->Duplex = 1;
374*5e7646d2SAndroid Build Coastguard Worker }
375*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(sides, "two-sided-short-edge"))
376*5e7646d2SAndroid Build Coastguard Worker {
377*5e7646d2SAndroid Build Coastguard Worker h->Duplex = 1;
378*5e7646d2SAndroid Build Coastguard Worker h->Tumble = 1;
379*5e7646d2SAndroid Build Coastguard Worker }
380*5e7646d2SAndroid Build Coastguard Worker else if (strcmp(sides, "one-sided"))
381*5e7646d2SAndroid Build Coastguard Worker {
382*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unsupported sides value \'%s\'.", sides);
383*5e7646d2SAndroid Build Coastguard Worker return (0);
384*5e7646d2SAndroid Build Coastguard Worker }
385*5e7646d2SAndroid Build Coastguard Worker
386*5e7646d2SAndroid Build Coastguard Worker if (sheet_back)
387*5e7646d2SAndroid Build Coastguard Worker {
388*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(sheet_back, "flipped"))
389*5e7646d2SAndroid Build Coastguard Worker {
390*5e7646d2SAndroid Build Coastguard Worker if (h->Tumble)
391*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 0xffffffffU;
392*5e7646d2SAndroid Build Coastguard Worker else
393*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_FeedTransform] = 0xffffffffU;
394*5e7646d2SAndroid Build Coastguard Worker }
395*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(sheet_back, "manual-tumble"))
396*5e7646d2SAndroid Build Coastguard Worker {
397*5e7646d2SAndroid Build Coastguard Worker if (h->Tumble)
398*5e7646d2SAndroid Build Coastguard Worker {
399*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 0xffffffffU;
400*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_FeedTransform] = 0xffffffffU;
401*5e7646d2SAndroid Build Coastguard Worker }
402*5e7646d2SAndroid Build Coastguard Worker }
403*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(sheet_back, "rotated"))
404*5e7646d2SAndroid Build Coastguard Worker {
405*5e7646d2SAndroid Build Coastguard Worker if (!h->Tumble)
406*5e7646d2SAndroid Build Coastguard Worker {
407*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_CrossFeedTransform] = 0xffffffffU;
408*5e7646d2SAndroid Build Coastguard Worker h->cupsInteger[CUPS_RASTER_PWG_FeedTransform] = 0xffffffffU;
409*5e7646d2SAndroid Build Coastguard Worker }
410*5e7646d2SAndroid Build Coastguard Worker }
411*5e7646d2SAndroid Build Coastguard Worker else if (strcmp(sheet_back, "normal"))
412*5e7646d2SAndroid Build Coastguard Worker {
413*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unsupported sheet_back value \'%s\'.", sheet_back);
414*5e7646d2SAndroid Build Coastguard Worker return (0);
415*5e7646d2SAndroid Build Coastguard Worker }
416*5e7646d2SAndroid Build Coastguard Worker }
417*5e7646d2SAndroid Build Coastguard Worker }
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker return (1);
420*5e7646d2SAndroid Build Coastguard Worker }
421*5e7646d2SAndroid Build Coastguard Worker
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker /*
424*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterNew()' - Create a raster stream using a callback function.
425*5e7646d2SAndroid Build Coastguard Worker *
426*5e7646d2SAndroid Build Coastguard Worker * This function associates a raster stream with the given callback function and
427*5e7646d2SAndroid Build Coastguard Worker * context pointer.
428*5e7646d2SAndroid Build Coastguard Worker *
429*5e7646d2SAndroid Build Coastguard Worker * When writing raster data, the @code CUPS_RASTER_WRITE@,
430*5e7646d2SAndroid Build Coastguard Worker * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can
431*5e7646d2SAndroid Build Coastguard Worker * be used - compressed and PWG output is generally 25-50% smaller but adds a
432*5e7646d2SAndroid Build Coastguard Worker * 100-300% execution time overhead.
433*5e7646d2SAndroid Build Coastguard Worker */
434*5e7646d2SAndroid Build Coastguard Worker
435*5e7646d2SAndroid Build Coastguard Worker cups_raster_t * /* O - New stream */
_cupsRasterNew(cups_raster_iocb_t iocb,void * ctx,cups_mode_t mode)436*5e7646d2SAndroid Build Coastguard Worker _cupsRasterNew(
437*5e7646d2SAndroid Build Coastguard Worker cups_raster_iocb_t iocb, /* I - Read/write callback */
438*5e7646d2SAndroid Build Coastguard Worker void *ctx, /* I - Context pointer for callback */
439*5e7646d2SAndroid Build Coastguard Worker cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@,
440*5e7646d2SAndroid Build Coastguard Worker @code CUPS_RASTER_WRITE@,
441*5e7646d2SAndroid Build Coastguard Worker @code CUPS_RASTER_WRITE_COMPRESSED@,
442*5e7646d2SAndroid Build Coastguard Worker or @code CUPS_RASTER_WRITE_PWG@ */
443*5e7646d2SAndroid Build Coastguard Worker {
444*5e7646d2SAndroid Build Coastguard Worker cups_raster_t *r; /* New stream */
445*5e7646d2SAndroid Build Coastguard Worker
446*5e7646d2SAndroid Build Coastguard Worker
447*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_cupsRasterOpenIO(iocb=%p, ctx=%p, mode=%s)", (void *)iocb, ctx, cups_modes[mode]));
448*5e7646d2SAndroid Build Coastguard Worker
449*5e7646d2SAndroid Build Coastguard Worker _cupsRasterClearError();
450*5e7646d2SAndroid Build Coastguard Worker
451*5e7646d2SAndroid Build Coastguard Worker if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL)
452*5e7646d2SAndroid Build Coastguard Worker {
453*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unable to allocate memory for raster stream: %s\n",
454*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
455*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterOpenIO: Returning NULL.");
456*5e7646d2SAndroid Build Coastguard Worker return (NULL);
457*5e7646d2SAndroid Build Coastguard Worker }
458*5e7646d2SAndroid Build Coastguard Worker
459*5e7646d2SAndroid Build Coastguard Worker r->ctx = ctx;
460*5e7646d2SAndroid Build Coastguard Worker r->iocb = iocb;
461*5e7646d2SAndroid Build Coastguard Worker r->mode = mode;
462*5e7646d2SAndroid Build Coastguard Worker
463*5e7646d2SAndroid Build Coastguard Worker if (mode == CUPS_RASTER_READ)
464*5e7646d2SAndroid Build Coastguard Worker {
465*5e7646d2SAndroid Build Coastguard Worker /*
466*5e7646d2SAndroid Build Coastguard Worker * Open for read - get sync word...
467*5e7646d2SAndroid Build Coastguard Worker */
468*5e7646d2SAndroid Build Coastguard Worker
469*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_io(r, (unsigned char *)&(r->sync), sizeof(r->sync)) !=
470*5e7646d2SAndroid Build Coastguard Worker sizeof(r->sync))
471*5e7646d2SAndroid Build Coastguard Worker {
472*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unable to read header from raster stream: %s\n",
473*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
474*5e7646d2SAndroid Build Coastguard Worker free(r);
475*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterOpenIO: Unable to read header, returning NULL.");
476*5e7646d2SAndroid Build Coastguard Worker return (NULL);
477*5e7646d2SAndroid Build Coastguard Worker }
478*5e7646d2SAndroid Build Coastguard Worker
479*5e7646d2SAndroid Build Coastguard Worker if (r->sync != CUPS_RASTER_SYNC &&
480*5e7646d2SAndroid Build Coastguard Worker r->sync != CUPS_RASTER_REVSYNC &&
481*5e7646d2SAndroid Build Coastguard Worker r->sync != CUPS_RASTER_SYNCv1 &&
482*5e7646d2SAndroid Build Coastguard Worker r->sync != CUPS_RASTER_REVSYNCv1 &&
483*5e7646d2SAndroid Build Coastguard Worker r->sync != CUPS_RASTER_SYNCv2 &&
484*5e7646d2SAndroid Build Coastguard Worker r->sync != CUPS_RASTER_REVSYNCv2 &&
485*5e7646d2SAndroid Build Coastguard Worker r->sync != CUPS_RASTER_SYNCapple &&
486*5e7646d2SAndroid Build Coastguard Worker r->sync != CUPS_RASTER_REVSYNCapple)
487*5e7646d2SAndroid Build Coastguard Worker {
488*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unknown raster format %08x!\n", r->sync);
489*5e7646d2SAndroid Build Coastguard Worker free(r);
490*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterOpenIO: Unknown format, returning NULL.");
491*5e7646d2SAndroid Build Coastguard Worker return (NULL);
492*5e7646d2SAndroid Build Coastguard Worker }
493*5e7646d2SAndroid Build Coastguard Worker
494*5e7646d2SAndroid Build Coastguard Worker if (r->sync == CUPS_RASTER_SYNCv2 ||
495*5e7646d2SAndroid Build Coastguard Worker r->sync == CUPS_RASTER_REVSYNCv2 ||
496*5e7646d2SAndroid Build Coastguard Worker r->sync == CUPS_RASTER_SYNCapple ||
497*5e7646d2SAndroid Build Coastguard Worker r->sync == CUPS_RASTER_REVSYNCapple)
498*5e7646d2SAndroid Build Coastguard Worker r->compressed = 1;
499*5e7646d2SAndroid Build Coastguard Worker
500*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterOpenIO: sync=%08x", r->sync));
501*5e7646d2SAndroid Build Coastguard Worker
502*5e7646d2SAndroid Build Coastguard Worker if (r->sync == CUPS_RASTER_REVSYNC ||
503*5e7646d2SAndroid Build Coastguard Worker r->sync == CUPS_RASTER_REVSYNCv1 ||
504*5e7646d2SAndroid Build Coastguard Worker r->sync == CUPS_RASTER_REVSYNCv2 ||
505*5e7646d2SAndroid Build Coastguard Worker r->sync == CUPS_RASTER_REVSYNCapple)
506*5e7646d2SAndroid Build Coastguard Worker r->swapped = 1;
507*5e7646d2SAndroid Build Coastguard Worker
508*5e7646d2SAndroid Build Coastguard Worker if (r->sync == CUPS_RASTER_SYNCapple ||
509*5e7646d2SAndroid Build Coastguard Worker r->sync == CUPS_RASTER_REVSYNCapple)
510*5e7646d2SAndroid Build Coastguard Worker {
511*5e7646d2SAndroid Build Coastguard Worker unsigned char header[8]; /* File header */
512*5e7646d2SAndroid Build Coastguard Worker
513*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_io(r, (unsigned char *)header, sizeof(header)) !=
514*5e7646d2SAndroid Build Coastguard Worker sizeof(header))
515*5e7646d2SAndroid Build Coastguard Worker {
516*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unable to read header from raster stream: %s\n",
517*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
518*5e7646d2SAndroid Build Coastguard Worker free(r);
519*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterOpenIO: Unable to read header, returning NULL.");
520*5e7646d2SAndroid Build Coastguard Worker return (NULL);
521*5e7646d2SAndroid Build Coastguard Worker }
522*5e7646d2SAndroid Build Coastguard Worker }
523*5e7646d2SAndroid Build Coastguard Worker
524*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
525*5e7646d2SAndroid Build Coastguard Worker r->iostart = r->iocount;
526*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
527*5e7646d2SAndroid Build Coastguard Worker }
528*5e7646d2SAndroid Build Coastguard Worker else
529*5e7646d2SAndroid Build Coastguard Worker {
530*5e7646d2SAndroid Build Coastguard Worker /*
531*5e7646d2SAndroid Build Coastguard Worker * Open for write - put sync word...
532*5e7646d2SAndroid Build Coastguard Worker */
533*5e7646d2SAndroid Build Coastguard Worker
534*5e7646d2SAndroid Build Coastguard Worker switch (mode)
535*5e7646d2SAndroid Build Coastguard Worker {
536*5e7646d2SAndroid Build Coastguard Worker default :
537*5e7646d2SAndroid Build Coastguard Worker case CUPS_RASTER_WRITE :
538*5e7646d2SAndroid Build Coastguard Worker r->sync = CUPS_RASTER_SYNC;
539*5e7646d2SAndroid Build Coastguard Worker break;
540*5e7646d2SAndroid Build Coastguard Worker
541*5e7646d2SAndroid Build Coastguard Worker case CUPS_RASTER_WRITE_COMPRESSED :
542*5e7646d2SAndroid Build Coastguard Worker r->compressed = 1;
543*5e7646d2SAndroid Build Coastguard Worker r->sync = CUPS_RASTER_SYNCv2;
544*5e7646d2SAndroid Build Coastguard Worker break;
545*5e7646d2SAndroid Build Coastguard Worker
546*5e7646d2SAndroid Build Coastguard Worker case CUPS_RASTER_WRITE_PWG :
547*5e7646d2SAndroid Build Coastguard Worker r->compressed = 1;
548*5e7646d2SAndroid Build Coastguard Worker r->sync = htonl(CUPS_RASTER_SYNC_PWG);
549*5e7646d2SAndroid Build Coastguard Worker r->swapped = r->sync != CUPS_RASTER_SYNC_PWG;
550*5e7646d2SAndroid Build Coastguard Worker break;
551*5e7646d2SAndroid Build Coastguard Worker
552*5e7646d2SAndroid Build Coastguard Worker case CUPS_RASTER_WRITE_APPLE :
553*5e7646d2SAndroid Build Coastguard Worker r->compressed = 1;
554*5e7646d2SAndroid Build Coastguard Worker r->sync = htonl(CUPS_RASTER_SYNCapple);
555*5e7646d2SAndroid Build Coastguard Worker r->swapped = r->sync != CUPS_RASTER_SYNCapple;
556*5e7646d2SAndroid Build Coastguard Worker r->apple_page_count = 0xffffffffU;
557*5e7646d2SAndroid Build Coastguard Worker break;
558*5e7646d2SAndroid Build Coastguard Worker }
559*5e7646d2SAndroid Build Coastguard Worker
560*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_io(r, (unsigned char *)&(r->sync), sizeof(r->sync)) < (ssize_t)sizeof(r->sync))
561*5e7646d2SAndroid Build Coastguard Worker {
562*5e7646d2SAndroid Build Coastguard Worker _cupsRasterAddError("Unable to write raster stream header: %s\n",
563*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
564*5e7646d2SAndroid Build Coastguard Worker free(r);
565*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterOpenIO: Unable to write header, returning NULL.");
566*5e7646d2SAndroid Build Coastguard Worker return (NULL);
567*5e7646d2SAndroid Build Coastguard Worker }
568*5e7646d2SAndroid Build Coastguard Worker }
569*5e7646d2SAndroid Build Coastguard Worker
570*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterOpenIO: compressed=%d, swapped=%d, returning %p", r->compressed, r->swapped, (void *)r));
571*5e7646d2SAndroid Build Coastguard Worker
572*5e7646d2SAndroid Build Coastguard Worker return (r);
573*5e7646d2SAndroid Build Coastguard Worker }
574*5e7646d2SAndroid Build Coastguard Worker
575*5e7646d2SAndroid Build Coastguard Worker
576*5e7646d2SAndroid Build Coastguard Worker /*
577*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterReadHeader()' - Read a raster page header.
578*5e7646d2SAndroid Build Coastguard Worker */
579*5e7646d2SAndroid Build Coastguard Worker
580*5e7646d2SAndroid Build Coastguard Worker unsigned /* O - 1 on success, 0 on fail */
_cupsRasterReadHeader(cups_raster_t * r)581*5e7646d2SAndroid Build Coastguard Worker _cupsRasterReadHeader(
582*5e7646d2SAndroid Build Coastguard Worker cups_raster_t *r) /* I - Raster stream */
583*5e7646d2SAndroid Build Coastguard Worker {
584*5e7646d2SAndroid Build Coastguard Worker size_t len; /* Length for read/swap */
585*5e7646d2SAndroid Build Coastguard Worker
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("3_cupsRasterReadHeader(r=%p), r->mode=%s", (void *)r, r ? cups_modes[r->mode] : ""));
588*5e7646d2SAndroid Build Coastguard Worker
589*5e7646d2SAndroid Build Coastguard Worker if (r == NULL || r->mode != CUPS_RASTER_READ)
590*5e7646d2SAndroid Build Coastguard Worker return (0);
591*5e7646d2SAndroid Build Coastguard Worker
592*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
593*5e7646d2SAndroid Build Coastguard Worker
594*5e7646d2SAndroid Build Coastguard Worker memset(&(r->header), 0, sizeof(r->header));
595*5e7646d2SAndroid Build Coastguard Worker
596*5e7646d2SAndroid Build Coastguard Worker /*
597*5e7646d2SAndroid Build Coastguard Worker * Read the header...
598*5e7646d2SAndroid Build Coastguard Worker */
599*5e7646d2SAndroid Build Coastguard Worker
600*5e7646d2SAndroid Build Coastguard Worker switch (r->sync)
601*5e7646d2SAndroid Build Coastguard Worker {
602*5e7646d2SAndroid Build Coastguard Worker default :
603*5e7646d2SAndroid Build Coastguard Worker /*
604*5e7646d2SAndroid Build Coastguard Worker * Get the length of the raster header...
605*5e7646d2SAndroid Build Coastguard Worker */
606*5e7646d2SAndroid Build Coastguard Worker
607*5e7646d2SAndroid Build Coastguard Worker if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1)
608*5e7646d2SAndroid Build Coastguard Worker len = sizeof(cups_page_header_t);
609*5e7646d2SAndroid Build Coastguard Worker else
610*5e7646d2SAndroid Build Coastguard Worker len = sizeof(cups_page_header2_t);
611*5e7646d2SAndroid Build Coastguard Worker
612*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: len=%d", (int)len));
613*5e7646d2SAndroid Build Coastguard Worker
614*5e7646d2SAndroid Build Coastguard Worker /*
615*5e7646d2SAndroid Build Coastguard Worker * Read it...
616*5e7646d2SAndroid Build Coastguard Worker */
617*5e7646d2SAndroid Build Coastguard Worker
618*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_read(r, (unsigned char *)&(r->header), len) < (ssize_t)len)
619*5e7646d2SAndroid Build Coastguard Worker {
620*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
621*5e7646d2SAndroid Build Coastguard Worker return (0);
622*5e7646d2SAndroid Build Coastguard Worker }
623*5e7646d2SAndroid Build Coastguard Worker
624*5e7646d2SAndroid Build Coastguard Worker /*
625*5e7646d2SAndroid Build Coastguard Worker * Swap bytes as needed...
626*5e7646d2SAndroid Build Coastguard Worker */
627*5e7646d2SAndroid Build Coastguard Worker
628*5e7646d2SAndroid Build Coastguard Worker if (r->swapped)
629*5e7646d2SAndroid Build Coastguard Worker {
630*5e7646d2SAndroid Build Coastguard Worker unsigned *s, /* Current word */
631*5e7646d2SAndroid Build Coastguard Worker temp; /* Temporary copy */
632*5e7646d2SAndroid Build Coastguard Worker
633*5e7646d2SAndroid Build Coastguard Worker
634*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("4_cupsRasterReadHeader: Swapping header bytes.");
635*5e7646d2SAndroid Build Coastguard Worker
636*5e7646d2SAndroid Build Coastguard Worker for (len = 81, s = &(r->header.AdvanceDistance);
637*5e7646d2SAndroid Build Coastguard Worker len > 0;
638*5e7646d2SAndroid Build Coastguard Worker len --, s ++)
639*5e7646d2SAndroid Build Coastguard Worker {
640*5e7646d2SAndroid Build Coastguard Worker temp = *s;
641*5e7646d2SAndroid Build Coastguard Worker *s = ((temp & 0xff) << 24) |
642*5e7646d2SAndroid Build Coastguard Worker ((temp & 0xff00) << 8) |
643*5e7646d2SAndroid Build Coastguard Worker ((temp & 0xff0000) >> 8) |
644*5e7646d2SAndroid Build Coastguard Worker ((temp & 0xff000000) >> 24);
645*5e7646d2SAndroid Build Coastguard Worker
646*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: %08x => %08x", temp, *s));
647*5e7646d2SAndroid Build Coastguard Worker }
648*5e7646d2SAndroid Build Coastguard Worker }
649*5e7646d2SAndroid Build Coastguard Worker break;
650*5e7646d2SAndroid Build Coastguard Worker
651*5e7646d2SAndroid Build Coastguard Worker case CUPS_RASTER_SYNCapple :
652*5e7646d2SAndroid Build Coastguard Worker case CUPS_RASTER_REVSYNCapple :
653*5e7646d2SAndroid Build Coastguard Worker {
654*5e7646d2SAndroid Build Coastguard Worker unsigned char appleheader[32]; /* Raw header */
655*5e7646d2SAndroid Build Coastguard Worker static const unsigned rawcspace[] =
656*5e7646d2SAndroid Build Coastguard Worker {
657*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_SW,
658*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_SRGB,
659*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_CIELab,
660*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_ADOBERGB,
661*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_W,
662*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_RGB,
663*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_CMYK
664*5e7646d2SAndroid Build Coastguard Worker };
665*5e7646d2SAndroid Build Coastguard Worker static const unsigned rawnumcolors[] =
666*5e7646d2SAndroid Build Coastguard Worker {
667*5e7646d2SAndroid Build Coastguard Worker 1,
668*5e7646d2SAndroid Build Coastguard Worker 3,
669*5e7646d2SAndroid Build Coastguard Worker 3,
670*5e7646d2SAndroid Build Coastguard Worker 3,
671*5e7646d2SAndroid Build Coastguard Worker 1,
672*5e7646d2SAndroid Build Coastguard Worker 3,
673*5e7646d2SAndroid Build Coastguard Worker 4
674*5e7646d2SAndroid Build Coastguard Worker };
675*5e7646d2SAndroid Build Coastguard Worker
676*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_read(r, appleheader, sizeof(appleheader)) < (ssize_t)sizeof(appleheader))
677*5e7646d2SAndroid Build Coastguard Worker {
678*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: EOF, r->iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
679*5e7646d2SAndroid Build Coastguard Worker return (0);
680*5e7646d2SAndroid Build Coastguard Worker }
681*5e7646d2SAndroid Build Coastguard Worker
682*5e7646d2SAndroid Build Coastguard Worker strlcpy(r->header.MediaClass, "PwgRaster", sizeof(r->header.MediaClass));
683*5e7646d2SAndroid Build Coastguard Worker /* PwgRaster */
684*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerPixel = appleheader[0];
685*5e7646d2SAndroid Build Coastguard Worker r->header.cupsColorSpace = appleheader[1] >= (sizeof(rawcspace) / sizeof(rawcspace[0])) ? CUPS_CSPACE_DEVICE1 : rawcspace[appleheader[1]];
686*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors = appleheader[1] >= (sizeof(rawnumcolors) / sizeof(rawnumcolors[0])) ? 1 : rawnumcolors[appleheader[1]];
687*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerColor = r->header.cupsBitsPerPixel / r->header.cupsNumColors;
688*5e7646d2SAndroid Build Coastguard Worker r->header.cupsWidth = ((((((unsigned)appleheader[12] << 8) | (unsigned)appleheader[13]) << 8) | (unsigned)appleheader[14]) << 8) | (unsigned)appleheader[15];
689*5e7646d2SAndroid Build Coastguard Worker r->header.cupsHeight = ((((((unsigned)appleheader[16] << 8) | (unsigned)appleheader[17]) << 8) | (unsigned)appleheader[18]) << 8) | (unsigned)appleheader[19];
690*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBytesPerLine = r->header.cupsWidth * r->header.cupsBitsPerPixel / 8;
691*5e7646d2SAndroid Build Coastguard Worker r->header.cupsColorOrder = CUPS_ORDER_CHUNKED;
692*5e7646d2SAndroid Build Coastguard Worker r->header.HWResolution[0] = r->header.HWResolution[1] = ((((((unsigned)appleheader[20] << 8) | (unsigned)appleheader[21]) << 8) | (unsigned)appleheader[22]) << 8) | (unsigned)appleheader[23];
693*5e7646d2SAndroid Build Coastguard Worker
694*5e7646d2SAndroid Build Coastguard Worker if (r->header.HWResolution[0] > 0)
695*5e7646d2SAndroid Build Coastguard Worker {
696*5e7646d2SAndroid Build Coastguard Worker r->header.PageSize[0] = (unsigned)(r->header.cupsWidth * 72 / r->header.HWResolution[0]);
697*5e7646d2SAndroid Build Coastguard Worker r->header.PageSize[1] = (unsigned)(r->header.cupsHeight * 72 / r->header.HWResolution[1]);
698*5e7646d2SAndroid Build Coastguard Worker r->header.cupsPageSize[0] = (float)(r->header.cupsWidth * 72.0 / r->header.HWResolution[0]);
699*5e7646d2SAndroid Build Coastguard Worker r->header.cupsPageSize[1] = (float)(r->header.cupsHeight * 72.0 / r->header.HWResolution[1]);
700*5e7646d2SAndroid Build Coastguard Worker }
701*5e7646d2SAndroid Build Coastguard Worker
702*5e7646d2SAndroid Build Coastguard Worker r->header.cupsInteger[CUPS_RASTER_PWG_TotalPageCount] = r->apple_page_count;
703*5e7646d2SAndroid Build Coastguard Worker r->header.cupsInteger[CUPS_RASTER_PWG_AlternatePrimary] = 0xffffff;
704*5e7646d2SAndroid Build Coastguard Worker r->header.cupsInteger[CUPS_RASTER_PWG_PrintQuality] = appleheader[3];
705*5e7646d2SAndroid Build Coastguard Worker
706*5e7646d2SAndroid Build Coastguard Worker if (appleheader[2] >= 2)
707*5e7646d2SAndroid Build Coastguard Worker r->header.Duplex = 1;
708*5e7646d2SAndroid Build Coastguard Worker if (appleheader[2] == 2)
709*5e7646d2SAndroid Build Coastguard Worker r->header.Tumble = 1;
710*5e7646d2SAndroid Build Coastguard Worker
711*5e7646d2SAndroid Build Coastguard Worker r->header.MediaPosition = appleheader[5];
712*5e7646d2SAndroid Build Coastguard Worker
713*5e7646d2SAndroid Build Coastguard Worker if (appleheader[4] < (int)(sizeof(apple_media_types) / sizeof(apple_media_types[0])))
714*5e7646d2SAndroid Build Coastguard Worker strlcpy(r->header.MediaType, apple_media_types[appleheader[4]], sizeof(r->header.MediaType));
715*5e7646d2SAndroid Build Coastguard Worker else
716*5e7646d2SAndroid Build Coastguard Worker strlcpy(r->header.MediaType, "other", sizeof(r->header.MediaType));
717*5e7646d2SAndroid Build Coastguard Worker }
718*5e7646d2SAndroid Build Coastguard Worker break;
719*5e7646d2SAndroid Build Coastguard Worker }
720*5e7646d2SAndroid Build Coastguard Worker
721*5e7646d2SAndroid Build Coastguard Worker /*
722*5e7646d2SAndroid Build Coastguard Worker * Update the header and row count...
723*5e7646d2SAndroid Build Coastguard Worker */
724*5e7646d2SAndroid Build Coastguard Worker
725*5e7646d2SAndroid Build Coastguard Worker if (!cups_raster_update(r))
726*5e7646d2SAndroid Build Coastguard Worker return (0);
727*5e7646d2SAndroid Build Coastguard Worker
728*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: cupsColorSpace=%s", _cupsRasterColorSpaceString(r->header.cupsColorSpace)));
729*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: cupsBitsPerColor=%u", r->header.cupsBitsPerColor));
730*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: cupsBitsPerPixel=%u", r->header.cupsBitsPerPixel));
731*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: cupsBytesPerLine=%u", r->header.cupsBytesPerLine));
732*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: cupsWidth=%u", r->header.cupsWidth));
733*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: cupsHeight=%u", r->header.cupsHeight));
734*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4_cupsRasterReadHeader: r->bpp=%d", r->bpp));
735*5e7646d2SAndroid Build Coastguard Worker
736*5e7646d2SAndroid Build Coastguard Worker return (r->header.cupsBitsPerPixel > 0 && r->header.cupsBitsPerPixel <= 240 && r->header.cupsBitsPerColor > 0 && r->header.cupsBitsPerColor <= 16 && r->header.cupsBytesPerLine > 0 && r->header.cupsBytesPerLine <= 0x7fffffff && r->header.cupsHeight != 0 && (r->header.cupsBytesPerLine % r->bpp) == 0);
737*5e7646d2SAndroid Build Coastguard Worker }
738*5e7646d2SAndroid Build Coastguard Worker
739*5e7646d2SAndroid Build Coastguard Worker
740*5e7646d2SAndroid Build Coastguard Worker /*
741*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterReadPixels()' - Read raster pixels.
742*5e7646d2SAndroid Build Coastguard Worker *
743*5e7646d2SAndroid Build Coastguard Worker * For best performance, filters should read one or more whole lines.
744*5e7646d2SAndroid Build Coastguard Worker * The "cupsBytesPerLine" value from the page header can be used to allocate
745*5e7646d2SAndroid Build Coastguard Worker * the line buffer and as the number of bytes to read.
746*5e7646d2SAndroid Build Coastguard Worker */
747*5e7646d2SAndroid Build Coastguard Worker
748*5e7646d2SAndroid Build Coastguard Worker unsigned /* O - Number of bytes read */
_cupsRasterReadPixels(cups_raster_t * r,unsigned char * p,unsigned len)749*5e7646d2SAndroid Build Coastguard Worker _cupsRasterReadPixels(
750*5e7646d2SAndroid Build Coastguard Worker cups_raster_t *r, /* I - Raster stream */
751*5e7646d2SAndroid Build Coastguard Worker unsigned char *p, /* I - Pointer to pixel buffer */
752*5e7646d2SAndroid Build Coastguard Worker unsigned len) /* I - Number of bytes to read */
753*5e7646d2SAndroid Build Coastguard Worker {
754*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Bytes read */
755*5e7646d2SAndroid Build Coastguard Worker unsigned cupsBytesPerLine; /* cupsBytesPerLine value */
756*5e7646d2SAndroid Build Coastguard Worker unsigned remaining; /* Bytes remaining */
757*5e7646d2SAndroid Build Coastguard Worker unsigned char *ptr, /* Pointer to read buffer */
758*5e7646d2SAndroid Build Coastguard Worker byte, /* Byte from file */
759*5e7646d2SAndroid Build Coastguard Worker *temp; /* Pointer into buffer */
760*5e7646d2SAndroid Build Coastguard Worker unsigned count; /* Repetition count */
761*5e7646d2SAndroid Build Coastguard Worker
762*5e7646d2SAndroid Build Coastguard Worker
763*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_cupsRasterReadPixels(r=%p, p=%p, len=%u)", (void *)r, (void *)p, len));
764*5e7646d2SAndroid Build Coastguard Worker
765*5e7646d2SAndroid Build Coastguard Worker if (r == NULL || r->mode != CUPS_RASTER_READ || r->remaining == 0 ||
766*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBytesPerLine == 0)
767*5e7646d2SAndroid Build Coastguard Worker {
768*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterReadPixels: Returning 0.");
769*5e7646d2SAndroid Build Coastguard Worker return (0);
770*5e7646d2SAndroid Build Coastguard Worker }
771*5e7646d2SAndroid Build Coastguard Worker
772*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterReadPixels: compressed=%d, remaining=%u", r->compressed, r->remaining));
773*5e7646d2SAndroid Build Coastguard Worker
774*5e7646d2SAndroid Build Coastguard Worker if (!r->compressed)
775*5e7646d2SAndroid Build Coastguard Worker {
776*5e7646d2SAndroid Build Coastguard Worker /*
777*5e7646d2SAndroid Build Coastguard Worker * Read without compression...
778*5e7646d2SAndroid Build Coastguard Worker */
779*5e7646d2SAndroid Build Coastguard Worker
780*5e7646d2SAndroid Build Coastguard Worker r->remaining -= len / r->header.cupsBytesPerLine;
781*5e7646d2SAndroid Build Coastguard Worker
782*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_io(r, p, len) < (ssize_t)len)
783*5e7646d2SAndroid Build Coastguard Worker {
784*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
785*5e7646d2SAndroid Build Coastguard Worker return (0);
786*5e7646d2SAndroid Build Coastguard Worker }
787*5e7646d2SAndroid Build Coastguard Worker
788*5e7646d2SAndroid Build Coastguard Worker /*
789*5e7646d2SAndroid Build Coastguard Worker * Swap bytes as needed...
790*5e7646d2SAndroid Build Coastguard Worker */
791*5e7646d2SAndroid Build Coastguard Worker
792*5e7646d2SAndroid Build Coastguard Worker if (r->swapped &&
793*5e7646d2SAndroid Build Coastguard Worker (r->header.cupsBitsPerColor == 16 ||
794*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerPixel == 12 ||
795*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerPixel == 16))
796*5e7646d2SAndroid Build Coastguard Worker cups_swap(p, len);
797*5e7646d2SAndroid Build Coastguard Worker
798*5e7646d2SAndroid Build Coastguard Worker /*
799*5e7646d2SAndroid Build Coastguard Worker * Return...
800*5e7646d2SAndroid Build Coastguard Worker */
801*5e7646d2SAndroid Build Coastguard Worker
802*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterReadPixels: Returning %u", len));
803*5e7646d2SAndroid Build Coastguard Worker
804*5e7646d2SAndroid Build Coastguard Worker return (len);
805*5e7646d2SAndroid Build Coastguard Worker }
806*5e7646d2SAndroid Build Coastguard Worker
807*5e7646d2SAndroid Build Coastguard Worker /*
808*5e7646d2SAndroid Build Coastguard Worker * Read compressed data...
809*5e7646d2SAndroid Build Coastguard Worker */
810*5e7646d2SAndroid Build Coastguard Worker
811*5e7646d2SAndroid Build Coastguard Worker remaining = len;
812*5e7646d2SAndroid Build Coastguard Worker cupsBytesPerLine = r->header.cupsBytesPerLine;
813*5e7646d2SAndroid Build Coastguard Worker
814*5e7646d2SAndroid Build Coastguard Worker while (remaining > 0 && r->remaining > 0)
815*5e7646d2SAndroid Build Coastguard Worker {
816*5e7646d2SAndroid Build Coastguard Worker if (r->count == 0)
817*5e7646d2SAndroid Build Coastguard Worker {
818*5e7646d2SAndroid Build Coastguard Worker /*
819*5e7646d2SAndroid Build Coastguard Worker * Need to read a new row...
820*5e7646d2SAndroid Build Coastguard Worker */
821*5e7646d2SAndroid Build Coastguard Worker
822*5e7646d2SAndroid Build Coastguard Worker if (remaining == cupsBytesPerLine)
823*5e7646d2SAndroid Build Coastguard Worker ptr = p;
824*5e7646d2SAndroid Build Coastguard Worker else
825*5e7646d2SAndroid Build Coastguard Worker ptr = r->pixels;
826*5e7646d2SAndroid Build Coastguard Worker
827*5e7646d2SAndroid Build Coastguard Worker /*
828*5e7646d2SAndroid Build Coastguard Worker * Read using a modified PackBits compression...
829*5e7646d2SAndroid Build Coastguard Worker */
830*5e7646d2SAndroid Build Coastguard Worker
831*5e7646d2SAndroid Build Coastguard Worker if (!cups_raster_read(r, &byte, 1))
832*5e7646d2SAndroid Build Coastguard Worker {
833*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
834*5e7646d2SAndroid Build Coastguard Worker return (0);
835*5e7646d2SAndroid Build Coastguard Worker }
836*5e7646d2SAndroid Build Coastguard Worker
837*5e7646d2SAndroid Build Coastguard Worker r->count = (unsigned)byte + 1;
838*5e7646d2SAndroid Build Coastguard Worker
839*5e7646d2SAndroid Build Coastguard Worker if (r->count > 1)
840*5e7646d2SAndroid Build Coastguard Worker ptr = r->pixels;
841*5e7646d2SAndroid Build Coastguard Worker
842*5e7646d2SAndroid Build Coastguard Worker temp = ptr;
843*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)cupsBytesPerLine;
844*5e7646d2SAndroid Build Coastguard Worker
845*5e7646d2SAndroid Build Coastguard Worker while (bytes > 0)
846*5e7646d2SAndroid Build Coastguard Worker {
847*5e7646d2SAndroid Build Coastguard Worker /*
848*5e7646d2SAndroid Build Coastguard Worker * Get a new repeat count...
849*5e7646d2SAndroid Build Coastguard Worker */
850*5e7646d2SAndroid Build Coastguard Worker
851*5e7646d2SAndroid Build Coastguard Worker if (!cups_raster_read(r, &byte, 1))
852*5e7646d2SAndroid Build Coastguard Worker {
853*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
854*5e7646d2SAndroid Build Coastguard Worker return (0);
855*5e7646d2SAndroid Build Coastguard Worker }
856*5e7646d2SAndroid Build Coastguard Worker
857*5e7646d2SAndroid Build Coastguard Worker if (byte == 128)
858*5e7646d2SAndroid Build Coastguard Worker {
859*5e7646d2SAndroid Build Coastguard Worker /*
860*5e7646d2SAndroid Build Coastguard Worker * Clear to end of line...
861*5e7646d2SAndroid Build Coastguard Worker */
862*5e7646d2SAndroid Build Coastguard Worker
863*5e7646d2SAndroid Build Coastguard Worker switch (r->header.cupsColorSpace)
864*5e7646d2SAndroid Build Coastguard Worker {
865*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_W :
866*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_RGB :
867*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_SW :
868*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_SRGB :
869*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_RGBW :
870*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ADOBERGB :
871*5e7646d2SAndroid Build Coastguard Worker memset(temp, 0xff, (size_t)bytes);
872*5e7646d2SAndroid Build Coastguard Worker break;
873*5e7646d2SAndroid Build Coastguard Worker default :
874*5e7646d2SAndroid Build Coastguard Worker memset(temp, 0x00, (size_t)bytes);
875*5e7646d2SAndroid Build Coastguard Worker break;
876*5e7646d2SAndroid Build Coastguard Worker }
877*5e7646d2SAndroid Build Coastguard Worker
878*5e7646d2SAndroid Build Coastguard Worker temp += bytes;
879*5e7646d2SAndroid Build Coastguard Worker bytes = 0;
880*5e7646d2SAndroid Build Coastguard Worker }
881*5e7646d2SAndroid Build Coastguard Worker else if (byte & 128)
882*5e7646d2SAndroid Build Coastguard Worker {
883*5e7646d2SAndroid Build Coastguard Worker /*
884*5e7646d2SAndroid Build Coastguard Worker * Copy N literal pixels...
885*5e7646d2SAndroid Build Coastguard Worker */
886*5e7646d2SAndroid Build Coastguard Worker
887*5e7646d2SAndroid Build Coastguard Worker count = (unsigned)(257 - byte) * r->bpp;
888*5e7646d2SAndroid Build Coastguard Worker
889*5e7646d2SAndroid Build Coastguard Worker if (count > (unsigned)bytes)
890*5e7646d2SAndroid Build Coastguard Worker count = (unsigned)bytes;
891*5e7646d2SAndroid Build Coastguard Worker
892*5e7646d2SAndroid Build Coastguard Worker if (!cups_raster_read(r, temp, count))
893*5e7646d2SAndroid Build Coastguard Worker {
894*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
895*5e7646d2SAndroid Build Coastguard Worker return (0);
896*5e7646d2SAndroid Build Coastguard Worker }
897*5e7646d2SAndroid Build Coastguard Worker
898*5e7646d2SAndroid Build Coastguard Worker temp += count;
899*5e7646d2SAndroid Build Coastguard Worker bytes -= (ssize_t)count;
900*5e7646d2SAndroid Build Coastguard Worker }
901*5e7646d2SAndroid Build Coastguard Worker else
902*5e7646d2SAndroid Build Coastguard Worker {
903*5e7646d2SAndroid Build Coastguard Worker /*
904*5e7646d2SAndroid Build Coastguard Worker * Repeat the next N bytes...
905*5e7646d2SAndroid Build Coastguard Worker */
906*5e7646d2SAndroid Build Coastguard Worker
907*5e7646d2SAndroid Build Coastguard Worker count = ((unsigned)byte + 1) * r->bpp;
908*5e7646d2SAndroid Build Coastguard Worker if (count > (unsigned)bytes)
909*5e7646d2SAndroid Build Coastguard Worker count = (unsigned)bytes;
910*5e7646d2SAndroid Build Coastguard Worker
911*5e7646d2SAndroid Build Coastguard Worker if (count < r->bpp)
912*5e7646d2SAndroid Build Coastguard Worker break;
913*5e7646d2SAndroid Build Coastguard Worker
914*5e7646d2SAndroid Build Coastguard Worker bytes -= (ssize_t)count;
915*5e7646d2SAndroid Build Coastguard Worker
916*5e7646d2SAndroid Build Coastguard Worker if (!cups_raster_read(r, temp, r->bpp))
917*5e7646d2SAndroid Build Coastguard Worker {
918*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterReadPixels: Read error, returning 0.");
919*5e7646d2SAndroid Build Coastguard Worker return (0);
920*5e7646d2SAndroid Build Coastguard Worker }
921*5e7646d2SAndroid Build Coastguard Worker
922*5e7646d2SAndroid Build Coastguard Worker temp += r->bpp;
923*5e7646d2SAndroid Build Coastguard Worker count -= r->bpp;
924*5e7646d2SAndroid Build Coastguard Worker
925*5e7646d2SAndroid Build Coastguard Worker while (count > 0)
926*5e7646d2SAndroid Build Coastguard Worker {
927*5e7646d2SAndroid Build Coastguard Worker memcpy(temp, temp - r->bpp, r->bpp);
928*5e7646d2SAndroid Build Coastguard Worker temp += r->bpp;
929*5e7646d2SAndroid Build Coastguard Worker count -= r->bpp;
930*5e7646d2SAndroid Build Coastguard Worker }
931*5e7646d2SAndroid Build Coastguard Worker }
932*5e7646d2SAndroid Build Coastguard Worker }
933*5e7646d2SAndroid Build Coastguard Worker
934*5e7646d2SAndroid Build Coastguard Worker /*
935*5e7646d2SAndroid Build Coastguard Worker * Swap bytes as needed...
936*5e7646d2SAndroid Build Coastguard Worker */
937*5e7646d2SAndroid Build Coastguard Worker
938*5e7646d2SAndroid Build Coastguard Worker if ((r->header.cupsBitsPerColor == 16 ||
939*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerPixel == 12 ||
940*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerPixel == 16) &&
941*5e7646d2SAndroid Build Coastguard Worker r->swapped)
942*5e7646d2SAndroid Build Coastguard Worker {
943*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterReadPixels: Swapping bytes.");
944*5e7646d2SAndroid Build Coastguard Worker cups_swap(ptr, (size_t)cupsBytesPerLine);
945*5e7646d2SAndroid Build Coastguard Worker }
946*5e7646d2SAndroid Build Coastguard Worker
947*5e7646d2SAndroid Build Coastguard Worker /*
948*5e7646d2SAndroid Build Coastguard Worker * Update pointers...
949*5e7646d2SAndroid Build Coastguard Worker */
950*5e7646d2SAndroid Build Coastguard Worker
951*5e7646d2SAndroid Build Coastguard Worker if (remaining >= cupsBytesPerLine)
952*5e7646d2SAndroid Build Coastguard Worker {
953*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)cupsBytesPerLine;
954*5e7646d2SAndroid Build Coastguard Worker r->pcurrent = r->pixels;
955*5e7646d2SAndroid Build Coastguard Worker r->count --;
956*5e7646d2SAndroid Build Coastguard Worker r->remaining --;
957*5e7646d2SAndroid Build Coastguard Worker }
958*5e7646d2SAndroid Build Coastguard Worker else
959*5e7646d2SAndroid Build Coastguard Worker {
960*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)remaining;
961*5e7646d2SAndroid Build Coastguard Worker r->pcurrent = r->pixels + bytes;
962*5e7646d2SAndroid Build Coastguard Worker }
963*5e7646d2SAndroid Build Coastguard Worker
964*5e7646d2SAndroid Build Coastguard Worker /*
965*5e7646d2SAndroid Build Coastguard Worker * Copy data as needed...
966*5e7646d2SAndroid Build Coastguard Worker */
967*5e7646d2SAndroid Build Coastguard Worker
968*5e7646d2SAndroid Build Coastguard Worker if (ptr != p)
969*5e7646d2SAndroid Build Coastguard Worker memcpy(p, ptr, (size_t)bytes);
970*5e7646d2SAndroid Build Coastguard Worker }
971*5e7646d2SAndroid Build Coastguard Worker else
972*5e7646d2SAndroid Build Coastguard Worker {
973*5e7646d2SAndroid Build Coastguard Worker /*
974*5e7646d2SAndroid Build Coastguard Worker * Copy fragment from buffer...
975*5e7646d2SAndroid Build Coastguard Worker */
976*5e7646d2SAndroid Build Coastguard Worker
977*5e7646d2SAndroid Build Coastguard Worker if ((unsigned)(bytes = (int)(r->pend - r->pcurrent)) > remaining)
978*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)remaining;
979*5e7646d2SAndroid Build Coastguard Worker
980*5e7646d2SAndroid Build Coastguard Worker memcpy(p, r->pcurrent, (size_t)bytes);
981*5e7646d2SAndroid Build Coastguard Worker r->pcurrent += bytes;
982*5e7646d2SAndroid Build Coastguard Worker
983*5e7646d2SAndroid Build Coastguard Worker if (r->pcurrent >= r->pend)
984*5e7646d2SAndroid Build Coastguard Worker {
985*5e7646d2SAndroid Build Coastguard Worker r->pcurrent = r->pixels;
986*5e7646d2SAndroid Build Coastguard Worker r->count --;
987*5e7646d2SAndroid Build Coastguard Worker r->remaining --;
988*5e7646d2SAndroid Build Coastguard Worker }
989*5e7646d2SAndroid Build Coastguard Worker }
990*5e7646d2SAndroid Build Coastguard Worker
991*5e7646d2SAndroid Build Coastguard Worker remaining -= (unsigned)bytes;
992*5e7646d2SAndroid Build Coastguard Worker p += bytes;
993*5e7646d2SAndroid Build Coastguard Worker }
994*5e7646d2SAndroid Build Coastguard Worker
995*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterReadPixels: Returning %u", len));
996*5e7646d2SAndroid Build Coastguard Worker
997*5e7646d2SAndroid Build Coastguard Worker return (len);
998*5e7646d2SAndroid Build Coastguard Worker }
999*5e7646d2SAndroid Build Coastguard Worker
1000*5e7646d2SAndroid Build Coastguard Worker
1001*5e7646d2SAndroid Build Coastguard Worker /*
1002*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterWriteHeader()' - Write a raster page header.
1003*5e7646d2SAndroid Build Coastguard Worker */
1004*5e7646d2SAndroid Build Coastguard Worker
1005*5e7646d2SAndroid Build Coastguard Worker unsigned /* O - 1 on success, 0 on failure */
_cupsRasterWriteHeader(cups_raster_t * r)1006*5e7646d2SAndroid Build Coastguard Worker _cupsRasterWriteHeader(
1007*5e7646d2SAndroid Build Coastguard Worker cups_raster_t *r) /* I - Raster stream */
1008*5e7646d2SAndroid Build Coastguard Worker {
1009*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_cupsRasterWriteHeader(r=%p)", (void *)r));
1010*5e7646d2SAndroid Build Coastguard Worker
1011*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterWriteHeader: cupsColorSpace=%s", _cupsRasterColorSpaceString(r->header.cupsColorSpace)));
1012*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterWriteHeader: cupsBitsPerColor=%u", r->header.cupsBitsPerColor));
1013*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterWriteHeader: cupsBitsPerPixel=%u", r->header.cupsBitsPerPixel));
1014*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterWriteHeader: cupsBytesPerLine=%u", r->header.cupsBytesPerLine));
1015*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterWriteHeader: cupsWidth=%u", r->header.cupsWidth));
1016*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1_cupsRasterWriteHeader: cupsHeight=%u", r->header.cupsHeight));
1017*5e7646d2SAndroid Build Coastguard Worker
1018*5e7646d2SAndroid Build Coastguard Worker /*
1019*5e7646d2SAndroid Build Coastguard Worker * Compute the number of raster lines in the page image...
1020*5e7646d2SAndroid Build Coastguard Worker */
1021*5e7646d2SAndroid Build Coastguard Worker
1022*5e7646d2SAndroid Build Coastguard Worker if (!cups_raster_update(r))
1023*5e7646d2SAndroid Build Coastguard Worker {
1024*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1_cupsRasterWriteHeader: Unable to update parameters, returning 0.");
1025*5e7646d2SAndroid Build Coastguard Worker return (0);
1026*5e7646d2SAndroid Build Coastguard Worker }
1027*5e7646d2SAndroid Build Coastguard Worker
1028*5e7646d2SAndroid Build Coastguard Worker if (r->mode == CUPS_RASTER_WRITE_APPLE)
1029*5e7646d2SAndroid Build Coastguard Worker {
1030*5e7646d2SAndroid Build Coastguard Worker r->rowheight = r->header.HWResolution[0] / r->header.HWResolution[1];
1031*5e7646d2SAndroid Build Coastguard Worker
1032*5e7646d2SAndroid Build Coastguard Worker if (r->header.HWResolution[0] != (r->rowheight * r->header.HWResolution[1]))
1033*5e7646d2SAndroid Build Coastguard Worker return (0);
1034*5e7646d2SAndroid Build Coastguard Worker }
1035*5e7646d2SAndroid Build Coastguard Worker else
1036*5e7646d2SAndroid Build Coastguard Worker r->rowheight = 1;
1037*5e7646d2SAndroid Build Coastguard Worker
1038*5e7646d2SAndroid Build Coastguard Worker /*
1039*5e7646d2SAndroid Build Coastguard Worker * Write the raster header...
1040*5e7646d2SAndroid Build Coastguard Worker */
1041*5e7646d2SAndroid Build Coastguard Worker
1042*5e7646d2SAndroid Build Coastguard Worker if (r->mode == CUPS_RASTER_WRITE_PWG)
1043*5e7646d2SAndroid Build Coastguard Worker {
1044*5e7646d2SAndroid Build Coastguard Worker /*
1045*5e7646d2SAndroid Build Coastguard Worker * PWG raster data is always network byte order with much of the page header
1046*5e7646d2SAndroid Build Coastguard Worker * zeroed.
1047*5e7646d2SAndroid Build Coastguard Worker */
1048*5e7646d2SAndroid Build Coastguard Worker
1049*5e7646d2SAndroid Build Coastguard Worker cups_page_header2_t fh; /* File page header */
1050*5e7646d2SAndroid Build Coastguard Worker
1051*5e7646d2SAndroid Build Coastguard Worker memset(&fh, 0, sizeof(fh));
1052*5e7646d2SAndroid Build Coastguard Worker strlcpy(fh.MediaClass, "PwgRaster", sizeof(fh.MediaClass));
1053*5e7646d2SAndroid Build Coastguard Worker strlcpy(fh.MediaColor, r->header.MediaColor, sizeof(fh.MediaColor));
1054*5e7646d2SAndroid Build Coastguard Worker strlcpy(fh.MediaType, r->header.MediaType, sizeof(fh.MediaType));
1055*5e7646d2SAndroid Build Coastguard Worker strlcpy(fh.OutputType, r->header.OutputType, sizeof(fh.OutputType));
1056*5e7646d2SAndroid Build Coastguard Worker strlcpy(fh.cupsRenderingIntent, r->header.cupsRenderingIntent,
1057*5e7646d2SAndroid Build Coastguard Worker sizeof(fh.cupsRenderingIntent));
1058*5e7646d2SAndroid Build Coastguard Worker strlcpy(fh.cupsPageSizeName, r->header.cupsPageSizeName,
1059*5e7646d2SAndroid Build Coastguard Worker sizeof(fh.cupsPageSizeName));
1060*5e7646d2SAndroid Build Coastguard Worker
1061*5e7646d2SAndroid Build Coastguard Worker fh.CutMedia = htonl(r->header.CutMedia);
1062*5e7646d2SAndroid Build Coastguard Worker fh.Duplex = htonl(r->header.Duplex);
1063*5e7646d2SAndroid Build Coastguard Worker fh.HWResolution[0] = htonl(r->header.HWResolution[0]);
1064*5e7646d2SAndroid Build Coastguard Worker fh.HWResolution[1] = htonl(r->header.HWResolution[1]);
1065*5e7646d2SAndroid Build Coastguard Worker fh.ImagingBoundingBox[0] = htonl(r->header.ImagingBoundingBox[0]);
1066*5e7646d2SAndroid Build Coastguard Worker fh.ImagingBoundingBox[1] = htonl(r->header.ImagingBoundingBox[1]);
1067*5e7646d2SAndroid Build Coastguard Worker fh.ImagingBoundingBox[2] = htonl(r->header.ImagingBoundingBox[2]);
1068*5e7646d2SAndroid Build Coastguard Worker fh.ImagingBoundingBox[3] = htonl(r->header.ImagingBoundingBox[3]);
1069*5e7646d2SAndroid Build Coastguard Worker fh.InsertSheet = htonl(r->header.InsertSheet);
1070*5e7646d2SAndroid Build Coastguard Worker fh.Jog = htonl(r->header.Jog);
1071*5e7646d2SAndroid Build Coastguard Worker fh.LeadingEdge = htonl(r->header.LeadingEdge);
1072*5e7646d2SAndroid Build Coastguard Worker fh.ManualFeed = htonl(r->header.ManualFeed);
1073*5e7646d2SAndroid Build Coastguard Worker fh.MediaPosition = htonl(r->header.MediaPosition);
1074*5e7646d2SAndroid Build Coastguard Worker fh.MediaWeight = htonl(r->header.MediaWeight);
1075*5e7646d2SAndroid Build Coastguard Worker fh.NumCopies = htonl(r->header.NumCopies);
1076*5e7646d2SAndroid Build Coastguard Worker fh.Orientation = htonl(r->header.Orientation);
1077*5e7646d2SAndroid Build Coastguard Worker fh.PageSize[0] = htonl(r->header.PageSize[0]);
1078*5e7646d2SAndroid Build Coastguard Worker fh.PageSize[1] = htonl(r->header.PageSize[1]);
1079*5e7646d2SAndroid Build Coastguard Worker fh.Tumble = htonl(r->header.Tumble);
1080*5e7646d2SAndroid Build Coastguard Worker fh.cupsWidth = htonl(r->header.cupsWidth);
1081*5e7646d2SAndroid Build Coastguard Worker fh.cupsHeight = htonl(r->header.cupsHeight);
1082*5e7646d2SAndroid Build Coastguard Worker fh.cupsBitsPerColor = htonl(r->header.cupsBitsPerColor);
1083*5e7646d2SAndroid Build Coastguard Worker fh.cupsBitsPerPixel = htonl(r->header.cupsBitsPerPixel);
1084*5e7646d2SAndroid Build Coastguard Worker fh.cupsBytesPerLine = htonl(r->header.cupsBytesPerLine);
1085*5e7646d2SAndroid Build Coastguard Worker fh.cupsColorOrder = htonl(r->header.cupsColorOrder);
1086*5e7646d2SAndroid Build Coastguard Worker fh.cupsColorSpace = htonl(r->header.cupsColorSpace);
1087*5e7646d2SAndroid Build Coastguard Worker fh.cupsNumColors = htonl(r->header.cupsNumColors);
1088*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[0] = htonl(r->header.cupsInteger[0]);
1089*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[1] = htonl(r->header.cupsInteger[1]);
1090*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[2] = htonl(r->header.cupsInteger[2]);
1091*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[3] = htonl((unsigned)(r->header.cupsImagingBBox[0] * r->header.HWResolution[0] / 72.0));
1092*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[4] = htonl((unsigned)(r->header.cupsImagingBBox[1] * r->header.HWResolution[1] / 72.0));
1093*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[5] = htonl((unsigned)(r->header.cupsImagingBBox[2] * r->header.HWResolution[0] / 72.0));
1094*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[6] = htonl((unsigned)(r->header.cupsImagingBBox[3] * r->header.HWResolution[1] / 72.0));
1095*5e7646d2SAndroid Build Coastguard Worker fh.cupsInteger[7] = htonl(0xffffff);
1096*5e7646d2SAndroid Build Coastguard Worker
1097*5e7646d2SAndroid Build Coastguard Worker return (cups_raster_io(r, (unsigned char *)&fh, sizeof(fh)) == sizeof(fh));
1098*5e7646d2SAndroid Build Coastguard Worker }
1099*5e7646d2SAndroid Build Coastguard Worker else if (r->mode == CUPS_RASTER_WRITE_APPLE)
1100*5e7646d2SAndroid Build Coastguard Worker {
1101*5e7646d2SAndroid Build Coastguard Worker /*
1102*5e7646d2SAndroid Build Coastguard Worker * Raw raster data is always network byte order with most of the page header
1103*5e7646d2SAndroid Build Coastguard Worker * zeroed.
1104*5e7646d2SAndroid Build Coastguard Worker */
1105*5e7646d2SAndroid Build Coastguard Worker
1106*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1107*5e7646d2SAndroid Build Coastguard Worker unsigned char appleheader[32];/* Raw page header */
1108*5e7646d2SAndroid Build Coastguard Worker unsigned height = r->header.cupsHeight * r->rowheight;
1109*5e7646d2SAndroid Build Coastguard Worker /* Computed page height */
1110*5e7646d2SAndroid Build Coastguard Worker
1111*5e7646d2SAndroid Build Coastguard Worker if (r->apple_page_count == 0xffffffffU)
1112*5e7646d2SAndroid Build Coastguard Worker {
1113*5e7646d2SAndroid Build Coastguard Worker /*
1114*5e7646d2SAndroid Build Coastguard Worker * Write raw page count from raster page header...
1115*5e7646d2SAndroid Build Coastguard Worker */
1116*5e7646d2SAndroid Build Coastguard Worker
1117*5e7646d2SAndroid Build Coastguard Worker r->apple_page_count = r->header.cupsInteger[0];
1118*5e7646d2SAndroid Build Coastguard Worker
1119*5e7646d2SAndroid Build Coastguard Worker appleheader[0] = 'A';
1120*5e7646d2SAndroid Build Coastguard Worker appleheader[1] = 'S';
1121*5e7646d2SAndroid Build Coastguard Worker appleheader[2] = 'T';
1122*5e7646d2SAndroid Build Coastguard Worker appleheader[3] = 0;
1123*5e7646d2SAndroid Build Coastguard Worker appleheader[4] = (unsigned char)(r->apple_page_count >> 24);
1124*5e7646d2SAndroid Build Coastguard Worker appleheader[5] = (unsigned char)(r->apple_page_count >> 16);
1125*5e7646d2SAndroid Build Coastguard Worker appleheader[6] = (unsigned char)(r->apple_page_count >> 8);
1126*5e7646d2SAndroid Build Coastguard Worker appleheader[7] = (unsigned char)(r->apple_page_count);
1127*5e7646d2SAndroid Build Coastguard Worker
1128*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_io(r, appleheader, 8) != 8)
1129*5e7646d2SAndroid Build Coastguard Worker return (0);
1130*5e7646d2SAndroid Build Coastguard Worker }
1131*5e7646d2SAndroid Build Coastguard Worker
1132*5e7646d2SAndroid Build Coastguard Worker memset(appleheader, 0, sizeof(appleheader));
1133*5e7646d2SAndroid Build Coastguard Worker
1134*5e7646d2SAndroid Build Coastguard Worker appleheader[0] = (unsigned char)r->header.cupsBitsPerPixel;
1135*5e7646d2SAndroid Build Coastguard Worker appleheader[1] = r->header.cupsColorSpace == CUPS_CSPACE_SRGB ? 1 :
1136*5e7646d2SAndroid Build Coastguard Worker r->header.cupsColorSpace == CUPS_CSPACE_CIELab ? 2 :
1137*5e7646d2SAndroid Build Coastguard Worker r->header.cupsColorSpace == CUPS_CSPACE_ADOBERGB ? 3 :
1138*5e7646d2SAndroid Build Coastguard Worker r->header.cupsColorSpace == CUPS_CSPACE_W ? 4 :
1139*5e7646d2SAndroid Build Coastguard Worker r->header.cupsColorSpace == CUPS_CSPACE_RGB ? 5 :
1140*5e7646d2SAndroid Build Coastguard Worker r->header.cupsColorSpace == CUPS_CSPACE_CMYK ? 6 : 0;
1141*5e7646d2SAndroid Build Coastguard Worker appleheader[2] = r->header.Duplex ? (r->header.Tumble ? 2 : 3) : 1;
1142*5e7646d2SAndroid Build Coastguard Worker appleheader[3] = (unsigned char)(r->header.cupsInteger[CUPS_RASTER_PWG_PrintQuality]);
1143*5e7646d2SAndroid Build Coastguard Worker appleheader[5] = (unsigned char)(r->header.MediaPosition);
1144*5e7646d2SAndroid Build Coastguard Worker appleheader[12] = (unsigned char)(r->header.cupsWidth >> 24);
1145*5e7646d2SAndroid Build Coastguard Worker appleheader[13] = (unsigned char)(r->header.cupsWidth >> 16);
1146*5e7646d2SAndroid Build Coastguard Worker appleheader[14] = (unsigned char)(r->header.cupsWidth >> 8);
1147*5e7646d2SAndroid Build Coastguard Worker appleheader[15] = (unsigned char)(r->header.cupsWidth);
1148*5e7646d2SAndroid Build Coastguard Worker appleheader[16] = (unsigned char)(height >> 24);
1149*5e7646d2SAndroid Build Coastguard Worker appleheader[17] = (unsigned char)(height >> 16);
1150*5e7646d2SAndroid Build Coastguard Worker appleheader[18] = (unsigned char)(height >> 8);
1151*5e7646d2SAndroid Build Coastguard Worker appleheader[19] = (unsigned char)(height);
1152*5e7646d2SAndroid Build Coastguard Worker appleheader[20] = (unsigned char)(r->header.HWResolution[0] >> 24);
1153*5e7646d2SAndroid Build Coastguard Worker appleheader[21] = (unsigned char)(r->header.HWResolution[0] >> 16);
1154*5e7646d2SAndroid Build Coastguard Worker appleheader[22] = (unsigned char)(r->header.HWResolution[0] >> 8);
1155*5e7646d2SAndroid Build Coastguard Worker appleheader[23] = (unsigned char)(r->header.HWResolution[0]);
1156*5e7646d2SAndroid Build Coastguard Worker
1157*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < (int)(sizeof(apple_media_types) / sizeof(apple_media_types[0])); i ++)
1158*5e7646d2SAndroid Build Coastguard Worker {
1159*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(r->header.MediaType, apple_media_types[i]))
1160*5e7646d2SAndroid Build Coastguard Worker {
1161*5e7646d2SAndroid Build Coastguard Worker appleheader[4] = (unsigned char)i;
1162*5e7646d2SAndroid Build Coastguard Worker break;
1163*5e7646d2SAndroid Build Coastguard Worker }
1164*5e7646d2SAndroid Build Coastguard Worker }
1165*5e7646d2SAndroid Build Coastguard Worker
1166*5e7646d2SAndroid Build Coastguard Worker return (cups_raster_io(r, appleheader, sizeof(appleheader)) == sizeof(appleheader));
1167*5e7646d2SAndroid Build Coastguard Worker }
1168*5e7646d2SAndroid Build Coastguard Worker else
1169*5e7646d2SAndroid Build Coastguard Worker return (cups_raster_io(r, (unsigned char *)&(r->header), sizeof(r->header))
1170*5e7646d2SAndroid Build Coastguard Worker == sizeof(r->header));
1171*5e7646d2SAndroid Build Coastguard Worker }
1172*5e7646d2SAndroid Build Coastguard Worker
1173*5e7646d2SAndroid Build Coastguard Worker
1174*5e7646d2SAndroid Build Coastguard Worker /*
1175*5e7646d2SAndroid Build Coastguard Worker * '_cupsRasterWritePixels()' - Write raster pixels.
1176*5e7646d2SAndroid Build Coastguard Worker *
1177*5e7646d2SAndroid Build Coastguard Worker * For best performance, filters should write one or more whole lines.
1178*5e7646d2SAndroid Build Coastguard Worker * The "cupsBytesPerLine" value from the page header can be used to allocate
1179*5e7646d2SAndroid Build Coastguard Worker * the line buffer and as the number of bytes to write.
1180*5e7646d2SAndroid Build Coastguard Worker */
1181*5e7646d2SAndroid Build Coastguard Worker
1182*5e7646d2SAndroid Build Coastguard Worker unsigned /* O - Number of bytes written */
_cupsRasterWritePixels(cups_raster_t * r,unsigned char * p,unsigned len)1183*5e7646d2SAndroid Build Coastguard Worker _cupsRasterWritePixels(
1184*5e7646d2SAndroid Build Coastguard Worker cups_raster_t *r, /* I - Raster stream */
1185*5e7646d2SAndroid Build Coastguard Worker unsigned char *p, /* I - Bytes to write */
1186*5e7646d2SAndroid Build Coastguard Worker unsigned len) /* I - Number of bytes to write */
1187*5e7646d2SAndroid Build Coastguard Worker {
1188*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Bytes read */
1189*5e7646d2SAndroid Build Coastguard Worker unsigned remaining; /* Bytes remaining */
1190*5e7646d2SAndroid Build Coastguard Worker
1191*5e7646d2SAndroid Build Coastguard Worker
1192*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("_cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u", (void *)r, (void *)p, len, r->remaining));
1193*5e7646d2SAndroid Build Coastguard Worker
1194*5e7646d2SAndroid Build Coastguard Worker if (r == NULL || r->mode == CUPS_RASTER_READ || r->remaining == 0)
1195*5e7646d2SAndroid Build Coastguard Worker return (0);
1196*5e7646d2SAndroid Build Coastguard Worker
1197*5e7646d2SAndroid Build Coastguard Worker if (!r->compressed)
1198*5e7646d2SAndroid Build Coastguard Worker {
1199*5e7646d2SAndroid Build Coastguard Worker /*
1200*5e7646d2SAndroid Build Coastguard Worker * Without compression, just write the raster data raw unless the data needs
1201*5e7646d2SAndroid Build Coastguard Worker * to be swapped...
1202*5e7646d2SAndroid Build Coastguard Worker */
1203*5e7646d2SAndroid Build Coastguard Worker
1204*5e7646d2SAndroid Build Coastguard Worker r->remaining -= len / r->header.cupsBytesPerLine;
1205*5e7646d2SAndroid Build Coastguard Worker
1206*5e7646d2SAndroid Build Coastguard Worker if (r->swapped &&
1207*5e7646d2SAndroid Build Coastguard Worker (r->header.cupsBitsPerColor == 16 ||
1208*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerPixel == 12 ||
1209*5e7646d2SAndroid Build Coastguard Worker r->header.cupsBitsPerPixel == 16))
1210*5e7646d2SAndroid Build Coastguard Worker {
1211*5e7646d2SAndroid Build Coastguard Worker unsigned char *bufptr; /* Pointer into write buffer */
1212*5e7646d2SAndroid Build Coastguard Worker
1213*5e7646d2SAndroid Build Coastguard Worker /*
1214*5e7646d2SAndroid Build Coastguard Worker * Allocate a write buffer as needed...
1215*5e7646d2SAndroid Build Coastguard Worker */
1216*5e7646d2SAndroid Build Coastguard Worker
1217*5e7646d2SAndroid Build Coastguard Worker if ((size_t)len > r->bufsize)
1218*5e7646d2SAndroid Build Coastguard Worker {
1219*5e7646d2SAndroid Build Coastguard Worker if (r->buffer)
1220*5e7646d2SAndroid Build Coastguard Worker bufptr = realloc(r->buffer, len);
1221*5e7646d2SAndroid Build Coastguard Worker else
1222*5e7646d2SAndroid Build Coastguard Worker bufptr = malloc(len);
1223*5e7646d2SAndroid Build Coastguard Worker
1224*5e7646d2SAndroid Build Coastguard Worker if (!bufptr)
1225*5e7646d2SAndroid Build Coastguard Worker return (0);
1226*5e7646d2SAndroid Build Coastguard Worker
1227*5e7646d2SAndroid Build Coastguard Worker r->buffer = bufptr;
1228*5e7646d2SAndroid Build Coastguard Worker r->bufsize = len;
1229*5e7646d2SAndroid Build Coastguard Worker }
1230*5e7646d2SAndroid Build Coastguard Worker
1231*5e7646d2SAndroid Build Coastguard Worker /*
1232*5e7646d2SAndroid Build Coastguard Worker * Byte swap the pixels and write them...
1233*5e7646d2SAndroid Build Coastguard Worker */
1234*5e7646d2SAndroid Build Coastguard Worker
1235*5e7646d2SAndroid Build Coastguard Worker cups_swap_copy(r->buffer, p, len);
1236*5e7646d2SAndroid Build Coastguard Worker
1237*5e7646d2SAndroid Build Coastguard Worker bytes = cups_raster_io(r, r->buffer, len);
1238*5e7646d2SAndroid Build Coastguard Worker }
1239*5e7646d2SAndroid Build Coastguard Worker else
1240*5e7646d2SAndroid Build Coastguard Worker bytes = cups_raster_io(r, p, len);
1241*5e7646d2SAndroid Build Coastguard Worker
1242*5e7646d2SAndroid Build Coastguard Worker if (bytes < (ssize_t)len)
1243*5e7646d2SAndroid Build Coastguard Worker return (0);
1244*5e7646d2SAndroid Build Coastguard Worker else
1245*5e7646d2SAndroid Build Coastguard Worker return (len);
1246*5e7646d2SAndroid Build Coastguard Worker }
1247*5e7646d2SAndroid Build Coastguard Worker
1248*5e7646d2SAndroid Build Coastguard Worker /*
1249*5e7646d2SAndroid Build Coastguard Worker * Otherwise, compress each line...
1250*5e7646d2SAndroid Build Coastguard Worker */
1251*5e7646d2SAndroid Build Coastguard Worker
1252*5e7646d2SAndroid Build Coastguard Worker for (remaining = len; remaining > 0; remaining -= (unsigned)bytes, p += bytes)
1253*5e7646d2SAndroid Build Coastguard Worker {
1254*5e7646d2SAndroid Build Coastguard Worker /*
1255*5e7646d2SAndroid Build Coastguard Worker * Figure out the number of remaining bytes on the current line...
1256*5e7646d2SAndroid Build Coastguard Worker */
1257*5e7646d2SAndroid Build Coastguard Worker
1258*5e7646d2SAndroid Build Coastguard Worker if ((bytes = (ssize_t)remaining) > (ssize_t)(r->pend - r->pcurrent))
1259*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)(r->pend - r->pcurrent);
1260*5e7646d2SAndroid Build Coastguard Worker
1261*5e7646d2SAndroid Build Coastguard Worker if (r->count > 0)
1262*5e7646d2SAndroid Build Coastguard Worker {
1263*5e7646d2SAndroid Build Coastguard Worker /*
1264*5e7646d2SAndroid Build Coastguard Worker * Check to see if this line is the same as the previous line...
1265*5e7646d2SAndroid Build Coastguard Worker */
1266*5e7646d2SAndroid Build Coastguard Worker
1267*5e7646d2SAndroid Build Coastguard Worker if (memcmp(p, r->pcurrent, (size_t)bytes))
1268*5e7646d2SAndroid Build Coastguard Worker {
1269*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_write(r, r->pixels) <= 0)
1270*5e7646d2SAndroid Build Coastguard Worker return (0);
1271*5e7646d2SAndroid Build Coastguard Worker
1272*5e7646d2SAndroid Build Coastguard Worker r->count = 0;
1273*5e7646d2SAndroid Build Coastguard Worker }
1274*5e7646d2SAndroid Build Coastguard Worker else
1275*5e7646d2SAndroid Build Coastguard Worker {
1276*5e7646d2SAndroid Build Coastguard Worker /*
1277*5e7646d2SAndroid Build Coastguard Worker * Mark more bytes as the same...
1278*5e7646d2SAndroid Build Coastguard Worker */
1279*5e7646d2SAndroid Build Coastguard Worker
1280*5e7646d2SAndroid Build Coastguard Worker r->pcurrent += bytes;
1281*5e7646d2SAndroid Build Coastguard Worker
1282*5e7646d2SAndroid Build Coastguard Worker if (r->pcurrent >= r->pend)
1283*5e7646d2SAndroid Build Coastguard Worker {
1284*5e7646d2SAndroid Build Coastguard Worker /*
1285*5e7646d2SAndroid Build Coastguard Worker * Increase the repeat count...
1286*5e7646d2SAndroid Build Coastguard Worker */
1287*5e7646d2SAndroid Build Coastguard Worker
1288*5e7646d2SAndroid Build Coastguard Worker r->count += r->rowheight;
1289*5e7646d2SAndroid Build Coastguard Worker r->pcurrent = r->pixels;
1290*5e7646d2SAndroid Build Coastguard Worker
1291*5e7646d2SAndroid Build Coastguard Worker /*
1292*5e7646d2SAndroid Build Coastguard Worker * Flush out this line if it is the last one...
1293*5e7646d2SAndroid Build Coastguard Worker */
1294*5e7646d2SAndroid Build Coastguard Worker
1295*5e7646d2SAndroid Build Coastguard Worker r->remaining --;
1296*5e7646d2SAndroid Build Coastguard Worker
1297*5e7646d2SAndroid Build Coastguard Worker if (r->remaining == 0)
1298*5e7646d2SAndroid Build Coastguard Worker {
1299*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_write(r, r->pixels) <= 0)
1300*5e7646d2SAndroid Build Coastguard Worker return (0);
1301*5e7646d2SAndroid Build Coastguard Worker else
1302*5e7646d2SAndroid Build Coastguard Worker return (len);
1303*5e7646d2SAndroid Build Coastguard Worker }
1304*5e7646d2SAndroid Build Coastguard Worker else if (r->count > (256 - r->rowheight))
1305*5e7646d2SAndroid Build Coastguard Worker {
1306*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_write(r, r->pixels) <= 0)
1307*5e7646d2SAndroid Build Coastguard Worker return (0);
1308*5e7646d2SAndroid Build Coastguard Worker
1309*5e7646d2SAndroid Build Coastguard Worker r->count = 0;
1310*5e7646d2SAndroid Build Coastguard Worker }
1311*5e7646d2SAndroid Build Coastguard Worker }
1312*5e7646d2SAndroid Build Coastguard Worker
1313*5e7646d2SAndroid Build Coastguard Worker continue;
1314*5e7646d2SAndroid Build Coastguard Worker }
1315*5e7646d2SAndroid Build Coastguard Worker }
1316*5e7646d2SAndroid Build Coastguard Worker
1317*5e7646d2SAndroid Build Coastguard Worker if (r->count == 0)
1318*5e7646d2SAndroid Build Coastguard Worker {
1319*5e7646d2SAndroid Build Coastguard Worker /*
1320*5e7646d2SAndroid Build Coastguard Worker * Copy the raster data to the buffer...
1321*5e7646d2SAndroid Build Coastguard Worker */
1322*5e7646d2SAndroid Build Coastguard Worker
1323*5e7646d2SAndroid Build Coastguard Worker memcpy(r->pcurrent, p, (size_t)bytes);
1324*5e7646d2SAndroid Build Coastguard Worker
1325*5e7646d2SAndroid Build Coastguard Worker r->pcurrent += bytes;
1326*5e7646d2SAndroid Build Coastguard Worker
1327*5e7646d2SAndroid Build Coastguard Worker if (r->pcurrent >= r->pend)
1328*5e7646d2SAndroid Build Coastguard Worker {
1329*5e7646d2SAndroid Build Coastguard Worker /*
1330*5e7646d2SAndroid Build Coastguard Worker * Increase the repeat count...
1331*5e7646d2SAndroid Build Coastguard Worker */
1332*5e7646d2SAndroid Build Coastguard Worker
1333*5e7646d2SAndroid Build Coastguard Worker r->count += r->rowheight;
1334*5e7646d2SAndroid Build Coastguard Worker r->pcurrent = r->pixels;
1335*5e7646d2SAndroid Build Coastguard Worker
1336*5e7646d2SAndroid Build Coastguard Worker /*
1337*5e7646d2SAndroid Build Coastguard Worker * Flush out this line if it is the last one...
1338*5e7646d2SAndroid Build Coastguard Worker */
1339*5e7646d2SAndroid Build Coastguard Worker
1340*5e7646d2SAndroid Build Coastguard Worker r->remaining --;
1341*5e7646d2SAndroid Build Coastguard Worker
1342*5e7646d2SAndroid Build Coastguard Worker if (r->remaining == 0)
1343*5e7646d2SAndroid Build Coastguard Worker {
1344*5e7646d2SAndroid Build Coastguard Worker if (cups_raster_write(r, r->pixels) <= 0)
1345*5e7646d2SAndroid Build Coastguard Worker return (0);
1346*5e7646d2SAndroid Build Coastguard Worker }
1347*5e7646d2SAndroid Build Coastguard Worker }
1348*5e7646d2SAndroid Build Coastguard Worker }
1349*5e7646d2SAndroid Build Coastguard Worker }
1350*5e7646d2SAndroid Build Coastguard Worker
1351*5e7646d2SAndroid Build Coastguard Worker return (len);
1352*5e7646d2SAndroid Build Coastguard Worker }
1353*5e7646d2SAndroid Build Coastguard Worker
1354*5e7646d2SAndroid Build Coastguard Worker
1355*5e7646d2SAndroid Build Coastguard Worker /*
1356*5e7646d2SAndroid Build Coastguard Worker * 'cups_raster_io()' - Read/write bytes from a context, handling interruptions.
1357*5e7646d2SAndroid Build Coastguard Worker */
1358*5e7646d2SAndroid Build Coastguard Worker
1359*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Bytes read/write or -1 */
cups_raster_io(cups_raster_t * r,unsigned char * buf,size_t bytes)1360*5e7646d2SAndroid Build Coastguard Worker cups_raster_io(cups_raster_t *r, /* I - Raster stream */
1361*5e7646d2SAndroid Build Coastguard Worker unsigned char *buf, /* I - Buffer for read/write */
1362*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number of bytes to read/write */
1363*5e7646d2SAndroid Build Coastguard Worker {
1364*5e7646d2SAndroid Build Coastguard Worker ssize_t count, /* Number of bytes read/written */
1365*5e7646d2SAndroid Build Coastguard Worker total; /* Total bytes read/written */
1366*5e7646d2SAndroid Build Coastguard Worker
1367*5e7646d2SAndroid Build Coastguard Worker
1368*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5cups_raster_io(r=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)r, (void *)buf, CUPS_LLCAST bytes));
1369*5e7646d2SAndroid Build Coastguard Worker
1370*5e7646d2SAndroid Build Coastguard Worker for (total = 0; total < (ssize_t)bytes; total += count, buf += count)
1371*5e7646d2SAndroid Build Coastguard Worker {
1372*5e7646d2SAndroid Build Coastguard Worker count = (*r->iocb)(r->ctx, buf, bytes - (size_t)total);
1373*5e7646d2SAndroid Build Coastguard Worker
1374*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("6cups_raster_io: count=%d, total=%d", (int)count, (int)total));
1375*5e7646d2SAndroid Build Coastguard Worker if (count == 0)
1376*5e7646d2SAndroid Build Coastguard Worker break;
1377*5e7646d2SAndroid Build Coastguard Worker // {
1378*5e7646d2SAndroid Build Coastguard Worker // DEBUG_puts("6cups_raster_io: Returning 0.");
1379*5e7646d2SAndroid Build Coastguard Worker // return (0);
1380*5e7646d2SAndroid Build Coastguard Worker // }
1381*5e7646d2SAndroid Build Coastguard Worker else if (count < 0)
1382*5e7646d2SAndroid Build Coastguard Worker {
1383*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("6cups_raster_io: Returning -1 on error.");
1384*5e7646d2SAndroid Build Coastguard Worker return (-1);
1385*5e7646d2SAndroid Build Coastguard Worker }
1386*5e7646d2SAndroid Build Coastguard Worker
1387*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
1388*5e7646d2SAndroid Build Coastguard Worker r->iocount += (size_t)count;
1389*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
1390*5e7646d2SAndroid Build Coastguard Worker }
1391*5e7646d2SAndroid Build Coastguard Worker
1392*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("6cups_raster_io: iocount=" CUPS_LLFMT, CUPS_LLCAST r->iocount));
1393*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("6cups_raster_io: Returning " CUPS_LLFMT ".", CUPS_LLCAST total));
1394*5e7646d2SAndroid Build Coastguard Worker
1395*5e7646d2SAndroid Build Coastguard Worker return (total);
1396*5e7646d2SAndroid Build Coastguard Worker }
1397*5e7646d2SAndroid Build Coastguard Worker
1398*5e7646d2SAndroid Build Coastguard Worker
1399*5e7646d2SAndroid Build Coastguard Worker /*
1400*5e7646d2SAndroid Build Coastguard Worker * 'cups_raster_read()' - Read through the raster buffer.
1401*5e7646d2SAndroid Build Coastguard Worker */
1402*5e7646d2SAndroid Build Coastguard Worker
1403*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes read */
cups_raster_read(cups_raster_t * r,unsigned char * buf,size_t bytes)1404*5e7646d2SAndroid Build Coastguard Worker cups_raster_read(cups_raster_t *r, /* I - Raster stream */
1405*5e7646d2SAndroid Build Coastguard Worker unsigned char *buf, /* I - Buffer */
1406*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number of bytes to read */
1407*5e7646d2SAndroid Build Coastguard Worker {
1408*5e7646d2SAndroid Build Coastguard Worker ssize_t count, /* Number of bytes read */
1409*5e7646d2SAndroid Build Coastguard Worker remaining, /* Remaining bytes in buffer */
1410*5e7646d2SAndroid Build Coastguard Worker total; /* Total bytes read */
1411*5e7646d2SAndroid Build Coastguard Worker
1412*5e7646d2SAndroid Build Coastguard Worker
1413*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cups_raster_read(r=%p, buf=%p, bytes=" CUPS_LLFMT "), offset=" CUPS_LLFMT, (void *)r, (void *)buf, CUPS_LLCAST bytes, CUPS_LLCAST (r->iostart + r->bufptr - r->buffer)));
1414*5e7646d2SAndroid Build Coastguard Worker
1415*5e7646d2SAndroid Build Coastguard Worker if (!r->compressed)
1416*5e7646d2SAndroid Build Coastguard Worker return (cups_raster_io(r, buf, bytes));
1417*5e7646d2SAndroid Build Coastguard Worker
1418*5e7646d2SAndroid Build Coastguard Worker /*
1419*5e7646d2SAndroid Build Coastguard Worker * Allocate a read buffer as needed...
1420*5e7646d2SAndroid Build Coastguard Worker */
1421*5e7646d2SAndroid Build Coastguard Worker
1422*5e7646d2SAndroid Build Coastguard Worker count = (ssize_t)(2 * r->header.cupsBytesPerLine);
1423*5e7646d2SAndroid Build Coastguard Worker if (count < 65536)
1424*5e7646d2SAndroid Build Coastguard Worker count = 65536;
1425*5e7646d2SAndroid Build Coastguard Worker
1426*5e7646d2SAndroid Build Coastguard Worker if ((size_t)count > r->bufsize)
1427*5e7646d2SAndroid Build Coastguard Worker {
1428*5e7646d2SAndroid Build Coastguard Worker ssize_t offset = r->bufptr - r->buffer;
1429*5e7646d2SAndroid Build Coastguard Worker /* Offset to current start of buffer */
1430*5e7646d2SAndroid Build Coastguard Worker ssize_t end = r->bufend - r->buffer;/* Offset to current end of buffer */
1431*5e7646d2SAndroid Build Coastguard Worker unsigned char *rptr; /* Pointer in read buffer */
1432*5e7646d2SAndroid Build Coastguard Worker
1433*5e7646d2SAndroid Build Coastguard Worker if (r->buffer)
1434*5e7646d2SAndroid Build Coastguard Worker rptr = realloc(r->buffer, (size_t)count);
1435*5e7646d2SAndroid Build Coastguard Worker else
1436*5e7646d2SAndroid Build Coastguard Worker rptr = malloc((size_t)count);
1437*5e7646d2SAndroid Build Coastguard Worker
1438*5e7646d2SAndroid Build Coastguard Worker if (!rptr)
1439*5e7646d2SAndroid Build Coastguard Worker return (0);
1440*5e7646d2SAndroid Build Coastguard Worker
1441*5e7646d2SAndroid Build Coastguard Worker r->buffer = rptr;
1442*5e7646d2SAndroid Build Coastguard Worker r->bufptr = rptr + offset;
1443*5e7646d2SAndroid Build Coastguard Worker r->bufend = rptr + end;
1444*5e7646d2SAndroid Build Coastguard Worker r->bufsize = (size_t)count;
1445*5e7646d2SAndroid Build Coastguard Worker }
1446*5e7646d2SAndroid Build Coastguard Worker
1447*5e7646d2SAndroid Build Coastguard Worker /*
1448*5e7646d2SAndroid Build Coastguard Worker * Loop until we have read everything...
1449*5e7646d2SAndroid Build Coastguard Worker */
1450*5e7646d2SAndroid Build Coastguard Worker
1451*5e7646d2SAndroid Build Coastguard Worker for (total = 0, remaining = (int)(r->bufend - r->bufptr);
1452*5e7646d2SAndroid Build Coastguard Worker total < (ssize_t)bytes;
1453*5e7646d2SAndroid Build Coastguard Worker total += count, buf += count)
1454*5e7646d2SAndroid Build Coastguard Worker {
1455*5e7646d2SAndroid Build Coastguard Worker count = (ssize_t)bytes - total;
1456*5e7646d2SAndroid Build Coastguard Worker
1457*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5cups_raster_read: count=" CUPS_LLFMT ", remaining=" CUPS_LLFMT ", buf=%p, bufptr=%p, bufend=%p", CUPS_LLCAST count, CUPS_LLCAST remaining, (void *)buf, (void *)r->bufptr, (void *)r->bufend));
1458*5e7646d2SAndroid Build Coastguard Worker
1459*5e7646d2SAndroid Build Coastguard Worker if (remaining == 0)
1460*5e7646d2SAndroid Build Coastguard Worker {
1461*5e7646d2SAndroid Build Coastguard Worker if (count < 16)
1462*5e7646d2SAndroid Build Coastguard Worker {
1463*5e7646d2SAndroid Build Coastguard Worker /*
1464*5e7646d2SAndroid Build Coastguard Worker * Read into the raster buffer and then copy...
1465*5e7646d2SAndroid Build Coastguard Worker */
1466*5e7646d2SAndroid Build Coastguard Worker
1467*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
1468*5e7646d2SAndroid Build Coastguard Worker r->iostart += (size_t)(r->bufend - r->buffer);
1469*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
1470*5e7646d2SAndroid Build Coastguard Worker
1471*5e7646d2SAndroid Build Coastguard Worker remaining = (*r->iocb)(r->ctx, r->buffer, r->bufsize);
1472*5e7646d2SAndroid Build Coastguard Worker if (remaining <= 0)
1473*5e7646d2SAndroid Build Coastguard Worker return (0);
1474*5e7646d2SAndroid Build Coastguard Worker
1475*5e7646d2SAndroid Build Coastguard Worker r->bufptr = r->buffer;
1476*5e7646d2SAndroid Build Coastguard Worker r->bufend = r->buffer + remaining;
1477*5e7646d2SAndroid Build Coastguard Worker
1478*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
1479*5e7646d2SAndroid Build Coastguard Worker r->iocount += (size_t)remaining;
1480*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
1481*5e7646d2SAndroid Build Coastguard Worker }
1482*5e7646d2SAndroid Build Coastguard Worker else
1483*5e7646d2SAndroid Build Coastguard Worker {
1484*5e7646d2SAndroid Build Coastguard Worker /*
1485*5e7646d2SAndroid Build Coastguard Worker * Read directly into "buf"...
1486*5e7646d2SAndroid Build Coastguard Worker */
1487*5e7646d2SAndroid Build Coastguard Worker
1488*5e7646d2SAndroid Build Coastguard Worker count = (*r->iocb)(r->ctx, buf, (size_t)count);
1489*5e7646d2SAndroid Build Coastguard Worker
1490*5e7646d2SAndroid Build Coastguard Worker if (count <= 0)
1491*5e7646d2SAndroid Build Coastguard Worker return (0);
1492*5e7646d2SAndroid Build Coastguard Worker
1493*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
1494*5e7646d2SAndroid Build Coastguard Worker r->iostart += (size_t)count;
1495*5e7646d2SAndroid Build Coastguard Worker r->iocount += (size_t)count;
1496*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
1497*5e7646d2SAndroid Build Coastguard Worker
1498*5e7646d2SAndroid Build Coastguard Worker continue;
1499*5e7646d2SAndroid Build Coastguard Worker }
1500*5e7646d2SAndroid Build Coastguard Worker }
1501*5e7646d2SAndroid Build Coastguard Worker
1502*5e7646d2SAndroid Build Coastguard Worker /*
1503*5e7646d2SAndroid Build Coastguard Worker * Copy bytes from raster buffer to "buf"...
1504*5e7646d2SAndroid Build Coastguard Worker */
1505*5e7646d2SAndroid Build Coastguard Worker
1506*5e7646d2SAndroid Build Coastguard Worker if (count > remaining)
1507*5e7646d2SAndroid Build Coastguard Worker count = remaining;
1508*5e7646d2SAndroid Build Coastguard Worker
1509*5e7646d2SAndroid Build Coastguard Worker if (count == 1)
1510*5e7646d2SAndroid Build Coastguard Worker {
1511*5e7646d2SAndroid Build Coastguard Worker /*
1512*5e7646d2SAndroid Build Coastguard Worker * Copy 1 byte...
1513*5e7646d2SAndroid Build Coastguard Worker */
1514*5e7646d2SAndroid Build Coastguard Worker
1515*5e7646d2SAndroid Build Coastguard Worker *buf = *(r->bufptr)++;
1516*5e7646d2SAndroid Build Coastguard Worker remaining --;
1517*5e7646d2SAndroid Build Coastguard Worker }
1518*5e7646d2SAndroid Build Coastguard Worker else if (count < 128)
1519*5e7646d2SAndroid Build Coastguard Worker {
1520*5e7646d2SAndroid Build Coastguard Worker /*
1521*5e7646d2SAndroid Build Coastguard Worker * Copy up to 127 bytes without using memcpy(); this is
1522*5e7646d2SAndroid Build Coastguard Worker * faster because it avoids an extra function call and is
1523*5e7646d2SAndroid Build Coastguard Worker * often further optimized by the compiler...
1524*5e7646d2SAndroid Build Coastguard Worker */
1525*5e7646d2SAndroid Build Coastguard Worker
1526*5e7646d2SAndroid Build Coastguard Worker unsigned char *bufptr; /* Temporary buffer pointer */
1527*5e7646d2SAndroid Build Coastguard Worker
1528*5e7646d2SAndroid Build Coastguard Worker remaining -= count;
1529*5e7646d2SAndroid Build Coastguard Worker
1530*5e7646d2SAndroid Build Coastguard Worker for (bufptr = r->bufptr; count > 0; count --, total ++)
1531*5e7646d2SAndroid Build Coastguard Worker *buf++ = *bufptr++;
1532*5e7646d2SAndroid Build Coastguard Worker
1533*5e7646d2SAndroid Build Coastguard Worker r->bufptr = bufptr;
1534*5e7646d2SAndroid Build Coastguard Worker }
1535*5e7646d2SAndroid Build Coastguard Worker else
1536*5e7646d2SAndroid Build Coastguard Worker {
1537*5e7646d2SAndroid Build Coastguard Worker /*
1538*5e7646d2SAndroid Build Coastguard Worker * Use memcpy() for a large read...
1539*5e7646d2SAndroid Build Coastguard Worker */
1540*5e7646d2SAndroid Build Coastguard Worker
1541*5e7646d2SAndroid Build Coastguard Worker memcpy(buf, r->bufptr, (size_t)count);
1542*5e7646d2SAndroid Build Coastguard Worker r->bufptr += count;
1543*5e7646d2SAndroid Build Coastguard Worker remaining -= count;
1544*5e7646d2SAndroid Build Coastguard Worker }
1545*5e7646d2SAndroid Build Coastguard Worker }
1546*5e7646d2SAndroid Build Coastguard Worker
1547*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5cups_raster_read: Returning %ld", (long)total));
1548*5e7646d2SAndroid Build Coastguard Worker
1549*5e7646d2SAndroid Build Coastguard Worker return (total);
1550*5e7646d2SAndroid Build Coastguard Worker }
1551*5e7646d2SAndroid Build Coastguard Worker
1552*5e7646d2SAndroid Build Coastguard Worker
1553*5e7646d2SAndroid Build Coastguard Worker /*
1554*5e7646d2SAndroid Build Coastguard Worker * 'cups_raster_update()' - Update the raster header and row count for the
1555*5e7646d2SAndroid Build Coastguard Worker * current page.
1556*5e7646d2SAndroid Build Coastguard Worker */
1557*5e7646d2SAndroid Build Coastguard Worker
1558*5e7646d2SAndroid Build Coastguard Worker static int /* O - 1 on success, 0 on failure */
cups_raster_update(cups_raster_t * r)1559*5e7646d2SAndroid Build Coastguard Worker cups_raster_update(cups_raster_t *r) /* I - Raster stream */
1560*5e7646d2SAndroid Build Coastguard Worker {
1561*5e7646d2SAndroid Build Coastguard Worker if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1 ||
1562*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors == 0)
1563*5e7646d2SAndroid Build Coastguard Worker {
1564*5e7646d2SAndroid Build Coastguard Worker /*
1565*5e7646d2SAndroid Build Coastguard Worker * Set the "cupsNumColors" field according to the colorspace...
1566*5e7646d2SAndroid Build Coastguard Worker */
1567*5e7646d2SAndroid Build Coastguard Worker
1568*5e7646d2SAndroid Build Coastguard Worker switch (r->header.cupsColorSpace)
1569*5e7646d2SAndroid Build Coastguard Worker {
1570*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_W :
1571*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_K :
1572*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_WHITE :
1573*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_GOLD :
1574*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_SILVER :
1575*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_SW :
1576*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors = 1;
1577*5e7646d2SAndroid Build Coastguard Worker break;
1578*5e7646d2SAndroid Build Coastguard Worker
1579*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_RGB :
1580*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_CMY :
1581*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_YMC :
1582*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_CIEXYZ :
1583*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_CIELab :
1584*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_SRGB :
1585*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ADOBERGB :
1586*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC1 :
1587*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC2 :
1588*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC3 :
1589*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC4 :
1590*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC5 :
1591*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC6 :
1592*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC7 :
1593*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC8 :
1594*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICC9 :
1595*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICCA :
1596*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICCB :
1597*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICCC :
1598*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICCD :
1599*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICCE :
1600*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_ICCF :
1601*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors = 3;
1602*5e7646d2SAndroid Build Coastguard Worker break;
1603*5e7646d2SAndroid Build Coastguard Worker
1604*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_RGBA :
1605*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_RGBW :
1606*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_CMYK :
1607*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_YMCK :
1608*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_KCMY :
1609*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_GMCK :
1610*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_GMCS :
1611*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors = 4;
1612*5e7646d2SAndroid Build Coastguard Worker break;
1613*5e7646d2SAndroid Build Coastguard Worker
1614*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_KCMYcm :
1615*5e7646d2SAndroid Build Coastguard Worker if (r->header.cupsBitsPerPixel < 8)
1616*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors = 6;
1617*5e7646d2SAndroid Build Coastguard Worker else
1618*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors = 4;
1619*5e7646d2SAndroid Build Coastguard Worker break;
1620*5e7646d2SAndroid Build Coastguard Worker
1621*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE1 :
1622*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE2 :
1623*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE3 :
1624*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE4 :
1625*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE5 :
1626*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE6 :
1627*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE7 :
1628*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE8 :
1629*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICE9 :
1630*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICEA :
1631*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICEB :
1632*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICEC :
1633*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICED :
1634*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICEE :
1635*5e7646d2SAndroid Build Coastguard Worker case CUPS_CSPACE_DEVICEF :
1636*5e7646d2SAndroid Build Coastguard Worker r->header.cupsNumColors = r->header.cupsColorSpace -
1637*5e7646d2SAndroid Build Coastguard Worker CUPS_CSPACE_DEVICE1 + 1;
1638*5e7646d2SAndroid Build Coastguard Worker break;
1639*5e7646d2SAndroid Build Coastguard Worker
1640*5e7646d2SAndroid Build Coastguard Worker default :
1641*5e7646d2SAndroid Build Coastguard Worker /* Unknown color space */
1642*5e7646d2SAndroid Build Coastguard Worker return (0);
1643*5e7646d2SAndroid Build Coastguard Worker }
1644*5e7646d2SAndroid Build Coastguard Worker }
1645*5e7646d2SAndroid Build Coastguard Worker
1646*5e7646d2SAndroid Build Coastguard Worker /*
1647*5e7646d2SAndroid Build Coastguard Worker * Set the number of bytes per pixel/color...
1648*5e7646d2SAndroid Build Coastguard Worker */
1649*5e7646d2SAndroid Build Coastguard Worker
1650*5e7646d2SAndroid Build Coastguard Worker if (r->header.cupsColorOrder == CUPS_ORDER_CHUNKED)
1651*5e7646d2SAndroid Build Coastguard Worker r->bpp = (r->header.cupsBitsPerPixel + 7) / 8;
1652*5e7646d2SAndroid Build Coastguard Worker else
1653*5e7646d2SAndroid Build Coastguard Worker r->bpp = (r->header.cupsBitsPerColor + 7) / 8;
1654*5e7646d2SAndroid Build Coastguard Worker
1655*5e7646d2SAndroid Build Coastguard Worker if (r->bpp == 0)
1656*5e7646d2SAndroid Build Coastguard Worker r->bpp = 1;
1657*5e7646d2SAndroid Build Coastguard Worker
1658*5e7646d2SAndroid Build Coastguard Worker /*
1659*5e7646d2SAndroid Build Coastguard Worker * Set the number of remaining rows...
1660*5e7646d2SAndroid Build Coastguard Worker */
1661*5e7646d2SAndroid Build Coastguard Worker
1662*5e7646d2SAndroid Build Coastguard Worker if (r->header.cupsColorOrder == CUPS_ORDER_PLANAR)
1663*5e7646d2SAndroid Build Coastguard Worker r->remaining = r->header.cupsHeight * r->header.cupsNumColors;
1664*5e7646d2SAndroid Build Coastguard Worker else
1665*5e7646d2SAndroid Build Coastguard Worker r->remaining = r->header.cupsHeight;
1666*5e7646d2SAndroid Build Coastguard Worker
1667*5e7646d2SAndroid Build Coastguard Worker /*
1668*5e7646d2SAndroid Build Coastguard Worker * Allocate the compression buffer...
1669*5e7646d2SAndroid Build Coastguard Worker */
1670*5e7646d2SAndroid Build Coastguard Worker
1671*5e7646d2SAndroid Build Coastguard Worker if (r->compressed)
1672*5e7646d2SAndroid Build Coastguard Worker {
1673*5e7646d2SAndroid Build Coastguard Worker if (r->pixels != NULL)
1674*5e7646d2SAndroid Build Coastguard Worker free(r->pixels);
1675*5e7646d2SAndroid Build Coastguard Worker
1676*5e7646d2SAndroid Build Coastguard Worker if ((r->pixels = calloc(r->header.cupsBytesPerLine, 1)) == NULL)
1677*5e7646d2SAndroid Build Coastguard Worker {
1678*5e7646d2SAndroid Build Coastguard Worker r->pcurrent = NULL;
1679*5e7646d2SAndroid Build Coastguard Worker r->pend = NULL;
1680*5e7646d2SAndroid Build Coastguard Worker r->count = 0;
1681*5e7646d2SAndroid Build Coastguard Worker
1682*5e7646d2SAndroid Build Coastguard Worker return (0);
1683*5e7646d2SAndroid Build Coastguard Worker }
1684*5e7646d2SAndroid Build Coastguard Worker
1685*5e7646d2SAndroid Build Coastguard Worker r->pcurrent = r->pixels;
1686*5e7646d2SAndroid Build Coastguard Worker r->pend = r->pixels + r->header.cupsBytesPerLine;
1687*5e7646d2SAndroid Build Coastguard Worker r->count = 0;
1688*5e7646d2SAndroid Build Coastguard Worker }
1689*5e7646d2SAndroid Build Coastguard Worker
1690*5e7646d2SAndroid Build Coastguard Worker return (1);
1691*5e7646d2SAndroid Build Coastguard Worker }
1692*5e7646d2SAndroid Build Coastguard Worker
1693*5e7646d2SAndroid Build Coastguard Worker
1694*5e7646d2SAndroid Build Coastguard Worker /*
1695*5e7646d2SAndroid Build Coastguard Worker * 'cups_raster_write()' - Write a row of compressed raster data...
1696*5e7646d2SAndroid Build Coastguard Worker */
1697*5e7646d2SAndroid Build Coastguard Worker
1698*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes written */
cups_raster_write(cups_raster_t * r,const unsigned char * pixels)1699*5e7646d2SAndroid Build Coastguard Worker cups_raster_write(
1700*5e7646d2SAndroid Build Coastguard Worker cups_raster_t *r, /* I - Raster stream */
1701*5e7646d2SAndroid Build Coastguard Worker const unsigned char *pixels) /* I - Pixel data to write */
1702*5e7646d2SAndroid Build Coastguard Worker {
1703*5e7646d2SAndroid Build Coastguard Worker const unsigned char *start, /* Start of sequence */
1704*5e7646d2SAndroid Build Coastguard Worker *ptr, /* Current pointer in sequence */
1705*5e7646d2SAndroid Build Coastguard Worker *pend, /* End of raster buffer */
1706*5e7646d2SAndroid Build Coastguard Worker *plast; /* Pointer to last pixel */
1707*5e7646d2SAndroid Build Coastguard Worker unsigned char *wptr; /* Pointer into write buffer */
1708*5e7646d2SAndroid Build Coastguard Worker unsigned bpp, /* Bytes per pixel */
1709*5e7646d2SAndroid Build Coastguard Worker count; /* Count */
1710*5e7646d2SAndroid Build Coastguard Worker _cups_copyfunc_t cf; /* Copy function */
1711*5e7646d2SAndroid Build Coastguard Worker
1712*5e7646d2SAndroid Build Coastguard Worker
1713*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("3cups_raster_write(r=%p, pixels=%p)", (void *)r, (void *)pixels));
1714*5e7646d2SAndroid Build Coastguard Worker
1715*5e7646d2SAndroid Build Coastguard Worker /*
1716*5e7646d2SAndroid Build Coastguard Worker * Determine whether we need to swap bytes...
1717*5e7646d2SAndroid Build Coastguard Worker */
1718*5e7646d2SAndroid Build Coastguard Worker
1719*5e7646d2SAndroid Build Coastguard Worker if (r->swapped && (r->header.cupsBitsPerColor == 16 || r->header.cupsBitsPerPixel == 12 || r->header.cupsBitsPerPixel == 16))
1720*5e7646d2SAndroid Build Coastguard Worker {
1721*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("4cups_raster_write: Swapping bytes when writing.");
1722*5e7646d2SAndroid Build Coastguard Worker cf = (_cups_copyfunc_t)cups_swap_copy;
1723*5e7646d2SAndroid Build Coastguard Worker }
1724*5e7646d2SAndroid Build Coastguard Worker else
1725*5e7646d2SAndroid Build Coastguard Worker cf = (_cups_copyfunc_t)memcpy;
1726*5e7646d2SAndroid Build Coastguard Worker
1727*5e7646d2SAndroid Build Coastguard Worker /*
1728*5e7646d2SAndroid Build Coastguard Worker * Allocate a write buffer as needed...
1729*5e7646d2SAndroid Build Coastguard Worker */
1730*5e7646d2SAndroid Build Coastguard Worker
1731*5e7646d2SAndroid Build Coastguard Worker count = r->header.cupsBytesPerLine * 2;
1732*5e7646d2SAndroid Build Coastguard Worker if (count < 65536)
1733*5e7646d2SAndroid Build Coastguard Worker count = 65536;
1734*5e7646d2SAndroid Build Coastguard Worker
1735*5e7646d2SAndroid Build Coastguard Worker if ((size_t)count > r->bufsize)
1736*5e7646d2SAndroid Build Coastguard Worker {
1737*5e7646d2SAndroid Build Coastguard Worker if (r->buffer)
1738*5e7646d2SAndroid Build Coastguard Worker wptr = realloc(r->buffer, count);
1739*5e7646d2SAndroid Build Coastguard Worker else
1740*5e7646d2SAndroid Build Coastguard Worker wptr = malloc(count);
1741*5e7646d2SAndroid Build Coastguard Worker
1742*5e7646d2SAndroid Build Coastguard Worker if (!wptr)
1743*5e7646d2SAndroid Build Coastguard Worker {
1744*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cups_raster_write: Unable to allocate " CUPS_LLFMT " bytes for raster buffer: %s", CUPS_LLCAST count, strerror(errno)));
1745*5e7646d2SAndroid Build Coastguard Worker return (-1);
1746*5e7646d2SAndroid Build Coastguard Worker }
1747*5e7646d2SAndroid Build Coastguard Worker
1748*5e7646d2SAndroid Build Coastguard Worker r->buffer = wptr;
1749*5e7646d2SAndroid Build Coastguard Worker r->bufsize = count;
1750*5e7646d2SAndroid Build Coastguard Worker }
1751*5e7646d2SAndroid Build Coastguard Worker
1752*5e7646d2SAndroid Build Coastguard Worker /*
1753*5e7646d2SAndroid Build Coastguard Worker * Write the row repeat count...
1754*5e7646d2SAndroid Build Coastguard Worker */
1755*5e7646d2SAndroid Build Coastguard Worker
1756*5e7646d2SAndroid Build Coastguard Worker bpp = r->bpp;
1757*5e7646d2SAndroid Build Coastguard Worker pend = pixels + r->header.cupsBytesPerLine;
1758*5e7646d2SAndroid Build Coastguard Worker plast = pend - bpp;
1759*5e7646d2SAndroid Build Coastguard Worker wptr = r->buffer;
1760*5e7646d2SAndroid Build Coastguard Worker *wptr++ = (unsigned char)(r->count - 1);
1761*5e7646d2SAndroid Build Coastguard Worker
1762*5e7646d2SAndroid Build Coastguard Worker /*
1763*5e7646d2SAndroid Build Coastguard Worker * Write using a modified PackBits compression...
1764*5e7646d2SAndroid Build Coastguard Worker */
1765*5e7646d2SAndroid Build Coastguard Worker
1766*5e7646d2SAndroid Build Coastguard Worker for (ptr = pixels; ptr < pend;)
1767*5e7646d2SAndroid Build Coastguard Worker {
1768*5e7646d2SAndroid Build Coastguard Worker start = ptr;
1769*5e7646d2SAndroid Build Coastguard Worker ptr += bpp;
1770*5e7646d2SAndroid Build Coastguard Worker
1771*5e7646d2SAndroid Build Coastguard Worker if (ptr == pend)
1772*5e7646d2SAndroid Build Coastguard Worker {
1773*5e7646d2SAndroid Build Coastguard Worker /*
1774*5e7646d2SAndroid Build Coastguard Worker * Encode a single pixel at the end...
1775*5e7646d2SAndroid Build Coastguard Worker */
1776*5e7646d2SAndroid Build Coastguard Worker
1777*5e7646d2SAndroid Build Coastguard Worker *wptr++ = 0;
1778*5e7646d2SAndroid Build Coastguard Worker (*cf)(wptr, start, bpp);
1779*5e7646d2SAndroid Build Coastguard Worker wptr += bpp;
1780*5e7646d2SAndroid Build Coastguard Worker }
1781*5e7646d2SAndroid Build Coastguard Worker else if (!memcmp(start, ptr, bpp))
1782*5e7646d2SAndroid Build Coastguard Worker {
1783*5e7646d2SAndroid Build Coastguard Worker /*
1784*5e7646d2SAndroid Build Coastguard Worker * Encode a sequence of repeating pixels...
1785*5e7646d2SAndroid Build Coastguard Worker */
1786*5e7646d2SAndroid Build Coastguard Worker
1787*5e7646d2SAndroid Build Coastguard Worker for (count = 2; count < 128 && ptr < plast; count ++, ptr += bpp)
1788*5e7646d2SAndroid Build Coastguard Worker if (memcmp(ptr, ptr + bpp, bpp))
1789*5e7646d2SAndroid Build Coastguard Worker break;
1790*5e7646d2SAndroid Build Coastguard Worker
1791*5e7646d2SAndroid Build Coastguard Worker *wptr++ = (unsigned char)(count - 1);
1792*5e7646d2SAndroid Build Coastguard Worker (*cf)(wptr, ptr, bpp);
1793*5e7646d2SAndroid Build Coastguard Worker wptr += bpp;
1794*5e7646d2SAndroid Build Coastguard Worker ptr += bpp;
1795*5e7646d2SAndroid Build Coastguard Worker }
1796*5e7646d2SAndroid Build Coastguard Worker else
1797*5e7646d2SAndroid Build Coastguard Worker {
1798*5e7646d2SAndroid Build Coastguard Worker /*
1799*5e7646d2SAndroid Build Coastguard Worker * Encode a sequence of non-repeating pixels...
1800*5e7646d2SAndroid Build Coastguard Worker */
1801*5e7646d2SAndroid Build Coastguard Worker
1802*5e7646d2SAndroid Build Coastguard Worker for (count = 1; count < 128 && ptr < plast; count ++, ptr += bpp)
1803*5e7646d2SAndroid Build Coastguard Worker if (!memcmp(ptr, ptr + bpp, bpp))
1804*5e7646d2SAndroid Build Coastguard Worker break;
1805*5e7646d2SAndroid Build Coastguard Worker
1806*5e7646d2SAndroid Build Coastguard Worker if (ptr >= plast && count < 128)
1807*5e7646d2SAndroid Build Coastguard Worker {
1808*5e7646d2SAndroid Build Coastguard Worker count ++;
1809*5e7646d2SAndroid Build Coastguard Worker ptr += bpp;
1810*5e7646d2SAndroid Build Coastguard Worker }
1811*5e7646d2SAndroid Build Coastguard Worker
1812*5e7646d2SAndroid Build Coastguard Worker *wptr++ = (unsigned char)(257 - count);
1813*5e7646d2SAndroid Build Coastguard Worker
1814*5e7646d2SAndroid Build Coastguard Worker count *= bpp;
1815*5e7646d2SAndroid Build Coastguard Worker (*cf)(wptr, start, count);
1816*5e7646d2SAndroid Build Coastguard Worker wptr += count;
1817*5e7646d2SAndroid Build Coastguard Worker }
1818*5e7646d2SAndroid Build Coastguard Worker }
1819*5e7646d2SAndroid Build Coastguard Worker
1820*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cups_raster_write: Writing " CUPS_LLFMT " bytes.", CUPS_LLCAST (wptr - r->buffer)));
1821*5e7646d2SAndroid Build Coastguard Worker
1822*5e7646d2SAndroid Build Coastguard Worker return (cups_raster_io(r, r->buffer, (size_t)(wptr - r->buffer)));
1823*5e7646d2SAndroid Build Coastguard Worker }
1824*5e7646d2SAndroid Build Coastguard Worker
1825*5e7646d2SAndroid Build Coastguard Worker
1826*5e7646d2SAndroid Build Coastguard Worker /*
1827*5e7646d2SAndroid Build Coastguard Worker * 'cups_swap()' - Swap bytes in raster data...
1828*5e7646d2SAndroid Build Coastguard Worker */
1829*5e7646d2SAndroid Build Coastguard Worker
1830*5e7646d2SAndroid Build Coastguard Worker static void
cups_swap(unsigned char * buf,size_t bytes)1831*5e7646d2SAndroid Build Coastguard Worker cups_swap(unsigned char *buf, /* I - Buffer to swap */
1832*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number of bytes to swap */
1833*5e7646d2SAndroid Build Coastguard Worker {
1834*5e7646d2SAndroid Build Coastguard Worker unsigned char even, odd; /* Temporary variables */
1835*5e7646d2SAndroid Build Coastguard Worker
1836*5e7646d2SAndroid Build Coastguard Worker
1837*5e7646d2SAndroid Build Coastguard Worker bytes /= 2;
1838*5e7646d2SAndroid Build Coastguard Worker
1839*5e7646d2SAndroid Build Coastguard Worker while (bytes > 0)
1840*5e7646d2SAndroid Build Coastguard Worker {
1841*5e7646d2SAndroid Build Coastguard Worker even = buf[0];
1842*5e7646d2SAndroid Build Coastguard Worker odd = buf[1];
1843*5e7646d2SAndroid Build Coastguard Worker buf[0] = odd;
1844*5e7646d2SAndroid Build Coastguard Worker buf[1] = even;
1845*5e7646d2SAndroid Build Coastguard Worker
1846*5e7646d2SAndroid Build Coastguard Worker buf += 2;
1847*5e7646d2SAndroid Build Coastguard Worker bytes --;
1848*5e7646d2SAndroid Build Coastguard Worker }
1849*5e7646d2SAndroid Build Coastguard Worker }
1850*5e7646d2SAndroid Build Coastguard Worker
1851*5e7646d2SAndroid Build Coastguard Worker
1852*5e7646d2SAndroid Build Coastguard Worker /*
1853*5e7646d2SAndroid Build Coastguard Worker * 'cups_swap_copy()' - Copy and swap bytes in raster data...
1854*5e7646d2SAndroid Build Coastguard Worker */
1855*5e7646d2SAndroid Build Coastguard Worker
1856*5e7646d2SAndroid Build Coastguard Worker static void
cups_swap_copy(unsigned char * dst,const unsigned char * src,size_t bytes)1857*5e7646d2SAndroid Build Coastguard Worker cups_swap_copy(
1858*5e7646d2SAndroid Build Coastguard Worker unsigned char *dst, /* I - Destination */
1859*5e7646d2SAndroid Build Coastguard Worker const unsigned char *src, /* I - Source */
1860*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number of bytes to swap */
1861*5e7646d2SAndroid Build Coastguard Worker {
1862*5e7646d2SAndroid Build Coastguard Worker bytes /= 2;
1863*5e7646d2SAndroid Build Coastguard Worker
1864*5e7646d2SAndroid Build Coastguard Worker while (bytes > 0)
1865*5e7646d2SAndroid Build Coastguard Worker {
1866*5e7646d2SAndroid Build Coastguard Worker dst[0] = src[1];
1867*5e7646d2SAndroid Build Coastguard Worker dst[1] = src[0];
1868*5e7646d2SAndroid Build Coastguard Worker
1869*5e7646d2SAndroid Build Coastguard Worker dst += 2;
1870*5e7646d2SAndroid Build Coastguard Worker src += 2;
1871*5e7646d2SAndroid Build Coastguard Worker bytes --;
1872*5e7646d2SAndroid Build Coastguard Worker }
1873*5e7646d2SAndroid Build Coastguard Worker }
1874