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