ImfWav.cpp 7.9 KB

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