Coverage Report

Created: 2023-12-08 06:53

/src/freeimage-svn/FreeImage/trunk/Source/OpenEXR/IlmImf/ImfWav.cpp
Line
Count
Source (jump to first uncovered line)
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
//  16-bit Haar Wavelet encoding and decoding
40
//
41
//  The source code in this file is derived from the encoding
42
//  and decoding routines written by Christian Rouet for his
43
//  PIZ image file format.
44
//
45
//-----------------------------------------------------------------------------
46
47
48
#include <ImfWav.h>
49
#include "ImfNamespace.h"
50
51
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
52
namespace {
53
54
55
//
56
// Wavelet basis functions without modulo arithmetic; they produce
57
// the best compression ratios when the wavelet-transformed data are
58
// Huffman-encoded, but the wavelet transform works only for 14-bit
59
// data (untransformed data values must be less than (1 << 14)).
60
//
61
62
inline void
63
wenc14 (unsigned short  a, unsigned short  b,
64
        unsigned short &l, unsigned short &h)
65
0
{
66
0
    short as = a;
67
0
    short bs = b;
68
69
0
    short ms = (as + bs) >> 1;
70
0
    short ds = as - bs;
71
72
0
    l = ms;
73
0
    h = ds;
74
0
}
75
76
77
inline void
78
wdec14 (unsigned short  l, unsigned short  h,
79
        unsigned short &a, unsigned short &b)
80
0
{
81
0
    short ls = l;
82
0
    short hs = h;
83
84
0
    int hi = hs;
85
0
    int ai = ls + (hi & 1) + (hi >> 1);
86
87
0
    short as = ai;
88
0
    short bs = ai - hi;
89
90
0
    a = as;
91
0
    b = bs;
92
0
}
93
94
95
//
96
// Wavelet basis functions with modulo arithmetic; they work with full
97
// 16-bit data, but Huffman-encoding the wavelet-transformed data doesn't
98
// compress the data quite as well.
99
//
100
101
const int NBITS = 16;
102
const int A_OFFSET =  1 << (NBITS  - 1);
103
const int M_OFFSET =  1 << (NBITS  - 1);
104
const int MOD_MASK = (1 <<  NBITS) - 1;
105
106
107
inline void
108
wenc16 (unsigned short  a, unsigned short  b,
109
        unsigned short &l, unsigned short &h)
110
0
{
111
0
    int ao =  (a + A_OFFSET) & MOD_MASK;
112
0
    int m  = ((ao + b) >> 1);
113
0
    int d  =   ao - b;
114
115
0
    if (d < 0)
116
0
  m = (m + M_OFFSET) & MOD_MASK;
117
118
0
    d &= MOD_MASK;
119
120
0
    l = m;
121
0
    h = d;
122
0
}
123
124
125
inline void
126
wdec16 (unsigned short  l, unsigned short  h,
127
        unsigned short &a, unsigned short &b)
128
0
{
129
0
    int m = l;
130
0
    int d = h;
131
0
    int bb = (m - (d >> 1)) & MOD_MASK;
132
0
    int aa = (d + bb - A_OFFSET) & MOD_MASK;
133
0
    b = bb;
134
0
    a = aa;
135
0
}
136
137
} // namespace
138
139
140
//
141
// 2D Wavelet encoding:
142
//
143
144
void
145
wav2Encode
146
    (unsigned short*  in, // io: values are transformed in place
147
     int    nx, // i : x size
148
     int    ox, // i : x offset
149
     int    ny, // i : y size
150
     int    oy, // i : y offset
151
     unsigned short mx) // i : maximum in[x][y] value
152
0
{
153
0
    bool w14 = (mx < (1 << 14));
154
0
    int n  = (nx > ny)? ny: nx;
155
0
    int p  = 1;     // == 1 <<  level
156
0
    int p2 = 2;     // == 1 << (level+1)
157
158
    //
159
    // Hierachical loop on smaller dimension n
160
    //
161
162
0
    while (p2 <= n)
163
0
    {
164
0
  unsigned short *py = in;
165
0
  unsigned short *ey = in + oy * (ny - p2);
166
0
  int oy1 = oy * p;
167
0
  int oy2 = oy * p2;
168
0
  int ox1 = ox * p;
169
0
  int ox2 = ox * p2;
170
0
  unsigned short i00,i01,i10,i11;
171
172
  //
173
  // Y loop
174
  //
175
176
0
  for (; py <= ey; py += oy2)
177
0
  {
178
0
      unsigned short *px = py;
179
0
      unsigned short *ex = py + ox * (nx - p2);
180
181
      //
182
      // X loop
183
      //
184
185
0
      for (; px <= ex; px += ox2)
186
0
      {
187
0
    unsigned short *p01 = px  + ox1;
188
0
    unsigned short *p10 = px  + oy1;
189
0
    unsigned short *p11 = p10 + ox1;
190
191
    //
192
    // 2D wavelet encoding
193
    //
194
195
0
    if (w14)
196
0
    {
197
0
        wenc14 (*px,  *p01, i00, i01);
198
0
        wenc14 (*p10, *p11, i10, i11);
199
0
        wenc14 (i00, i10, *px,  *p10);
200
0
        wenc14 (i01, i11, *p01, *p11);
201
0
    }
202
0
    else
203
0
    {
204
0
        wenc16 (*px,  *p01, i00, i01);
205
0
        wenc16 (*p10, *p11, i10, i11);
206
0
        wenc16 (i00, i10, *px,  *p10);
207
0
        wenc16 (i01, i11, *p01, *p11);
208
0
    }
209
0
      }
210
211
      //
212
      // Encode (1D) odd column (still in Y loop)
213
      //
214
215
0
      if (nx & p)
216
0
      {
217
0
    unsigned short *p10 = px + oy1;
218
219
0
    if (w14)
220
0
        wenc14 (*px, *p10, i00, *p10);
221
0
    else
222
0
        wenc16 (*px, *p10, i00, *p10);
223
224
0
    *px= i00;
225
0
      }
226
0
  }
227
228
  //
229
  // Encode (1D) odd line (must loop in X)
230
  //
231
232
0
  if (ny & p)
233
0
  {
234
0
      unsigned short *px = py;
235
0
      unsigned short *ex = py + ox * (nx - p2);
236
237
0
      for (; px <= ex; px += ox2)
238
0
      {
239
0
    unsigned short *p01 = px + ox1;
240
241
0
    if (w14)
242
0
        wenc14 (*px, *p01, i00, *p01);
243
0
    else
244
0
        wenc16 (*px, *p01, i00, *p01);
245
246
0
    *px= i00;
247
0
      }
248
0
  }
249
250
  //
251
  // Next level
252
  //
253
254
0
  p = p2;
255
0
  p2 <<= 1;
256
0
    }
257
0
}
258
259
260
//
261
// 2D Wavelet decoding:
262
//
263
264
void
265
wav2Decode
266
    (unsigned short*  in, // io: values are transformed in place
267
     int    nx, // i : x size
268
     int    ox, // i : x offset
269
     int    ny, // i : y size
270
     int    oy, // i : y offset
271
     unsigned short mx) // i : maximum in[x][y] value
272
0
{
273
0
    bool w14 = (mx < (1 << 14));
274
0
    int n = (nx > ny)? ny: nx;
275
0
    int p = 1;
276
0
    int p2;
277
278
    //
279
    // Search max level
280
    //
281
282
0
    while (p <= n)
283
0
  p <<= 1;
284
285
0
    p >>= 1;
286
0
    p2 = p;
287
0
    p >>= 1;
288
289
    //
290
    // Hierarchical loop on smaller dimension n
291
    //
292
293
0
    while (p >= 1)
294
0
    {
295
0
  unsigned short *py = in;
296
0
  unsigned short *ey = in + oy * (ny - p2);
297
0
  int oy1 = oy * p;
298
0
  int oy2 = oy * p2;
299
0
  int ox1 = ox * p;
300
0
  int ox2 = ox * p2;
301
0
  unsigned short i00,i01,i10,i11;
302
303
  //
304
  // Y loop
305
  //
306
307
0
  for (; py <= ey; py += oy2)
308
0
  {
309
0
      unsigned short *px = py;
310
0
      unsigned short *ex = py + ox * (nx - p2);
311
312
      //
313
      // X loop
314
      //
315
316
0
      for (; px <= ex; px += ox2)
317
0
      {
318
0
    unsigned short *p01 = px  + ox1;
319
0
    unsigned short *p10 = px  + oy1;
320
0
    unsigned short *p11 = p10 + ox1;
321
322
    //
323
    // 2D wavelet decoding
324
    //
325
326
0
    if (w14)
327
0
    {
328
0
        wdec14 (*px,  *p10, i00, i10);
329
0
        wdec14 (*p01, *p11, i01, i11);
330
0
        wdec14 (i00, i01, *px,  *p01);
331
0
        wdec14 (i10, i11, *p10, *p11);
332
0
    }
333
0
    else
334
0
    {
335
0
        wdec16 (*px,  *p10, i00, i10);
336
0
        wdec16 (*p01, *p11, i01, i11);
337
0
        wdec16 (i00, i01, *px,  *p01);
338
0
        wdec16 (i10, i11, *p10, *p11);
339
0
    }
340
0
      }
341
342
      //
343
      // Decode (1D) odd column (still in Y loop)
344
      //
345
346
0
      if (nx & p)
347
0
      {
348
0
    unsigned short *p10 = px + oy1;
349
350
0
    if (w14)
351
0
        wdec14 (*px, *p10, i00, *p10);
352
0
    else
353
0
        wdec16 (*px, *p10, i00, *p10);
354
355
0
    *px= i00;
356
0
      }
357
0
  }
358
359
  //
360
  // Decode (1D) odd line (must loop in X)
361
  //
362
363
0
  if (ny & p)
364
0
  {
365
0
      unsigned short *px = py;
366
0
      unsigned short *ex = py + ox * (nx - p2);
367
368
0
      for (; px <= ex; px += ox2)
369
0
      {
370
0
    unsigned short *p01 = px + ox1;
371
372
0
    if (w14)
373
0
        wdec14 (*px, *p01, i00, *p01);
374
0
    else
375
0
        wdec16 (*px, *p01, i00, *p01);
376
377
0
    *px= i00;
378
0
      }
379
0
  }
380
381
  //
382
  // Next level
383
  //
384
385
0
  p2 = p;
386
0
  p >>= 1;
387
0
    }
388
0
}
389
390
391
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT