]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/raster.c
Load cups into easysw/current.
[thirdparty/cups.git] / filter / raster.c
1 /*
2 * "$Id: raster.c 5523 2006-05-15 05:02:43Z mike $"
3 *
4 * Raster file routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2006 by Easy Software Products.
7 *
8 * This file is part of the CUPS Imaging library.
9 *
10 * These coded instructions, statements, and computer programs are the
11 * property of Easy Software Products and are protected by Federal
12 * copyright law. Distribution and use rights are outlined in the file
13 * "LICENSE.txt" which should have been included with this file. If this
14 * file is missing or damaged please contact Easy Software Products
15 * at:
16 *
17 * Attn: CUPS Licensing Information
18 * Easy Software Products
19 * 44141 Airport View Drive, Suite 204
20 * Hollywood, Maryland 20636 USA
21 *
22 * Voice: (301) 373-9600
23 * EMail: cups-info@cups.org
24 * WWW: http://www.cups.org
25 *
26 * This code and any derivative of it may be used and distributed
27 * freely under the terms of the GNU General Public License when
28 * used with GNU/GPL Ghostscript or its derivatives. Use of the
29 * code (or any derivative of it) with software other than GNU/GPL
30 * GhostScript (or its derivatives) is governed by the CUPS license
31 * agreement.
32 *
33 * This file is subject to the Apple OS-Developed Software exception.
34 *
35 * Contents:
36 *
37 * cupsRasterClose() - Close a raster stream.
38 * cupsRasterOpen() - Open a raster stream.
39 * cupsRasterReadHeader() - Read a raster page header and store it in a
40 * V1 page header structure.
41 * cupsRasterReadHeader2() - Read a raster page header and store it in a
42 * V2 page header structure.
43 * cupsRasterReadPixels() - Read raster pixels.
44 * cupsRasterWriteHeader() - Write a raster page header from a V1 page
45 * header structure.
46 * cupsRasterWriteHeader2() - Write a raster page header from a V2 page
47 * header structure.
48 * cupsRasterWritePixels() - Write raster pixels.
49 * cups_raster_update() - Update the raster header and row count for the
50 * current page.
51 * cups_raster_write() - Write a row of raster data...
52 * cups_read() - Read bytes from a file.
53 * cups_write() - Write bytes to a file.
54 */
55
56 /*
57 * Include necessary headers...
58 */
59
60 #include "raster.h"
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <errno.h>
64 #include <cups/string.h>
65
66 #if defined(WIN32) || defined(__EMX__)
67 # include <io.h>
68 #else
69 # include <unistd.h>
70 #endif /* WIN32 || __EMX__ */
71
72
73 /*
74 * Private structures...
75 */
76
77 struct _cups_raster_s /**** Raster stream data ****/
78 {
79 unsigned sync; /* Sync word from start of stream */
80 int fd; /* File descriptor */
81 cups_mode_t mode; /* Read/write mode */
82 cups_page_header2_t header; /* Raster header for current page */
83 int count, /* Current row run-length count */
84 remaining, /* Remaining rows in page image */
85 bpp; /* Bytes per pixel/color */
86 unsigned char *pixels, /* Pixels for current row */
87 *pend, /* End of pixel buffer */
88 *pcurrent; /* Current byte in pixel buffer */
89 };
90
91 /*
92 * Local functions...
93 */
94
95 static unsigned cups_raster_read_header(cups_raster_t *r);
96 static void cups_raster_update(cups_raster_t *r);
97 static int cups_raster_write(cups_raster_t *r);
98 static int cups_read(int fd, unsigned char *buf, int bytes);
99 static int cups_write(int fd, const unsigned char *buf, int bytes);
100
101
102 /*
103 * 'cupsRasterClose()' - Close a raster stream.
104 */
105
106 void
107 cupsRasterClose(cups_raster_t *r) /* I - Stream to close */
108 {
109 if (r != NULL)
110 {
111 if (r->pixels)
112 free(r->pixels);
113
114 free(r);
115 }
116 }
117
118
119 /*
120 * 'cupsRasterOpen()' - Open a raster stream.
121 */
122
123 cups_raster_t * /* O - New stream */
124 cupsRasterOpen(int fd, /* I - File descriptor */
125 cups_mode_t mode) /* I - Mode */
126 {
127 cups_raster_t *r; /* New stream */
128
129
130 if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL)
131 return (NULL);
132
133 r->fd = fd;
134 r->mode = mode;
135
136 if (mode == CUPS_RASTER_READ)
137 {
138 /*
139 * Open for read - get sync word...
140 */
141
142 if (cups_read(r->fd, (unsigned char *)&(r->sync), sizeof(r->sync))
143 < sizeof(r->sync))
144 {
145 free(r);
146 return (NULL);
147 }
148
149 if (r->sync != CUPS_RASTER_SYNC &&
150 r->sync != CUPS_RASTER_REVSYNC &&
151 r->sync != CUPS_RASTER_SYNCv1 &&
152 r->sync != CUPS_RASTER_REVSYNCv1)
153 {
154 free(r);
155 return (NULL);
156 }
157 }
158 else
159 {
160 /*
161 * Open for write - put sync word...
162 */
163
164 r->sync = CUPS_RASTER_SYNC;
165 if (cups_write(r->fd, (unsigned char *)&(r->sync), sizeof(r->sync))
166 < sizeof(r->sync))
167 {
168 free(r);
169 return (NULL);
170 }
171 }
172
173 return (r);
174 }
175
176
177 /*
178 * 'cupsRasterReadHeader()' - Read a raster page header and store it in a
179 * V1 page header structure.
180 */
181
182 unsigned /* O - 1 on success, 0 on fail */
183 cupsRasterReadHeader(
184 cups_raster_t *r, /* I - Raster stream */
185 cups_page_header_t *h) /* I - Pointer to header data */
186 {
187 /*
188 * Get the raster header...
189 */
190
191 if (!cups_raster_read_header(r))
192 return (0);
193
194 /*
195 * Copy the header to the user-supplied buffer...
196 */
197
198 memcpy(h, &(r->header), sizeof(cups_page_header_t));
199
200 return (1);
201 }
202
203
204 /*
205 * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a
206 * V2 page header structure.
207 *
208 * @since CUPS 1.2@
209 */
210
211 unsigned /* O - 1 on success, 0 on fail */
212 cupsRasterReadHeader2(
213 cups_raster_t *r, /* I - Raster stream */
214 cups_page_header2_t *h) /* I - Pointer to header data */
215 {
216 /*
217 * Get the raster header...
218 */
219
220 if (!cups_raster_read_header(r))
221 return (0);
222
223 /*
224 * Copy the header to the user-supplied buffer...
225 */
226
227 memcpy(h, &(r->header), sizeof(cups_page_header2_t));
228
229 return (1);
230 }
231
232
233 /*
234 * 'cupsRasterReadPixels()' - Read raster pixels.
235 */
236
237 unsigned /* O - Number of bytes read */
238 cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */
239 unsigned char *p, /* I - Pointer to pixel buffer */
240 unsigned len) /* I - Number of bytes to read */
241 {
242 int bytes; /* Bytes read */
243 unsigned remaining; /* Bytes remaining */
244 unsigned char *ptr, /* Pointer to read buffer */
245 byte; /* Byte from file */
246
247
248 if (r == NULL || r->mode != CUPS_RASTER_READ || r->remaining == 0)
249 return (0);
250
251 remaining = len;
252
253 while (remaining > 0 && r->remaining > 0)
254 {
255 if (r->count == 0)
256 {
257 /*
258 * Need to read a new row...
259 */
260
261 if (remaining == r->header.cupsBytesPerLine)
262 ptr = p;
263 else
264 ptr = r->pixels;
265
266 if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1)
267 {
268 /*
269 * Read without compression...
270 */
271
272 if (cups_read(r->fd, ptr, r->header.cupsBytesPerLine) <
273 r->header.cupsBytesPerLine)
274 return (0);
275
276 r->count = 1;
277 }
278 else
279 {
280 /*
281 * Read using a modified TIFF "packbits" compression...
282 */
283
284 unsigned char *temp; /* Pointer into buffer */
285 int count; /* Repetition count */
286
287
288 if (cups_read(r->fd, &byte, 1) < 1)
289 return (0);
290
291 r->count = byte + 1;
292
293 if (r->count > 1)
294 ptr = r->pixels;
295
296 temp = ptr;
297 bytes = r->header.cupsBytesPerLine;
298
299 while (bytes > 0)
300 {
301 /*
302 * Get a new repeat count...
303 */
304
305 if (cups_read(r->fd, &byte, 1) < 1)
306 return (0);
307
308 if (byte & 128)
309 {
310 /*
311 * Copy N literal pixels...
312 */
313
314 count = (257 - byte) * r->bpp;
315
316 if (count > bytes)
317 count = bytes;
318
319 if (cups_read(r->fd, temp, count) < count)
320 return (0);
321
322 temp += count;
323 bytes -= count;
324 }
325 else
326 {
327 /*
328 * Repeat the next N bytes...
329 */
330
331 count = (byte + 1) * r->bpp;
332 if (count > bytes)
333 count = bytes;
334
335 if (count < r->bpp)
336 break;
337
338 bytes -= count;
339
340 if (cups_read(r->fd, temp, r->bpp) < r->bpp)
341 return (0);
342
343 temp += r->bpp;
344 count -= r->bpp;
345
346 while (count > 0)
347 {
348 memcpy(temp, temp - r->bpp, r->bpp);
349 temp += r->bpp;
350 count -= r->bpp;
351 }
352 }
353 }
354 }
355
356 if ((r->header.cupsBitsPerColor == 16 ||
357 r->header.cupsBitsPerPixel == 12 ||
358 r->header.cupsBitsPerPixel == 16) &&
359 (r->sync == CUPS_RASTER_REVSYNC || r->sync == CUPS_RASTER_REVSYNCv1))
360 {
361 /*
362 * Swap bytes in the pixel data...
363 */
364
365 unsigned char *temp;
366 int count;
367
368
369 for (temp = ptr, count = r->header.cupsBytesPerLine;
370 count > 0;
371 temp += 2, count -= 2)
372 {
373 byte = temp[0];
374 temp[0] = temp[1];
375 temp[1] = byte;
376 }
377 }
378
379 if (remaining >= r->header.cupsBytesPerLine)
380 {
381 bytes = r->header.cupsBytesPerLine;
382 r->pcurrent = r->pixels;
383 r->count --;
384 r->remaining --;
385 }
386 else
387 {
388 bytes = remaining;
389 r->pcurrent = r->pixels + bytes;
390 }
391
392 if (ptr != p)
393 memcpy(p, ptr, bytes);
394 }
395 else
396 {
397 /*
398 * Copy fragment from buffer...
399 */
400
401 if ((bytes = r->pend - r->pcurrent) > remaining)
402 bytes = remaining;
403
404 memcpy(p, r->pcurrent, bytes);
405 r->pcurrent += bytes;
406
407 if (r->pcurrent >= r->pend)
408 {
409 r->pcurrent = r->pixels;
410 r->count --;
411 r->remaining --;
412 }
413 }
414
415 remaining -= bytes;
416 p += bytes;
417 }
418
419 return (len);
420 }
421
422
423 /*
424 * 'cupsRasterWriteHeader()' - Write a raster page header from a V1 page
425 * header structure.
426 */
427
428 unsigned /* O - 1 on success, 0 on failure */
429 cupsRasterWriteHeader(
430 cups_raster_t *r, /* I - Raster stream */
431 cups_page_header_t *h) /* I - Raster page header */
432 {
433 if (r == NULL || r->mode != CUPS_RASTER_WRITE)
434 return (0);
435
436 /*
437 * Make a copy of the header, and compute the number of raster
438 * lines in the page image...
439 */
440
441 memset(&(r->header), 0, sizeof(r->header));
442 memcpy(&(r->header), h, sizeof(cups_page_header_t));
443
444 cups_raster_update(r);
445
446 /*
447 * Write the raster header...
448 */
449
450 return (cups_write(r->fd, (unsigned char *)&(r->header), sizeof(r->header))
451 > 0);
452 }
453
454
455 /*
456 * 'cupsRasterWriteHeader2()' - Write a raster page header from a V2 page
457 * header structure.
458 *
459 * @since CUPS 1.2@
460 */
461
462 unsigned /* O - 1 on success, 0 on failure */
463 cupsRasterWriteHeader2(
464 cups_raster_t *r, /* I - Raster stream */
465 cups_page_header2_t *h) /* I - Raster page header */
466 {
467 if (r == NULL || r->mode != CUPS_RASTER_WRITE)
468 return (0);
469
470 /*
471 * Make a copy of the header, and compute the number of raster
472 * lines in the page image...
473 */
474
475 memcpy(&(r->header), h, sizeof(cups_page_header2_t));
476
477 cups_raster_update(r);
478
479 /*
480 * Write the raster header...
481 */
482
483 return (cups_write(r->fd, (unsigned char *)&(r->header), sizeof(r->header))
484 > 0);
485 }
486
487
488 /*
489 * 'cupsRasterWritePixels()' - Write raster pixels.
490 */
491
492 unsigned /* O - Number of bytes written */
493 cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */
494 unsigned char *p, /* I - Bytes to write */
495 unsigned len)/* I - Number of bytes to write */
496 {
497 int bytes; /* Bytes read */
498 unsigned remaining; /* Bytes remaining */
499
500
501 #ifdef DEBUG
502 fprintf(stderr, "cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u\n",
503 r, p, len, r->remaining);
504 #endif /* DEBUG */
505
506 if (r == NULL || r->mode != CUPS_RASTER_WRITE || r->remaining == 0)
507 return (0);
508
509 for (remaining = len; remaining > 0; remaining -= bytes, p += bytes)
510
511 {
512 /*
513 * Figure out the number of remaining bytes on the current line...
514 */
515
516 if ((bytes = remaining) > (r->pend - r->pcurrent))
517 bytes = r->pend - r->pcurrent;
518
519 if (r->count > 0)
520 {
521 /*
522 * Check to see if this line is the same as the previous line...
523 */
524
525 if (memcmp(p, r->pcurrent, bytes))
526 {
527 if (!cups_raster_write(r))
528 return (0);
529
530 r->count = 0;
531 }
532 else
533 {
534 /*
535 * Mark more bytes as the same...
536 */
537
538 r->pcurrent += bytes;
539
540 if (r->pcurrent >= r->pend)
541 {
542 /*
543 * Increase the repeat count...
544 */
545
546 r->count ++;
547 r->pcurrent = r->pixels;
548
549 /*
550 * Flush out this line if it is the last one...
551 */
552
553 r->remaining --;
554
555 if (r->remaining == 0)
556 return (cups_raster_write(r));
557 else if (r->count == 256)
558 {
559 if (cups_raster_write(r) == 0)
560 return (0);
561
562 r->count = 0;
563 }
564 }
565
566 continue;
567 }
568 }
569
570 if (r->count == 0)
571 {
572 /*
573 * Copy the raster data to the buffer...
574 */
575
576 memcpy(r->pcurrent, p, bytes);
577
578 r->pcurrent += bytes;
579
580 if (r->pcurrent >= r->pend)
581 {
582 /*
583 * Increase the repeat count...
584 */
585
586 r->count ++;
587 r->pcurrent = r->pixels;
588
589 /*
590 * Flush out this line if it is the last one...
591 */
592
593 r->remaining --;
594
595 if (r->remaining == 0)
596 return (cups_raster_write(r));
597 }
598 }
599 }
600
601 return (len);
602 }
603
604
605 /*
606 * 'cups_raster_read_header()' - Read a raster page header.
607 */
608
609 static unsigned /* O - 1 on success, 0 on fail */
610 cups_raster_read_header(
611 cups_raster_t *r) /* I - Raster stream */
612 {
613 int len; /* Number of words to swap */
614 union swap_s /* Swapping structure */
615 {
616 unsigned char b[4];
617 unsigned v;
618 } *s;
619
620
621 if (r == NULL || r->mode != CUPS_RASTER_READ)
622 return (0);
623
624 /*
625 * Get the length of the raster header...
626 */
627
628 if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1)
629 len = sizeof(cups_page_header_t);
630 else
631 len = sizeof(cups_page_header2_t);
632
633 /*
634 * Read the header...
635 */
636
637 memset(&(r->header), 0, sizeof(r->header));
638
639 if (cups_read(r->fd, (unsigned char *)&(r->header), len) < len)
640 return (0);
641
642 /*
643 * Swap bytes as needed...
644 */
645
646 if (r->sync == CUPS_RASTER_REVSYNC || r->sync == CUPS_RASTER_REVSYNCv1)
647 for (len = 81, s = (union swap_s *)&(r->header.AdvanceDistance);
648 len > 0;
649 len --, s ++)
650 s->v = (((((s->b[3] << 8) | s->b[2]) << 8) | s->b[1]) << 8) | s->b[0];
651
652 /*
653 * Update the header and row count...
654 */
655
656 cups_raster_update(r);
657
658 return (1);
659 }
660
661
662 /*
663 * 'cups_raster_update()' - Update the raster header and row count for the
664 * current page.
665 */
666
667 static void
668 cups_raster_update(cups_raster_t *r) /* I - Raster stream */
669 {
670 if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1 ||
671 r->header.cupsNumColors == 0)
672 {
673 /*
674 * Set the "cupsNumColors" field according to the colorspace...
675 */
676
677 switch (r->header.cupsColorSpace)
678 {
679 case CUPS_CSPACE_W :
680 case CUPS_CSPACE_K :
681 case CUPS_CSPACE_WHITE :
682 case CUPS_CSPACE_GOLD :
683 case CUPS_CSPACE_SILVER :
684 r->header.cupsNumColors = 1;
685 break;
686
687 case CUPS_CSPACE_RGB :
688 case CUPS_CSPACE_CMY :
689 case CUPS_CSPACE_YMC :
690 case CUPS_CSPACE_CIEXYZ :
691 case CUPS_CSPACE_CIELab :
692 case CUPS_CSPACE_ICC1 :
693 case CUPS_CSPACE_ICC2 :
694 case CUPS_CSPACE_ICC3 :
695 case CUPS_CSPACE_ICC4 :
696 case CUPS_CSPACE_ICC5 :
697 case CUPS_CSPACE_ICC6 :
698 case CUPS_CSPACE_ICC7 :
699 case CUPS_CSPACE_ICC8 :
700 case CUPS_CSPACE_ICC9 :
701 case CUPS_CSPACE_ICCA :
702 case CUPS_CSPACE_ICCB :
703 case CUPS_CSPACE_ICCC :
704 case CUPS_CSPACE_ICCD :
705 case CUPS_CSPACE_ICCE :
706 case CUPS_CSPACE_ICCF :
707 r->header.cupsNumColors = 3;
708 break;
709
710 case CUPS_CSPACE_RGBA :
711 case CUPS_CSPACE_RGBW :
712 case CUPS_CSPACE_CMYK :
713 case CUPS_CSPACE_YMCK :
714 case CUPS_CSPACE_KCMY :
715 case CUPS_CSPACE_GMCK :
716 case CUPS_CSPACE_GMCS :
717 r->header.cupsNumColors = 4;
718 break;
719
720 case CUPS_CSPACE_KCMYcm :
721 if (r->header.cupsBitsPerPixel < 8)
722 r->header.cupsNumColors = 6;
723 else
724 r->header.cupsNumColors = 4;
725 break;
726 }
727 }
728
729 /*
730 * Set the number of bytes per pixel/color...
731 */
732
733 if (r->header.cupsColorOrder == CUPS_ORDER_CHUNKED)
734 r->bpp = (r->header.cupsBitsPerPixel + 7) / 8;
735 else
736 r->bpp = (r->header.cupsBitsPerColor + 7) / 8;
737
738 /*
739 * Set the number of remaining rows...
740 */
741
742 if (r->header.cupsColorOrder == CUPS_ORDER_PLANAR)
743 r->remaining = r->header.cupsHeight * r->header.cupsNumColors;
744 else
745 r->remaining = r->header.cupsHeight;
746
747 /*
748 * Allocate the read/write buffer...
749 */
750
751 if (r->pixels != NULL)
752 free(r->pixels);
753
754 r->pixels = calloc(r->header.cupsBytesPerLine, 1);
755 r->pcurrent = r->pixels;
756 r->pend = r->pixels + r->header.cupsBytesPerLine;
757 r->count = 0;
758 }
759
760
761 /*
762 * 'cups_raster_write()' - Write a row of raster data...
763 */
764
765 static int /* O - Number of bytes written */
766 cups_raster_write(cups_raster_t *r) /* I - Raster stream */
767 {
768 unsigned char *start, /* Start of sequence */
769 *ptr, /* Current pointer in sequence */
770 byte; /* Byte to write */
771 int count; /* Count */
772
773
774 #ifdef DEBUG
775 fprintf(stderr, "cups_raster_write(r=%p)\n", r);
776 #endif /* DEBUG */
777
778 /*
779 * Write the row repeat count...
780 */
781
782 byte = r->count - 1;
783
784 if (cups_write(r->fd, &byte, 1) < 1)
785 {
786 #ifdef DEBUG
787 fputs("cups_raster_write: Unable to write row repeat count...\n",
788 stderr);
789 #endif /* DEBUG */
790
791 return (0);
792 }
793
794 /*
795 * Write using a modified TIFF "packbits" compression...
796 */
797
798 for (ptr = r->pixels; ptr < r->pend;)
799 {
800 start = ptr;
801 ptr += r->bpp;
802
803 if (ptr == r->pend)
804 {
805 /*
806 * Encode a single pixel at the end...
807 */
808
809 byte = 0;
810 if (cups_write(r->fd, &byte, 1) < 1)
811 {
812 #ifdef DEBUG
813 fputs("cups_raster_write: Unable to write last pixel count...\n", stderr);
814 #endif /* DEBUG */
815
816 return (0);
817 }
818
819 if (cups_write(r->fd, start, r->bpp) < r->bpp)
820 {
821 #ifdef DEBUG
822 fputs("cups_raster_write: Unable to write last pixel data...\n", stderr);
823 #endif /* DEBUG */
824
825 return (0);
826 }
827 }
828 else if (!memcmp(start, ptr, r->bpp))
829 {
830 /*
831 * Encode a sequence of repeating pixels...
832 */
833
834 for (count = 2; count < 128 && ptr < (r->pend - r->bpp); count ++, ptr += r->bpp)
835 if (memcmp(ptr, ptr + r->bpp, r->bpp) != 0)
836 break;
837
838 ptr += r->bpp;
839
840 byte = count - 1;
841
842 if (cups_write(r->fd, &byte, 1) < 1)
843 {
844 #ifdef DEBUG
845 fputs("cups_raster_write: Unable to write repeated pixel count...\n", stderr);
846 #endif /* DEBUG */
847
848 return (0);
849 }
850
851 if (cups_write(r->fd, start, r->bpp) < r->bpp)
852 {
853 #ifdef DEBUG
854 fputs("cups_raster_write: Unable to write repeated pixel data...\n", stderr);
855 #endif /* DEBUG */
856
857 return (0);
858 }
859 }
860 else
861 {
862 /*
863 * Encode a sequence of non-repeating pixels...
864 */
865
866 for (count = 1; count < 127 && ptr < (r->pend - r->bpp); count ++, ptr += r->bpp)
867 if (!memcmp(ptr, ptr + r->bpp, r->bpp))
868 break;
869
870 if (ptr >= (r->pend - r->bpp) && count < 128)
871 {
872 count ++;
873 ptr += r->bpp;
874 }
875
876 byte = 257 - count;
877
878 if (cups_write(r->fd, &byte, 1) < 1)
879 {
880 #ifdef DEBUG
881 fputs("cups_raster_write: Unable to write non-repeating pixel count...\n", stderr);
882 #endif /* DEBUG */
883
884 return (0);
885 }
886
887 count *= r->bpp;
888
889 if (cups_write(r->fd, start, count) < count)
890 {
891 #ifdef DEBUG
892 fputs("cups_raster_write: Unable to write non-repeating pixel data...\n", stderr);
893 #endif /* DEBUG */
894
895 return (0);
896 }
897 }
898 }
899
900 return (r->header.cupsBytesPerLine);
901 }
902
903
904 /*
905 * 'cups_read()' - Read bytes from a file.
906 */
907
908 static int /* O - Bytes read or -1 */
909 cups_read(int fd, /* I - File descriptor */
910 unsigned char *buf, /* I - Buffer for read */
911 int bytes) /* I - Number of bytes to read */
912 {
913 int count, /* Number of bytes read */
914 total; /* Total bytes read */
915
916
917 for (total = 0; total < bytes; total += count, buf += count)
918 {
919 count = read(fd, buf, bytes - total);
920
921 if (count == 0)
922 return (0);
923 else if (count < 0)
924 {
925 if (errno == EINTR)
926 count = 0;
927 else
928 return (-1);
929 }
930 }
931
932 return (total);
933 }
934
935
936 /*
937 * 'cups_write()' - Write bytes to a file.
938 */
939
940 static int /* O - Bytes written or -1 */
941 cups_write(int fd, /* I - File descriptor */
942 const unsigned char *buf, /* I - Bytes to write */
943 int bytes) /* I - Number of bytes to write */
944 {
945 int count, /* Number of bytes written */
946 total; /* Total bytes written */
947
948
949 for (total = 0; total < bytes; total += count, buf += count)
950 {
951 count = write(fd, buf, bytes - total);
952
953 if (count < 0)
954 {
955 if (errno == EINTR)
956 count = 0;
957 else
958 return (-1);
959 }
960 }
961
962 return (total);
963 }
964
965
966 /*
967 * End of "$Id: raster.c 5523 2006-05-15 05:02:43Z mike $".
968 */