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