2 * Discrete wavelet transform
3 * Copyright (c) 2007 Kamil Nowosad
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * Discrete wavelet transform
25 * @author Kamil Nowosad
30 const static float scale97[] = {1.625786, 1.230174};
32 static inline void extend53(int *p, int i0, int i1)
34 p[i0 - 1] = p[i0 + 1];
36 p[i0 - 2] = p[i0 + 2];
37 p[i1 + 1] = p[i1 - 3];
40 static inline void extend97(float *p, int i0, int i1)
44 for (i = 1; i <= 4; i++){
45 p[i0 - i] = p[i0 + i];
46 p[i1 + i - 1] = p[i1 - i - 1];
50 static void sd_1d53(int *p, int i0, int i1)
59 for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++)
60 p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1;
61 for (i = (i0+1)/2; i < (i1+1)/2; i++)
62 p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2;
65 static void dwt_encode53(DWTContext *s, int *t)
68 w = s->linelen[s->ndeclevels-1][0];
69 int *line = s->linebuf;
72 for (lev = s->ndeclevels-1; lev >= 0; lev--){
73 int lh = s->linelen[lev][0],
74 lv = s->linelen[lev][1],
82 for (lp = 0; lp < lv; lp++){
85 for (i = 0; i < lh; i++)
88 sd_1d53(line, mh, mh + lh);
90 // copy back and deinterleave
91 for (i = mh; i < lh; i+=2, j++)
93 for (i = 1-mh; i < lh; i+=2, j++)
99 for (lp = 0; lp < lh; lp++) {
102 for (i = 0; i < lv; i++)
105 sd_1d53(line, mv, mv + lv);
107 // copy back and deinterleave
108 for (i = mv; i < lv; i+=2, j++)
110 for (i = 1-mv; i < lv; i+=2, j++)
116 static void sd_1d97(float *p, int i0, int i1)
126 for (i = i0/2 - 2; i < i1/2 + 1; i++)
127 p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]);
128 for (i = i0/2 - 1; i < i1/2 + 1; i++)
129 p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]);
130 for (i = i0/2 - 1; i < i1/2; i++)
131 p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]);
132 for (i = i0/2; i < i1/2; i++)
133 p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]);
136 static void dwt_encode97(DWTContext *s, int *t)
139 w = s->linelen[s->ndeclevels-1][0];
140 float *line = s->linebuf;
143 for (lev = s->ndeclevels-1; lev >= 0; lev--){
144 int lh = s->linelen[lev][0],
145 lv = s->linelen[lev][1],
153 for (lp = 0; lp < lv; lp++){
156 for (i = 0; i < lh; i++)
159 sd_1d97(line, mh, mh + lh);
161 // copy back and deinterleave
162 for (i = mh; i < lh; i+=2, j++)
163 t[w*lp + j] = scale97[mh] * l[i] / 2;
164 for (i = 1-mh; i < lh; i+=2, j++)
165 t[w*lp + j] = scale97[mh] * l[i] / 2;
170 for (lp = 0; lp < lh; lp++) {
173 for (i = 0; i < lv; i++)
176 sd_1d97(line, mv, mv + lv);
178 // copy back and deinterleave
179 for (i = mv; i < lv; i+=2, j++)
180 t[w*j + lp] = scale97[mv] * l[i] / 2;
181 for (i = 1-mv; i < lv; i+=2, j++)
182 t[w*j + lp] = scale97[mv] * l[i] / 2;
187 static void sr_1d53(int *p, int i0, int i1)
196 for (i = i0/2; i < i1/2 + 1; i++)
197 p[2*i] -= (p[2*i-1] + p[2*i+1] + 2) >> 2;
198 for (i = i0/2; i < i1/2; i++)
199 p[2*i+1] += (p[2*i] + p[2*i+2]) >> 1;
202 static void dwt_decode53(DWTContext *s, int *t)
205 w = s->linelen[s->ndeclevels-1][0];
206 int *line = s->linebuf;
209 for (lev = 0; lev < s->ndeclevels; lev++){
210 int lh = s->linelen[lev][0],
211 lv = s->linelen[lev][1],
219 for (lp = 0; lp < lv; lp++){
221 // copy with interleaving
222 for (i = mh; i < lh; i+=2, j++)
224 for (i = 1-mh; i < lh; i+=2, j++)
227 sr_1d53(line, mh, mh + lh);
229 for (i = 0; i < lh; i++)
235 for (lp = 0; lp < lh; lp++){
237 // copy with interleaving
238 for (i = mv; i < lv; i+=2, j++)
240 for (i = 1-mv; i < lv; i+=2, j++)
243 sr_1d53(line, mv, mv + lv);
245 for (i = 0; i < lv; i++)
251 static void sr_1d97(float *p, int i0, int i1)
260 for (i = i0/2 - 1; i < i1/2 + 2; i++)
261 p[2*i] -= 0.443506 * (p[2*i-1] + p[2*i+1]);
262 for (i = i0/2 - 1; i < i1/2 + 1; i++)
263 p[2*i+1] -= 0.882911 * (p[2*i] + p[2*i+2]);
264 for (i = i0/2; i < i1/2 + 1; i++)
265 p[2*i] += 0.052980 * (p[2*i-1] + p[2*i+1]);
266 for (i = i0/2; i < i1/2; i++)
267 p[2*i+1] += 1.586134 * (p[2*i] + p[2*i+2]);
270 static void dwt_decode97(DWTContext *s, int *t)
273 w = s->linelen[s->ndeclevels-1][0];
274 float *line = s->linebuf;
277 for (lev = 0; lev < s->ndeclevels; lev++){
278 int lh = s->linelen[lev][0],
279 lv = s->linelen[lev][1],
287 for (lp = 0; lp < lv; lp++){
289 // copy with interleaving
290 for (i = mh; i < lh; i+=2, j++)
291 l[i] = scale97[1-mh] * t[w*lp + j];
292 for (i = 1-mh; i < lh; i+=2, j++)
293 l[i] = scale97[1-mh] * t[w*lp + j];
295 sr_1d97(line, mh, mh + lh);
297 for (i = 0; i < lh; i++)
303 for (lp = 0; lp < lh; lp++){
305 // copy with interleaving
306 for (i = mv; i < lv; i+=2, j++)
307 l[i] = scale97[1-mv] * t[w*j + lp];
308 for (i = 1-mv; i < lv; i+=2, j++)
309 l[i] = scale97[1-mv] * t[w*j + lp];
311 sr_1d97(line, mv, mv + lv);
313 for (i = 0; i < lv; i++)
319 int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type)
321 int i, j, lev = decomp_levels, maxlen,
324 if ((unsigned)decomp_levels >= FF_DWT_MAX_DECLVLS)
325 return AVERROR_INVALIDDATA;
326 s->ndeclevels = decomp_levels;
329 for (i = 0; i < 2; i++)
330 for(j = 0; j < 2; j++)
331 b[i][j] = border[i][j];
333 maxlen = FFMAX(b[0][1] - b[0][0],
337 for (i = 0; i < 2; i++){
338 s->linelen[lev][i] = b[i][1] - b[i][0];
339 s->mod[lev][i] = b[i][0] & 1;
340 for (j = 0; j < 2; j++)
341 b[i][j] = (b[i][j] + 1) >> 1;
344 if (type == FF_DWT97)
345 s->linebuf = av_malloc((maxlen + 12) * sizeof(float));
346 else if (type == FF_DWT53)
347 s->linebuf = av_malloc((maxlen + 6) * sizeof(int));
352 return AVERROR(ENOMEM);
357 int ff_j2k_dwt_encode(DWTContext *s, int *t)
361 dwt_encode97(s, t); break;
363 dwt_encode53(s, t); break;
370 int ff_j2k_dwt_decode(DWTContext *s, int *t)
374 dwt_decode97(s, t); break;
376 dwt_decode53(s, t); break;
383 void ff_j2k_dwt_destroy(DWTContext *s)
385 av_freep(&s->linebuf);