]> git.ipfire.org Git - thirdparty/cups.git/blame - filter/image.c
Load cups into easysw/current.
[thirdparty/cups.git] / filter / image.c
CommitLineData
ef416fc2 1/*
f7faf1f5 2 * "$Id: image.c 4741 2005-10-02 04:25:52Z mike $"
ef416fc2 3 *
4 * Base image support for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2005 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * cupsImageClose() - Close an image file.
29 * cupsImageGetCol() - Get a column of pixels from an image.
30 * cupsImageGetColorSpace() - Get the image colorspace.
31 * cupsImageGetDepth() - Get the number of bytes per pixel.
32 * cupsImageGetHeight() - Get the height of an image.
33 * cupsImageGetRow() - Get a row of pixels from an image.
34 * cupsImageGetWidth() - Get the width of an image.
35 * cupsImageGetXPPI() - Get the horizontal resolution of an image.
36 * cupsImageGetYPPI() - Get the vertical resolution of an image.
37 * cupsImageOpen() - Open an image file and read it into memory.
38 * _cupsImagePutCol() - Put a column of pixels to an image.
39 * _cupsImagePutRow() - Put a row of pixels to an image.
40 * cupsImageSetMaxTiles() - Set the maximum number of tiles to cache.
41 * flush_tile() - Flush the least-recently-used tile in the cache.
42 * get_tile() - Get a cached tile.
43 */
44
45/*
46 * Include necessary headers...
47 */
48
49#include "image-private.h"
50
51
52/*
53 * Local functions...
54 */
55
56static void flush_tile(cups_image_t *img);
57static cups_ib_t *get_tile(cups_image_t *img, int x, int y);
58
59
60/*
61 * 'cupsImageClose()' - Close an image file.
62 */
63
64void
65cupsImageClose(cups_image_t *img) /* I - Image to close */
66{
67 cups_ic_t *current, /* Current cached tile */
68 *next; /* Next cached tile */
69
70
71 /*
72 * Wipe the tile cache file (if any)...
73 */
74
75 if (img->cachefile != NULL)
76 {
77 DEBUG_printf(("Closing/removing swap file \"%s\"...\n", img->cachename));
78
79 fclose(img->cachefile);
80 unlink(img->cachename);
81 }
82
83 /*
84 * Free the image cache...
85 */
86
87 DEBUG_puts("Freeing memory...");
88
89 for (current = img->first, next = NULL; current != NULL; current = next)
90 {
91 DEBUG_printf(("Freeing cache (%p, next = %p)...\n", current, next));
92
93 next = current->next;
94 free(current);
95 }
96
97 /*
98 * Free the rest of memory...
99 */
100
101 if (img->tiles != NULL)
102 {
103 DEBUG_printf(("Freeing tiles (%p)...\n", img->tiles[0]));
104
105 free(img->tiles[0]);
106
107 DEBUG_printf(("Freeing tile pointers (%p)...\n", img->tiles));
108
109 free(img->tiles);
110 }
111
112 free(img);
113}
114
115
116/*
117 * 'cupsImageGetCol()' - Get a column of pixels from an image.
118 */
119
120int /* O - -1 on error, 0 on success */
121cupsImageGetCol(cups_image_t *img, /* I - Image */
122 int x, /* I - Column */
123 int y, /* I - Start row */
124 int height, /* I - Column height */
125 cups_ib_t *pixels) /* O - Pixel data */
126{
127 int bpp, /* Bytes per pixel */
128 twidth, /* Tile width */
129 count; /* Number of pixels to get */
130 const cups_ib_t *ib; /* Pointer into tile */
131
132
133 if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
134 return (-1);
135
136 if (y < 0)
137 {
138 height += y;
139 y = 0;
140 }
141
142 if ((y + height) > img->ysize)
143 height = img->ysize - y;
144
145 if (height < 1)
146 return (-1);
147
148 bpp = cupsImageGetDepth(img);
149 twidth = bpp * (CUPS_TILE_SIZE - 1);
150
151 while (height > 0)
152 {
153 ib = get_tile(img, x, y);
154
155 if (ib == NULL)
156 return (-1);
157
158 count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
159 if (count > height)
160 count = height;
161
162 y += count;
163 height -= count;
164
165 for (; count > 0; count --, ib += twidth)
166 switch (bpp)
167 {
168 case 4 :
169 *pixels++ = *ib++;
170 case 3 :
171 *pixels++ = *ib++;
172 *pixels++ = *ib++;
173 case 1 :
174 *pixels++ = *ib++;
175 break;
176 }
177 }
178
179 return (0);
180}
181
182
183/*
184 * 'cupsImageGetColorSpace()' - Get the image colorspace.
185 */
186
187cups_icspace_t /* O - Colorspace */
188cupsImageGetColorSpace(
189 cups_image_t *img) /* I - Image */
190{
191 return (img->colorspace);
192}
193
194
195/*
196 * 'cupsImageGetDepth()' - Get the number of bytes per pixel.
197 */
198
199int /* O - Bytes per pixel */
200cupsImageGetDepth(cups_image_t *img) /* I - Image */
201{
202 return (abs(img->colorspace));
203}
204
205
206/*
207 * 'cupsImageGetHeight()' - Get the height of an image.
208 */
209
210unsigned /* O - Height in pixels */
211cupsImageGetHeight(cups_image_t *img) /* I - Image */
212{
213 return (img->ysize);
214}
215
216
217/*
218 * 'cupsImageGetRow()' - Get a row of pixels from an image.
219 */
220
221int /* O - -1 on error, 0 on success */
222cupsImageGetRow(cups_image_t *img, /* I - Image */
223 int x, /* I - Start column */
224 int y, /* I - Row */
225 int width, /* I - Width of row */
226 cups_ib_t *pixels) /* O - Pixel data */
227{
228 int bpp, /* Bytes per pixel */
229 count; /* Number of pixels to get */
230 const cups_ib_t *ib; /* Pointer to pixels */
231
232
233 if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
234 return (-1);
235
236 if (x < 0)
237 {
238 width += x;
239 x = 0;
240 }
241
242 if ((x + width) > img->xsize)
243 width = img->xsize - x;
244
245 if (width < 1)
246 return (-1);
247
248 bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
249
250 while (width > 0)
251 {
252 ib = get_tile(img, x, y);
253
254 if (ib == NULL)
255 return (-1);
256
257 count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1));
258 if (count > width)
259 count = width;
260 memcpy(pixels, ib, count * bpp);
261 pixels += count * bpp;
262 x += count;
263 width -= count;
264 }
265
266 return (0);
267}
268
269
270/*
271 * 'cupsImageGetWidth()' - Get the width of an image.
272 */
273
274unsigned /* O - Width in pixels */
275cupsImageGetWidth(cups_image_t *img) /* I - Image */
276{
277 return (img->xsize);
278}
279
280
281/*
282 * 'cupsImageGetXPPI()' - Get the horizontal resolution of an image.
283 */
284
285unsigned /* O - Horizontal PPI */
286cupsImageGetXPPI(cups_image_t *img) /* I - Image */
287{
288 return (img->xppi);
289}
290
291
292/*
293 * 'cupsImageGetYPPI()' - Get the vertical resolution of an image.
294 */
295
296unsigned /* O - Vertical PPI */
297cupsImageGetYPPI(cups_image_t *img) /* I - Image */
298{
299 return (img->yppi);
300}
301
302
303/*
304 * 'cupsImageOpen()' - Open an image file and read it into memory.
305 */
306
307cups_image_t * /* O - New image */
308cupsImageOpen(
309 const char *filename, /* I - Filename of image */
310 cups_icspace_t primary, /* I - Primary colorspace needed */
311 cups_icspace_t secondary, /* I - Secondary colorspace if primary no good */
312 int saturation, /* I - Color saturation level */
313 int hue, /* I - Color hue adjustment */
314 const cups_ib_t *lut) /* I - RGB gamma/brightness LUT */
315{
316 FILE *fp; /* File pointer */
317 unsigned char header[16], /* First 16 bytes of file */
318 header2[16]; /* Bytes 2048-2064 (PhotoCD) */
319 cups_image_t *img; /* New image buffer */
320 int status; /* Status of load... */
321
322
323 DEBUG_printf(("cupsImageOpen(\"%s\", %d, %d, %d, %d, %p)\n",
324 filename ? filename : "(null)", primary, secondary,
325 saturation, hue, lut));
326
327 /*
328 * Figure out the file type...
329 */
330
331 if ((fp = fopen(filename, "r")) == NULL)
332 {
333/* perror("ERROR: Unable to open image file");
334*/ return (NULL);
335 }
336
337 if (fread(header, 1, sizeof(header), fp) == 0)
338 {
339/* perror("ERROR: Unable to read image file header");
340*/
341 fclose(fp);
342 return (NULL);
343 }
344
345 fseek(fp, 2048, SEEK_SET);
346 memset(header2, 0, sizeof(header2));
347 fread(header2, 1, sizeof(header2), fp);
348 fseek(fp, 0, SEEK_SET);
349
350 /*
351 * Allocate memory...
352 */
353
354 img = calloc(sizeof(cups_image_t), 1);
355
356 if (img == NULL)
357 {
358/* perror("ERROR: Unable to allocate memory for image file");
359*/ fclose(fp);
360 return (NULL);
361 }
362
363 /*
364 * Load the image as appropriate...
365 */
366
367 img->max_ics = CUPS_TILE_MINIMUM;
368 img->xppi = 128;
369 img->yppi = 128;
370
371 if (!memcmp(header, "GIF87a", 6) || !memcmp(header, "GIF89a", 6))
372 status = _cupsImageReadGIF(img, fp, primary, secondary, saturation, hue,
373 lut);
374 else if (!memcmp(header, "BM", 2))
375 status = _cupsImageReadBMP(img, fp, primary, secondary, saturation, hue,
376 lut);
377 else if (header[0] == 0x01 && header[1] == 0xda)
378 status = _cupsImageReadSGI(img, fp, primary, secondary, saturation, hue,
379 lut);
380 else if (header[0] == 0x59 && header[1] == 0xa6 &&
381 header[2] == 0x6a && header[3] == 0x95)
382 status = _cupsImageReadSunRaster(img, fp, primary, secondary, saturation,
383 hue, lut);
384 else if (header[0] == 'P' && header[1] >= '1' && header[1] <= '6')
385 status = _cupsImageReadPNM(img, fp, primary, secondary, saturation, hue,
386 lut);
387 else if (!memcmp(header2, "PCD_IPI", 7))
388 status = _cupsImageReadPhotoCD(img, fp, primary, secondary, saturation,
389 hue, lut);
390 else if (!memcmp(header + 8, "\000\010", 2) ||
391 !memcmp(header + 8, "\000\030", 2))
392 status = _cupsImageReadPIX(img, fp, primary, secondary, saturation, hue,
393 lut);
394#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
395 else if (!memcmp(header, "\211PNG", 4))
396 status = _cupsImageReadPNG(img, fp, primary, secondary, saturation, hue,
397 lut);
398#endif /* HAVE_LIBPNG && HAVE_LIBZ */
399#ifdef HAVE_LIBJPEG
400 else if (!memcmp(header, "\377\330\377", 3) && /* Start-of-Image */
401 header[3] >= 0xe0 && header[3] <= 0xef) /* APPn */
402 status = _cupsImageReadJPEG(img, fp, primary, secondary, saturation, hue,
403 lut);
404#endif /* HAVE_LIBJPEG */
405#ifdef HAVE_LIBTIFF
406 else if (!memcmp(header, "MM\000\052", 4) ||
407 !memcmp(header, "II\052\000", 4))
408 status = _cupsImageReadTIFF(img, fp, primary, secondary, saturation, hue,
409 lut);
410#endif /* HAVE_LIBTIFF */
411 else
412 {
413/* fputs("ERROR: Unknown image file format!");
414*/ fclose(fp);
415 status = -1;
416 }
417
418 if (status)
419 {
420 free(img);
421 return (NULL);
422 }
423 else
424 return (img);
425}
426
427
428/*
429 * '_cupsImagePutCol()' - Put a column of pixels to an image.
430 */
431
432int /* O - -1 on error, 0 on success */
433_cupsImagePutCol(
434 cups_image_t *img, /* I - Image */
435 int x, /* I - Column */
436 int y, /* I - Start row */
437 int height, /* I - Column height */
438 const cups_ib_t *pixels) /* I - Pixels to put */
439{
440 int bpp, /* Bytes per pixel */
441 twidth, /* Width of tile */
442 count; /* Number of pixels to put */
443 int tilex, /* Column within tile */
444 tiley; /* Row within tile */
445 cups_ib_t *ib; /* Pointer to pixels in tile */
446
447
448 if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
449 return (-1);
450
451 if (y < 0)
452 {
453 height += y;
454 y = 0;
455 }
456
457 if ((y + height) > img->ysize)
458 height = img->ysize - y;
459
460 if (height < 1)
461 return (-1);
462
463 bpp = cupsImageGetDepth(img);
464 twidth = bpp * (CUPS_TILE_SIZE - 1);
465 tilex = x / CUPS_TILE_SIZE;
466 tiley = y / CUPS_TILE_SIZE;
467
468 while (height > 0)
469 {
470 ib = get_tile(img, x, y);
471
472 if (ib == NULL)
473 return (-1);
474
475 img->tiles[tiley][tilex].dirty = 1;
476 tiley ++;
477
478 count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
479 if (count > height)
480 count = height;
481
482 y += count;
483 height -= count;
484
485 for (; count > 0; count --, ib += twidth)
486 switch (bpp)
487 {
488 case 4 :
489 *ib++ = *pixels++;
490 case 3 :
491 *ib++ = *pixels++;
492 *ib++ = *pixels++;
493 case 1 :
494 *ib++ = *pixels++;
495 break;
496 }
497 }
498
499 return (0);
500}
501
502
503/*
504 * '_cupsImagePutRow()' - Put a row of pixels to an image.
505 */
506
507int /* O - -1 on error, 0 on success */
508_cupsImagePutRow(
509 cups_image_t *img, /* I - Image */
510 int x, /* I - Start column */
511 int y, /* I - Row */
512 int width, /* I - Row width */
513 const cups_ib_t *pixels) /* I - Pixel data */
514{
515 int bpp, /* Bytes per pixel */
516 count; /* Number of pixels to put */
517 int tilex, /* Column within tile */
518 tiley; /* Row within tile */
519 cups_ib_t *ib; /* Pointer to pixels in tile */
520
521
522 if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
523 return (-1);
524
525 if (x < 0)
526 {
527 width += x;
528 x = 0;
529 }
530
531 if ((x + width) > img->xsize)
532 width = img->xsize - x;
533
534 if (width < 1)
535 return (-1);
536
537 bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
538 tilex = x / CUPS_TILE_SIZE;
539 tiley = y / CUPS_TILE_SIZE;
540
541 while (width > 0)
542 {
543 ib = get_tile(img, x, y);
544
545 if (ib == NULL)
546 return (-1);
547
548 img->tiles[tiley][tilex].dirty = 1;
549
550 count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1));
551 if (count > width)
552 count = width;
553 memcpy(ib, pixels, count * bpp);
554 pixels += count * bpp;
555 x += count;
556 width -= count;
557 tilex ++;
558 }
559
560 return (0);
561}
562
563
564/*
565 * 'cupsImageSetMaxTiles()' - Set the maximum number of tiles to cache.
566 *
567 * If the "max_tiles" argument is 0 then the maximum number of tiles is
568 * computed from the image size or the RIP_CACHE environment variable.
569 */
570
571void
572cupsImageSetMaxTiles(
573 cups_image_t *img, /* I - Image to set */
574 int max_tiles) /* I - Number of tiles to cache */
575{
576 int cache_size, /* Size of tile cache in bytes */
577 min_tiles, /* Minimum number of tiles to cache */
578 max_size; /* Maximum cache size in bytes */
579 char *cache_env, /* Cache size environment variable */
580 cache_units[255]; /* Cache size units */
581
582
583 min_tiles = max(CUPS_TILE_MINIMUM,
584 1 + max((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE,
585 (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE));
586
587 if (max_tiles == 0)
588 max_tiles = ((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE) *
589 ((img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE);
590
591 cache_size = max_tiles * CUPS_TILE_SIZE * CUPS_TILE_SIZE *
592 cupsImageGetDepth(img);
593
594 if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL)
595 {
596 switch (sscanf(cache_env, "%d%254s", &max_size, cache_units))
597 {
598 case 0 :
599 max_size = 32 * 1024 * 1024;
600 break;
601 case 1 :
602 max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
603 break;
604 case 2 :
605 if (tolower(cache_units[0] & 255) == 'g')
606 max_size *= 1024 * 1024 * 1024;
607 else if (tolower(cache_units[0] & 255) == 'm')
608 max_size *= 1024 * 1024;
609 else if (tolower(cache_units[0] & 255) == 'k')
610 max_size *= 1024;
611 else if (tolower(cache_units[0] & 255) == 't')
612 max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
613 break;
614 }
615 }
616 else
617 max_size = 32 * 1024 * 1024;
618
619 if (cache_size > max_size)
620 max_tiles = max_size / CUPS_TILE_SIZE / CUPS_TILE_SIZE /
621 cupsImageGetDepth(img);
622
623 if (max_tiles < min_tiles)
624 max_tiles = min_tiles;
625
626 img->max_ics = max_tiles;
627
628 DEBUG_printf(("max_ics=%d...\n", img->max_ics));
629}
630
631
632/*
633 * 'flush_tile()' - Flush the least-recently-used tile in the cache.
634 */
635
636static void
637flush_tile(cups_image_t *img) /* I - Image */
638{
639 int fd; /* Cache file descriptor */
640 int bpp; /* Bytes per pixel */
641 cups_itile_t *tile; /* Pointer to tile */
642
643
644 bpp = cupsImageGetDepth(img);
645 tile = img->first->tile;
646
647 if (!tile->dirty)
648 {
649 tile->ic = NULL;
650 return;
651 }
652
653 if (img->cachefile == NULL)
654 {
655 if ((fd = cupsTempFd(img->cachename, sizeof(img->cachename))) < 0)
656 {
657/* perror("ERROR: Unable to create image swap file");
658*/ tile->ic = NULL;
659 tile->dirty = 0;
660 return;
661 }
662
663 DEBUG_printf(("Created swap file \"%s\"...\n", img->cachename));
664
665 if ((img->cachefile = fdopen(fd, "wb+")) == NULL)
666 {
667/* perror("ERROR: Unable to create image swap file");
668*/ close(fd);
669 unlink(img->cachename);
670 tile->ic = NULL;
671 tile->dirty = 0;
672 return;
673 }
674 }
675
676 if (tile->pos >= 0)
677 {
678 if (ftell(img->cachefile) != tile->pos)
679 if (fseek(img->cachefile, tile->pos, SEEK_SET))
680 {
681/* perror("ERROR: Unable to seek in swap file");
682*/ tile->ic = NULL;
683 tile->dirty = 0;
684 return;
685 }
686 }
687 else
688 {
689 if (fseek(img->cachefile, 0, SEEK_END))
690 {
691/* perror("ERROR: Unable to append to swap file");
692*/ tile->ic = NULL;
693 tile->dirty = 0;
694 return;
695 }
696
697 tile->pos = ftell(img->cachefile);
698 }
699
700
701/* if (fwrite(tile->ic->pixels, bpp, CUPS_TILE_SIZE * CUPS_TILE_SIZE,
702 img->cachefile) < 1)
703 perror("ERROR: Unable to write tile to swap file");
704 else
705 DEBUG_printf(("Wrote tile at position %ld...\n", tile->pos));
706*/
707
708 fwrite(tile->ic->pixels, bpp, CUPS_TILE_SIZE * CUPS_TILE_SIZE,
709 img->cachefile);
710
711 tile->ic = NULL;
712 tile->dirty = 0;
713}
714
715
716/*
717 * 'get_tile()' - Get a cached tile.
718 */
719
720static cups_ib_t * /* O - Pointer to tile or NULL */
721get_tile(cups_image_t *img, /* I - Image */
722 int x, /* I - Column in image */
723 int y) /* I - Row in image */
724{
725 int bpp, /* Bytes per pixel */
726 tilex, /* Column within tile */
727 tiley, /* Row within tile */
728 xtiles, /* Number of tiles horizontally */
729 ytiles; /* Number of tiles vertically */
730 cups_ic_t *ic; /* Cache pointer */
731 cups_itile_t *tile; /* Tile pointer */
732
733
734 if (img->tiles == NULL)
735 {
736 xtiles = (img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;
737 ytiles = (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;
738
739 DEBUG_printf(("Creating tile array (%dx%d)\n", xtiles, ytiles));
740
741 img->tiles = calloc(sizeof(cups_itile_t *), ytiles);
742 tile = calloc(sizeof(cups_itile_t), xtiles * ytiles);
743
744 for (tiley = 0; tiley < ytiles; tiley ++)
745 {
746 img->tiles[tiley] = tile;
747 for (tilex = xtiles; tilex > 0; tilex --, tile ++)
748 tile->pos = -1;
749 }
750 }
751
752 bpp = cupsImageGetDepth(img);
753 tilex = x / CUPS_TILE_SIZE;
754 tiley = y / CUPS_TILE_SIZE;
755 tile = img->tiles[tiley] + tilex;
756 x &= (CUPS_TILE_SIZE - 1);
757 y &= (CUPS_TILE_SIZE - 1);
758
759 if ((ic = tile->ic) == NULL)
760 {
761 if (img->num_ics < img->max_ics)
762 {
763 ic = calloc(sizeof(cups_ic_t) + bpp * CUPS_TILE_SIZE *
764 CUPS_TILE_SIZE, 1);
765 ic->pixels = ((cups_ib_t *)ic) + sizeof(cups_ic_t);
766
767 img->num_ics ++;
768
769 DEBUG_printf(("Allocated cache tile %d (%p)...\n", img->num_ics, ic));
770 }
771 else
772 {
773 DEBUG_printf(("Flushing old cache tile (%p)...\n", img->first));
774
775 flush_tile(img);
776 ic = img->first;
777 }
778
779 ic->tile = tile;
780 tile->ic = ic;
781
782 if (tile->pos >= 0)
783 {
784 DEBUG_printf(("Loading cache tile from file position %ld...\n",
785 tile->pos));
786
787 if (ftell(img->cachefile) != tile->pos)
788 fseek(img->cachefile, tile->pos, SEEK_SET);
789/* if (fseek(img->cachefile, tile->pos, SEEK_SET))
790 perror("get_tile:");
791*/
792
793 fread(ic->pixels, bpp, CUPS_TILE_SIZE * CUPS_TILE_SIZE, img->cachefile);
794 }
795 else
796 {
797 DEBUG_puts("Clearing cache tile...");
798
799 memset(ic->pixels, 0, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);
800 }
801 }
802
803 if (ic == img->first)
804 {
805 if (ic->next != NULL)
806 ic->next->prev = NULL;
807
808 img->first = ic->next;
809 ic->next = NULL;
810 ic->prev = NULL;
811 }
812 else if (img->first == NULL)
813 img->first = ic;
814
815 if (ic != img->last)
816 {
817 /*
818 * Remove the cache entry from the list...
819 */
820
821 if (ic->prev != NULL)
822 ic->prev->next = ic->next;
823 if (ic->next != NULL)
824 ic->next->prev = ic->prev;
825
826 /*
827 * And add it to the end...
828 */
829
830 if (img->last != NULL)
831 img->last->next = ic;
832
833 ic->prev = img->last;
834 img->last = ic;
835 }
836
837 ic->next = NULL;
838
839 return (ic->pixels + bpp * (y * CUPS_TILE_SIZE + x));
840}
841
842
843/*
f7faf1f5 844 * End of "$Id: image.c 4741 2005-10-02 04:25:52Z mike $".
ef416fc2 845 */