1
/* $Header: /cvsroot/osrs/libtiff/libtiff/tif_packbits.c,v 1.7 2003/07/08 16:40:46 warmerda Exp $ */
4
* Copyright (c) 1988-1997 Sam Leffler
5
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
28
#ifdef PACKBITS_SUPPORT
32
* PackBits Compression Algorithm Support
38
PackBitsPreEncode(TIFF* tif, tsample_t s)
42
* Calculate the scanline/tile-width size in bytes.
45
tif->tif_data = (tidata_t) TIFFTileRowSize(tif);
47
tif->tif_data = (tidata_t) TIFFScanlineSize(tif);
52
* NB: tidata is the type representing *(tidata_t);
53
* if tidata_t is made signed then this type must
54
* be adjusted accordingly.
56
typedef unsigned char tidata;
59
* Encode a run of pixels.
62
PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
64
u_char* bp = (u_char*) buf;
65
tidata_t op, ep, lastliteral;
68
enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
72
ep = tif->tif_rawdata + tif->tif_rawdatasize;
77
* Find the longest string of identical bytes.
79
b = *bp++, cc--, n = 1;
80
for (; cc > 0 && b == *bp; cc--, bp++)
83
if (op + 2 >= ep) { /* insure space for new data */
85
* Be careful about writing the last
86
* literal. Must write up to that point
87
* and then copy the remainder to the
88
* front of the buffer.
90
if (state == LITERAL || state == LITERAL_RUN) {
91
slop = op - lastliteral;
92
tif->tif_rawcc += lastliteral - tif->tif_rawcp;
93
if (!TIFFFlushData1(tif))
97
*op++ = *lastliteral++;
98
lastliteral = tif->tif_rawcp;
100
tif->tif_rawcc += op - tif->tif_rawcp;
101
if (!TIFFFlushData1(tif))
107
case BASE: /* initial state, set run/literal */
111
*op++ = (tidata) -127;
112
*op++ = (tidataval_t) b;
116
*op++ = (tidataval_t)(-(n-1));
117
*op++ = (tidataval_t) b;
121
*op++ = (tidataval_t) b;
125
case LITERAL: /* last object was literal string */
129
*op++ = (tidata) -127;
130
*op++ = (tidataval_t) b;
134
*op++ = (tidataval_t)(-(n-1)); /* encode run */
135
*op++ = (tidataval_t) b;
136
} else { /* extend literal */
137
if (++(*lastliteral) == 127)
139
*op++ = (tidataval_t) b;
142
case RUN: /* last object was run */
145
*op++ = (tidata) -127;
146
*op++ = (tidataval_t) b;
150
*op++ = (tidataval_t)(-(n-1));
151
*op++ = (tidataval_t) b;
155
*op++ = (tidataval_t) b;
159
case LITERAL_RUN: /* literal followed by a run */
161
* Check to see if previous run should
162
* be converted to a literal, in which
163
* case we convert literal-run-literal
164
* to a single literal.
166
if (n == 1 && op[-2] == (tidata) -1 &&
167
*lastliteral < 126) {
168
state = (((*lastliteral) += 2) == 127 ?
170
op[-2] = op[-1]; /* replicate */
176
tif->tif_rawcc += op - tif->tif_rawcp;
182
* Encode a rectangular chunk of pixels. We break it up
183
* into row-sized pieces to insure that encoded runs do
184
* not span rows. Otherwise, there can be problems with
185
* the decoder if data is read, for example, by scanlines
186
* when it was encoded by strips.
189
PackBitsEncodeChunk(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
191
#if defined(__hpux) && defined(__LP64__)
192
tsize_t rowsize = (tsize_t)(unsigned long) tif->tif_data;
194
tsize_t rowsize = (tsize_t) tif->tif_data;
201
* YCBCR data isn't really separable into rows, so we
202
* might as well encode the whole tile/strip as one chunk.
204
if( tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR ) {
205
#if defined(__hpux) && defined(__LP64__)
206
rowsize = (tsize_t)(unsigned long) tif->tif_data;
208
rowsize = (tsize_t) tif->tif_data;
213
while ((long)cc > 0) {
219
if (PackBitsEncode(tif, bp, chunk, s) < 0)
228
PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
236
bp = (char*) tif->tif_rawcp;
238
while (cc > 0 && (long)occ > 0) {
239
n = (long) *bp++, cc--;
241
* Watch out for compilers that
242
* don't sign extend chars...
246
if (n < 0) { /* replicate next byte -n+1 times */
247
if (n == -128) /* nop */
252
TIFFWarning(tif->tif_name,
253
"PackBitsDecode: discarding %d bytes "
254
"to avoid buffer overrun",
261
*op++ = (tidataval_t) b;
262
} else { /* copy next n+1 bytes literally */
265
TIFFWarning(tif->tif_name,
266
"PackBitsDecode: discarding %d bytes "
267
"to avoid buffer overrun",
271
_TIFFmemcpy(op, bp, ++n);
276
tif->tif_rawcp = (tidata_t) bp;
279
TIFFError(tif->tif_name,
280
"PackBitsDecode: Not enough data for scanline %ld",
281
(long) tif->tif_row);
288
TIFFInitPackBits(TIFF* tif, int scheme)
291
tif->tif_decoderow = PackBitsDecode;
292
tif->tif_decodestrip = PackBitsDecode;
293
tif->tif_decodetile = PackBitsDecode;
294
tif->tif_preencode = PackBitsPreEncode;
295
tif->tif_encoderow = PackBitsEncode;
296
tif->tif_encodestrip = PackBitsEncodeChunk;
297
tif->tif_encodetile = PackBitsEncodeChunk;
300
#endif /* PACKBITS_SUPPORT */