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