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 "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
cupsRasterClose(cups_raster_t * r)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` */
cupsRasterErrorString(void)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 */
cupsRasterInitPWGHeader(cups_page_header2_t * h,pwg_media_t * media,const char * type,int xdpi,int ydpi,const char * sides,const char * sheet_back)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 */
cupsRasterOpen(int fd,cups_mode_t mode)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 */
cupsRasterOpenIO(cups_raster_iocb_t iocb,void * ctx,cups_mode_t mode)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 */
cupsRasterReadHeader(cups_raster_t * r,cups_page_header_t * h)160 cupsRasterReadHeader(
161 cups_raster_t *r, /* I - Raster stream */
162 cups_page_header_t *h) /* I - Pointer to header data */
163 {
164 /*
165 * Get the raster header...
166 */
167
168 if (!_cupsRasterReadHeader(r))
169 {
170 memset(h, 0, sizeof(cups_page_header_t));
171 return (0);
172 }
173
174 /*
175 * Copy the header to the user-supplied buffer...
176 */
177
178 memcpy(h, &(r->header), sizeof(cups_page_header_t));
179 return (1);
180 }
181
182
183 /*
184 * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a
185 * version 2 page header structure.
186 *
187 * @since CUPS 1.2/macOS 10.5@
188 */
189
190 unsigned /* O - 1 on success, 0 on failure/end-of-file */
cupsRasterReadHeader2(cups_raster_t * r,cups_page_header2_t * h)191 cupsRasterReadHeader2(
192 cups_raster_t *r, /* I - Raster stream */
193 cups_page_header2_t *h) /* I - Pointer to header data */
194 {
195 /*
196 * Get the raster header...
197 */
198
199 if (!_cupsRasterReadHeader(r))
200 {
201 memset(h, 0, sizeof(cups_page_header2_t));
202 return (0);
203 }
204
205 /*
206 * Copy the header to the user-supplied buffer...
207 */
208
209 memcpy(h, &(r->header), sizeof(cups_page_header2_t));
210 return (1);
211 }
212
213
214 /*
215 * 'cupsRasterReadPixels()' - Read raster pixels.
216 *
217 * For best performance, filters should read one or more whole lines.
218 * The "cupsBytesPerLine" value from the page header can be used to allocate
219 * the line buffer and as the number of bytes to read.
220 */
221
222 unsigned /* O - Number of bytes read */
cupsRasterReadPixels(cups_raster_t * r,unsigned char * p,unsigned len)223 cupsRasterReadPixels(
224 cups_raster_t *r, /* I - Raster stream */
225 unsigned char *p, /* I - Pointer to pixel buffer */
226 unsigned len) /* I - Number of bytes to read */
227 {
228 return (_cupsRasterReadPixels(r, p, len));
229 }
230
231
232 /*
233 * 'cupsRasterWriteHeader()' - Write a raster page header from a version 1 page
234 * header structure.
235 *
236 * This function is deprecated. Use @link cupsRasterWriteHeader2@ instead.
237 *
238 * @deprecated@
239 */
240
241 unsigned /* O - 1 on success, 0 on failure */
cupsRasterWriteHeader(cups_raster_t * r,cups_page_header_t * h)242 cupsRasterWriteHeader(
243 cups_raster_t *r, /* I - Raster stream */
244 cups_page_header_t *h) /* I - Raster page header */
245 {
246 if (r == NULL || r->mode == CUPS_RASTER_READ)
247 return (0);
248
249 /*
250 * Make a copy of the header and write using the private function...
251 */
252
253 memset(&(r->header), 0, sizeof(r->header));
254 memcpy(&(r->header), h, sizeof(cups_page_header_t));
255
256 return (_cupsRasterWriteHeader(r));
257 }
258
259
260 /*
261 * 'cupsRasterWriteHeader2()' - Write a raster page header from a version 2
262 * page header structure.
263 *
264 * The page header can be initialized using @link cupsRasterInitPWGHeader@.
265 *
266 * @since CUPS 1.2/macOS 10.5@
267 */
268
269 unsigned /* O - 1 on success, 0 on failure */
cupsRasterWriteHeader2(cups_raster_t * r,cups_page_header2_t * h)270 cupsRasterWriteHeader2(
271 cups_raster_t *r, /* I - Raster stream */
272 cups_page_header2_t *h) /* I - Raster page header */
273 {
274 if (r == NULL || r->mode == CUPS_RASTER_READ)
275 return (0);
276
277 /*
278 * Make a copy of the header, and compute the number of raster
279 * lines in the page image...
280 */
281
282 memcpy(&(r->header), h, sizeof(cups_page_header2_t));
283
284 return (_cupsRasterWriteHeader(r));
285 }
286
287
288 /*
289 * 'cupsRasterWritePixels()' - Write raster pixels.
290 *
291 * For best performance, filters should write one or more whole lines.
292 * The "cupsBytesPerLine" value from the page header can be used to allocate
293 * the line buffer and as the number of bytes to write.
294 */
295
296 unsigned /* O - Number of bytes written */
cupsRasterWritePixels(cups_raster_t * r,unsigned char * p,unsigned len)297 cupsRasterWritePixels(
298 cups_raster_t *r, /* I - Raster stream */
299 unsigned char *p, /* I - Bytes to write */
300 unsigned len) /* I - Number of bytes to write */
301 {
302 return (_cupsRasterWritePixels(r, p, len));
303 }
304
305
306 /*
307 * 'cups_read_fd()' - Read bytes from a file.
308 */
309
310 static ssize_t /* O - Bytes read or -1 */
cups_read_fd(void * ctx,unsigned char * buf,size_t bytes)311 cups_read_fd(void *ctx, /* I - File descriptor as pointer */
312 unsigned char *buf, /* I - Buffer for read */
313 size_t bytes) /* I - Maximum number of bytes to read */
314 {
315 int fd = (int)((intptr_t)ctx);
316 /* File descriptor */
317 ssize_t count; /* Number of bytes read */
318
319
320 #ifdef _WIN32 /* Sigh */
321 while ((count = read(fd, buf, (unsigned)bytes)) < 0)
322 #else
323 while ((count = read(fd, buf, bytes)) < 0)
324 #endif /* _WIN32 */
325 if (errno != EINTR && errno != EAGAIN)
326 return (-1);
327
328 return (count);
329 }
330
331
332 /*
333 * 'cups_write_fd()' - Write bytes to a file.
334 */
335
336 static ssize_t /* O - Bytes written or -1 */
cups_write_fd(void * ctx,unsigned char * buf,size_t bytes)337 cups_write_fd(void *ctx, /* I - File descriptor pointer */
338 unsigned char *buf, /* I - Bytes to write */
339 size_t bytes) /* I - Number of bytes to write */
340 {
341 int fd = (int)((intptr_t)ctx);
342 /* File descriptor */
343 ssize_t count; /* Number of bytes written */
344
345
346 #ifdef _WIN32 /* Sigh */
347 while ((count = write(fd, buf, (unsigned)bytes)) < 0)
348 #else
349 while ((count = write(fd, buf, bytes)) < 0)
350 #endif /* _WIN32 */
351 if (errno != EINTR && errno != EAGAIN)
352 return (-1);
353
354 return (count);
355 }
356