Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4758 | right-hear | 1 | /* |
2 | * Copyright (c) 2001-2003, David Janssens |
||
3 | * Copyright (c) 2002-2003, Yannick Verschueren |
||
4 | * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe |
||
5 | * Copyright (c) 2005, Hervé Drolon, FreeImage Team |
||
6 | * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium |
||
7 | * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain |
||
8 | * All rights reserved. |
||
9 | * |
||
10 | * Redistribution and use in source and binary forms, with or without |
||
11 | * modification, are permitted provided that the following conditions |
||
12 | * are met: |
||
13 | * 1. Redistributions of source code must retain the above copyright |
||
14 | * notice, this list of conditions and the following disclaimer. |
||
15 | * 2. Redistributions in binary form must reproduce the above copyright |
||
16 | * notice, this list of conditions and the following disclaimer in the |
||
17 | * documentation and/or other materials provided with the distribution. |
||
18 | * |
||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' |
||
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||
29 | * POSSIBILITY OF SUCH DAMAGE. |
||
30 | */ |
||
31 | |||
32 | /* |
||
33 | * NOTE: |
||
34 | * This is a modified version of the openjpeg dwt.c file. |
||
35 | * Average speed improvement compared to the original file (measured on |
||
36 | * my own machine, a P4 running at 3.0 GHz): |
||
37 | * 5x3 wavelets about 2 times faster |
||
38 | * 9x7 wavelets about 3 times faster |
||
39 | * for both, encoding and decoding. |
||
40 | * |
||
41 | * The better performance is caused by doing the 1-dimensional DWT |
||
42 | * within a temporary buffer where the data can be accessed sequential |
||
43 | * for both directions, horizontal and vertical. The 2d vertical DWT was |
||
44 | * the major bottleneck in the former version. |
||
45 | * |
||
46 | * I have also removed the "Add Patrick" part because it is not longer |
||
47 | * needed. |
||
48 | * |
||
49 | * 6/6/2005 |
||
50 | * -Ive (aka Reiner Wahler) |
||
51 | * mail: ive@lilysoft.com |
||
52 | */ |
||
53 | |||
54 | #include "opj_includes.h" |
||
55 | |||
56 | /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ |
||
57 | /*@{*/ |
||
58 | |||
59 | /** @name Local static functions */ |
||
60 | /*@{*/ |
||
61 | unsigned int ops; |
||
62 | /** |
||
63 | Forward lazy transform (horizontal) |
||
64 | */ |
||
65 | static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas); |
||
66 | /** |
||
67 | Forward lazy transform (vertical) |
||
68 | */ |
||
69 | static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas); |
||
70 | /** |
||
71 | Forward lazy transform (axial) |
||
72 | */ |
||
73 | static void dwt_deinterleave_z(int *a, int *b, int dn, int sn, int xy, int cas); |
||
74 | /** |
||
75 | Inverse lazy transform (horizontal) |
||
76 | */ |
||
77 | static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas); |
||
78 | /** |
||
79 | Inverse lazy transform (vertical) |
||
80 | */ |
||
81 | static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas); |
||
82 | /** |
||
83 | Inverse lazy transform (axial) |
||
84 | */ |
||
85 | static void dwt_interleave_z(int *a, int *b, int dn, int sn, int xy, int cas); |
||
86 | /** |
||
87 | Forward 5-3 wavelet tranform in 1-D |
||
88 | */ |
||
89 | static void dwt_encode_53(int *a, int dn, int sn, int cas); |
||
90 | static void dwt_encode_97(int *a, int dn, int sn, int cas); |
||
91 | /** |
||
92 | Inverse 5-3 wavelet tranform in 1-D |
||
93 | */ |
||
94 | static void dwt_decode_53(int *a, int dn, int sn, int cas); |
||
95 | static void dwt_decode_97(int *a, int dn, int sn, int cas); |
||
96 | /** |
||
97 | Computing of wavelet transform L2 norms for arbitrary transforms |
||
98 | */ |
||
99 | static double dwt_calc_wtnorms(int orient, int level[3], int dwtid[3], opj_wtfilt_t *wtfiltx, opj_wtfilt_t *wtfilty, opj_wtfilt_t *wtfiltz); |
||
100 | /** |
||
101 | Encoding of quantification stepsize |
||
102 | */ |
||
103 | static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize); |
||
104 | /*@}*/ |
||
105 | |||
106 | /*@}*/ |
||
107 | |||
108 | #define S(i) a[(i)*2] |
||
109 | #define D(i) a[(1+(i)*2)] |
||
110 | #define S_(i) ((i)<0?S(0):((i)>=sn?S(sn-1):S(i))) |
||
111 | #define D_(i) ((i)<0?D(0):((i)>=dn?D(dn-1):D(i))) |
||
112 | /* new */ |
||
113 | #define SS_(i) ((i)<0?S(0):((i)>=dn?S(dn-1):S(i))) |
||
114 | #define DD_(i) ((i)<0?D(0):((i)>=sn?D(sn-1):D(i))) |
||
115 | |||
116 | /* |
||
117 | /* This table contains the norms of the 5-3 wavelets for different bands. */ |
||
118 | /* */ |
||
119 | static double dwt_norm[10][10][10][8]; |
||
120 | static int flagnorm[10][10][10][8]; |
||
121 | |||
122 | /*static const double dwt_norms[5][8][10] = { |
||
123 | {//ResZ=1 |
||
124 | {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, |
||
125 | {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
126 | {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
127 | {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93} |
||
128 | },{//ResZ=2 |
||
129 | {1.000, 1.8371, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, |
||
130 | {1.2717, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
131 | {1.2717, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
132 | {.8803, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}, |
||
133 | {1.2717}, |
||
134 | {.8803}, |
||
135 | {.8803}, |
||
136 | {.6093}, |
||
137 | },{ //ResZ=3 |
||
138 | {1.000, 1.8371, 4.5604, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, |
||
139 | {1.2717, 2.6403, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
140 | {1.2717, 2.6403, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
141 | {.8803, 1.5286, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}, |
||
142 | {1.2717, 2.6403}, |
||
143 | {.8803, 1.5286}, |
||
144 | {.8803, 1.5286}, |
||
145 | {.6093, 0.8850}, |
||
146 | },{ //ResZ=4 |
||
147 | {1.000, 1.8371, 4.5604, 12.4614, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, |
||
148 | {1.2717, 2.6403, 6.7691 , 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
149 | {1.2717, 2.6403, 6.7691 , 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
150 | {.8803, 1.5286, 3.6770 , 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}, |
||
151 | {1.2717, 2.6403, 6.7691 }, |
||
152 | {.8803, 1.5286, 3.6770 }, |
||
153 | {.8803, 1.5286, 3.6770 }, |
||
154 | {.6093, 0.8850, 1.9974 }, |
||
155 | },{ //ResZ=5 |
||
156 | {1.000, 1.8371, 4.5604, 12.4614, 34.9025, 21.34, 42.67, 85.33, 170.7, 341.3}, |
||
157 | {1.2717, 2.6403, 6.7691 , 18.6304 , 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
158 | {1.2717, 2.6403, 6.7691 , 18.6304, 11.33, 22.64, 45.25, 90.48, 180.9}, |
||
159 | {.8803, 1.5286, 3.6770 , 9.9446, 6.019, 12.01, 24.00, 47.97, 95.93}, |
||
160 | {1.2717, 2.6403, 6.7691, 18.6304}, |
||
161 | {.8803, 1.5286, 3.6770, 9.9446 }, |
||
162 | {.8803, 1.5286, 3.6770, 9.9446 }, |
||
163 | {.6093, 0.8850, 1.9974, 5.3083 }, |
||
164 | } |
||
165 | };*/ |
||
166 | |||
167 | /* |
||
168 | /* This table contains the norms of the 9-7 wavelets for different bands. */ |
||
169 | /* */ |
||
170 | /*static const double dwt_norms_real[5][8][10] = { |
||
171 | {//ResZ==1 |
||
172 | {1.000, 1.9659, 4.1224, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, |
||
173 | {1.0113, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
174 | {1.0113, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
175 | {0.5202, 0.9672, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722} |
||
176 | }, { //ResZ==2 |
||
177 | {1.000, 2.7564, 4.1224, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, |
||
178 | {1.4179, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
179 | {1.4179, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
180 | {0.7294, 0.9672, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, |
||
181 | {1.4179}, |
||
182 | {0.7294}, |
||
183 | {0.7294}, |
||
184 | {0.3752} //HHH |
||
185 | },{ //ResZ==3 |
||
186 | {1.000, 2.7564, 8.3700, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, |
||
187 | {1.4179, 4.0543, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
188 | {1.4179, 4.0543, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
189 | {0.7294, 1.9638, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, |
||
190 | {1.4179, 4.0543}, |
||
191 | {0.7294, 1.9638}, |
||
192 | {0.7294, 1.9638}, |
||
193 | {0.3752, 0.9512} //HHH |
||
194 | },{ //ResZ==4 |
||
195 | {1.000, 2.7564, 8.3700, 24.4183, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, |
||
196 | {1.4179, 4.0543, 12.1366, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
197 | {1.4179, 4.0543, 12.1366, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
198 | {0.7294, 1.9638, 6.0323, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, |
||
199 | {1.4179, 4.0543, 12.1366}, |
||
200 | {0.7294, 1.9638, 6.0323}, |
||
201 | {0.7294, 1.9638, 6.0323}, |
||
202 | {0.3752, 0.9512, 2.9982} //HHH |
||
203 | },{ //ResZ==5 |
||
204 | {1.000, 2.7564, 8.3700, 24.4183, 69.6947, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, |
||
205 | {1.4179, 4.0543, 12.1366, 35.1203, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
206 | {1.4179, 4.0543, 12.1366, 35.1203, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, |
||
207 | {0.7294, 1.9638, 6.0323, 17.6977, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, |
||
208 | {1.4179, 4.0543, 12.1366, 35.1203}, |
||
209 | {0.7294, 1.9638, 6.0323, 17.6977}, |
||
210 | {0.7294, 1.9638, 6.0323, 17.6977}, |
||
211 | {0.3752, 0.9512, 2.9982, 8.9182} //HHH |
||
212 | } |
||
213 | };*/ |
||
214 | |||
215 | static opj_atk_t atk_info_wt[] = { |
||
216 | {0, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1.230174104, 4, {0}, {0}, {0}, {1,1,1,1}, {-1.586134342059924, -0.052980118572961, 0.882911075530934, 0.443506852043971}},/* WT 9-7 IRR*/ |
||
217 | {1, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {1,2}, {1,2}, {1,1}, {-1,1}},/* WT 5-3 REV*/ |
||
218 | {2, 0, J3D_ATK_ARB, J3D_ATK_REV, 0, J3D_ATK_CON, 0, 2, {0,0}, {0,1}, {0,1}, {1,1}, {{-1},{1}}}, /* WT 2-2 REV*/ |
||
219 | {3, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-1}, {0,1,2}, {0,1,2}, {1,1,3}, {{-1},{1},{1,0,-1}}}, /* WT 2-6 REV*/ |
||
220 | {4, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-2}, {0,1,6}, {0,1,32}, {1,1,5}, {{-1},{1},{-3,22,0,-22,3}}}, /* WT 2-10 REV*/ |
||
221 | {5, 1, J3D_ATK_ARB, J3D_ATK_IRR, 1, J3D_ATK_WS, 1, 7, {0}, {0}, {0}, {1,1,2,1,2,1,3},{{-1},{1.58613434206},{-0.460348209828, 0.460348209828},{0.25},{0.374213867768,-0.374213867768},{-1.33613434206},{0.29306717103,0,-0.29306717103}}}, /* WT 6-10 IRR*/ |
||
222 | {6, 1, J3D_ATK_ARB, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 11, {0}, {0}, {0}, {1,1,2,1,2,1,2,1,2,1,5},{{-1},{0,99715069105},{-1.00573127827, 1.00573127827},{-0.27040357631},{2.20509972343, -2.20509972343},{0.08059995736}, |
||
223 | {-1.62682532350, 1.62682532350},{0.52040357631},{0.60404664250, -0.60404664250},{-0.82775064841},{-0.06615812964, 0.29402137720, 0, -0.29402137720, 0.06615812964}}}, /* WT 10-18 IRR*/ |
||
224 | {7, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 2, {0}, {0}, {0}, {1,1}, {-0.5, 0.25}}, /* WT 5-3 IRR*/ |
||
225 | {8, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {4,4}, {8,8}, {2,2}, {{-9,1},{5,-1}}} /* WT 13-7 REV*/ |
||
226 | }; |
||
227 | /* |
||
228 | ========================================================== |
||
229 | local functions |
||
230 | ========================================================== |
||
231 | */ |
||
232 | |||
233 | /* |
||
234 | /* Forward lazy transform (horizontal). */ |
||
235 | /* */ |
||
236 | static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) { |
||
237 | int i; |
||
238 | for (i=0; i |
||
239 | for (i=0; i |
||
240 | } |
||
241 | |||
242 | /* |
||
243 | /* Forward lazy transform (vertical). */ |
||
244 | /* */ |
||
245 | static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) { |
||
246 | int i; |
||
247 | for (i=0; i |
||
248 | for (i=0; i |
||
249 | } |
||
250 | |||
251 | /* |
||
252 | /* Forward lazy transform (axial). */ |
||
253 | /* */ |
||
254 | static void dwt_deinterleave_z(int *a, int *b, int dn, int sn, int xy, int cas) { |
||
255 | int i; |
||
256 | for (i=0; i |
||
257 | for (i=0; i |
||
258 | } |
||
259 | |||
260 | /* |
||
261 | /* Inverse lazy transform (horizontal). */ |
||
262 | /* */ |
||
263 | static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas) { |
||
264 | int i; |
||
265 | int *ai = NULL; |
||
266 | int *bi = NULL; |
||
267 | ai = a; |
||
268 | bi = b + cas; |
||
269 | for (i = 0; i < sn; i++) { |
||
270 | *bi = *ai; |
||
271 | bi += 2; |
||
272 | ai++; |
||
273 | } |
||
274 | ai = a + sn; |
||
275 | bi = b + 1 - cas; |
||
276 | for (i = 0; i < dn; i++) { |
||
277 | *bi = *ai; |
||
278 | bi += 2; |
||
279 | ai++; |
||
280 | } |
||
281 | } |
||
282 | |||
283 | /* |
||
284 | /* Inverse lazy transform (vertical). */ |
||
285 | /* */ |
||
286 | static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas) { |
||
287 | int i; |
||
288 | int *ai = NULL; |
||
289 | int *bi = NULL; |
||
290 | ai = a; |
||
291 | bi = b + cas; |
||
292 | for (i = 0; i < sn; i++) { |
||
293 | *bi = *ai; |
||
294 | bi += 2; |
||
295 | ai += x; |
||
296 | } |
||
297 | ai = a + (sn * x); |
||
298 | bi = b + 1 - cas; |
||
299 | for (i = 0; i < dn; i++) { |
||
300 | *bi = *ai; |
||
301 | bi += 2; |
||
302 | ai += x; |
||
303 | } |
||
304 | } |
||
305 | |||
306 | /* |
||
307 | /* Inverse lazy transform (axial). */ |
||
308 | /* */ |
||
309 | static void dwt_interleave_z(int *a, int *b, int dn, int sn, int xy, int cas) { |
||
310 | int i; |
||
311 | int *ai = NULL; |
||
312 | int *bi = NULL; |
||
313 | ai = a; |
||
314 | bi = b + cas; |
||
315 | for (i = 0; i < sn; i++) { |
||
316 | *bi = *ai; |
||
317 | bi += 2; |
||
318 | ai += xy; |
||
319 | } |
||
320 | ai = a + (sn * xy); |
||
321 | bi = b + 1 - cas; |
||
322 | for (i = 0; i < dn; i++) { |
||
323 | *bi = *ai; |
||
324 | bi += 2; |
||
325 | ai += xy; |
||
326 | } |
||
327 | } |
||
328 | |||
329 | |||
330 | /* |
||
331 | /* Forward 5-3 or 9-7 wavelet tranform in 1-D. */ |
||
332 | /* */ |
||
333 | static void dwt_encode_53(int *a, int dn, int sn, int cas) { |
||
334 | int i; |
||
335 | |||
336 | if (!cas) { |
||
337 | if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ |
||
338 | //for (i = 0; i < dn; i++) D(i) -= (S_(i) + S_(i + 1)) >> 1; |
||
339 | //for (i = 0; i < sn; i++) S(i) += (D_(i - 1) + D_(i) + 2) >> 2; |
||
340 | for (i = 0; i < dn; i++){ |
||
341 | D(i) -= (S_(i) + S_(i + 1)) >> 1; |
||
342 | //ops += 2; |
||
343 | } |
||
344 | for (i = 0; i < sn; i++){ |
||
345 | S(i) += (D_(i - 1) + D_(i) + 2) >> 2; |
||
346 | //ops += 3; |
||
347 | } |
||
348 | } |
||
349 | } else { |
||
350 | /*if (!sn && dn == 1) |
||
351 | S(0) *= 2; |
||
352 | else { |
||
353 | for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1; |
||
354 | for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2; |
||
355 | }*/ |
||
356 | if (!sn && dn == 1){ |
||
357 | S(0) *= 2; |
||
358 | //ops++; |
||
359 | } else { |
||
360 | for (i = 0; i < dn; i++){ |
||
361 | S(i) -= (DD_(i) + DD_(i - 1)) >> 1; |
||
362 | // ops += 2; |
||
363 | } |
||
364 | for (i = 0; i < sn; i++){ |
||
365 | D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2; |
||
366 | // ops += 3; |
||
367 | } |
||
368 | } |
||
369 | } |
||
370 | } |
||
371 | static void dwt_encode_97(int *a, int dn, int sn, int cas) { |
||
372 | int i; |
||
373 | |||
374 | if (!cas) { |
||
375 | if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ |
||
376 | for (i = 0; i < dn; i++) |
||
377 | D(i) -= fix_mul(S_(i) + S_(i + 1), 12993); |
||
378 | for (i = 0; i < sn; i++) |
||
379 | S(i) -= fix_mul(D_(i - 1) + D_(i), 434); |
||
380 | for (i = 0; i < dn; i++) |
||
381 | D(i) += fix_mul(S_(i) + S_(i + 1), 7233); |
||
382 | for (i = 0; i < sn; i++) |
||
383 | S(i) += fix_mul(D_(i - 1) + D_(i), 3633); |
||
384 | for (i = 0; i < dn; i++) |
||
385 | D(i) = fix_mul(D(i), 5038); /*5038 */ |
||
386 | for (i = 0; i < sn; i++) |
||
387 | S(i) = fix_mul(S(i), 6659); /*6660 */ |
||
388 | } |
||
389 | } else { |
||
390 | if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ |
||
391 | for (i = 0; i < dn; i++) |
||
392 | S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993); |
||
393 | for (i = 0; i < sn; i++) |
||
394 | D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434); |
||
395 | for (i = 0; i < dn; i++) |
||
396 | S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233); |
||
397 | for (i = 0; i < sn; i++) |
||
398 | D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633); |
||
399 | for (i = 0; i < dn; i++) |
||
400 | S(i) = fix_mul(S(i), 5038); /*5038 */ |
||
401 | for (i = 0; i < sn; i++) |
||
402 | D(i) = fix_mul(D(i), 6659); /*6660 */ |
||
403 | } |
||
404 | } |
||
405 | } |
||
406 | /* |
||
407 | /* Inverse 5-3 or 9-7 wavelet tranform in 1-D. */ |
||
408 | /* */ |
||
409 | static void dwt_decode_53(int *a, int dn, int sn, int cas) { |
||
410 | int i; |
||
411 | if (!cas) { |
||
412 | if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ |
||
413 | for (i = 0; i < sn; i++) S(i) -= (D_(i - 1) + D_(i) + 2) >> 2; |
||
414 | for (i = 0; i < dn; i++) D(i) += (S_(i) + S_(i + 1)) >> 1; |
||
415 | } |
||
416 | } else { |
||
417 | if (!sn && dn == 1) /* NEW : CASE ONE ELEMENT */ |
||
418 | S(0) /= 2; |
||
419 | else { |
||
420 | for (i = 0; i < sn; i++) D(i) -= (SS_(i) + SS_(i + 1) + 2) >> 2; |
||
421 | for (i = 0; i < dn; i++) S(i) += (DD_(i) + DD_(i - 1)) >> 1; |
||
422 | } |
||
423 | } |
||
424 | } |
||
425 | static void dwt_decode_97(int *a, int dn, int sn, int cas) { |
||
426 | int i; |
||
427 | |||
428 | if (!cas) { |
||
429 | if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ |
||
430 | for (i = 0; i < sn; i++) |
||
431 | S(i) = fix_mul(S(i), 10078); /* 10076 */ |
||
432 | for (i = 0; i < dn; i++) |
||
433 | D(i) = fix_mul(D(i), 13318); /* 13320 */ |
||
434 | for (i = 0; i < sn; i++) |
||
435 | S(i) -= fix_mul(D_(i - 1) + D_(i), 3633); |
||
436 | for (i = 0; i < dn; i++) |
||
437 | D(i) -= fix_mul(S_(i) + S_(i + 1), 7233); |
||
438 | for (i = 0; i < sn; i++) |
||
439 | S(i) += fix_mul(D_(i - 1) + D_(i), 434); |
||
440 | for (i = 0; i < dn; i++) |
||
441 | D(i) += fix_mul(S_(i) + S_(i + 1), 12994); /* 12993 */ |
||
442 | } |
||
443 | } else { |
||
444 | if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ |
||
445 | for (i = 0; i < sn; i++) |
||
446 | D(i) = fix_mul(D(i), 10078); /* 10076 */ |
||
447 | for (i = 0; i < dn; i++) |
||
448 | S(i) = fix_mul(S(i), 13318); /* 13320 */ |
||
449 | for (i = 0; i < sn; i++) |
||
450 | D(i) -= fix_mul(SS_(i) + SS_(i + 1), 3633); |
||
451 | for (i = 0; i < dn; i++) |
||
452 | S(i) -= fix_mul(DD_(i) + DD_(i - 1), 7233); |
||
453 | for (i = 0; i < sn; i++) |
||
454 | D(i) += fix_mul(SS_(i) + SS_(i + 1), 434); |
||
455 | for (i = 0; i < dn; i++) |
||
456 | S(i) += fix_mul(DD_(i) + DD_(i - 1), 12994); /* 12993 */ |
||
457 | } |
||
458 | } |
||
459 | } |
||
460 | |||
461 | |||
462 | /* |
||
463 | /* Get norm of arbitrary wavelet transform. */ |
||
464 | /* */ |
||
465 | static int upandconv(double *nXPS, double *LPS, int lenXPS, int lenLPS) { |
||
466 | /* Perform the convolution of the vectors. */ |
||
467 | int i,j; |
||
468 | double *tmp = (double *)opj_malloc(2*lenXPS * sizeof(double)); |
||
469 | //Upsample |
||
470 | memset(tmp, 0, 2*lenXPS*sizeof(double)); |
||
471 | for (i = 0; i < lenXPS; i++) { |
||
472 | *(tmp + 2*i) = *(nXPS + i); |
||
473 | *(nXPS + i) = 0; |
||
474 | } |
||
475 | //Convolution |
||
476 | for (i = 0; i < 2*lenXPS; i++) { |
||
477 | for (j = 0; j < lenLPS; j++) { |
||
478 | *(nXPS+i+j) = *(nXPS+i+j) + *(tmp + i) * *(LPS + j); |
||
479 | //fprintf(stdout,"*(tmp + %d) * *(LPS + %d) = %f * %f \n",i,j,*(tmp + i),*(LPS + j)); |
||
480 | } |
||
481 | } |
||
482 | free(tmp); |
||
483 | return 2*lenXPS+lenLPS-1; |
||
484 | } |
||
485 | |||
486 | static double dwt_calc_wtnorms(int orient, int level[3], int dwtid[3], opj_wtfilt_t *wtfiltX, opj_wtfilt_t *wtfiltY, opj_wtfilt_t *wtfiltZ) { |
||
487 | int i, lenLPS, lenHPS; |
||
488 | double Lx = 0, Ly= 0, Hx= 0, Hy= 0, Lz= 0, Hz= 0; |
||
489 | double *nLPSx, *nHPSx,*nLPSy, *nHPSy,*nLPSz, *nHPSz; |
||
490 | int levelx, levely, levelz; |
||
491 | |||
492 | levelx = (orient == 0) ? level[0]-1 : level[0]; |
||
493 | levely = (orient == 0) ? level[1]-1 : level[1]; |
||
494 | levelz = (orient == 0) ? level[2]-1 : level[2]; |
||
495 | |||
496 | //X axis |
||
497 | lenLPS = wtfiltX->lenLPS; |
||
498 | lenHPS = wtfiltX->lenHPS; |
||
499 | for (i = 0; i < levelx; i++) { |
||
500 | lenLPS *= 2; |
||
501 | lenHPS *= 2; |
||
502 | lenLPS += wtfiltX->lenLPS - 1; |
||
503 | lenHPS += wtfiltX->lenLPS - 1; |
||
504 | } |
||
505 | nLPSx = (double *)opj_malloc(lenLPS * sizeof(double)); |
||
506 | nHPSx = (double *)opj_malloc(lenHPS * sizeof(double)); |
||
507 | |||
508 | memcpy(nLPSx, wtfiltX->LPS, wtfiltX->lenLPS * sizeof(double)); |
||
509 | memcpy(nHPSx, wtfiltX->HPS, wtfiltX->lenHPS * sizeof(double)); |
||
510 | lenLPS = wtfiltX->lenLPS; |
||
511 | lenHPS = wtfiltX->lenHPS; |
||
512 | for (i = 0; i < levelx; i++) { |
||
513 | lenLPS = upandconv(nLPSx, wtfiltX->LPS, lenLPS, wtfiltX->lenLPS); |
||
514 | lenHPS = upandconv(nHPSx, wtfiltX->LPS, lenHPS, wtfiltX->lenLPS); |
||
515 | } |
||
516 | for (i = 0; i < lenLPS; i++) |
||
517 | Lx += nLPSx[i] * nLPSx[i]; |
||
518 | for (i = 0; i < lenHPS; i++) |
||
519 | Hx += nHPSx[i] * nHPSx[i]; |
||
520 | Lx = sqrt(Lx); |
||
521 | Hx = sqrt(Hx); |
||
522 | free(nLPSx); |
||
523 | free(nHPSx); |
||
524 | |||
525 | //Y axis |
||
526 | if (dwtid[0] != dwtid[1] || level[0] != level[1]){ |
||
527 | lenLPS = wtfiltY->lenLPS; |
||
528 | lenHPS = wtfiltY->lenHPS; |
||
529 | for (i = 0; i < levely; i++) { |
||
530 | lenLPS *= 2; |
||
531 | lenHPS *= 2; |
||
532 | lenLPS += wtfiltY->lenLPS - 1; |
||
533 | lenHPS += wtfiltY->lenLPS - 1; |
||
534 | } |
||
535 | nLPSy = (double *)opj_malloc(lenLPS * sizeof(double)); |
||
536 | nHPSy = (double *)opj_malloc(lenHPS * sizeof(double)); |
||
537 | |||
538 | memcpy(nLPSy, wtfiltY->LPS, wtfiltY->lenLPS * sizeof(double)); |
||
539 | memcpy(nHPSy, wtfiltY->HPS, wtfiltY->lenHPS * sizeof(double)); |
||
540 | lenLPS = wtfiltY->lenLPS; |
||
541 | lenHPS = wtfiltY->lenHPS; |
||
542 | for (i = 0; i < levely; i++) { |
||
543 | lenLPS = upandconv(nLPSy, wtfiltY->LPS, lenLPS, wtfiltY->lenLPS); |
||
544 | lenHPS = upandconv(nHPSy, wtfiltY->LPS, lenHPS, wtfiltY->lenLPS); |
||
545 | } |
||
546 | for (i = 0; i < lenLPS; i++) |
||
547 | Ly += nLPSy[i] * nLPSy[i]; |
||
548 | for (i = 0; i < lenHPS; i++) |
||
549 | Hy += nHPSy[i] * nHPSy[i]; |
||
550 | Ly = sqrt(Ly); |
||
551 | Hy = sqrt(Hy); |
||
552 | free(nLPSy); |
||
553 | free(nHPSy); |
||
554 | } else { |
||
555 | Ly = Lx; |
||
556 | Hy = Hx; |
||
557 | } |
||
558 | //Z axis |
||
559 | if (levelz >= 0) { |
||
560 | lenLPS = wtfiltZ->lenLPS; |
||
561 | lenHPS = wtfiltZ->lenHPS; |
||
562 | for (i = 0; i < levelz; i++) { |
||
563 | lenLPS *= 2; |
||
564 | lenHPS *= 2; |
||
565 | lenLPS += wtfiltZ->lenLPS - 1; |
||
566 | lenHPS += wtfiltZ->lenLPS - 1; |
||
567 | } |
||
568 | nLPSz = (double *)opj_malloc(lenLPS * sizeof(double)); |
||
569 | nHPSz = (double *)opj_malloc(lenHPS * sizeof(double)); |
||
570 | |||
571 | memcpy(nLPSz, wtfiltZ->LPS, wtfiltZ->lenLPS * sizeof(double)); |
||
572 | memcpy(nHPSz, wtfiltZ->HPS, wtfiltZ->lenHPS * sizeof(double)); |
||
573 | lenLPS = wtfiltZ->lenLPS; |
||
574 | lenHPS = wtfiltZ->lenHPS; |
||
575 | for (i = 0; i < levelz; i++) { |
||
576 | lenLPS = upandconv(nLPSz, wtfiltZ->LPS, lenLPS, wtfiltZ->lenLPS); |
||
577 | lenHPS = upandconv(nHPSz, wtfiltZ->LPS, lenHPS, wtfiltZ->lenLPS); |
||
578 | } |
||
579 | for (i = 0; i < lenLPS; i++) |
||
580 | Lz += nLPSz[i] * nLPSz[i]; |
||
581 | for (i = 0; i < lenHPS; i++) |
||
582 | Hz += nHPSz[i] * nHPSz[i]; |
||
583 | Lz = sqrt(Lz); |
||
584 | Hz = sqrt(Hz); |
||
585 | free(nLPSz); |
||
586 | free(nHPSz); |
||
587 | } else { |
||
588 | Lz = 1.0; Hz = 1.0; |
||
589 | } |
||
590 | switch (orient) { |
||
591 | case 0: |
||
592 | return Lx * Ly * Lz; |
||
593 | case 1: |
||
594 | return Lx * Hy * Lz; |
||
595 | case 2: |
||
596 | return Hx * Ly * Lz; |
||
597 | case 3: |
||
598 | return Hx * Hy * Lz; |
||
599 | case 4: |
||
600 | return Lx * Ly * Hz; |
||
601 | case 5: |
||
602 | return Lx * Hy * Hz; |
||
603 | case 6: |
||
604 | return Hx * Ly * Hz; |
||
605 | case 7: |
||
606 | return Hx * Hy * Hz; |
||
607 | default: |
||
608 | return -1; |
||
609 | } |
||
610 | |||
611 | } |
||
612 | static void dwt_getwtfilters(opj_wtfilt_t *wtfilt, int dwtid) { |
||
613 | if (dwtid == 0) { //DWT 9-7 |
||
614 | wtfilt->lenLPS = 7; wtfilt->lenHPS = 9; |
||
615 | wtfilt->LPS = (double *)opj_malloc(wtfilt->lenLPS * sizeof(double)); |
||
616 | wtfilt->HPS = (double *)opj_malloc(wtfilt->lenHPS * sizeof(double)); |
||
617 | wtfilt->LPS[0] = -0.091271763114; wtfilt->HPS[0] = 0.026748757411; |
||
618 | wtfilt->LPS[1] = -0.057543526228; wtfilt->HPS[1] = 0.016864118443; |
||
619 | wtfilt->LPS[2] = 0.591271763114; wtfilt->HPS[2] = -0.078223266529; |
||
620 | wtfilt->LPS[3] = 1.115087052457; wtfilt->HPS[3] = -0.266864118443; |
||
621 | wtfilt->LPS[4] = 0.591271763114; wtfilt->HPS[4] = 0.602949018236; |
||
622 | wtfilt->LPS[5] = -0.057543526228; wtfilt->HPS[5] = -0.266864118443; |
||
623 | wtfilt->LPS[6] = -0.091271763114; wtfilt->HPS[6] = -0.078223266529; |
||
624 | wtfilt->HPS[7] = 0.016864118443; |
||
625 | wtfilt->HPS[8] = 0.026748757411; |
||
626 | } else if (dwtid == 1) { //DWT 5-3 |
||
627 | wtfilt->lenLPS = 3; wtfilt->lenHPS = 5; |
||
628 | wtfilt->LPS = (double *)opj_malloc(wtfilt->lenLPS * sizeof(double)); |
||
629 | wtfilt->HPS = (double *)opj_malloc(wtfilt->lenHPS * sizeof(double)); |
||
630 | wtfilt->LPS[0] = 0.5; wtfilt->HPS[0] = -0.125; |
||
631 | wtfilt->LPS[1] = 1; wtfilt->HPS[1] = -0.25; |
||
632 | wtfilt->LPS[2] = 0.5; wtfilt->HPS[2] = 0.75; |
||
633 | wtfilt->HPS[3] = -0.25; |
||
634 | wtfilt->HPS[4] = -0.125; |
||
635 | } else { |
||
636 | fprintf(stdout,"[ERROR] Sorry, this wavelet hasn't been implemented so far ... Try another one :-)\n"); |
||
637 | exit(1); |
||
638 | } |
||
639 | } |
||
640 | /* |
||
641 | /* Encoding of quantization stepsize for each subband. */ |
||
642 | /* */ |
||
643 | static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) { |
||
644 | int p, n; |
||
645 | p = int_floorlog2(stepsize) - 13; |
||
646 | n = 11 - int_floorlog2(stepsize); |
||
647 | bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff; |
||
648 | bandno_stepsize->expn = numbps - p; |
||
649 | //if J3D_CCP_QNTSTY_NOQNT --> stepsize = 8192.0 --> p = 0, n = -2 --> mant = 0; expn = (prec+gain) |
||
650 | //else --> bandno_stepsize = (1<<(numbps - expn)) + (1<<(numbps - expn - 11)) * Ub |
||
651 | } |
||
652 | |||
653 | /* |
||
654 | ========================================================== |
||
655 | DWT interface |
||
656 | ========================================================== |
||
657 | */ |
||
658 | /* |
||
659 | /* Forward 5-3 wavelet tranform in 3-D. */ |
||
660 | /* */ |
||
661 | void dwt_encode(opj_tcd_tilecomp_t * tilec, int dwtid[3]) { |
||
662 | int i, j, k; |
||
663 | int x, y, z; |
||
664 | int w, h, wh, d; |
||
665 | int level,levelx,levely,levelz,diff; |
||
666 | int *a = NULL; |
||
667 | int *aj = NULL; |
||
668 | int *bj = NULL; |
||
669 | int *cj = NULL; |
||
670 | |||
671 | ops = 0; |
||
672 | |||
673 | memset(flagnorm,0,8000*sizeof(int)); |
||
674 | w = tilec->x1-tilec->x0; |
||
675 | h = tilec->y1-tilec->y0; |
||
676 | d = tilec->z1-tilec->z0; |
||
677 | wh = w * h; |
||
678 | levelx = tilec->numresolution[0]-1; |
||
679 | levely = tilec->numresolution[1]-1; |
||
680 | levelz = tilec->numresolution[2]-1; |
||
681 | level = int_max(levelx,int_max(levely,levelz)); |
||
682 | diff = tilec->numresolution[0] - tilec->numresolution[2]; |
||
683 | |||
684 | a = tilec->data; |
||
685 | |||
686 | for (x = 0, y = 0, z = 0; (x < levelx) && (y < levely); x++, y++, z++) { |
||
687 | int rw; /* width of the resolution level computed */ |
||
688 | int rh; /* heigth of the resolution level computed */ |
||
689 | int rd; /* depth of the resolution level computed */ |
||
690 | int rw1; /* width of the resolution level once lower than computed one */ |
||
691 | int rh1; /* height of the resolution level once lower than computed one */ |
||
692 | int rd1; /* depth of the resolution level once lower than computed one */ |
||
693 | int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ |
||
694 | int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ |
||
695 | int cas_axl; /* 0 = non inversion on axial filtering 1 = inversion between low-pass and high-pass filtering */ |
||
696 | int dn, sn; |
||
697 | |||
698 | rw = tilec->resolutions[level - x].x1 - tilec->resolutions[level - x].x0; |
||
699 | rh = tilec->resolutions[level - y].y1 - tilec->resolutions[level - y].y0; |
||
700 | rd = tilec->resolutions[level - z].z1 - tilec->resolutions[level - z].z0; |
||
701 | rw1= tilec->resolutions[level - x - 1].x1 - tilec->resolutions[level - x - 1].x0; |
||
702 | rh1= tilec->resolutions[level - y - 1].y1 - tilec->resolutions[level - y - 1].y0; |
||
703 | rd1= tilec->resolutions[level - z - 1].z1 - tilec->resolutions[level - z - 1].z0; |
||
704 | |||
705 | cas_col = tilec->resolutions[level - x].x0 % 2; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ |
||
706 | cas_row = tilec->resolutions[level - y].y0 % 2; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ |
||
707 | cas_axl = tilec->resolutions[level - z].z0 % 2; |
||
708 | |||
709 | /*fprintf(stdout," x %d y %d z %d \n",x,y,z); |
||
710 | fprintf(stdout," levelx %d levely %d levelz %d \n",levelx,levely,levelz); |
||
711 | fprintf(stdout," z1 %d z0 %d\n",tilec->resolutions[level - z].z1,tilec->resolutions[level - z].z0); |
||
712 | fprintf(stdout," rw %d rh %d rd %d \n rw1 %d rh1 %d rd1 %d \n",rw,rh,rd,rw1,rh1,rd1);*/ |
||
713 | |||
714 | for (i = 0; i < rd; i++) { |
||
715 | |||
716 | cj = a + (i * wh); |
||
717 | |||
718 | //Horizontal |
||
719 | sn = rw1; |
||
720 | dn = rw - rw1; |
||
721 | bj = (int*)opj_malloc(rw * sizeof(int)); |
||
722 | if (dwtid[0] == 0) { |
||
723 | for (j = 0; j < rh; j++) { |
||
724 | aj = cj + j * w; |
||
725 | for (k = 0; k < rw; k++) bj[k] = aj[k]; |
||
726 | dwt_encode_97(bj, dn, sn, cas_row); |
||
727 | dwt_deinterleave_h(bj, aj, dn, sn, cas_row); |
||
728 | } |
||
729 | } else if (dwtid[0] == 1) { |
||
730 | for (j = 0; j < rh; j++) { |
||
731 | aj = cj + j * w; |
||
732 | for (k = 0; k < rw; k++) bj[k] = aj[k]; |
||
733 | dwt_encode_53(bj, dn, sn, cas_row); |
||
734 | dwt_deinterleave_h(bj, aj, dn, sn, cas_row); |
||
735 | } |
||
736 | } |
||
737 | opj_free(bj); |
||
738 | |||
739 | //Vertical |
||
740 | sn = rh1; |
||
741 | dn = rh - rh1; |
||
742 | bj = (int*)opj_malloc(rh * sizeof(int)); |
||
743 | if (dwtid[1] == 0) { /*DWT 9-7*/ |
||
744 | for (j = 0; j < rw; j++) { |
||
745 | aj = cj + j; |
||
746 | for (k = 0; k < rh; k++) bj[k] = aj[k*w]; |
||
747 | dwt_encode_97(bj, dn, sn, cas_col); |
||
748 | dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); |
||
749 | } |
||
750 | } else if (dwtid[1] == 1) { /*DWT 5-3*/ |
||
751 | for (j = 0; j < rw; j++) { |
||
752 | aj = cj + j; |
||
753 | for (k = 0; k < rh; k++) bj[k] = aj[k*w]; |
||
754 | dwt_encode_53(bj, dn, sn, cas_col); |
||
755 | dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); |
||
756 | } |
||
757 | } |
||
758 | opj_free(bj); |
||
759 | } |
||
760 | |||
761 | if (z < levelz){ |
||
762 | //Axial fprintf(stdout,"Axial DWT Transform %d %d %d\n",z,rd,rd1); |
||
763 | sn = rd1; |
||
764 | dn = rd - rd1; |
||
765 | bj = (int*)opj_malloc(rd * sizeof(int)); |
||
766 | if (dwtid[2] == 0) { |
||
767 | for (j = 0; j < (rw*rh); j++) { |
||
768 | aj = a + j; |
||
769 | for (k = 0; k < rd; k++) bj[k] = aj[k*wh]; |
||
770 | dwt_encode_97(bj, dn, sn, cas_axl); |
||
771 | dwt_deinterleave_z(bj, aj, dn, sn, wh, cas_axl); |
||
772 | } |
||
773 | } else if (dwtid[2] == 1) { |
||
774 | for (j = 0; j < (rw*rh); j++) { |
||
775 | aj = a + j; |
||
776 | for (k = 0; k < rd; k++) bj[k] = aj[k*wh]; |
||
777 | dwt_encode_53(bj, dn, sn, cas_axl); |
||
778 | dwt_deinterleave_z(bj, aj, dn, sn, wh, cas_axl); |
||
779 | } |
||
780 | } |
||
781 | opj_free(bj); |
||
782 | } |
||
783 | } |
||
784 | |||
785 | //fprintf(stdout,"[INFO] Ops: %d \n",ops); |
||
786 | } |
||
787 | |||
788 | |||
789 | /* |
||
790 | /* Inverse 5-3 wavelet tranform in 3-D. */ |
||
791 | /* */ |
||
792 | void dwt_decode(opj_tcd_tilecomp_t * tilec, int stops[3], int dwtid[3]) { |
||
793 | int i, j, k; |
||
794 | int x, y, z; |
||
795 | int w, h, wh, d; |
||
796 | int level, levelx, levely, levelz, diff; |
||
797 | int *a = NULL; |
||
798 | int *aj = NULL; |
||
799 | int *bj = NULL; |
||
800 | int *cj = NULL; |
||
801 | |||
802 | a = tilec->data; |
||
803 | |||
804 | w = tilec->x1-tilec->x0; |
||
805 | h = tilec->y1-tilec->y0; |
||
806 | d = tilec->z1-tilec->z0; |
||
807 | wh = w * h; |
||
808 | levelx = tilec->numresolution[0]-1; |
||
809 | levely = tilec->numresolution[1]-1; |
||
810 | levelz = tilec->numresolution[2]-1; |
||
811 | level = int_max(levelx,int_max(levely,levelz)); |
||
812 | diff = tilec->numresolution[0] - tilec->numresolution[2]; |
||
813 | |||
814 | /* General lifting framework -- DCCS-LIWT */ |
||
815 | for (x = level - 1, y = level - 1, z = level - 1; (x >= stops[0]) && (y >= stops[1]); x--, y--, z--) { |
||
816 | int rw; /* width of the resolution level computed */ |
||
817 | int rh; /* heigth of the resolution level computed */ |
||
818 | int rd; /* depth of the resolution level computed */ |
||
819 | int rw1; /* width of the resolution level once lower than computed one */ |
||
820 | int rh1; /* height of the resolution level once lower than computed one */ |
||
821 | int rd1; /* depth of the resolution level once lower than computed one */ |
||
822 | int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ |
||
823 | int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ |
||
824 | int cas_axl; /* 0 = non inversion on axial filtering 1 = inversion between low-pass and high-pass filtering */ |
||
825 | int dn, sn; |
||
826 | |||
827 | rw = tilec->resolutions[level - x].x1 - tilec->resolutions[level - x].x0; |
||
828 | rh = tilec->resolutions[level - y].y1 - tilec->resolutions[level - y].y0; |
||
829 | rd = tilec->resolutions[level - z].z1 - tilec->resolutions[level - z].z0; |
||
830 | rw1= tilec->resolutions[level - x - 1].x1 - tilec->resolutions[level - x - 1].x0; |
||
831 | rh1= tilec->resolutions[level - y - 1].y1 - tilec->resolutions[level - y - 1].y0; |
||
832 | rd1= tilec->resolutions[level - z - 1].z1 - tilec->resolutions[level - z - 1].z0; |
||
833 | |||
834 | cas_col = tilec->resolutions[level - x].x0 % 2; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ |
||
835 | cas_row = tilec->resolutions[level - y].y0 % 2; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ |
||
836 | cas_axl = tilec->resolutions[level - z].z0 % 2; |
||
837 | |||
838 | /*fprintf(stdout," x %d y %d z %d \n",x,y,z); |
||
839 | fprintf(stdout," levelx %d levely %d levelz %d \n",levelx,levely,levelz); |
||
840 | fprintf(stdout," dwtid[0] %d [1] %d [2] %d \n",dwtid[0],dwtid[1],dwtid[2]); |
||
841 | fprintf(stdout," rw %d rh %d rd %d \n rw1 %d rh1 %d rd1 %d \n",rw,rh,rd,rw1,rh1,rd1); |
||
842 | fprintf(stdout,"IDWT Transform %d %d %d %d\n",level, z, rd,rd1);*/ |
||
843 | |||
844 | if (z >= stops[2] && rd != rd1) { |
||
845 | //fprintf(stdout,"Axial Transform %d %d %d %d\n",levelz, z, rd,rd1); |
||
846 | sn = rd1; |
||
847 | dn = rd - rd1; |
||
848 | bj = (int*)opj_malloc(rd * sizeof(int)); |
||
849 | if (dwtid[2] == 0) { |
||
850 | for (j = 0; j < (rw*rh); j++) { |
||
851 | aj = a + j; |
||
852 | dwt_interleave_z(aj, bj, dn, sn, wh, cas_axl); |
||
853 | dwt_decode_97(bj, dn, sn, cas_axl); |
||
854 | for (k = 0; k < rd; k++) aj[k * wh] = bj[k]; |
||
855 | } |
||
856 | } else if (dwtid[2] == 1) { |
||
857 | for (j = 0; j < (rw*rh); j++) { |
||
858 | aj = a + j; |
||
859 | dwt_interleave_z(aj, bj, dn, sn, wh, cas_axl); |
||
860 | dwt_decode_53(bj, dn, sn, cas_axl); |
||
861 | for (k = 0; k < rd; k++) aj[k * wh] = bj[k]; |
||
862 | } |
||
863 | } |
||
864 | opj_free(bj); |
||
865 | } |
||
866 | |||
867 | for (i = 0; i < rd; i++) { |
||
868 | //Fetch corresponding slice for doing DWT-2D |
||
869 | cj = tilec->data + (i * wh); |
||
870 | |||
871 | //Vertical |
||
872 | sn = rh1; |
||
873 | dn = rh - rh1; |
||
874 | bj = (int*)opj_malloc(rh * sizeof(int)); |
||
875 | if (dwtid[1] == 0) { |
||
876 | for (j = 0; j < rw; j++) { |
||
877 | aj = cj + j; |
||
878 | dwt_interleave_v(aj, bj, dn, sn, w, cas_col); |
||
879 | dwt_decode_97(bj, dn, sn, cas_col); |
||
880 | for (k = 0; k < rh; k++) aj[k * w] = bj[k]; |
||
881 | } |
||
882 | } else if (dwtid[1] == 1) { |
||
883 | for (j = 0; j < rw; j++) { |
||
884 | aj = cj + j; |
||
885 | dwt_interleave_v(aj, bj, dn, sn, w, cas_col); |
||
886 | dwt_decode_53(bj, dn, sn, cas_col); |
||
887 | for (k = 0; k < rh; k++) aj[k * w] = bj[k]; |
||
888 | } |
||
889 | } |
||
890 | opj_free(bj); |
||
891 | |||
892 | //Horizontal |
||
893 | sn = rw1; |
||
894 | dn = rw - rw1; |
||
895 | bj = (int*)opj_malloc(rw * sizeof(int)); |
||
896 | if (dwtid[0]==0) { |
||
897 | for (j = 0; j < rh; j++) { |
||
898 | aj = cj + j*w; |
||
899 | dwt_interleave_h(aj, bj, dn, sn, cas_row); |
||
900 | dwt_decode_97(bj, dn, sn, cas_row); |
||
901 | for (k = 0; k < rw; k++) aj[k] = bj[k]; |
||
902 | } |
||
903 | } else if (dwtid[0]==1) { |
||
904 | for (j = 0; j < rh; j++) { |
||
905 | aj = cj + j*w; |
||
906 | dwt_interleave_h(aj, bj, dn, sn, cas_row); |
||
907 | dwt_decode_53(bj, dn, sn, cas_row); |
||
908 | for (k = 0; k < rw; k++) aj[k] = bj[k]; |
||
909 | } |
||
910 | } |
||
911 | opj_free(bj); |
||
912 | |||
913 | } |
||
914 | |||
915 | } |
||
916 | |||
917 | } |
||
918 | |||
919 | |||
920 | /* |
||
921 | /* Get gain of wavelet transform. */ |
||
922 | /* */ |
||
923 | int dwt_getgain(int orient, int reversible) { |
||
924 | if (reversible == 1) { |
||
925 | if (orient == 0) |
||
926 | return 0; |
||
927 | else if (orient == 1 || orient == 2 || orient == 4 ) |
||
928 | return 1; |
||
929 | else if (orient == 3 || orient == 5 || orient == 6 ) |
||
930 | return 2; |
||
931 | else |
||
932 | return 3; |
||
933 | } |
||
934 | //else if (reversible == 0){ |
||
935 | return 0; |
||
936 | } |
||
937 | |||
938 | /* |
||
939 | /* Get norm of wavelet transform. */ |
||
940 | /* */ |
||
941 | double dwt_getnorm(int orient, int level[3], int dwtid[3]) { |
||
942 | int levelx = level[0]; |
||
943 | int levely = level[1]; |
||
944 | int levelz = (level[2] < 0) ? 0 : level[2]; |
||
945 | double norm; |
||
946 | |||
947 | if (flagnorm[levelx][levely][levelz][orient] == 1) { |
||
948 | norm = dwt_norm[levelx][levely][levelz][orient]; |
||
949 | //fprintf(stdout,"[INFO] Level: %d %d %d Orient %d Dwt_norm: %f \n",level[0],level[1],level[2],orient,norm); |
||
950 | } else { |
||
951 | opj_wtfilt_t *wtfiltx =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t)); |
||
952 | opj_wtfilt_t *wtfilty =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t)); |
||
953 | opj_wtfilt_t *wtfiltz =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t)); |
||
954 | //Fetch equivalent filters for each dimension |
||
955 | dwt_getwtfilters(wtfiltx, dwtid[0]); |
||
956 | dwt_getwtfilters(wtfilty, dwtid[1]); |
||
957 | dwt_getwtfilters(wtfiltz, dwtid[2]); |
||
958 | //Calculate the corresponding norm |
||
959 | norm = dwt_calc_wtnorms(orient, level, dwtid, wtfiltx, wtfilty, wtfiltz); |
||
960 | //Save norm in array (no recalculation) |
||
961 | dwt_norm[levelx][levely][levelz][orient] = norm; |
||
962 | flagnorm[levelx][levely][levelz][orient] = 1; |
||
963 | //Free reserved space |
||
964 | opj_free(wtfiltx->LPS); opj_free(wtfilty->LPS); opj_free(wtfiltz->LPS); |
||
965 | opj_free(wtfiltx->HPS); opj_free(wtfilty->HPS); opj_free(wtfiltz->HPS); |
||
966 | opj_free(wtfiltx); opj_free(wtfilty); opj_free(wtfiltz); |
||
967 | //fprintf(stdout,"[INFO] Dwtid: %d %d %d Level: %d %d %d Orient %d Norm: %f \n",dwtid[0],dwtid[1],dwtid[2],level[0],level[1],level[2],orient,norm); |
||
968 | } |
||
969 | return norm; |
||
970 | } |
||
971 | /* |
||
972 | /* Calculate explicit stepsizes for DWT. */ |
||
973 | /* */ |
||
974 | void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) { |
||
975 | int totnumbands, bandno, diff; |
||
976 | |||
977 | assert(tccp->numresolution[0] >= tccp->numresolution[2]); |
||
978 | diff = tccp->numresolution[0] - tccp->numresolution[2]; /*if RESx=RESy != RESz */ |
||
979 | totnumbands = (7 * tccp->numresolution[0] - 6) - 4 * diff; /* 3-D */ |
||
980 | |||
981 | for (bandno = 0; bandno < totnumbands; bandno++) { |
||
982 | double stepsize; |
||
983 | int resno, level[3], orient, gain; |
||
984 | |||
985 | /* Bandno: 0 - LLL 1 - LHL |
||
986 | 2 - HLL 3 - HHL |
||
987 | 4 - LLH 5 - LHH |
||
988 | 6 - HLH 7 - HHH */ |
||
989 | |||
990 | resno = (bandno == 0) ? 0 : ( (bandno <= 3 * diff) ? ((bandno - 1) / 3 + 1) : ((bandno + 4*diff - 1) / 7 + 1)); |
||
991 | orient = (bandno == 0) ? 0 : ( (bandno <= 3 * diff) ? ((bandno - 1) % 3 + 1) : ((bandno + 4*diff - 1) % 7 + 1)); |
||
992 | level[0] = tccp->numresolution[0] - 1 - resno; |
||
993 | level[1] = tccp->numresolution[1] - 1 - resno; |
||
994 | level[2] = tccp->numresolution[2] - 1 - resno; |
||
995 | |||
996 | /* Gain: 0 - LLL 1 - LHL |
||
997 | 1 - HLL 2 - HHL |
||
998 | 1 - LLH 2 - LHH |
||
999 | 2 - HLH 3 - HHH */ |
||
1000 | gain = (tccp->reversible == 0) ? 0 : ( (orient == 0) ? 0 : |
||
1001 | ( ((orient == 1) || (orient == 2) || (orient == 4)) ? 1 : |
||
1002 | (((orient == 3) || (orient == 5) || (orient == 6)) ? 2 : 3)) ); |
||
1003 | |||
1004 | if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) { |
||
1005 | stepsize = 1.0; |
||
1006 | } else { |
||
1007 | double norm = dwt_getnorm(orient,level,tccp->dwtid); //Fetch norms if irreversible transform (by the moment only I9.7) |
||
1008 | stepsize = (1 << (gain + 1)) / norm; |
||
1009 | } |
||
1010 | //fprintf(stdout,"[INFO] Bandno: %d Orient: %d Level: %d %d %d Stepsize: %f\n",bandno,orient,level[0],level[1],level[2],stepsize); |
||
1011 | dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]); |
||
1012 | } |
||
1013 | }><>=>=>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(numbps><(numbps>(numbps><(numbps>><>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>0?D(0):((i)>0?S(0):((i)>0?D(0):((i)>0?S(0):((i)> |
||
1014 |