summaryrefslogtreecommitdiff
path: root/filter/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'filter/image.c')
-rw-r--r--filter/image.c813
1 files changed, 0 insertions, 813 deletions
diff --git a/filter/image.c b/filter/image.c
deleted file mode 100644
index 3cb11acf..00000000
--- a/filter/image.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * "$Id: image.c 9873 2011-08-06 06:47:46Z mike $"
- *
- * Base image support for CUPS.
- *
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1993-2005 by Easy Software Products.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- * cupsImageClose() - Close an image file.
- * cupsImageGetCol() - Get a column of pixels from an image.
- * cupsImageGetColorSpace() - Get the image colorspace.
- * cupsImageGetDepth() - Get the number of bytes per pixel.
- * cupsImageGetHeight() - Get the height of an image.
- * cupsImageGetRow() - Get a row of pixels from an image.
- * cupsImageGetWidth() - Get the width of an image.
- * cupsImageGetXPPI() - Get the horizontal resolution of an image.
- * cupsImageGetYPPI() - Get the vertical resolution of an image.
- * cupsImageOpen() - Open an image file and read it into memory.
- * _cupsImagePutCol() - Put a column of pixels to an image.
- * _cupsImagePutRow() - Put a row of pixels to an image.
- * cupsImageSetMaxTiles() - Set the maximum number of tiles to cache.
- * flush_tile() - Flush the least-recently-used tile in the cache.
- * get_tile() - Get a cached tile.
- */
-
-/*
- * Include necessary headers...
- */
-
-#include "image-private.h"
-
-
-/*
- * Local functions...
- */
-
-static void flush_tile(cups_image_t *img);
-static cups_ib_t *get_tile(cups_image_t *img, int x, int y);
-
-
-/*
- * 'cupsImageClose()' - Close an image file.
- */
-
-void
-cupsImageClose(cups_image_t *img) /* I - Image to close */
-{
- cups_ic_t *current, /* Current cached tile */
- *next; /* Next cached tile */
-
-
- /*
- * Wipe the tile cache file (if any)...
- */
-
- if (img->cachefile >= 0)
- {
- DEBUG_printf(("Closing/removing swap file \"%s\"...\n", img->cachename));
-
- close(img->cachefile);
- unlink(img->cachename);
- }
-
- /*
- * Free the image cache...
- */
-
- DEBUG_puts("Freeing memory...");
-
- for (current = img->first, next = NULL; current != NULL; current = next)
- {
- DEBUG_printf(("Freeing cache (%p, next = %p)...\n", current, next));
-
- next = current->next;
- free(current);
- }
-
- /*
- * Free the rest of memory...
- */
-
- if (img->tiles != NULL)
- {
- DEBUG_printf(("Freeing tiles (%p)...\n", img->tiles[0]));
-
- free(img->tiles[0]);
-
- DEBUG_printf(("Freeing tile pointers (%p)...\n", img->tiles));
-
- free(img->tiles);
- }
-
- free(img);
-}
-
-
-/*
- * 'cupsImageGetCol()' - Get a column of pixels from an image.
- */
-
-int /* O - -1 on error, 0 on success */
-cupsImageGetCol(cups_image_t *img, /* I - Image */
- int x, /* I - Column */
- int y, /* I - Start row */
- int height, /* I - Column height */
- cups_ib_t *pixels) /* O - Pixel data */
-{
- int bpp, /* Bytes per pixel */
- twidth, /* Tile width */
- count; /* Number of pixels to get */
- const cups_ib_t *ib; /* Pointer into tile */
-
-
- if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
- return (-1);
-
- if (y < 0)
- {
- height += y;
- y = 0;
- }
-
- if ((y + height) > img->ysize)
- height = img->ysize - y;
-
- if (height < 1)
- return (-1);
-
- bpp = cupsImageGetDepth(img);
- twidth = bpp * (CUPS_TILE_SIZE - 1);
-
- while (height > 0)
- {
- ib = get_tile(img, x, y);
-
- if (ib == NULL)
- return (-1);
-
- count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
- if (count > height)
- count = height;
-
- y += count;
- height -= count;
-
- for (; count > 0; count --, ib += twidth)
- switch (bpp)
- {
- case 4 :
- *pixels++ = *ib++;
- case 3 :
- *pixels++ = *ib++;
- *pixels++ = *ib++;
- case 1 :
- *pixels++ = *ib++;
- break;
- }
- }
-
- return (0);
-}
-
-
-/*
- * 'cupsImageGetColorSpace()' - Get the image colorspace.
- */
-
-cups_icspace_t /* O - Colorspace */
-cupsImageGetColorSpace(
- cups_image_t *img) /* I - Image */
-{
- return (img->colorspace);
-}
-
-
-/*
- * 'cupsImageGetDepth()' - Get the number of bytes per pixel.
- */
-
-int /* O - Bytes per pixel */
-cupsImageGetDepth(cups_image_t *img) /* I - Image */
-{
- return (abs(img->colorspace));
-}
-
-
-/*
- * 'cupsImageGetHeight()' - Get the height of an image.
- */
-
-unsigned /* O - Height in pixels */
-cupsImageGetHeight(cups_image_t *img) /* I - Image */
-{
- return (img->ysize);
-}
-
-
-/*
- * 'cupsImageGetRow()' - Get a row of pixels from an image.
- */
-
-int /* O - -1 on error, 0 on success */
-cupsImageGetRow(cups_image_t *img, /* I - Image */
- int x, /* I - Start column */
- int y, /* I - Row */
- int width, /* I - Width of row */
- cups_ib_t *pixels) /* O - Pixel data */
-{
- int bpp, /* Bytes per pixel */
- count; /* Number of pixels to get */
- const cups_ib_t *ib; /* Pointer to pixels */
-
-
- if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
- return (-1);
-
- if (x < 0)
- {
- width += x;
- x = 0;
- }
-
- if ((x + width) > img->xsize)
- width = img->xsize - x;
-
- if (width < 1)
- return (-1);
-
- bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
-
- while (width > 0)
- {
- ib = get_tile(img, x, y);
-
- if (ib == NULL)
- return (-1);
-
- count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1));
- if (count > width)
- count = width;
- memcpy(pixels, ib, count * bpp);
- pixels += count * bpp;
- x += count;
- width -= count;
- }
-
- return (0);
-}
-
-
-/*
- * 'cupsImageGetWidth()' - Get the width of an image.
- */
-
-unsigned /* O - Width in pixels */
-cupsImageGetWidth(cups_image_t *img) /* I - Image */
-{
- return (img->xsize);
-}
-
-
-/*
- * 'cupsImageGetXPPI()' - Get the horizontal resolution of an image.
- */
-
-unsigned /* O - Horizontal PPI */
-cupsImageGetXPPI(cups_image_t *img) /* I - Image */
-{
- return (img->xppi);
-}
-
-
-/*
- * 'cupsImageGetYPPI()' - Get the vertical resolution of an image.
- */
-
-unsigned /* O - Vertical PPI */
-cupsImageGetYPPI(cups_image_t *img) /* I - Image */
-{
- return (img->yppi);
-}
-
-
-/*
- * 'cupsImageOpen()' - Open an image file and read it into memory.
- */
-
-cups_image_t * /* O - New image */
-cupsImageOpen(
- const char *filename, /* I - Filename of image */
- cups_icspace_t primary, /* I - Primary colorspace needed */
- cups_icspace_t secondary, /* I - Secondary colorspace if primary no good */
- int saturation, /* I - Color saturation level */
- int hue, /* I - Color hue adjustment */
- const cups_ib_t *lut) /* I - RGB gamma/brightness LUT */
-{
- FILE *fp; /* File pointer */
- unsigned char header[16], /* First 16 bytes of file */
- header2[16]; /* Bytes 2048-2064 (PhotoCD) */
- cups_image_t *img; /* New image buffer */
- int status; /* Status of load... */
-
-
- DEBUG_printf(("cupsImageOpen(\"%s\", %d, %d, %d, %d, %p)\n",
- filename ? filename : "(null)", primary, secondary,
- saturation, hue, lut));
-
- /*
- * Figure out the file type...
- */
-
- if ((fp = fopen(filename, "r")) == NULL)
- return (NULL);
-
- if (fread(header, 1, sizeof(header), fp) == 0)
- {
- fclose(fp);
- return (NULL);
- }
-
- fseek(fp, 2048, SEEK_SET);
- memset(header2, 0, sizeof(header2));
- fread(header2, 1, sizeof(header2), fp);
- fseek(fp, 0, SEEK_SET);
-
- /*
- * Allocate memory...
- */
-
- img = calloc(sizeof(cups_image_t), 1);
-
- if (img == NULL)
- {
- fclose(fp);
- return (NULL);
- }
-
- /*
- * Load the image as appropriate...
- */
-
- img->cachefile = -1;
- img->max_ics = CUPS_TILE_MINIMUM;
- img->xppi = 128;
- img->yppi = 128;
-
- if (!memcmp(header, "GIF87a", 6) || !memcmp(header, "GIF89a", 6))
- status = _cupsImageReadGIF(img, fp, primary, secondary, saturation, hue,
- lut);
- else if (!memcmp(header, "BM", 2))
- status = _cupsImageReadBMP(img, fp, primary, secondary, saturation, hue,
- lut);
- else if (header[0] == 0x01 && header[1] == 0xda)
- status = _cupsImageReadSGI(img, fp, primary, secondary, saturation, hue,
- lut);
- else if (header[0] == 0x59 && header[1] == 0xa6 &&
- header[2] == 0x6a && header[3] == 0x95)
- status = _cupsImageReadSunRaster(img, fp, primary, secondary, saturation,
- hue, lut);
- else if (header[0] == 'P' && header[1] >= '1' && header[1] <= '6')
- status = _cupsImageReadPNM(img, fp, primary, secondary, saturation, hue,
- lut);
- else if (!memcmp(header2, "PCD_IPI", 7))
- status = _cupsImageReadPhotoCD(img, fp, primary, secondary, saturation,
- hue, lut);
- else if (!memcmp(header + 8, "\000\010", 2) ||
- !memcmp(header + 8, "\000\030", 2))
- status = _cupsImageReadPIX(img, fp, primary, secondary, saturation, hue,
- lut);
-#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
- else if (!memcmp(header, "\211PNG", 4))
- status = _cupsImageReadPNG(img, fp, primary, secondary, saturation, hue,
- lut);
-#endif /* HAVE_LIBPNG && HAVE_LIBZ */
-#ifdef HAVE_LIBJPEG
- else if (!memcmp(header, "\377\330\377", 3) && /* Start-of-Image */
- header[3] >= 0xe0 && header[3] <= 0xef) /* APPn */
- status = _cupsImageReadJPEG(img, fp, primary, secondary, saturation, hue,
- lut);
-#endif /* HAVE_LIBJPEG */
-#ifdef HAVE_LIBTIFF
- else if (!memcmp(header, "MM\000\052", 4) ||
- !memcmp(header, "II\052\000", 4))
- status = _cupsImageReadTIFF(img, fp, primary, secondary, saturation, hue,
- lut);
-#endif /* HAVE_LIBTIFF */
- else
- {
- fclose(fp);
- status = -1;
- }
-
- if (status)
- {
- free(img);
- return (NULL);
- }
- else
- return (img);
-}
-
-
-/*
- * '_cupsImagePutCol()' - Put a column of pixels to an image.
- */
-
-int /* O - -1 on error, 0 on success */
-_cupsImagePutCol(
- cups_image_t *img, /* I - Image */
- int x, /* I - Column */
- int y, /* I - Start row */
- int height, /* I - Column height */
- const cups_ib_t *pixels) /* I - Pixels to put */
-{
- int bpp, /* Bytes per pixel */
- twidth, /* Width of tile */
- count; /* Number of pixels to put */
- int tilex, /* Column within tile */
- tiley; /* Row within tile */
- cups_ib_t *ib; /* Pointer to pixels in tile */
-
-
- if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
- return (-1);
-
- if (y < 0)
- {
- height += y;
- y = 0;
- }
-
- if ((y + height) > img->ysize)
- height = img->ysize - y;
-
- if (height < 1)
- return (-1);
-
- bpp = cupsImageGetDepth(img);
- twidth = bpp * (CUPS_TILE_SIZE - 1);
- tilex = x / CUPS_TILE_SIZE;
- tiley = y / CUPS_TILE_SIZE;
-
- while (height > 0)
- {
- ib = get_tile(img, x, y);
-
- if (ib == NULL)
- return (-1);
-
- img->tiles[tiley][tilex].dirty = 1;
- tiley ++;
-
- count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
- if (count > height)
- count = height;
-
- y += count;
- height -= count;
-
- for (; count > 0; count --, ib += twidth)
- switch (bpp)
- {
- case 4 :
- *ib++ = *pixels++;
- case 3 :
- *ib++ = *pixels++;
- *ib++ = *pixels++;
- case 1 :
- *ib++ = *pixels++;
- break;
- }
- }
-
- return (0);
-}
-
-
-/*
- * '_cupsImagePutRow()' - Put a row of pixels to an image.
- */
-
-int /* O - -1 on error, 0 on success */
-_cupsImagePutRow(
- cups_image_t *img, /* I - Image */
- int x, /* I - Start column */
- int y, /* I - Row */
- int width, /* I - Row width */
- const cups_ib_t *pixels) /* I - Pixel data */
-{
- int bpp, /* Bytes per pixel */
- count; /* Number of pixels to put */
- int tilex, /* Column within tile */
- tiley; /* Row within tile */
- cups_ib_t *ib; /* Pointer to pixels in tile */
-
-
- if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize)
- return (-1);
-
- if (x < 0)
- {
- width += x;
- x = 0;
- }
-
- if ((x + width) > img->xsize)
- width = img->xsize - x;
-
- if (width < 1)
- return (-1);
-
- bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace;
- tilex = x / CUPS_TILE_SIZE;
- tiley = y / CUPS_TILE_SIZE;
-
- while (width > 0)
- {
- ib = get_tile(img, x, y);
-
- if (ib == NULL)
- return (-1);
-
- img->tiles[tiley][tilex].dirty = 1;
-
- count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1));
- if (count > width)
- count = width;
- memcpy(ib, pixels, count * bpp);
- pixels += count * bpp;
- x += count;
- width -= count;
- tilex ++;
- }
-
- return (0);
-}
-
-
-/*
- * 'cupsImageSetMaxTiles()' - Set the maximum number of tiles to cache.
- *
- * If the "max_tiles" argument is 0 then the maximum number of tiles is
- * computed from the image size or the RIP_CACHE environment variable.
- */
-
-void
-cupsImageSetMaxTiles(
- cups_image_t *img, /* I - Image to set */
- int max_tiles) /* I - Number of tiles to cache */
-{
- int cache_size, /* Size of tile cache in bytes */
- min_tiles, /* Minimum number of tiles to cache */
- max_size; /* Maximum cache size in bytes */
- char *cache_env, /* Cache size environment variable */
- cache_units[255]; /* Cache size units */
-
-
- min_tiles = max(CUPS_TILE_MINIMUM,
- 1 + max((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE,
- (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE));
-
- if (max_tiles == 0)
- max_tiles = ((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE) *
- ((img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE);
-
- cache_size = max_tiles * CUPS_TILE_SIZE * CUPS_TILE_SIZE *
- cupsImageGetDepth(img);
-
- if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL)
- {
- switch (sscanf(cache_env, "%d%254s", &max_size, cache_units))
- {
- case 0 :
- max_size = 32 * 1024 * 1024;
- break;
- case 1 :
- max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
- break;
- case 2 :
- if (tolower(cache_units[0] & 255) == 'g')
- max_size *= 1024 * 1024 * 1024;
- else if (tolower(cache_units[0] & 255) == 'm')
- max_size *= 1024 * 1024;
- else if (tolower(cache_units[0] & 255) == 'k')
- max_size *= 1024;
- else if (tolower(cache_units[0] & 255) == 't')
- max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
- break;
- }
- }
- else
- max_size = 32 * 1024 * 1024;
-
- if (cache_size > max_size)
- max_tiles = max_size / CUPS_TILE_SIZE / CUPS_TILE_SIZE /
- cupsImageGetDepth(img);
-
- if (max_tiles < min_tiles)
- max_tiles = min_tiles;
-
- img->max_ics = max_tiles;
-
- DEBUG_printf(("max_ics=%d...\n", img->max_ics));
-}
-
-
-/*
- * 'flush_tile()' - Flush the least-recently-used tile in the cache.
- */
-
-static void
-flush_tile(cups_image_t *img) /* I - Image */
-{
- int bpp; /* Bytes per pixel */
- cups_itile_t *tile; /* Pointer to tile */
-
-
- bpp = cupsImageGetDepth(img);
- tile = img->first->tile;
-
- if (!tile->dirty)
- {
- tile->ic = NULL;
- return;
- }
-
- if (img->cachefile < 0)
- {
- if ((img->cachefile = cupsTempFd(img->cachename,
- sizeof(img->cachename))) < 0)
- {
- tile->ic = NULL;
- tile->dirty = 0;
- return;
- }
-
- DEBUG_printf(("Created swap file \"%s\"...\n", img->cachename));
- }
-
- if (tile->pos >= 0)
- {
- if (lseek(img->cachefile, tile->pos, SEEK_SET) != tile->pos)
- {
- tile->ic = NULL;
- tile->dirty = 0;
- return;
- }
- }
- else
- {
- if ((tile->pos = lseek(img->cachefile, 0, SEEK_END)) < 0)
- {
- tile->ic = NULL;
- tile->dirty = 0;
- return;
- }
- }
-
- write(img->cachefile, tile->ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);
-
- tile->ic = NULL;
- tile->dirty = 0;
-}
-
-
-/*
- * 'get_tile()' - Get a cached tile.
- */
-
-static cups_ib_t * /* O - Pointer to tile or NULL */
-get_tile(cups_image_t *img, /* I - Image */
- int x, /* I - Column in image */
- int y) /* I - Row in image */
-{
- int bpp, /* Bytes per pixel */
- tilex, /* Column within tile */
- tiley, /* Row within tile */
- xtiles, /* Number of tiles horizontally */
- ytiles; /* Number of tiles vertically */
- cups_ic_t *ic; /* Cache pointer */
- cups_itile_t *tile; /* Tile pointer */
-
-
- if (img->tiles == NULL)
- {
- xtiles = (img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;
- ytiles = (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;
-
- DEBUG_printf(("Creating tile array (%dx%d)\n", xtiles, ytiles));
-
- if ((img->tiles = calloc(sizeof(cups_itile_t *), ytiles)) == NULL)
- return (NULL);
-
- if ((tile = calloc(xtiles * sizeof(cups_itile_t), ytiles)) == NULL)
- return (NULL);
-
- for (tiley = 0; tiley < ytiles; tiley ++)
- {
- img->tiles[tiley] = tile;
- for (tilex = xtiles; tilex > 0; tilex --, tile ++)
- tile->pos = -1;
- }
- }
-
- bpp = cupsImageGetDepth(img);
- tilex = x / CUPS_TILE_SIZE;
- tiley = y / CUPS_TILE_SIZE;
- tile = img->tiles[tiley] + tilex;
- x &= (CUPS_TILE_SIZE - 1);
- y &= (CUPS_TILE_SIZE - 1);
-
- if ((ic = tile->ic) == NULL)
- {
- if (img->num_ics < img->max_ics)
- {
- if ((ic = calloc(sizeof(cups_ic_t) +
- bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE, 1)) == NULL)
- {
- if (img->num_ics == 0)
- return (NULL);
-
- flush_tile(img);
- ic = img->first;
- }
- else
- {
- ic->pixels = ((cups_ib_t *)ic) + sizeof(cups_ic_t);
-
- img->num_ics ++;
-
- DEBUG_printf(("Allocated cache tile %d (%p)...\n", img->num_ics, ic));
- }
- }
- else
- {
- DEBUG_printf(("Flushing old cache tile (%p)...\n", img->first));
-
- flush_tile(img);
- ic = img->first;
- }
-
- ic->tile = tile;
- tile->ic = ic;
-
- if (tile->pos >= 0)
- {
- DEBUG_printf(("Loading cache tile from file position " CUPS_LLFMT "...\n",
- CUPS_LLCAST tile->pos));
-
- lseek(img->cachefile, tile->pos, SEEK_SET);
- read(img->cachefile, ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);
- }
- else
- {
- DEBUG_puts("Clearing cache tile...");
-
- memset(ic->pixels, 0, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);
- }
- }
-
- if (ic == img->first)
- {
- if (ic->next != NULL)
- ic->next->prev = NULL;
-
- img->first = ic->next;
- ic->next = NULL;
- ic->prev = NULL;
- }
- else if (img->first == NULL)
- img->first = ic;
-
- if (ic != img->last)
- {
- /*
- * Remove the cache entry from the list...
- */
-
- if (ic->prev != NULL)
- ic->prev->next = ic->next;
- if (ic->next != NULL)
- ic->next->prev = ic->prev;
-
- /*
- * And add it to the end...
- */
-
- if (img->last != NULL)
- img->last->next = ic;
-
- ic->prev = img->last;
- img->last = ic;
- }
-
- ic->next = NULL;
-
- return (ic->pixels + bpp * (y * CUPS_TILE_SIZE + x));
-}
-
-
-/*
- * End of "$Id: image.c 9873 2011-08-06 06:47:46Z mike $".
- */