diff options
Diffstat (limited to 'filter/image-sgilib.c')
-rw-r--r-- | filter/image-sgilib.c | 890 |
1 files changed, 0 insertions, 890 deletions
diff --git a/filter/image-sgilib.c b/filter/image-sgilib.c deleted file mode 100644 index 826cdf27..00000000 --- a/filter/image-sgilib.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * "$Id: image-sgilib.c 9771 2011-05-12 05:21:56Z mike $" - * - * SGI image file format library routines 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: - * - * sgiClose() - Close an SGI image file. - * sgiGetRow() - Get a row of image data from a file. - * sgiOpen() - Open an SGI image file for reading or writing. - * sgiOpenFile() - Open an SGI image file for reading or writing. - * sgiPutRow() - Put a row of image data to a file. - * getlong() - Get a 32-bit big-endian integer. - * getshort() - Get a 16-bit big-endian integer. - * putlong() - Put a 32-bit big-endian integer. - * putshort() - Put a 16-bit big-endian integer. - * read_rle8() - Read 8-bit RLE data. - * read_rle16() - Read 16-bit RLE data. - * write_rle8() - Write 8-bit RLE data. - * write_rle16() - Write 16-bit RLE data. - */ - -#include "image-sgi.h" - - -/* - * Local functions... - */ - -static int getlong(FILE *); -static int getshort(FILE *); -static int putlong(long, FILE *); -static int putshort(unsigned short, FILE *); -static int read_rle8(FILE *, unsigned short *, int); -static int read_rle16(FILE *, unsigned short *, int); -static int write_rle8(FILE *, unsigned short *, int); -static int write_rle16(FILE *, unsigned short *, int); - - -/* - * 'sgiClose()' - Close an SGI image file. - */ - -int /* O - 0 on success, -1 on error */ -sgiClose(sgi_t *sgip) /* I - SGI image */ -{ - int i; /* Return status */ - long *offset; /* Looping var for offset table */ - - - if (sgip == NULL) - return (-1); - - if (sgip->mode == SGI_WRITE && sgip->comp != SGI_COMP_NONE) - { - /* - * Write the scanline offset table to the file... - */ - - fseek(sgip->file, 512, SEEK_SET); - - for (i = sgip->ysize * sgip->zsize, offset = sgip->table[0]; - i > 0; - i --, offset ++) - if (putlong(offset[0], sgip->file) < 0) - return (-1); - - for (i = sgip->ysize * sgip->zsize, offset = sgip->length[0]; - i > 0; - i --, offset ++) - if (putlong(offset[0], sgip->file) < 0) - return (-1); - } - - if (sgip->table != NULL) - { - free(sgip->table[0]); - free(sgip->table); - } - - if (sgip->length != NULL) - { - free(sgip->length[0]); - free(sgip->length); - } - - if (sgip->comp == SGI_COMP_ARLE) - free(sgip->arle_row); - - i = fclose(sgip->file); - free(sgip); - - return (i); -} - - -/* - * 'sgiGetRow()' - Get a row of image data from a file. - */ - -int /* O - 0 on success, -1 on error */ -sgiGetRow(sgi_t *sgip, /* I - SGI image */ - unsigned short *row, /* O - Row to read */ - int y, /* I - Line to read */ - int z) /* I - Channel to read */ -{ - int x; /* X coordinate */ - long offset; /* File offset */ - - - if (sgip == NULL || - row == NULL || - y < 0 || y >= sgip->ysize || - z < 0 || z >= sgip->zsize) - return (-1); - - switch (sgip->comp) - { - case SGI_COMP_NONE : - /* - * Seek to the image row - optimize buffering by only seeking if - * necessary... - */ - - offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp; - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - { - for (x = sgip->xsize; x > 0; x --, row ++) - *row = getc(sgip->file); - } - else - { - for (x = sgip->xsize; x > 0; x --, row ++) - *row = getshort(sgip->file); - } - break; - - case SGI_COMP_RLE : - offset = sgip->table[z][y]; - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - return (read_rle8(sgip->file, row, sgip->xsize)); - else - return (read_rle16(sgip->file, row, sgip->xsize)); - } - - return (0); -} - - -/* - * 'sgiOpen()' - Open an SGI image file for reading or writing. - */ - -sgi_t * /* O - New image */ -sgiOpen(const char *filename, /* I - File to open */ - int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */ - int comp, /* I - Type of compression */ - int bpp, /* I - Bytes per pixel */ - int xsize, /* I - Width of image in pixels */ - int ysize, /* I - Height of image in pixels */ - int zsize) /* I - Number of channels */ -{ - sgi_t *sgip; /* New SGI image file */ - FILE *file; /* Image file pointer */ - - - if (mode == SGI_READ) - file = fopen(filename, "rb"); - else - file = fopen(filename, "wb+"); - - if (file == NULL) - return (NULL); - - if ((sgip = sgiOpenFile(file, mode, comp, bpp, xsize, ysize, zsize)) == NULL) - fclose(file); - - return (sgip); -} - - -/* - * 'sgiOpenFile()' - Open an SGI image file for reading or writing. - */ - -sgi_t * /* O - New image */ -sgiOpenFile(FILE *file, /* I - File to open */ - int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */ - int comp, /* I - Type of compression */ - int bpp, /* I - Bytes per pixel */ - int xsize, /* I - Width of image in pixels */ - int ysize, /* I - Height of image in pixels */ - int zsize) /* I - Number of channels */ -{ - int i, j; /* Looping var */ - char name[80]; /* Name of file in image header */ - short magic; /* Magic number */ - sgi_t *sgip; /* New image pointer */ - - - if ((sgip = calloc(sizeof(sgi_t), 1)) == NULL) - return (NULL); - - sgip->file = file; - - switch (mode) - { - case SGI_READ : - sgip->mode = SGI_READ; - - magic = getshort(sgip->file); - if (magic != SGI_MAGIC) - { - free(sgip); - return (NULL); - } - - sgip->comp = getc(sgip->file); - sgip->bpp = getc(sgip->file); - getshort(sgip->file); /* Dimensions */ - sgip->xsize = getshort(sgip->file); - sgip->ysize = getshort(sgip->file); - sgip->zsize = getshort(sgip->file); - getlong(sgip->file); /* Minimum pixel */ - getlong(sgip->file); /* Maximum pixel */ - - if (sgip->comp) - { - /* - * This file is compressed; read the scanline tables... - */ - - fseek(sgip->file, 512, SEEK_SET); - - if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL) - { - free(sgip); - return (NULL); - } - - if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize, - sizeof(long))) == NULL) - { - free(sgip->table); - free(sgip); - return (NULL); - } - - for (i = 1; i < sgip->zsize; i ++) - sgip->table[i] = sgip->table[0] + i * sgip->ysize; - - for (i = 0; i < sgip->zsize; i ++) - for (j = 0; j < sgip->ysize; j ++) - sgip->table[i][j] = getlong(sgip->file); - } - break; - - case SGI_WRITE : - if (xsize < 1 || - ysize < 1 || - zsize < 1 || - bpp < 1 || bpp > 2 || - comp < SGI_COMP_NONE || comp > SGI_COMP_ARLE) - { - free(sgip); - return (NULL); - } - - sgip->mode = SGI_WRITE; - - putshort(SGI_MAGIC, sgip->file); - putc((sgip->comp = comp) != 0, sgip->file); - putc(sgip->bpp = bpp, sgip->file); - putshort(3, sgip->file); /* Dimensions */ - putshort(sgip->xsize = xsize, sgip->file); - putshort(sgip->ysize = ysize, sgip->file); - putshort(sgip->zsize = zsize, sgip->file); - if (bpp == 1) - { - putlong(0, sgip->file); /* Minimum pixel */ - putlong(255, sgip->file); /* Maximum pixel */ - } - else - { - putlong(-32768, sgip->file); /* Minimum pixel */ - putlong(32767, sgip->file); /* Maximum pixel */ - } - putlong(0, sgip->file); /* Reserved */ - - memset(name, 0, sizeof(name)); - fwrite(name, sizeof(name), 1, sgip->file); - - for (i = 0; i < 102; i ++) - putlong(0, sgip->file); - - switch (comp) - { - case SGI_COMP_NONE : /* No compression */ - /* - * This file is uncompressed. To avoid problems with sparse files, - * we need to write blank pixels for the entire image... - */ - - if (bpp == 1) - { - for (i = xsize * ysize * zsize; i > 0; i --) - putc(0, sgip->file); - } - else - { - for (i = xsize * ysize * zsize; i > 0; i --) - putshort(0, sgip->file); - } - break; - - case SGI_COMP_ARLE : /* Aggressive RLE */ - sgip->arle_row = calloc(xsize, sizeof(unsigned short)); - sgip->arle_offset = 0; - - case SGI_COMP_RLE : /* Run-Length Encoding */ - /* - * This file is compressed; write the (blank) scanline tables... - */ - - for (i = 2 * ysize * zsize; i > 0; i --) - putlong(0, sgip->file); - - sgip->firstrow = ftell(sgip->file); - sgip->nextrow = ftell(sgip->file); - if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL) - { - free(sgip); - return (NULL); - } - - if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize, - sizeof(long))) == NULL) - { - free(sgip->table); - free(sgip); - return (NULL); - } - - for (i = 1; i < sgip->zsize; i ++) - sgip->table[i] = sgip->table[0] + i * sgip->ysize; - - if ((sgip->length = calloc(sgip->zsize, sizeof(long *))) == NULL) - { - free(sgip->table); - free(sgip); - return (NULL); - } - - if ((sgip->length[0] = calloc(sgip->ysize * sgip->zsize, - sizeof(long))) == NULL) - { - free(sgip->length); - free(sgip->table); - free(sgip); - return (NULL); - } - - for (i = 1; i < sgip->zsize; i ++) - sgip->length[i] = sgip->length[0] + i * sgip->ysize; - break; - } - break; - - default : - free(sgip); - return (NULL); - } - - return (sgip); -} - - -/* - * 'sgiPutRow()' - Put a row of image data to a file. - */ - -int /* O - 0 on success, -1 on error */ -sgiPutRow(sgi_t *sgip, /* I - SGI image */ - unsigned short *row, /* I - Row to write */ - int y, /* I - Line to write */ - int z) /* I - Channel to write */ -{ - int x; /* X coordinate */ - long offset; /* File offset */ - - - if (sgip == NULL || - row == NULL || - y < 0 || y >= sgip->ysize || - z < 0 || z >= sgip->zsize) - return (-1); - - switch (sgip->comp) - { - case SGI_COMP_NONE : - /* - * Seek to the image row - optimize buffering by only seeking if - * necessary... - */ - - offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp; - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - { - for (x = sgip->xsize; x > 0; x --, row ++) - putc(*row, sgip->file); - } - else - { - for (x = sgip->xsize; x > 0; x --, row ++) - putshort(*row, sgip->file); - } - break; - - case SGI_COMP_ARLE : - if (sgip->table[z][y] != 0) - return (-1); - - /* - * First check the last row written... - */ - - if (sgip->arle_offset > 0) - { - for (x = 0; x < sgip->xsize; x ++) - if (row[x] != sgip->arle_row[x]) - break; - - if (x == sgip->xsize) - { - sgip->table[z][y] = sgip->arle_offset; - sgip->length[z][y] = sgip->arle_length; - return (0); - } - } - - /* - * If that didn't match, search all the previous rows... - */ - - fseek(sgip->file, sgip->firstrow, SEEK_SET); - - if (sgip->bpp == 1) - { - for (;;) - { - sgip->arle_offset = ftell(sgip->file); - if ((sgip->arle_length = read_rle8(sgip->file, sgip->arle_row, sgip->xsize)) < 0) - { - x = 0; - break; - } - - if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0) - { - x = sgip->xsize; - break; - } - } - } - else - { - for (;;) - { - sgip->arle_offset = ftell(sgip->file); - if ((sgip->arle_length = read_rle16(sgip->file, sgip->arle_row, sgip->xsize)) < 0) - { - x = 0; - break; - } - - if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0) - { - x = sgip->xsize; - break; - } - } - } - - if (x == sgip->xsize) - { - sgip->table[z][y] = sgip->arle_offset; - sgip->length[z][y] = sgip->arle_length; - return (0); - } - else - fseek(sgip->file, 0, SEEK_END); /* Clear EOF */ - - case SGI_COMP_RLE : - if (sgip->table[z][y] != 0) - return (-1); - - offset = sgip->table[z][y] = sgip->nextrow; - - if (offset != ftell(sgip->file)) - fseek(sgip->file, offset, SEEK_SET); - - if (sgip->bpp == 1) - x = write_rle8(sgip->file, row, sgip->xsize); - else - x = write_rle16(sgip->file, row, sgip->xsize); - - if (sgip->comp == SGI_COMP_ARLE) - { - sgip->arle_offset = offset; - sgip->arle_length = x; - memcpy(sgip->arle_row, row, sgip->xsize * sizeof(unsigned short)); - } - - sgip->nextrow = ftell(sgip->file); - sgip->length[z][y] = x; - - return (x); - } - - return (0); -} - - -/* - * 'getlong()' - Get a 32-bit big-endian integer. - */ - -static int /* O - Long value */ -getlong(FILE *fp) /* I - File to read from */ -{ - unsigned char b[4]; /* Bytes from file */ - - - fread(b, 4, 1, fp); - return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]); -} - - -/* - * 'getshort()' - Get a 16-bit big-endian integer. - */ - -static int /* O - Short value */ -getshort(FILE *fp) /* I - File to read from */ -{ - unsigned char b[2]; /* Bytes from file */ - - - fread(b, 2, 1, fp); - return ((b[0] << 8) | b[1]); -} - - -/* - * 'putlong()' - Put a 32-bit big-endian integer. - */ - -static int /* O - 0 on success, -1 on error */ -putlong(long n, /* I - Long to write */ - FILE *fp) /* I - File to write to */ -{ - if (putc(n >> 24, fp) == EOF) - return (EOF); - if (putc(n >> 16, fp) == EOF) - return (EOF); - if (putc(n >> 8, fp) == EOF) - return (EOF); - if (putc(n, fp) == EOF) - return (EOF); - else - return (0); -} - - -/* - * 'putshort()' - Put a 16-bit big-endian integer. - */ - -static int /* O - 0 on success, -1 on error */ -putshort(unsigned short n, /* I - Short to write */ - FILE *fp) /* I - File to write to */ -{ - if (putc(n >> 8, fp) == EOF) - return (EOF); - if (putc(n, fp) == EOF) - return (EOF); - else - return (0); -} - - -/* - * 'read_rle8()' - Read 8-bit RLE data. - */ - -static int /* O - Value on success, -1 on error */ -read_rle8(FILE *fp, /* I - File to read from */ - unsigned short *row, /* O - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int i, /* Looping var */ - ch, /* Current character */ - count, /* RLE count */ - length; /* Number of bytes read... */ - - - length = 0; - - while (xsize > 0) - { - if ((ch = getc(fp)) == EOF) - return (-1); - length ++; - - count = ch & 127; - if (count == 0) - break; - - if (ch & 128) - { - for (i = 0; i < count; i ++, row ++, xsize --, length ++) - if (xsize > 0) - *row = getc(fp); - } - else - { - ch = getc(fp); - length ++; - for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) - *row = ch; - } - } - - return (xsize > 0 ? -1 : length); -} - - -/* - * 'read_rle16()' - Read 16-bit RLE data. - */ - -static int /* O - Value on success, -1 on error */ -read_rle16(FILE *fp, /* I - File to read from */ - unsigned short *row, /* O - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int i, /* Looping var */ - ch, /* Current character */ - count, /* RLE count */ - length; /* Number of bytes read... */ - - - length = 0; - - while (xsize > 0) - { - if ((ch = getshort(fp)) == EOF) - return (-1); - length ++; - - count = ch & 127; - if (count == 0) - break; - - if (ch & 128) - { - for (i = 0; i < count; i ++, row ++, xsize --, length ++) - if (xsize > 0) - *row = getshort(fp); - } - else - { - ch = getshort(fp); - length ++; - for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) - *row = ch; - } - } - - return (xsize > 0 ? -1 : length * 2); -} - - -/* - * 'write_rle8()' - Write 8-bit RLE data. - */ - -static int /* O - Length on success, -1 on error */ -write_rle8(FILE *fp, /* I - File to write to */ - unsigned short *row, /* I - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int length, /* Length in bytes */ - count, /* Number of repeating pixels */ - i, /* Looping var */ - x; /* Current column */ - unsigned short *start, /* Start of current sequence */ - repeat; /* Repeated pixel */ - - - for (x = xsize, length = 0; x > 0;) - { - start = row; - row += 2; - x -= 2; - - while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0])) - { - row ++; - x --; - } - - row -= 2; - x += 2; - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putc(128 | i, fp) == EOF) - return (-1); - length ++; - - while (i > 0) - { - if (putc(*start, fp) == EOF) - return (-1); - start ++; - i --; - length ++; - } - } - - if (x <= 0) - break; - - start = row; - repeat = row[0]; - - row ++; - x --; - - while (x > 0 && *row == repeat) - { - row ++; - x --; - } - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putc(i, fp) == EOF) - return (-1); - length ++; - - if (putc(repeat, fp) == EOF) - return (-1); - length ++; - } - } - - length ++; - - if (putc(0, fp) == EOF) - return (-1); - else - return (length); -} - - -/* - * 'write_rle16()' - Write 16-bit RLE data. - */ - -static int /* O - Length in words */ -write_rle16(FILE *fp, /* I - File to write to */ - unsigned short *row, /* I - Data */ - int xsize) /* I - Width of data in pixels */ -{ - int length, /* Length in words */ - count, /* Number of repeating pixels */ - i, /* Looping var */ - x; /* Current column */ - unsigned short *start, /* Start of current sequence */ - repeat; /* Repeated pixel */ - - - for (x = xsize, length = 0; x > 0;) - { - start = row; - row += 2; - x -= 2; - - while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0])) - { - row ++; - x --; - } - - row -= 2; - x += 2; - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putshort(128 | i, fp) == EOF) - return (-1); - length ++; - - while (i > 0) - { - if (putshort(*start, fp) == EOF) - return (-1); - start ++; - i --; - length ++; - } - } - - if (x <= 0) - break; - - start = row; - repeat = row[0]; - - row ++; - x --; - - while (x > 0 && *row == repeat) - { - row ++; - x --; - } - - count = row - start; - while (count > 0) - { - i = count > 126 ? 126 : count; - count -= i; - - if (putshort(i, fp) == EOF) - return (-1); - length ++; - - if (putshort(repeat, fp) == EOF) - return (-1); - length ++; - } - } - - length ++; - - if (putshort(0, fp) == EOF) - return (-1); - else - return (2 * length); -} - - -/* - * End of "$Id: image-sgilib.c 9771 2011-05-12 05:21:56Z mike $". - */ |