1/* PDFlib GmbH cvsid: $Id: tif_next.c 14574 2005-10-29 16:27:43Z bonefish $ */ 2 3/* 4 * Copyright (c) 1988-1997 Sam Leffler 5 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and 8 * its documentation for any purpose is hereby granted without fee, provided 9 * that (i) the above copyright notices and this permission notice appear in 10 * all copies of the software and related documentation, and (ii) the names of 11 * Sam Leffler and Silicon Graphics may not be used in any advertising or 12 * publicity relating to the software without the specific, prior written 13 * permission of Sam Leffler and Silicon Graphics. 14 * 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 24 * OF THIS SOFTWARE. 25 */ 26 27#include "tiffiop.h" 28#ifdef NEXT_SUPPORT 29/* 30 * TIFF Library. 31 * 32 * NeXT 2-bit Grey Scale Compression Algorithm Support 33 */ 34 35#define SETPIXEL(op, v) { \ 36 switch (npixels++ & 3) { \ 37 case 0: op[0] = (v) << 6; break; \ 38 case 1: op[0] |= (v) << 4; break; \ 39 case 2: op[0] |= (v) << 2; break; \ 40 case 3: *op++ |= (v); break; \ 41 } \ 42} 43 44#define LITERALROW 0x00 45#define LITERALSPAN 0x40 46#define WHITE ((1<<2)-1) 47 48static int 49NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) 50{ 51 register tif_char *bp, *op; 52 register tsize_t cc; 53 register int n; 54 tidata_t row; 55 tsize_t scanline; 56 57 (void) s; 58 /* 59 * Each scanline is assumed to start off as all 60 * white (we assume a PhotometricInterpretation 61 * of ``min-is-black''). 62 */ 63 for (op = buf, cc = occ; cc-- > 0;) 64 *op++ = 0xff; 65 66 bp = (tif_char *)tif->tif_rawcp; 67 cc = tif->tif_rawcc; 68 scanline = tif->tif_scanlinesize; 69 for (row = buf; (long)occ > 0; occ -= scanline, row += scanline) { 70 n = *bp++, cc--; 71 switch (n) { 72 case LITERALROW: 73 /* 74 * The entire scanline is given as literal values. 75 */ 76 if (cc < scanline) 77 goto bad; 78 _TIFFmemcpy(row, bp, scanline); 79 bp += scanline; 80 cc -= scanline; 81 break; 82 case LITERALSPAN: { 83 int off; 84 /* 85 * The scanline has a literal span 86 * that begins at some offset. 87 */ 88 off = (bp[0] * 256) + bp[1]; 89 n = (bp[2] * 256) + bp[3]; 90 if (cc < 4+n) 91 goto bad; 92 _TIFFmemcpy(row+off, bp+4, n); 93 bp += 4+n; 94 cc -= 4+n; 95 break; 96 } 97 default: { 98 register int npixels = 0, grey; 99 tif_long imagewidth = tif->tif_dir.td_imagewidth; 100 101 /* 102 * The scanline is composed of a sequence 103 * of constant color ``runs''. We shift 104 * into ``run mode'' and interpret bytes 105 * as codes of the form <color><npixels> 106 * until we've filled the scanline. 107 */ 108 op = row; 109 for (;;) { 110 grey = (n>>6) & 0x3; 111 n &= 0x3f; 112 while (n-- > 0) 113 SETPIXEL(op, grey); 114 if (npixels >= (int) imagewidth) 115 break; 116 if (cc == 0) 117 goto bad; 118 n = *bp++, cc--; 119 } 120 break; 121 } 122 } 123 } 124 tif->tif_rawcp = (tidata_t) bp; 125 tif->tif_rawcc = cc; 126 return (1); 127bad: 128 TIFFError(tif->tif_name, "NeXTDecode: Not enough data for scanline %ld", 129 (long) tif->tif_row); 130 return (0); 131} 132 133int 134TIFFInitNeXT(TIFF* tif, int scheme) 135{ 136 (void) scheme; 137 tif->tif_decoderow = NeXTDecode; 138 tif->tif_decodestrip = NeXTDecode; 139 tif->tif_decodetile = NeXTDecode; 140 return (1); 141} 142#endif /* NEXT_SUPPORT */ 143