~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/3rdparty/libtiff/tif_packbits.c

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tif_packbits.c,v 1.20 2010-03-10 18:56:49 bfriesen 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 PACKBITS_SUPPORT
 
29
/*
 
30
 * TIFF Library.
 
31
 *
 
32
 * PackBits Compression Algorithm Support
 
33
 */
 
34
#include <stdio.h>
 
35
 
 
36
static int
 
37
PackBitsPreEncode(TIFF* tif, uint16 s)
 
38
{
 
39
    (void) s;
 
40
 
 
41
    if (!(tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t))))
 
42
        return (0);
 
43
    /*
 
44
     * Calculate the scanline/tile-width size in bytes.
 
45
     */
 
46
    if (isTiled(tif))
 
47
        *(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif);
 
48
    else
 
49
        *(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif);
 
50
    return (1);
 
51
}
 
52
 
 
53
static int
 
54
PackBitsPostEncode(TIFF* tif)
 
55
{
 
56
        if (tif->tif_data)
 
57
            _TIFFfree(tif->tif_data);
 
58
    return (1);
 
59
}
 
60
 
 
61
/*
 
62
 * Encode a run of pixels.
 
63
 */
 
64
static int
 
65
PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
 
66
{
 
67
    unsigned char* bp = (unsigned char*) buf;
 
68
    uint8* op;
 
69
    uint8* ep;
 
70
    uint8* lastliteral;
 
71
    long n, slop;
 
72
    int b;
 
73
    enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
 
74
 
 
75
    (void) s;
 
76
    op = tif->tif_rawcp;
 
77
    ep = tif->tif_rawdata + tif->tif_rawdatasize;
 
78
    state = BASE;
 
79
    lastliteral = 0;
 
80
    while (cc > 0) {
 
81
        /*
 
82
         * Find the longest string of identical bytes.
 
83
         */
 
84
        b = *bp++, cc--, n = 1;
 
85
        for (; cc > 0 && b == *bp; cc--, bp++)
 
86
            n++;
 
87
    again:
 
88
        if (op + 2 >= ep) {             /* insure space for new data */
 
89
            /*
 
90
             * Be careful about writing the last
 
91
             * literal.  Must write up to that point
 
92
             * and then copy the remainder to the
 
93
             * front of the buffer.
 
94
             */
 
95
            if (state == LITERAL || state == LITERAL_RUN) {
 
96
                slop = (long)(op - lastliteral);
 
97
                tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
 
98
                if (!TIFFFlushData1(tif))
 
99
                    return (-1);
 
100
                op = tif->tif_rawcp;
 
101
                while (slop-- > 0)
 
102
                    *op++ = *lastliteral++;
 
103
                lastliteral = tif->tif_rawcp;
 
104
            } else {
 
105
                tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
 
106
                if (!TIFFFlushData1(tif))
 
107
                    return (-1);
 
108
                op = tif->tif_rawcp;
 
109
            }
 
110
        }
 
111
        switch (state) {
 
112
        case BASE:              /* initial state, set run/literal */
 
113
            if (n > 1) {
 
114
                state = RUN;
 
115
                if (n > 128) {
 
116
                    *op++ = (uint8) -127;
 
117
                    *op++ = (uint8) b;
 
118
                    n -= 128;
 
119
                    goto again;
 
120
                }
 
121
                *op++ = (uint8)(-(n-1));
 
122
                *op++ = (uint8) b;
 
123
            } else {
 
124
                lastliteral = op;
 
125
                *op++ = 0;
 
126
                *op++ = (uint8) b;
 
127
                state = LITERAL;
 
128
            }
 
129
            break;
 
130
        case LITERAL:           /* last object was literal string */
 
131
            if (n > 1) {
 
132
                state = LITERAL_RUN;
 
133
                if (n > 128) {
 
134
                    *op++ = (uint8) -127;
 
135
                    *op++ = (uint8) b;
 
136
                    n -= 128;
 
137
                    goto again;
 
138
                }
 
139
                *op++ = (uint8)(-(n-1));        /* encode run */
 
140
                *op++ = (uint8) b;
 
141
            } else {                    /* extend literal */
 
142
                if (++(*lastliteral) == 127)
 
143
                    state = BASE;
 
144
                *op++ = (uint8) b;
 
145
            }
 
146
            break;
 
147
        case RUN:               /* last object was run */
 
148
            if (n > 1) {
 
149
                if (n > 128) {
 
150
                    *op++ = (uint8) -127;
 
151
                    *op++ = (uint8) b;
 
152
                    n -= 128;
 
153
                    goto again;
 
154
                }
 
155
                *op++ = (uint8)(-(n-1));
 
156
                *op++ = (uint8) b;
 
157
            } else {
 
158
                lastliteral = op;
 
159
                *op++ = 0;
 
160
                *op++ = (uint8) b;
 
161
                state = LITERAL;
 
162
            }
 
163
            break;
 
164
        case LITERAL_RUN:       /* literal followed by a run */
 
165
            /*
 
166
             * Check to see if previous run should
 
167
             * be converted to a literal, in which
 
168
             * case we convert literal-run-literal
 
169
             * to a single literal.
 
170
             */
 
171
            if (n == 1 && op[-2] == (uint8) -1 &&
 
172
                *lastliteral < 126) {
 
173
                state = (((*lastliteral) += 2) == 127 ?
 
174
                    BASE : LITERAL);
 
175
                op[-2] = op[-1];        /* replicate */
 
176
            } else
 
177
                state = RUN;
 
178
            goto again;
 
179
        }
 
180
    }
 
181
    tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
 
182
    tif->tif_rawcp = op;
 
183
    return (1);
 
184
}
 
185
 
 
186
/*
 
187
 * Encode a rectangular chunk of pixels.  We break it up
 
188
 * into row-sized pieces to insure that encoded runs do
 
189
 * not span rows.  Otherwise, there can be problems with
 
190
 * the decoder if data is read, for example, by scanlines
 
191
 * when it was encoded by strips.
 
192
 */
 
193
static int
 
194
PackBitsEncodeChunk(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
 
195
{
 
196
    tmsize_t rowsize = *(tmsize_t*)tif->tif_data;
 
197
 
 
198
    while (cc > 0) {
 
199
        tmsize_t chunk = rowsize;
 
200
 
 
201
        if( cc < chunk )
 
202
            chunk = cc;
 
203
 
 
204
        if (PackBitsEncode(tif, bp, chunk, s) < 0)
 
205
            return (-1);
 
206
        bp += chunk;
 
207
        cc -= chunk;
 
208
    }
 
209
    return (1);
 
210
}
 
211
 
 
212
static int
 
213
PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
 
214
{
 
215
    static const char module[] = "PackBitsDecode";
 
216
    char *bp;
 
217
    tmsize_t cc;
 
218
    long n;
 
219
    int b;
 
220
 
 
221
    (void) s;
 
222
    bp = (char*) tif->tif_rawcp;
 
223
    cc = tif->tif_rawcc;
 
224
    while (cc > 0 && occ > 0) {
 
225
        n = (long) *bp++, cc--;
 
226
        /*
 
227
         * Watch out for compilers that
 
228
         * don't sign extend chars...
 
229
         */
 
230
        if (n >= 128)
 
231
            n -= 256;
 
232
        if (n < 0) {            /* replicate next byte -n+1 times */
 
233
            if (n == -128)      /* nop */
 
234
                continue;
 
235
            n = -n + 1;
 
236
            if( occ < (tmsize_t)n )
 
237
            {
 
238
                TIFFWarningExt(tif->tif_clientdata, module,
 
239
                    "Discarding %lu bytes to avoid buffer overrun",
 
240
                    (unsigned long) ((tmsize_t)n - occ));
 
241
                n = (long)occ;
 
242
            }
 
243
            occ -= n;
 
244
            b = *bp++, cc--;      /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */
 
245
            while (n-- > 0)
 
246
                *op++ = (uint8) b;
 
247
        } else {                /* copy next n+1 bytes literally */
 
248
            if (occ < (tmsize_t)(n + 1))
 
249
            {
 
250
                TIFFWarningExt(tif->tif_clientdata, module,
 
251
                    "Discarding %lu bytes to avoid buffer overrun",
 
252
                    (unsigned long) ((tmsize_t)n - occ + 1));
 
253
                n = (long)occ - 1;
 
254
            }
 
255
            _TIFFmemcpy(op, bp, ++n);  /* TODO: may be reading past input buffer here when input data is corrupt or ends prematurely */
 
256
            op += n; occ -= n;
 
257
            bp += n; cc -= n;
 
258
        }
 
259
    }
 
260
    tif->tif_rawcp = (uint8*) bp;
 
261
    tif->tif_rawcc = cc;
 
262
    if (occ > 0) {
 
263
        TIFFErrorExt(tif->tif_clientdata, module,
 
264
            "Not enough data for scanline %lu",
 
265
            (unsigned long) tif->tif_row);
 
266
        return (0);
 
267
    }
 
268
    return (1);
 
269
}
 
270
 
 
271
int
 
272
TIFFInitPackBits(TIFF* tif, int scheme)
 
273
{
 
274
    (void) scheme;
 
275
    tif->tif_decoderow = PackBitsDecode;
 
276
    tif->tif_decodestrip = PackBitsDecode;
 
277
    tif->tif_decodetile = PackBitsDecode;
 
278
    tif->tif_preencode = PackBitsPreEncode;
 
279
    tif->tif_postencode = PackBitsPostEncode;
 
280
    tif->tif_encoderow = PackBitsEncode;
 
281
    tif->tif_encodestrip = PackBitsEncodeChunk;
 
282
    tif->tif_encodetile = PackBitsEncodeChunk;
 
283
    return (1);
 
284
}
 
285
#endif /* PACKBITS_SUPPORT */
 
286
 
 
287
/* vim: set ts=8 sts=8 sw=8 noet: */
 
288
/*
 
289
 * Local Variables:
 
290
 * mode: c
 
291
 * c-basic-offset: 8
 
292
 * fill-column: 78
 
293
 * End:
 
294
 */