1 /* $Id: tif_next.c,v 1.16 2014-12-29 12:09:11 erouault Exp $ */ 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] = (unsigned char) ((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 48 static int 49 NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) 50 { 51 static const char module[] = "NeXTDecode"; 52 unsigned char *bp, *op; 53 tmsize_t cc; 54 uint8* row; 55 tmsize_t scanline, n; 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 = (unsigned char*) buf, cc = occ; cc-- > 0;) 64 *op++ = 0xff; 65 66 bp = (unsigned char *)tif->tif_rawcp; 67 cc = tif->tif_rawcc; 68 scanline = tif->tif_scanlinesize; 69 if (occ % scanline) 70 { 71 TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); 72 return (0); 73 } 74 for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) { 75 n = *bp++, cc--; 76 switch (n) { 77 case LITERALROW: 78 /* 79 * The entire scanline is given as literal values. 80 */ 81 if (cc < scanline) 82 goto bad; 83 _TIFFmemcpy(row, bp, scanline); 84 bp += scanline; 85 cc -= scanline; 86 break; 87 case LITERALSPAN: { 88 tmsize_t off; 89 /* 90 * The scanline has a literal span that begins at some 91 * offset. 92 */ 93 if( cc < 4 ) 94 goto bad; 95 off = (bp[0] * 256) + bp[1]; 96 n = (bp[2] * 256) + bp[3]; 97 if (cc < 4+n || off+n > scanline) 98 goto bad; 99 _TIFFmemcpy(row+off, bp+4, n); 100 bp += 4+n; 101 cc -= 4+n; 102 break; 103 } 104 default: { 105 uint32 npixels = 0, grey; 106 uint32 imagewidth = tif->tif_dir.td_imagewidth; 107 if( isTiled(tif) ) 108 imagewidth = tif->tif_dir.td_tilewidth; 109 110 /* 111 * The scanline is composed of a sequence of constant 112 * color ``runs''. We shift into ``run mode'' and 113 * interpret bytes as codes of the form 114 * <color><npixels> until we've filled the scanline. 115 */ 116 op = row; 117 for (;;) { 118 grey = (uint32)((n>>6) & 0x3); 119 n &= 0x3f; 120 /* 121 * Ensure the run does not exceed the scanline 122 * bounds, potentially resulting in a security 123 * issue. 124 */ 125 while (n-- > 0 && npixels < imagewidth) 126 SETPIXEL(op, grey); 127 if (npixels >= imagewidth) 128 break; 129 if (cc == 0) 130 goto bad; 131 n = *bp++, cc--; 132 } 133 break; 134 } 135 } 136 } 137 tif->tif_rawcp = (uint8*) bp; 138 tif->tif_rawcc = cc; 139 return (1); 140 bad: 141 TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld", 142 (long) tif->tif_row); 143 return (0); 144 } 145 146 static int 147 NeXTPreDecode(TIFF* tif, uint16 s) 148 { 149 static const char module[] = "NeXTPreDecode"; 150 TIFFDirectory *td = &tif->tif_dir; 151 (void)s; 152 153 if( td->td_bitspersample != 2 ) 154 { 155 TIFFErrorExt(tif->tif_clientdata, module, "Unsupported BitsPerSample = %d", 156 td->td_bitspersample); 157 return (0); 158 } 159 return (1); 160 } 161 162 int 163 TIFFInitNeXT(TIFF* tif, int scheme) 164 { 165 (void) scheme; 166 tif->tif_predecode = NeXTPreDecode; 167 tif->tif_decoderow = NeXTDecode; 168 tif->tif_decodestrip = NeXTDecode; 169 tif->tif_decodetile = NeXTDecode; 170 return (1); 171 } 172 #endif /* NEXT_SUPPORT */ 173 174 /* vim: set ts=8 sts=8 sw=8 noet: */ 175 /* 176 * Local Variables: 177 * mode: c 178 * c-basic-offset: 8 179 * fill-column: 78 180 * End: 181 */ 182