opencv
1/*
2* Copyright (c) 1988-1997 Sam Leffler
3* Copyright (c) 1991-1997 Silicon Graphics, Inc.
4*
5* Permission to use, copy, modify, distribute, and sell this software and
6* its documentation for any purpose is hereby granted without fee, provided
7* that (i) the above copyright notices and this permission notice appear in
8* all copies of the software and related documentation, and (ii) the names of
9* Sam Leffler and Silicon Graphics may not be used in any advertising or
10* publicity relating to the software without the specific, prior written
11* permission of Sam Leffler and Silicon Graphics.
12*
13* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16*
17* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22* OF THIS SOFTWARE.
23*/
24
25#include "tiffiop.h"26#ifdef NEXT_SUPPORT27/*
28* TIFF Library.
29*
30* NeXT 2-bit Grey Scale Compression Algorithm Support
31*/
32
33#define SETPIXEL(op, v) \34{ \35switch (npixels++ & 3) \36{ \37case 0: \38op[0] = (unsigned char)((v) << 6); \39break; \40case 1: \41op[0] |= (v) << 4; \42break; \43case 2: \44op[0] |= (v) << 2; \45break; \46case 3: \47*op++ |= (v); \48op_offset++; \49break; \50} \51}52
53#define LITERALROW 0x0054#define LITERALSPAN 0x4055#define WHITE ((1 << 2) - 1)56
57static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)58{
59static const char module[] = "NeXTDecode";60unsigned char *bp, *op;61tmsize_t cc;62uint8_t *row;63tmsize_t scanline, n;64
65(void)s;66/*67* Each scanline is assumed to start off as all
68* white (we assume a PhotometricInterpretation
69* of ``min-is-black'').
70*/
71for (op = (unsigned char *)buf, cc = occ; cc-- > 0;)72*op++ = 0xff;73
74bp = (unsigned char *)tif->tif_rawcp;75cc = tif->tif_rawcc;76scanline = tif->tif_scanlinesize;77if (occ % scanline)78{79TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");80return (0);81}82for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline)83{84n = *bp++;85cc--;86switch (n)87{88case LITERALROW:89/*90* The entire scanline is given as literal values.
91*/
92if (cc < scanline)93goto bad;94_TIFFmemcpy(row, bp, scanline);95bp += scanline;96cc -= scanline;97break;98case LITERALSPAN:99{100tmsize_t off;101/*102* The scanline has a literal span that begins at some
103* offset.
104*/
105if (cc < 4)106goto bad;107off = (bp[0] * 256) + bp[1];108n = (bp[2] * 256) + bp[3];109if (cc < 4 + n || off + n > scanline)110goto bad;111_TIFFmemcpy(row + off, bp + 4, n);112bp += 4 + n;113cc -= 4 + n;114break;115}116default:117{118uint32_t npixels = 0, grey;119tmsize_t op_offset = 0;120uint32_t imagewidth = tif->tif_dir.td_imagewidth;121if (isTiled(tif))122imagewidth = tif->tif_dir.td_tilewidth;123
124/*125* The scanline is composed of a sequence of constant
126* color ``runs''. We shift into ``run mode'' and
127* interpret bytes as codes of the form
128* <color><npixels> until we've filled the scanline.
129*/
130op = row;131for (;;)132{133grey = (uint32_t)((n >> 6) & 0x3);134n &= 0x3f;135/*136* Ensure the run does not exceed the scanline
137* bounds, potentially resulting in a security
138* issue.
139*/
140while (n-- > 0 && npixels < imagewidth &&141op_offset < scanline)142SETPIXEL(op, grey);143if (npixels >= imagewidth)144break;145if (op_offset >= scanline)146{147TIFFErrorExtR(tif, module,148"Invalid data for scanline %" PRIu32,149tif->tif_row);150return (0);151}152if (cc == 0)153goto bad;154n = *bp++;155cc--;156}157break;158}159}160}161tif->tif_rawcp = (uint8_t *)bp;162tif->tif_rawcc = cc;163return (1);164bad:165TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,166tif->tif_row);167return (0);168}
169
170static int NeXTPreDecode(TIFF *tif, uint16_t s)171{
172static const char module[] = "NeXTPreDecode";173TIFFDirectory *td = &tif->tif_dir;174(void)s;175
176if (td->td_bitspersample != 2)177{178TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16,179td->td_bitspersample);180return (0);181}182return (1);183}
184
185int TIFFInitNeXT(TIFF *tif, int scheme)186{
187(void)scheme;188tif->tif_predecode = NeXTPreDecode;189tif->tif_decoderow = NeXTDecode;190tif->tif_decodestrip = NeXTDecode;191tif->tif_decodetile = NeXTDecode;192return (1);193}
194#endif /* NEXT_SUPPORT */195