]>
Commit | Line | Data |
---|---|---|
dd204f7a MS |
1 | /* |
2 | * Imaging library stubs for CUPS. | |
3 | * | |
4 | * Copyright © 2018 by Apple Inc. | |
5 | * | |
6 | * Licensed under Apache License v2.0. See the file "LICENSE" for more | |
7 | * information. | |
8 | */ | |
9 | ||
10 | /* | |
11 | * Include necessary headers... | |
12 | */ | |
13 | ||
14 | #include <cups/raster-private.h> | |
15 | ||
16 | ||
17 | /* | |
18 | * These stubs wrap the real functions in libcups - this allows one library to | |
19 | * provide all of the CUPS API functions while still supporting the old split | |
20 | * library organization... | |
21 | */ | |
22 | ||
23 | ||
24 | /* | |
25 | * Local functions... | |
26 | */ | |
27 | ||
28 | static ssize_t cups_read_fd(void *ctx, unsigned char *buf, size_t bytes); | |
29 | static ssize_t cups_write_fd(void *ctx, unsigned char *buf, size_t bytes); | |
30 | ||
31 | ||
32 | ||
33 | /* | |
34 | * 'cupsRasterClose()' - Close a raster stream. | |
35 | * | |
36 | * The file descriptor associated with the raster stream must be closed | |
37 | * separately as needed. | |
38 | */ | |
39 | ||
40 | void | |
41 | cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ | |
42 | { | |
43 | _cupsRasterDelete(r); | |
44 | } | |
45 | ||
46 | ||
47 | /* | |
48 | * 'cupsRasterErrorString()' - Return the last error from a raster function. | |
49 | * | |
50 | * If there are no recent errors, `NULL` is returned. | |
51 | * | |
52 | * @since CUPS 1.3/macOS 10.5@ | |
53 | */ | |
54 | ||
55 | const char * /* O - Last error or `NULL` */ | |
56 | cupsRasterErrorString(void) | |
57 | { | |
58 | return (_cupsRasterErrorString()); | |
59 | } | |
60 | ||
61 | ||
62 | /* | |
63 | * 'cupsRasterInitPWGHeader()' - Initialize a page header for PWG Raster output. | |
64 | * | |
65 | * The "media" argument specifies the media to use. | |
66 | * | |
67 | * The "type" argument specifies a "pwg-raster-document-type-supported" value | |
68 | * that controls the color space and bit depth of the raster data. | |
69 | * | |
70 | * The "xres" and "yres" arguments specify the raster resolution in dots per | |
71 | * inch. | |
72 | * | |
73 | * The "sheet_back" argument specifies a "pwg-raster-document-sheet-back" value | |
74 | * to apply for the back side of a page. Pass @code NULL@ for the front side. | |
75 | * | |
76 | * @since CUPS 2.2/macOS 10.12@ | |
77 | */ | |
78 | ||
79 | int /* O - 1 on success, 0 on failure */ | |
80 | cupsRasterInitPWGHeader( | |
81 | cups_page_header2_t *h, /* I - Page header */ | |
82 | pwg_media_t *media, /* I - PWG media information */ | |
83 | const char *type, /* I - PWG raster type string */ | |
84 | int xdpi, /* I - Cross-feed direction (horizontal) resolution */ | |
85 | int ydpi, /* I - Feed direction (vertical) resolution */ | |
86 | const char *sides, /* I - IPP "sides" option value */ | |
87 | const char *sheet_back) /* I - Transform for back side or @code NULL@ for none */ | |
88 | { | |
89 | return (_cupsRasterInitPWGHeader(h, media, type, xdpi, ydpi, sides, sheet_back)); | |
90 | } | |
91 | ||
92 | ||
93 | /* | |
94 | * 'cupsRasterOpen()' - Open a raster stream using a file descriptor. | |
95 | * | |
96 | * This function associates a raster stream with the given file descriptor. | |
97 | * For most printer driver filters, "fd" will be 0 (stdin). For most raster | |
98 | * image processor (RIP) filters that generate raster data, "fd" will be 1 | |
99 | * (stdout). | |
100 | * | |
101 | * When writing raster data, the @code CUPS_RASTER_WRITE@, | |
102 | * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can | |
103 | * be used - compressed and PWG output is generally 25-50% smaller but adds a | |
104 | * 100-300% execution time overhead. | |
105 | */ | |
106 | ||
107 | cups_raster_t * /* O - New stream */ | |
108 | cupsRasterOpen(int fd, /* I - File descriptor */ | |
109 | cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, | |
110 | @code CUPS_RASTER_WRITE@, | |
111 | @code CUPS_RASTER_WRITE_COMPRESSED@, | |
112 | or @code CUPS_RASTER_WRITE_PWG@ */ | |
113 | { | |
114 | if (mode == CUPS_RASTER_READ) | |
115 | return (_cupsRasterNew(cups_read_fd, (void *)((intptr_t)fd), mode)); | |
116 | else | |
117 | return (_cupsRasterNew(cups_write_fd, (void *)((intptr_t)fd), mode)); | |
118 | } | |
119 | ||
120 | ||
121 | /* | |
122 | * 'cupsRasterOpenIO()' - Open a raster stream using a callback function. | |
123 | * | |
124 | * This function associates a raster stream with the given callback function and | |
125 | * context pointer. | |
126 | * | |
127 | * When writing raster data, the @code CUPS_RASTER_WRITE@, | |
128 | * @code CUPS_RASTER_WRITE_COMPRESS@, or @code CUPS_RASTER_WRITE_PWG@ mode can | |
129 | * be used - compressed and PWG output is generally 25-50% smaller but adds a | |
130 | * 100-300% execution time overhead. | |
131 | */ | |
132 | ||
133 | cups_raster_t * /* O - New stream */ | |
134 | cupsRasterOpenIO( | |
135 | cups_raster_iocb_t iocb, /* I - Read/write callback */ | |
136 | void *ctx, /* I - Context pointer for callback */ | |
137 | cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, | |
138 | @code CUPS_RASTER_WRITE@, | |
139 | @code CUPS_RASTER_WRITE_COMPRESSED@, | |
140 | or @code CUPS_RASTER_WRITE_PWG@ */ | |
141 | { | |
142 | return (_cupsRasterNew(iocb, ctx, mode)); | |
143 | } | |
144 | ||
145 | ||
146 | /* | |
147 | * 'cupsRasterReadHeader()' - Read a raster page header and store it in a | |
148 | * version 1 page header structure. | |
149 | * | |
150 | * This function is deprecated. Use @link cupsRasterReadHeader2@ instead. | |
151 | * | |
152 | * Version 1 page headers were used in CUPS 1.0 and 1.1 and contain a subset | |
153 | * of the version 2 page header data. This function handles reading version 2 | |
154 | * page headers and copying only the version 1 data into the provided buffer. | |
155 | * | |
156 | * @deprecated@ | |
157 | */ | |
158 | ||
159 | unsigned /* O - 1 on success, 0 on failure/end-of-file */ | |
160 | cupsRasterReadHeader( | |
161 | cups_raster_t *r, /* I - Raster stream */ | |
162 | cups_page_header_t *h) /* I - Pointer to header data */ | |
163 | { | |
164 | DEBUG_printf(("cupsRasterReadHeader(r=%p, h=%p)", (void *)r, (void *)h)); | |
165 | ||
166 | /* | |
167 | * Get the raster header... | |
168 | */ | |
169 | ||
170 | if (!_cupsRasterReadHeader(r)) | |
171 | { | |
172 | memset(h, 0, sizeof(cups_page_header_t)); | |
173 | DEBUG_puts("1cupsRasterReadHeader: Unable to read page header, returning 0."); | |
174 | return (0); | |
175 | } | |
176 | ||
177 | /* | |
178 | * Copy the header to the user-supplied buffer... | |
179 | */ | |
180 | ||
181 | memcpy(h, &(r->header), sizeof(cups_page_header_t)); | |
182 | ||
183 | DEBUG_printf(("1cupsRasterReadHeader: cupsColorSpace=%s", _cupsRasterColorSpaceString(h->cupsColorSpace))); | |
184 | DEBUG_printf(("1cupsRasterReadHeader: cupsBitsPerColor=%u", h->cupsBitsPerColor)); | |
185 | DEBUG_printf(("1cupsRasterReadHeader: cupsBitsPerPixel=%u", h->cupsBitsPerPixel)); | |
186 | DEBUG_printf(("1cupsRasterReadHeader: cupsBytesPerLine=%u", h->cupsBytesPerLine)); | |
187 | DEBUG_printf(("1cupsRasterReadHeader: cupsWidth=%u", h->cupsWidth)); | |
188 | DEBUG_printf(("1cupsRasterReadHeader: cupsHeight=%u", h->cupsHeight)); | |
189 | ||
190 | DEBUG_puts("1cupsRasterReadHeader: Returning 1."); | |
191 | return (1); | |
192 | } | |
193 | ||
194 | ||
195 | /* | |
196 | * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a | |
197 | * version 2 page header structure. | |
198 | * | |
199 | * @since CUPS 1.2/macOS 10.5@ | |
200 | */ | |
201 | ||
202 | unsigned /* O - 1 on success, 0 on failure/end-of-file */ | |
203 | cupsRasterReadHeader2( | |
204 | cups_raster_t *r, /* I - Raster stream */ | |
205 | cups_page_header2_t *h) /* I - Pointer to header data */ | |
206 | { | |
207 | /* | |
208 | * Get the raster header... | |
209 | */ | |
210 | ||
211 | DEBUG_printf(("cupsRasterReadHeader2(r=%p, h=%p)", (void *)r, (void *)h)); | |
212 | ||
213 | if (!_cupsRasterReadHeader(r)) | |
214 | { | |
215 | memset(h, 0, sizeof(cups_page_header2_t)); | |
216 | DEBUG_puts("1cupsRasterReadHeader2: Unable to read header, returning 0."); | |
217 | return (0); | |
218 | } | |
219 | ||
220 | /* | |
221 | * Copy the header to the user-supplied buffer... | |
222 | */ | |
223 | ||
224 | memcpy(h, &(r->header), sizeof(cups_page_header2_t)); | |
225 | ||
226 | DEBUG_printf(("1cupsRasterReadHeader2: cupsColorSpace=%s", _cupsRasterColorSpaceString(h->cupsColorSpace))); | |
227 | DEBUG_printf(("1cupsRasterReadHeader2: cupsBitsPerColor=%u", h->cupsBitsPerColor)); | |
228 | DEBUG_printf(("1cupsRasterReadHeader2: cupsBitsPerPixel=%u", h->cupsBitsPerPixel)); | |
229 | DEBUG_printf(("1cupsRasterReadHeader2: cupsBytesPerLine=%u", h->cupsBytesPerLine)); | |
230 | DEBUG_printf(("1cupsRasterReadHeader2: cupsWidth=%u", h->cupsWidth)); | |
231 | DEBUG_printf(("1cupsRasterReadHeader2: cupsHeight=%u", h->cupsHeight)); | |
232 | ||
233 | DEBUG_puts("1cupsRasterReadHeader2: Returning 1."); | |
234 | return (1); | |
235 | } | |
236 | ||
237 | ||
238 | /* | |
239 | * 'cupsRasterReadPixels()' - Read raster pixels. | |
240 | * | |
241 | * For best performance, filters should read one or more whole lines. | |
242 | * The "cupsBytesPerLine" value from the page header can be used to allocate | |
243 | * the line buffer and as the number of bytes to read. | |
244 | */ | |
245 | ||
246 | unsigned /* O - Number of bytes read */ | |
247 | cupsRasterReadPixels( | |
248 | cups_raster_t *r, /* I - Raster stream */ | |
249 | unsigned char *p, /* I - Pointer to pixel buffer */ | |
250 | unsigned len) /* I - Number of bytes to read */ | |
251 | { | |
252 | return (_cupsRasterReadPixels(r, p, len)); | |
253 | } | |
254 | ||
255 | ||
256 | /* | |
257 | * 'cupsRasterWriteHeader()' - Write a raster page header from a version 1 page | |
258 | * header structure. | |
259 | * | |
260 | * This function is deprecated. Use @link cupsRasterWriteHeader2@ instead. | |
261 | * | |
262 | * @deprecated@ | |
263 | */ | |
264 | ||
265 | unsigned /* O - 1 on success, 0 on failure */ | |
266 | cupsRasterWriteHeader( | |
267 | cups_raster_t *r, /* I - Raster stream */ | |
268 | cups_page_header_t *h) /* I - Raster page header */ | |
269 | { | |
270 | DEBUG_printf(("cupsRasterWriteHeader(r=%p, h=%p)", (void *)r, (void *)h)); | |
271 | ||
272 | if (r == NULL || r->mode == CUPS_RASTER_READ) | |
273 | { | |
274 | DEBUG_puts("1cupsRasterWriteHeader: Stream NULL or open for reading, returning 0."); | |
275 | return (0); | |
276 | } | |
277 | ||
278 | /* | |
279 | * Make a copy of the header and write using the private function... | |
280 | */ | |
281 | ||
282 | memset(&(r->header), 0, sizeof(r->header)); | |
283 | memcpy(&(r->header), h, sizeof(cups_page_header_t)); | |
284 | ||
285 | return (_cupsRasterWriteHeader(r)); | |
286 | } | |
287 | ||
288 | ||
289 | /* | |
290 | * 'cupsRasterWriteHeader2()' - Write a raster page header from a version 2 | |
291 | * page header structure. | |
292 | * | |
293 | * The page header can be initialized using @link cupsRasterInitPWGHeader@. | |
294 | * | |
295 | * @since CUPS 1.2/macOS 10.5@ | |
296 | */ | |
297 | ||
298 | unsigned /* O - 1 on success, 0 on failure */ | |
299 | cupsRasterWriteHeader2( | |
300 | cups_raster_t *r, /* I - Raster stream */ | |
301 | cups_page_header2_t *h) /* I - Raster page header */ | |
302 | { | |
303 | DEBUG_printf(("cupsRasterWriteHeader(r=%p, h=%p)", (void *)r, (void *)h)); | |
304 | ||
305 | if (r == NULL || r->mode == CUPS_RASTER_READ) | |
306 | { | |
307 | DEBUG_puts("1cupsRasterWriteHeader2: Stream NULL or open for reading, returning 0."); | |
308 | return (0); | |
309 | } | |
310 | ||
311 | /* | |
312 | * Make a copy of the header, and compute the number of raster | |
313 | * lines in the page image... | |
314 | */ | |
315 | ||
316 | memcpy(&(r->header), h, sizeof(cups_page_header2_t)); | |
317 | ||
318 | return (_cupsRasterWriteHeader(r)); | |
319 | } | |
320 | ||
321 | ||
322 | /* | |
323 | * 'cupsRasterWritePixels()' - Write raster pixels. | |
324 | * | |
325 | * For best performance, filters should write one or more whole lines. | |
326 | * The "cupsBytesPerLine" value from the page header can be used to allocate | |
327 | * the line buffer and as the number of bytes to write. | |
328 | */ | |
329 | ||
330 | unsigned /* O - Number of bytes written */ | |
331 | cupsRasterWritePixels( | |
332 | cups_raster_t *r, /* I - Raster stream */ | |
333 | unsigned char *p, /* I - Bytes to write */ | |
334 | unsigned len) /* I - Number of bytes to write */ | |
335 | { | |
336 | return (_cupsRasterWritePixels(r, p, len)); | |
337 | } | |
338 | ||
339 | ||
340 | /* | |
341 | * 'cups_read_fd()' - Read bytes from a file. | |
342 | */ | |
343 | ||
344 | static ssize_t /* O - Bytes read or -1 */ | |
345 | cups_read_fd(void *ctx, /* I - File descriptor as pointer */ | |
346 | unsigned char *buf, /* I - Buffer for read */ | |
347 | size_t bytes) /* I - Maximum number of bytes to read */ | |
348 | { | |
349 | int fd = (int)((intptr_t)ctx); | |
350 | /* File descriptor */ | |
351 | ssize_t count; /* Number of bytes read */ | |
352 | ||
353 | ||
354 | #ifdef _WIN32 /* Sigh */ | |
355 | while ((count = read(fd, buf, (unsigned)bytes)) < 0) | |
356 | #else | |
357 | while ((count = read(fd, buf, bytes)) < 0) | |
358 | #endif /* _WIN32 */ | |
359 | if (errno != EINTR && errno != EAGAIN) | |
360 | { | |
361 | DEBUG_printf(("8cups_read_fd: %s", strerror(errno))); | |
362 | return (-1); | |
363 | } | |
364 | ||
365 | DEBUG_printf(("8cups_read_fd: Returning %d bytes.", (int)count)); | |
366 | ||
367 | return (count); | |
368 | } | |
369 | ||
370 | ||
371 | /* | |
372 | * 'cups_write_fd()' - Write bytes to a file. | |
373 | */ | |
374 | ||
375 | static ssize_t /* O - Bytes written or -1 */ | |
376 | cups_write_fd(void *ctx, /* I - File descriptor pointer */ | |
377 | unsigned char *buf, /* I - Bytes to write */ | |
378 | size_t bytes) /* I - Number of bytes to write */ | |
379 | { | |
380 | int fd = (int)((intptr_t)ctx); | |
381 | /* File descriptor */ | |
382 | ssize_t count; /* Number of bytes written */ | |
383 | ||
384 | ||
385 | #ifdef _WIN32 /* Sigh */ | |
386 | while ((count = write(fd, buf, (unsigned)bytes)) < 0) | |
387 | #else | |
388 | while ((count = write(fd, buf, bytes)) < 0) | |
389 | #endif /* _WIN32 */ | |
390 | if (errno != EINTR && errno != EAGAIN) | |
391 | { | |
392 | DEBUG_printf(("8cups_write_fd: %s", strerror(errno))); | |
393 | return (-1); | |
394 | } | |
395 | ||
396 | return (count); | |
397 | } |