1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Discrete wavelet transform 3cabdff1aSopenharmony_ci * Copyright (c) 2007 Kamil Nowosad 4cabdff1aSopenharmony_ci * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@gmail.com> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci/** 24cabdff1aSopenharmony_ci * @file 25cabdff1aSopenharmony_ci * Discrete wavelet transform 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#include "libavutil/error.h" 29cabdff1aSopenharmony_ci#include "libavutil/macros.h" 30cabdff1aSopenharmony_ci#include "libavutil/mem.h" 31cabdff1aSopenharmony_ci#include "jpeg2000dwt.h" 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci/* Defines for 9/7 DWT lifting parameters. 34cabdff1aSopenharmony_ci * Parameters are in float. */ 35cabdff1aSopenharmony_ci#define F_LFTG_ALPHA 1.586134342059924f 36cabdff1aSopenharmony_ci#define F_LFTG_BETA 0.052980118572961f 37cabdff1aSopenharmony_ci#define F_LFTG_GAMMA 0.882911075530934f 38cabdff1aSopenharmony_ci#define F_LFTG_DELTA 0.443506852043971f 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_ci/* Lifting parameters in integer format. 41cabdff1aSopenharmony_ci * Computed as param = (float param) * (1 << 16) */ 42cabdff1aSopenharmony_ci#define I_LFTG_ALPHA 103949ll 43cabdff1aSopenharmony_ci#define I_LFTG_BETA 3472ll 44cabdff1aSopenharmony_ci#define I_LFTG_GAMMA 57862ll 45cabdff1aSopenharmony_ci#define I_LFTG_DELTA 29066ll 46cabdff1aSopenharmony_ci#define I_LFTG_K 80621ll 47cabdff1aSopenharmony_ci#define I_LFTG_X 53274ll 48cabdff1aSopenharmony_ci#define I_PRESHIFT 8 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_cistatic inline void extend53(int *p, int i0, int i1) 51cabdff1aSopenharmony_ci{ 52cabdff1aSopenharmony_ci p[i0 - 1] = p[i0 + 1]; 53cabdff1aSopenharmony_ci p[i1] = p[i1 - 2]; 54cabdff1aSopenharmony_ci p[i0 - 2] = p[i0 + 2]; 55cabdff1aSopenharmony_ci p[i1 + 1] = p[i1 - 3]; 56cabdff1aSopenharmony_ci} 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_cistatic inline void extend97_float(float *p, int i0, int i1) 59cabdff1aSopenharmony_ci{ 60cabdff1aSopenharmony_ci int i; 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci for (i = 1; i <= 4; i++) { 63cabdff1aSopenharmony_ci p[i0 - i] = p[i0 + i]; 64cabdff1aSopenharmony_ci p[i1 + i - 1] = p[i1 - i - 1]; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci} 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_cistatic inline void extend97_int(int32_t *p, int i0, int i1) 69cabdff1aSopenharmony_ci{ 70cabdff1aSopenharmony_ci int i; 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci for (i = 1; i <= 4; i++) { 73cabdff1aSopenharmony_ci p[i0 - i] = p[i0 + i]; 74cabdff1aSopenharmony_ci p[i1 + i - 1] = p[i1 - i - 1]; 75cabdff1aSopenharmony_ci } 76cabdff1aSopenharmony_ci} 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_cistatic void sd_1d53(int *p, int i0, int i1) 79cabdff1aSopenharmony_ci{ 80cabdff1aSopenharmony_ci int i; 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci if (i1 <= i0 + 1) { 83cabdff1aSopenharmony_ci if (i0 == 1) 84cabdff1aSopenharmony_ci p[1] <<= 1; 85cabdff1aSopenharmony_ci return; 86cabdff1aSopenharmony_ci } 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci extend53(p, i0, i1); 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_ci for (i = ((i0+1)>>1) - 1; i < (i1+1)>>1; i++) 91cabdff1aSopenharmony_ci p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1; 92cabdff1aSopenharmony_ci for (i = ((i0+1)>>1); i < (i1+1)>>1; i++) 93cabdff1aSopenharmony_ci p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2; 94cabdff1aSopenharmony_ci} 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_cistatic void dwt_encode53(DWTContext *s, int *t) 97cabdff1aSopenharmony_ci{ 98cabdff1aSopenharmony_ci int lev, 99cabdff1aSopenharmony_ci w = s->linelen[s->ndeclevels-1][0]; 100cabdff1aSopenharmony_ci int *line = s->i_linebuf; 101cabdff1aSopenharmony_ci line += 3; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci for (lev = s->ndeclevels-1; lev >= 0; lev--){ 104cabdff1aSopenharmony_ci int lh = s->linelen[lev][0], 105cabdff1aSopenharmony_ci lv = s->linelen[lev][1], 106cabdff1aSopenharmony_ci mh = s->mod[lev][0], 107cabdff1aSopenharmony_ci mv = s->mod[lev][1], 108cabdff1aSopenharmony_ci lp; 109cabdff1aSopenharmony_ci int *l; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_ci // VER_SD 112cabdff1aSopenharmony_ci l = line + mv; 113cabdff1aSopenharmony_ci for (lp = 0; lp < lh; lp++) { 114cabdff1aSopenharmony_ci int i, j = 0; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci for (i = 0; i < lv; i++) 117cabdff1aSopenharmony_ci l[i] = t[w*i + lp]; 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci sd_1d53(line, mv, mv + lv); 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci // copy back and deinterleave 122cabdff1aSopenharmony_ci for (i = mv; i < lv; i+=2, j++) 123cabdff1aSopenharmony_ci t[w*j + lp] = l[i]; 124cabdff1aSopenharmony_ci for (i = 1-mv; i < lv; i+=2, j++) 125cabdff1aSopenharmony_ci t[w*j + lp] = l[i]; 126cabdff1aSopenharmony_ci } 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci // HOR_SD 129cabdff1aSopenharmony_ci l = line + mh; 130cabdff1aSopenharmony_ci for (lp = 0; lp < lv; lp++){ 131cabdff1aSopenharmony_ci int i, j = 0; 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci for (i = 0; i < lh; i++) 134cabdff1aSopenharmony_ci l[i] = t[w*lp + i]; 135cabdff1aSopenharmony_ci 136cabdff1aSopenharmony_ci sd_1d53(line, mh, mh + lh); 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci // copy back and deinterleave 139cabdff1aSopenharmony_ci for (i = mh; i < lh; i+=2, j++) 140cabdff1aSopenharmony_ci t[w*lp + j] = l[i]; 141cabdff1aSopenharmony_ci for (i = 1-mh; i < lh; i+=2, j++) 142cabdff1aSopenharmony_ci t[w*lp + j] = l[i]; 143cabdff1aSopenharmony_ci } 144cabdff1aSopenharmony_ci } 145cabdff1aSopenharmony_ci} 146cabdff1aSopenharmony_cistatic void sd_1d97_float(float *p, int i0, int i1) 147cabdff1aSopenharmony_ci{ 148cabdff1aSopenharmony_ci int i; 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ci if (i1 <= i0 + 1) { 151cabdff1aSopenharmony_ci if (i0 == 1) 152cabdff1aSopenharmony_ci p[1] *= F_LFTG_X * 2; 153cabdff1aSopenharmony_ci else 154cabdff1aSopenharmony_ci p[0] *= F_LFTG_K; 155cabdff1aSopenharmony_ci return; 156cabdff1aSopenharmony_ci } 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci extend97_float(p, i0, i1); 159cabdff1aSopenharmony_ci i0++; i1++; 160cabdff1aSopenharmony_ci 161cabdff1aSopenharmony_ci for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) 162cabdff1aSopenharmony_ci p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]); 163cabdff1aSopenharmony_ci for (i = (i0>>1) - 1; i < (i1>>1) + 1; i++) 164cabdff1aSopenharmony_ci p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]); 165cabdff1aSopenharmony_ci for (i = (i0>>1) - 1; i < (i1>>1); i++) 166cabdff1aSopenharmony_ci p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]); 167cabdff1aSopenharmony_ci for (i = (i0>>1); i < (i1>>1); i++) 168cabdff1aSopenharmony_ci p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]); 169cabdff1aSopenharmony_ci} 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_cistatic void dwt_encode97_float(DWTContext *s, float *t) 172cabdff1aSopenharmony_ci{ 173cabdff1aSopenharmony_ci int lev, 174cabdff1aSopenharmony_ci w = s->linelen[s->ndeclevels-1][0]; 175cabdff1aSopenharmony_ci float *line = s->f_linebuf; 176cabdff1aSopenharmony_ci line += 5; 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci for (lev = s->ndeclevels-1; lev >= 0; lev--){ 179cabdff1aSopenharmony_ci int lh = s->linelen[lev][0], 180cabdff1aSopenharmony_ci lv = s->linelen[lev][1], 181cabdff1aSopenharmony_ci mh = s->mod[lev][0], 182cabdff1aSopenharmony_ci mv = s->mod[lev][1], 183cabdff1aSopenharmony_ci lp; 184cabdff1aSopenharmony_ci float *l; 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci // HOR_SD 187cabdff1aSopenharmony_ci l = line + mh; 188cabdff1aSopenharmony_ci for (lp = 0; lp < lv; lp++){ 189cabdff1aSopenharmony_ci int i, j = 0; 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci for (i = 0; i < lh; i++) 192cabdff1aSopenharmony_ci l[i] = t[w*lp + i]; 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci sd_1d97_float(line, mh, mh + lh); 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_ci // copy back and deinterleave 197cabdff1aSopenharmony_ci for (i = mh; i < lh; i+=2, j++) 198cabdff1aSopenharmony_ci t[w*lp + j] = l[i]; 199cabdff1aSopenharmony_ci for (i = 1-mh; i < lh; i+=2, j++) 200cabdff1aSopenharmony_ci t[w*lp + j] = l[i]; 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci // VER_SD 204cabdff1aSopenharmony_ci l = line + mv; 205cabdff1aSopenharmony_ci for (lp = 0; lp < lh; lp++) { 206cabdff1aSopenharmony_ci int i, j = 0; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci for (i = 0; i < lv; i++) 209cabdff1aSopenharmony_ci l[i] = t[w*i + lp]; 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci sd_1d97_float(line, mv, mv + lv); 212cabdff1aSopenharmony_ci 213cabdff1aSopenharmony_ci // copy back and deinterleave 214cabdff1aSopenharmony_ci for (i = mv; i < lv; i+=2, j++) 215cabdff1aSopenharmony_ci t[w*j + lp] = l[i]; 216cabdff1aSopenharmony_ci for (i = 1-mv; i < lv; i+=2, j++) 217cabdff1aSopenharmony_ci t[w*j + lp] = l[i]; 218cabdff1aSopenharmony_ci } 219cabdff1aSopenharmony_ci } 220cabdff1aSopenharmony_ci} 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_cistatic void sd_1d97_int(int *p, int i0, int i1) 223cabdff1aSopenharmony_ci{ 224cabdff1aSopenharmony_ci int i; 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci if (i1 <= i0 + 1) { 227cabdff1aSopenharmony_ci if (i0 == 1) 228cabdff1aSopenharmony_ci p[1] = (p[1] * I_LFTG_X + (1<<14)) >> 15; 229cabdff1aSopenharmony_ci else 230cabdff1aSopenharmony_ci p[0] = (p[0] * I_LFTG_K + (1<<15)) >> 16; 231cabdff1aSopenharmony_ci return; 232cabdff1aSopenharmony_ci } 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci extend97_int(p, i0, i1); 235cabdff1aSopenharmony_ci i0++; i1++; 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) 238cabdff1aSopenharmony_ci p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16; 239cabdff1aSopenharmony_ci for (i = (i0>>1) - 1; i < (i1>>1) + 1; i++) 240cabdff1aSopenharmony_ci p[2 * i] -= (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16; 241cabdff1aSopenharmony_ci for (i = (i0>>1) - 1; i < (i1>>1); i++) 242cabdff1aSopenharmony_ci p[2 * i + 1] += (I_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16; 243cabdff1aSopenharmony_ci for (i = (i0>>1); i < (i1>>1); i++) 244cabdff1aSopenharmony_ci p[2 * i] += (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16; 245cabdff1aSopenharmony_ci} 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_cistatic void dwt_encode97_int(DWTContext *s, int *t) 248cabdff1aSopenharmony_ci{ 249cabdff1aSopenharmony_ci int lev; 250cabdff1aSopenharmony_ci int w = s->linelen[s->ndeclevels-1][0]; 251cabdff1aSopenharmony_ci int h = s->linelen[s->ndeclevels-1][1]; 252cabdff1aSopenharmony_ci int i; 253cabdff1aSopenharmony_ci int *line = s->i_linebuf; 254cabdff1aSopenharmony_ci line += 5; 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci for (i = 0; i < w * h; i++) 257cabdff1aSopenharmony_ci t[i] *= 1 << I_PRESHIFT; 258cabdff1aSopenharmony_ci 259cabdff1aSopenharmony_ci for (lev = s->ndeclevels-1; lev >= 0; lev--){ 260cabdff1aSopenharmony_ci int lh = s->linelen[lev][0], 261cabdff1aSopenharmony_ci lv = s->linelen[lev][1], 262cabdff1aSopenharmony_ci mh = s->mod[lev][0], 263cabdff1aSopenharmony_ci mv = s->mod[lev][1], 264cabdff1aSopenharmony_ci lp; 265cabdff1aSopenharmony_ci int *l; 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_ci // VER_SD 268cabdff1aSopenharmony_ci l = line + mv; 269cabdff1aSopenharmony_ci for (lp = 0; lp < lh; lp++) { 270cabdff1aSopenharmony_ci int i, j = 0; 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci for (i = 0; i < lv; i++) 273cabdff1aSopenharmony_ci l[i] = t[w*i + lp]; 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci sd_1d97_int(line, mv, mv + lv); 276cabdff1aSopenharmony_ci 277cabdff1aSopenharmony_ci // copy back and deinterleave 278cabdff1aSopenharmony_ci for (i = mv; i < lv; i+=2, j++) 279cabdff1aSopenharmony_ci t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; 280cabdff1aSopenharmony_ci for (i = 1-mv; i < lv; i+=2, j++) 281cabdff1aSopenharmony_ci t[w*j + lp] = l[i]; 282cabdff1aSopenharmony_ci } 283cabdff1aSopenharmony_ci 284cabdff1aSopenharmony_ci // HOR_SD 285cabdff1aSopenharmony_ci l = line + mh; 286cabdff1aSopenharmony_ci for (lp = 0; lp < lv; lp++){ 287cabdff1aSopenharmony_ci int i, j = 0; 288cabdff1aSopenharmony_ci 289cabdff1aSopenharmony_ci for (i = 0; i < lh; i++) 290cabdff1aSopenharmony_ci l[i] = t[w*lp + i]; 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci sd_1d97_int(line, mh, mh + lh); 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_ci // copy back and deinterleave 295cabdff1aSopenharmony_ci for (i = mh; i < lh; i+=2, j++) 296cabdff1aSopenharmony_ci t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; 297cabdff1aSopenharmony_ci for (i = 1-mh; i < lh; i+=2, j++) 298cabdff1aSopenharmony_ci t[w*lp + j] = l[i]; 299cabdff1aSopenharmony_ci } 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci 303cabdff1aSopenharmony_ci for (i = 0; i < w * h; i++) 304cabdff1aSopenharmony_ci t[i] = (t[i] + ((1<<I_PRESHIFT)>>1)) >> I_PRESHIFT; 305cabdff1aSopenharmony_ci} 306cabdff1aSopenharmony_ci 307cabdff1aSopenharmony_cistatic void sr_1d53(unsigned *p, int i0, int i1) 308cabdff1aSopenharmony_ci{ 309cabdff1aSopenharmony_ci int i; 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_ci if (i1 <= i0 + 1) { 312cabdff1aSopenharmony_ci if (i0 == 1) 313cabdff1aSopenharmony_ci p[1] = (int)p[1] >> 1; 314cabdff1aSopenharmony_ci return; 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci 317cabdff1aSopenharmony_ci extend53(p, i0, i1); 318cabdff1aSopenharmony_ci 319cabdff1aSopenharmony_ci for (i = (i0 >> 1); i < (i1 >> 1) + 1; i++) 320cabdff1aSopenharmony_ci p[2 * i] -= (int)(p[2 * i - 1] + p[2 * i + 1] + 2) >> 2; 321cabdff1aSopenharmony_ci for (i = (i0 >> 1); i < (i1 >> 1); i++) 322cabdff1aSopenharmony_ci p[2 * i + 1] += (int)(p[2 * i] + p[2 * i + 2]) >> 1; 323cabdff1aSopenharmony_ci} 324cabdff1aSopenharmony_ci 325cabdff1aSopenharmony_cistatic void dwt_decode53(DWTContext *s, int *t) 326cabdff1aSopenharmony_ci{ 327cabdff1aSopenharmony_ci int lev; 328cabdff1aSopenharmony_ci int w = s->linelen[s->ndeclevels - 1][0]; 329cabdff1aSopenharmony_ci int32_t *line = s->i_linebuf; 330cabdff1aSopenharmony_ci line += 3; 331cabdff1aSopenharmony_ci 332cabdff1aSopenharmony_ci for (lev = 0; lev < s->ndeclevels; lev++) { 333cabdff1aSopenharmony_ci int lh = s->linelen[lev][0], 334cabdff1aSopenharmony_ci lv = s->linelen[lev][1], 335cabdff1aSopenharmony_ci mh = s->mod[lev][0], 336cabdff1aSopenharmony_ci mv = s->mod[lev][1], 337cabdff1aSopenharmony_ci lp; 338cabdff1aSopenharmony_ci int *l; 339cabdff1aSopenharmony_ci 340cabdff1aSopenharmony_ci // HOR_SD 341cabdff1aSopenharmony_ci l = line + mh; 342cabdff1aSopenharmony_ci for (lp = 0; lp < lv; lp++) { 343cabdff1aSopenharmony_ci int i, j = 0; 344cabdff1aSopenharmony_ci // copy with interleaving 345cabdff1aSopenharmony_ci for (i = mh; i < lh; i += 2, j++) 346cabdff1aSopenharmony_ci l[i] = t[w * lp + j]; 347cabdff1aSopenharmony_ci for (i = 1 - mh; i < lh; i += 2, j++) 348cabdff1aSopenharmony_ci l[i] = t[w * lp + j]; 349cabdff1aSopenharmony_ci 350cabdff1aSopenharmony_ci sr_1d53(line, mh, mh + lh); 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci for (i = 0; i < lh; i++) 353cabdff1aSopenharmony_ci t[w * lp + i] = l[i]; 354cabdff1aSopenharmony_ci } 355cabdff1aSopenharmony_ci 356cabdff1aSopenharmony_ci // VER_SD 357cabdff1aSopenharmony_ci l = line + mv; 358cabdff1aSopenharmony_ci for (lp = 0; lp < lh; lp++) { 359cabdff1aSopenharmony_ci int i, j = 0; 360cabdff1aSopenharmony_ci // copy with interleaving 361cabdff1aSopenharmony_ci for (i = mv; i < lv; i += 2, j++) 362cabdff1aSopenharmony_ci l[i] = t[w * j + lp]; 363cabdff1aSopenharmony_ci for (i = 1 - mv; i < lv; i += 2, j++) 364cabdff1aSopenharmony_ci l[i] = t[w * j + lp]; 365cabdff1aSopenharmony_ci 366cabdff1aSopenharmony_ci sr_1d53(line, mv, mv + lv); 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ci for (i = 0; i < lv; i++) 369cabdff1aSopenharmony_ci t[w * i + lp] = l[i]; 370cabdff1aSopenharmony_ci } 371cabdff1aSopenharmony_ci } 372cabdff1aSopenharmony_ci} 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_cistatic void sr_1d97_float(float *p, int i0, int i1) 375cabdff1aSopenharmony_ci{ 376cabdff1aSopenharmony_ci int i; 377cabdff1aSopenharmony_ci 378cabdff1aSopenharmony_ci if (i1 <= i0 + 1) { 379cabdff1aSopenharmony_ci if (i0 == 1) 380cabdff1aSopenharmony_ci p[1] *= F_LFTG_K/2; 381cabdff1aSopenharmony_ci else 382cabdff1aSopenharmony_ci p[0] *= F_LFTG_X; 383cabdff1aSopenharmony_ci return; 384cabdff1aSopenharmony_ci } 385cabdff1aSopenharmony_ci 386cabdff1aSopenharmony_ci extend97_float(p, i0, i1); 387cabdff1aSopenharmony_ci 388cabdff1aSopenharmony_ci for (i = (i0 >> 1) - 1; i < (i1 >> 1) + 2; i++) 389cabdff1aSopenharmony_ci p[2 * i] -= F_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]); 390cabdff1aSopenharmony_ci /* step 4 */ 391cabdff1aSopenharmony_ci for (i = (i0 >> 1) - 1; i < (i1 >> 1) + 1; i++) 392cabdff1aSopenharmony_ci p[2 * i + 1] -= F_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]); 393cabdff1aSopenharmony_ci /*step 5*/ 394cabdff1aSopenharmony_ci for (i = (i0 >> 1); i < (i1 >> 1) + 1; i++) 395cabdff1aSopenharmony_ci p[2 * i] += F_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]); 396cabdff1aSopenharmony_ci /* step 6 */ 397cabdff1aSopenharmony_ci for (i = (i0 >> 1); i < (i1 >> 1); i++) 398cabdff1aSopenharmony_ci p[2 * i + 1] += F_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]); 399cabdff1aSopenharmony_ci} 400cabdff1aSopenharmony_ci 401cabdff1aSopenharmony_cistatic void dwt_decode97_float(DWTContext *s, float *t) 402cabdff1aSopenharmony_ci{ 403cabdff1aSopenharmony_ci int lev; 404cabdff1aSopenharmony_ci int w = s->linelen[s->ndeclevels - 1][0]; 405cabdff1aSopenharmony_ci float *line = s->f_linebuf; 406cabdff1aSopenharmony_ci float *data = t; 407cabdff1aSopenharmony_ci /* position at index O of line range [0-5,w+5] cf. extend function */ 408cabdff1aSopenharmony_ci line += 5; 409cabdff1aSopenharmony_ci 410cabdff1aSopenharmony_ci for (lev = 0; lev < s->ndeclevels; lev++) { 411cabdff1aSopenharmony_ci int lh = s->linelen[lev][0], 412cabdff1aSopenharmony_ci lv = s->linelen[lev][1], 413cabdff1aSopenharmony_ci mh = s->mod[lev][0], 414cabdff1aSopenharmony_ci mv = s->mod[lev][1], 415cabdff1aSopenharmony_ci lp; 416cabdff1aSopenharmony_ci float *l; 417cabdff1aSopenharmony_ci // HOR_SD 418cabdff1aSopenharmony_ci l = line + mh; 419cabdff1aSopenharmony_ci for (lp = 0; lp < lv; lp++) { 420cabdff1aSopenharmony_ci int i, j = 0; 421cabdff1aSopenharmony_ci // copy with interleaving 422cabdff1aSopenharmony_ci for (i = mh; i < lh; i += 2, j++) 423cabdff1aSopenharmony_ci l[i] = data[w * lp + j]; 424cabdff1aSopenharmony_ci for (i = 1 - mh; i < lh; i += 2, j++) 425cabdff1aSopenharmony_ci l[i] = data[w * lp + j]; 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci sr_1d97_float(line, mh, mh + lh); 428cabdff1aSopenharmony_ci 429cabdff1aSopenharmony_ci for (i = 0; i < lh; i++) 430cabdff1aSopenharmony_ci data[w * lp + i] = l[i]; 431cabdff1aSopenharmony_ci } 432cabdff1aSopenharmony_ci 433cabdff1aSopenharmony_ci // VER_SD 434cabdff1aSopenharmony_ci l = line + mv; 435cabdff1aSopenharmony_ci for (lp = 0; lp < lh; lp++) { 436cabdff1aSopenharmony_ci int i, j = 0; 437cabdff1aSopenharmony_ci // copy with interleaving 438cabdff1aSopenharmony_ci for (i = mv; i < lv; i += 2, j++) 439cabdff1aSopenharmony_ci l[i] = data[w * j + lp]; 440cabdff1aSopenharmony_ci for (i = 1 - mv; i < lv; i += 2, j++) 441cabdff1aSopenharmony_ci l[i] = data[w * j + lp]; 442cabdff1aSopenharmony_ci 443cabdff1aSopenharmony_ci sr_1d97_float(line, mv, mv + lv); 444cabdff1aSopenharmony_ci 445cabdff1aSopenharmony_ci for (i = 0; i < lv; i++) 446cabdff1aSopenharmony_ci data[w * i + lp] = l[i]; 447cabdff1aSopenharmony_ci } 448cabdff1aSopenharmony_ci } 449cabdff1aSopenharmony_ci} 450cabdff1aSopenharmony_ci 451cabdff1aSopenharmony_cistatic void sr_1d97_int(int32_t *p, int i0, int i1) 452cabdff1aSopenharmony_ci{ 453cabdff1aSopenharmony_ci int i; 454cabdff1aSopenharmony_ci 455cabdff1aSopenharmony_ci if (i1 <= i0 + 1) { 456cabdff1aSopenharmony_ci if (i0 == 1) 457cabdff1aSopenharmony_ci p[1] = (p[1] * I_LFTG_K + (1<<16)) >> 17; 458cabdff1aSopenharmony_ci else 459cabdff1aSopenharmony_ci p[0] = (p[0] * I_LFTG_X + (1<<15)) >> 16; 460cabdff1aSopenharmony_ci return; 461cabdff1aSopenharmony_ci } 462cabdff1aSopenharmony_ci 463cabdff1aSopenharmony_ci extend97_int(p, i0, i1); 464cabdff1aSopenharmony_ci 465cabdff1aSopenharmony_ci for (i = (i0 >> 1) - 1; i < (i1 >> 1) + 2; i++) 466cabdff1aSopenharmony_ci p[2 * i] -= (I_LFTG_DELTA * (p[2 * i - 1] + (int64_t)p[2 * i + 1]) + (1 << 15)) >> 16; 467cabdff1aSopenharmony_ci /* step 4 */ 468cabdff1aSopenharmony_ci for (i = (i0 >> 1) - 1; i < (i1 >> 1) + 1; i++) 469cabdff1aSopenharmony_ci p[2 * i + 1] -= (I_LFTG_GAMMA * (p[2 * i] + (int64_t)p[2 * i + 2]) + (1 << 15)) >> 16; 470cabdff1aSopenharmony_ci /*step 5*/ 471cabdff1aSopenharmony_ci for (i = (i0 >> 1); i < (i1 >> 1) + 1; i++) 472cabdff1aSopenharmony_ci p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + (int64_t)p[2 * i + 1]) + (1 << 15)) >> 16; 473cabdff1aSopenharmony_ci /* step 6 */ 474cabdff1aSopenharmony_ci for (i = (i0 >> 1); i < (i1 >> 1); i++) 475cabdff1aSopenharmony_ci p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + (int64_t)p[2 * i + 2]) + (1 << 15)) >> 16; 476cabdff1aSopenharmony_ci} 477cabdff1aSopenharmony_ci 478cabdff1aSopenharmony_cistatic void dwt_decode97_int(DWTContext *s, int32_t *t) 479cabdff1aSopenharmony_ci{ 480cabdff1aSopenharmony_ci int lev; 481cabdff1aSopenharmony_ci int w = s->linelen[s->ndeclevels - 1][0]; 482cabdff1aSopenharmony_ci int h = s->linelen[s->ndeclevels - 1][1]; 483cabdff1aSopenharmony_ci int i; 484cabdff1aSopenharmony_ci int32_t *line = s->i_linebuf; 485cabdff1aSopenharmony_ci int32_t *data = t; 486cabdff1aSopenharmony_ci /* position at index O of line range [0-5,w+5] cf. extend function */ 487cabdff1aSopenharmony_ci line += 5; 488cabdff1aSopenharmony_ci 489cabdff1aSopenharmony_ci for (i = 0; i < w * h; i++) 490cabdff1aSopenharmony_ci data[i] *= 1LL << I_PRESHIFT; 491cabdff1aSopenharmony_ci 492cabdff1aSopenharmony_ci for (lev = 0; lev < s->ndeclevels; lev++) { 493cabdff1aSopenharmony_ci int lh = s->linelen[lev][0], 494cabdff1aSopenharmony_ci lv = s->linelen[lev][1], 495cabdff1aSopenharmony_ci mh = s->mod[lev][0], 496cabdff1aSopenharmony_ci mv = s->mod[lev][1], 497cabdff1aSopenharmony_ci lp; 498cabdff1aSopenharmony_ci int32_t *l; 499cabdff1aSopenharmony_ci // HOR_SD 500cabdff1aSopenharmony_ci l = line + mh; 501cabdff1aSopenharmony_ci for (lp = 0; lp < lv; lp++) { 502cabdff1aSopenharmony_ci int i, j = 0; 503cabdff1aSopenharmony_ci // rescale with interleaving 504cabdff1aSopenharmony_ci for (i = mh; i < lh; i += 2, j++) 505cabdff1aSopenharmony_ci l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16; 506cabdff1aSopenharmony_ci for (i = 1 - mh; i < lh; i += 2, j++) 507cabdff1aSopenharmony_ci l[i] = data[w * lp + j]; 508cabdff1aSopenharmony_ci 509cabdff1aSopenharmony_ci sr_1d97_int(line, mh, mh + lh); 510cabdff1aSopenharmony_ci 511cabdff1aSopenharmony_ci for (i = 0; i < lh; i++) 512cabdff1aSopenharmony_ci data[w * lp + i] = l[i]; 513cabdff1aSopenharmony_ci } 514cabdff1aSopenharmony_ci 515cabdff1aSopenharmony_ci // VER_SD 516cabdff1aSopenharmony_ci l = line + mv; 517cabdff1aSopenharmony_ci for (lp = 0; lp < lh; lp++) { 518cabdff1aSopenharmony_ci int i, j = 0; 519cabdff1aSopenharmony_ci // rescale with interleaving 520cabdff1aSopenharmony_ci for (i = mv; i < lv; i += 2, j++) 521cabdff1aSopenharmony_ci l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16; 522cabdff1aSopenharmony_ci for (i = 1 - mv; i < lv; i += 2, j++) 523cabdff1aSopenharmony_ci l[i] = data[w * j + lp]; 524cabdff1aSopenharmony_ci 525cabdff1aSopenharmony_ci sr_1d97_int(line, mv, mv + lv); 526cabdff1aSopenharmony_ci 527cabdff1aSopenharmony_ci for (i = 0; i < lv; i++) 528cabdff1aSopenharmony_ci data[w * i + lp] = l[i]; 529cabdff1aSopenharmony_ci } 530cabdff1aSopenharmony_ci } 531cabdff1aSopenharmony_ci 532cabdff1aSopenharmony_ci for (i = 0; i < w * h; i++) 533cabdff1aSopenharmony_ci data[i] = (data[i] + ((1LL<<I_PRESHIFT)>>1)) >> I_PRESHIFT; 534cabdff1aSopenharmony_ci} 535cabdff1aSopenharmony_ci 536cabdff1aSopenharmony_ciint ff_jpeg2000_dwt_init(DWTContext *s, int border[2][2], 537cabdff1aSopenharmony_ci int decomp_levels, int type) 538cabdff1aSopenharmony_ci{ 539cabdff1aSopenharmony_ci int i, j, lev = decomp_levels, maxlen, 540cabdff1aSopenharmony_ci b[2][2]; 541cabdff1aSopenharmony_ci 542cabdff1aSopenharmony_ci s->ndeclevels = decomp_levels; 543cabdff1aSopenharmony_ci s->type = type; 544cabdff1aSopenharmony_ci 545cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) 546cabdff1aSopenharmony_ci for (j = 0; j < 2; j++) 547cabdff1aSopenharmony_ci b[i][j] = border[i][j]; 548cabdff1aSopenharmony_ci 549cabdff1aSopenharmony_ci maxlen = FFMAX(b[0][1] - b[0][0], 550cabdff1aSopenharmony_ci b[1][1] - b[1][0]); 551cabdff1aSopenharmony_ci while (--lev >= 0) 552cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 553cabdff1aSopenharmony_ci s->linelen[lev][i] = b[i][1] - b[i][0]; 554cabdff1aSopenharmony_ci s->mod[lev][i] = b[i][0] & 1; 555cabdff1aSopenharmony_ci for (j = 0; j < 2; j++) 556cabdff1aSopenharmony_ci b[i][j] = (b[i][j] + 1) >> 1; 557cabdff1aSopenharmony_ci } 558cabdff1aSopenharmony_ci switch (type) { 559cabdff1aSopenharmony_ci case FF_DWT97: 560cabdff1aSopenharmony_ci s->f_linebuf = av_malloc_array((maxlen + 12), sizeof(*s->f_linebuf)); 561cabdff1aSopenharmony_ci if (!s->f_linebuf) 562cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 563cabdff1aSopenharmony_ci break; 564cabdff1aSopenharmony_ci case FF_DWT97_INT: 565cabdff1aSopenharmony_ci s->i_linebuf = av_malloc_array((maxlen + 12), sizeof(*s->i_linebuf)); 566cabdff1aSopenharmony_ci if (!s->i_linebuf) 567cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 568cabdff1aSopenharmony_ci break; 569cabdff1aSopenharmony_ci case FF_DWT53: 570cabdff1aSopenharmony_ci s->i_linebuf = av_malloc_array((maxlen + 6), sizeof(*s->i_linebuf)); 571cabdff1aSopenharmony_ci if (!s->i_linebuf) 572cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 573cabdff1aSopenharmony_ci break; 574cabdff1aSopenharmony_ci default: 575cabdff1aSopenharmony_ci return -1; 576cabdff1aSopenharmony_ci } 577cabdff1aSopenharmony_ci return 0; 578cabdff1aSopenharmony_ci} 579cabdff1aSopenharmony_ci 580cabdff1aSopenharmony_ciint ff_dwt_encode(DWTContext *s, void *t) 581cabdff1aSopenharmony_ci{ 582cabdff1aSopenharmony_ci if (s->ndeclevels == 0) 583cabdff1aSopenharmony_ci return 0; 584cabdff1aSopenharmony_ci 585cabdff1aSopenharmony_ci switch(s->type){ 586cabdff1aSopenharmony_ci case FF_DWT97: 587cabdff1aSopenharmony_ci dwt_encode97_float(s, t); break; 588cabdff1aSopenharmony_ci case FF_DWT97_INT: 589cabdff1aSopenharmony_ci dwt_encode97_int(s, t); break; 590cabdff1aSopenharmony_ci case FF_DWT53: 591cabdff1aSopenharmony_ci dwt_encode53(s, t); break; 592cabdff1aSopenharmony_ci default: 593cabdff1aSopenharmony_ci return -1; 594cabdff1aSopenharmony_ci } 595cabdff1aSopenharmony_ci return 0; 596cabdff1aSopenharmony_ci} 597cabdff1aSopenharmony_ci 598cabdff1aSopenharmony_ciint ff_dwt_decode(DWTContext *s, void *t) 599cabdff1aSopenharmony_ci{ 600cabdff1aSopenharmony_ci if (s->ndeclevels == 0) 601cabdff1aSopenharmony_ci return 0; 602cabdff1aSopenharmony_ci 603cabdff1aSopenharmony_ci switch (s->type) { 604cabdff1aSopenharmony_ci case FF_DWT97: 605cabdff1aSopenharmony_ci dwt_decode97_float(s, t); 606cabdff1aSopenharmony_ci break; 607cabdff1aSopenharmony_ci case FF_DWT97_INT: 608cabdff1aSopenharmony_ci dwt_decode97_int(s, t); 609cabdff1aSopenharmony_ci break; 610cabdff1aSopenharmony_ci case FF_DWT53: 611cabdff1aSopenharmony_ci dwt_decode53(s, t); 612cabdff1aSopenharmony_ci break; 613cabdff1aSopenharmony_ci default: 614cabdff1aSopenharmony_ci return -1; 615cabdff1aSopenharmony_ci } 616cabdff1aSopenharmony_ci return 0; 617cabdff1aSopenharmony_ci} 618cabdff1aSopenharmony_ci 619cabdff1aSopenharmony_civoid ff_dwt_destroy(DWTContext *s) 620cabdff1aSopenharmony_ci{ 621cabdff1aSopenharmony_ci av_freep(&s->f_linebuf); 622cabdff1aSopenharmony_ci av_freep(&s->i_linebuf); 623cabdff1aSopenharmony_ci} 624