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

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/3rdparty/openexr/IlmImf/ImfRleCompressor.cpp

  • 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
///////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 
4
// Digital Ltd. LLC
 
5
//
 
6
// All rights reserved.
 
7
//
 
8
// Redistribution and use in source and binary forms, with or without
 
9
// modification, are permitted provided that the following conditions are
 
10
// met:
 
11
// *       Redistributions of source code must retain the above copyright
 
12
// notice, this list of conditions and the following disclaimer.
 
13
// *       Redistributions in binary form must reproduce the above
 
14
// copyright notice, this list of conditions and the following disclaimer
 
15
// in the documentation and/or other materials provided with the
 
16
// distribution.
 
17
// *       Neither the name of Industrial Light & Magic nor the names of
 
18
// its contributors may be used to endorse or promote products derived
 
19
// from this software without specific prior written permission.
 
20
//
 
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
32
//
 
33
///////////////////////////////////////////////////////////////////////////
 
34
 
 
35
 
 
36
 
 
37
//-----------------------------------------------------------------------------
 
38
//
 
39
//      class RleCompressor
 
40
//
 
41
//-----------------------------------------------------------------------------
 
42
 
 
43
#include <ImfRleCompressor.h>
 
44
#include <ImfCheckedArithmetic.h>
 
45
#include "Iex.h"
 
46
 
 
47
namespace Imf {
 
48
namespace {
 
49
 
 
50
const int MIN_RUN_LENGTH = 3;
 
51
const int MAX_RUN_LENGTH = 127;
 
52
 
 
53
 
 
54
//
 
55
// Compress an array of bytes, using run-length encoding,
 
56
// and return the length of the compressed data.
 
57
//
 
58
 
 
59
int
 
60
rleCompress (int inLength, const char in[], signed char out[])
 
61
{
 
62
    const char *inEnd = in + inLength;
 
63
    const char *runStart = in;
 
64
    const char *runEnd = in + 1;
 
65
    signed char *outWrite = out;
 
66
 
 
67
    while (runStart < inEnd)
 
68
    {
 
69
    while (runEnd < inEnd &&
 
70
           *runStart == *runEnd &&
 
71
           runEnd - runStart - 1 < MAX_RUN_LENGTH)
 
72
    {
 
73
        ++runEnd;
 
74
    }
 
75
 
 
76
    if (runEnd - runStart >= MIN_RUN_LENGTH)
 
77
    {
 
78
        //
 
79
        // Compressable run
 
80
        //
 
81
 
 
82
        *outWrite++ = (runEnd - runStart) - 1;
 
83
        *outWrite++ = *(signed char *) runStart;
 
84
        runStart = runEnd;
 
85
    }
 
86
    else
 
87
    {
 
88
        //
 
89
        // Uncompressable run
 
90
        //
 
91
 
 
92
        while (runEnd < inEnd &&
 
93
           ((runEnd + 1 >= inEnd ||
 
94
             *runEnd != *(runEnd + 1)) ||
 
95
            (runEnd + 2 >= inEnd ||
 
96
             *(runEnd + 1) != *(runEnd + 2))) &&
 
97
           runEnd - runStart < MAX_RUN_LENGTH)
 
98
        {
 
99
        ++runEnd;
 
100
        }
 
101
 
 
102
        *outWrite++ = runStart - runEnd;
 
103
 
 
104
        while (runStart < runEnd)
 
105
        {
 
106
        *outWrite++ = *(signed char *) (runStart++);
 
107
        }
 
108
    }
 
109
 
 
110
    ++runEnd;
 
111
    }
 
112
 
 
113
    return outWrite - out;
 
114
}
 
115
 
 
116
 
 
117
//
 
118
// Uncompress an array of bytes compressed with rleCompress().
 
119
// Returns the length of the oncompressed data, or 0 if the
 
120
// length of the uncompressed data would be more than maxLength.
 
121
//
 
122
 
 
123
int
 
124
rleUncompress (int inLength, int maxLength, const signed char in[], char out[])
 
125
{
 
126
    char *outStart = out;
 
127
 
 
128
    while (inLength > 0)
 
129
    {
 
130
    if (*in < 0)
 
131
    {
 
132
        int count = -((int)*in++);
 
133
        inLength -= count + 1;
 
134
 
 
135
        if (0 > (maxLength -= count))
 
136
        return 0;
 
137
 
 
138
        while (count-- > 0)
 
139
        *out++ = *(char *) (in++);
 
140
    }
 
141
    else
 
142
    {
 
143
        int count = *in++;
 
144
        inLength -= 2;
 
145
 
 
146
        if (0 > (maxLength -= count + 1))
 
147
        return 0;
 
148
 
 
149
        while (count-- >= 0)
 
150
        *out++ = *(char *) in;
 
151
 
 
152
        in++;
 
153
    }
 
154
    }
 
155
 
 
156
    return out - outStart;
 
157
}
 
158
 
 
159
} // namespace
 
160
 
 
161
 
 
162
RleCompressor::RleCompressor (const Header &hdr, size_t maxScanLineSize):
 
163
    Compressor (hdr),
 
164
    _maxScanLineSize (maxScanLineSize),
 
165
    _tmpBuffer (0),
 
166
    _outBuffer (0)
 
167
{
 
168
    _tmpBuffer = new char [maxScanLineSize];
 
169
    _outBuffer = new char [uiMult (maxScanLineSize, size_t (3)) / 2];
 
170
}
 
171
 
 
172
 
 
173
RleCompressor::~RleCompressor ()
 
174
{
 
175
    delete [] _tmpBuffer;
 
176
    delete [] _outBuffer;
 
177
}
 
178
 
 
179
 
 
180
int
 
181
RleCompressor::numScanLines () const
 
182
{
 
183
    //
 
184
    // This compressor compresses individual scan lines.
 
185
    //
 
186
 
 
187
    return 1;
 
188
}
 
189
 
 
190
 
 
191
int
 
192
RleCompressor::compress (const char *inPtr,
 
193
             int inSize,
 
194
             int /*minY*/,
 
195
             const char *&outPtr)
 
196
{
 
197
    //
 
198
    // Special case �- empty input buffer
 
199
    //
 
200
 
 
201
    if (inSize == 0)
 
202
    {
 
203
    outPtr = _outBuffer;
 
204
    return 0;
 
205
    }
 
206
 
 
207
    //
 
208
    // Reorder the pixel data.
 
209
    //
 
210
 
 
211
    {
 
212
    char *t1 = _tmpBuffer;
 
213
    char *t2 = _tmpBuffer + (inSize + 1) / 2;
 
214
    const char *stop = inPtr + inSize;
 
215
 
 
216
    while (true)
 
217
    {
 
218
        if (inPtr < stop)
 
219
        *(t1++) = *(inPtr++);
 
220
        else
 
221
        break;
 
222
 
 
223
        if (inPtr < stop)
 
224
        *(t2++) = *(inPtr++);
 
225
        else
 
226
        break;
 
227
    }
 
228
    }
 
229
 
 
230
    //
 
231
    // Predictor.
 
232
    //
 
233
 
 
234
    {
 
235
    unsigned char *t = (unsigned char *) _tmpBuffer + 1;
 
236
    unsigned char *stop = (unsigned char *) _tmpBuffer + inSize;
 
237
    int p = t[-1];
 
238
 
 
239
    while (t < stop)
 
240
    {
 
241
        int d = int (t[0]) - p + (128 + 256);
 
242
        p = t[0];
 
243
        t[0] = d;
 
244
        ++t;
 
245
    }
 
246
    }
 
247
 
 
248
    //
 
249
    // Run-length encode the data.
 
250
    //
 
251
 
 
252
    outPtr = _outBuffer;
 
253
    return rleCompress (inSize, _tmpBuffer, (signed char *) _outBuffer);
 
254
}
 
255
 
 
256
 
 
257
int
 
258
RleCompressor::uncompress (const char *inPtr,
 
259
               int inSize,
 
260
               int /*minY*/,
 
261
               const char *&outPtr)
 
262
{
 
263
    //
 
264
    // Special case �- empty input buffer
 
265
    //
 
266
 
 
267
    if (inSize == 0)
 
268
    {
 
269
    outPtr = _outBuffer;
 
270
    return 0;
 
271
    }
 
272
 
 
273
    //
 
274
    // Decode the run-length encoded data
 
275
    //
 
276
 
 
277
    int outSize;
 
278
 
 
279
    if (0 == (outSize = rleUncompress (inSize, _maxScanLineSize,
 
280
                       (const signed char *) inPtr,
 
281
                       _tmpBuffer)))
 
282
    {
 
283
    throw Iex::InputExc ("Data decoding (rle) failed.");
 
284
    }
 
285
 
 
286
    //
 
287
    // Predictor.
 
288
    //
 
289
 
 
290
    {
 
291
    unsigned char *t = (unsigned char *) _tmpBuffer + 1;
 
292
    unsigned char *stop = (unsigned char *) _tmpBuffer + outSize;
 
293
 
 
294
    while (t < stop)
 
295
    {
 
296
        int d = int (t[-1]) + int (t[0]) - 128;
 
297
        t[0] = d;
 
298
        ++t;
 
299
    }
 
300
    }
 
301
 
 
302
    //
 
303
    // Reorder the pixel data.
 
304
    //
 
305
 
 
306
    {
 
307
    const char *t1 = _tmpBuffer;
 
308
    const char *t2 = _tmpBuffer + (outSize + 1) / 2;
 
309
    char *s = _outBuffer;
 
310
    char *stop = s + outSize;
 
311
 
 
312
    while (true)
 
313
    {
 
314
        if (s < stop)
 
315
        *(s++) = *(t1++);
 
316
        else
 
317
        break;
 
318
 
 
319
        if (s < stop)
 
320
        *(s++) = *(t2++);
 
321
        else
 
322
        break;
 
323
    }
 
324
    }
 
325
 
 
326
    outPtr = _outBuffer;
 
327
    return outSize;
 
328
}
 
329
 
 
330
 
 
331
} // namespace Imf