00001 /* 00002 * JPEG2000 encoder and decoder common functions 00003 * Copyright (c) 2007 Kamil Nowosad 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00029 #include "avcodec.h" 00030 #include "j2k.h" 00031 00032 #define SHL(a, n) ((n)>=0 ? (a) << (n) : (a) >> -(n)) 00033 00034 #if 0 00035 void ff_j2k_printv(int *tab, int l) 00036 { 00037 int i; 00038 for (i = 0; i < l; i++) 00039 printf("%.3d ", tab[i]); 00040 printf("\n"); 00041 } 00042 00043 void ff_j2k_printu(uint8_t *tab, int l) 00044 { 00045 int i; 00046 for (i = 0; i < l; i++) 00047 printf("%.3hd ", tab[i]); 00048 printf("\n"); 00049 } 00050 #endif 00051 00052 /* tag tree routines */ 00053 00056 static int tag_tree_size(int w, int h) 00057 { 00058 int res = 0; 00059 while (w > 1 || h > 1){ 00060 res += w * h; 00061 w = (w+1) >> 1; 00062 h = (h+1) >> 1; 00063 } 00064 return res + 1; 00065 } 00066 00067 J2kTgtNode *ff_j2k_tag_tree_init(int w, int h) 00068 { 00069 int pw = w, ph = h; 00070 J2kTgtNode *res, *t, *t2; 00071 00072 t = res = av_mallocz(tag_tree_size(w, h)*sizeof(J2kTgtNode)); 00073 00074 if (res == NULL) 00075 return NULL; 00076 00077 while (w > 1 || h > 1){ 00078 int i, j; 00079 pw = w; 00080 ph = h; 00081 00082 w = (w+1) >> 1; 00083 h = (h+1) >> 1; 00084 t2 = t + pw*ph; 00085 00086 for (i = 0; i < ph; i++) 00087 for (j = 0; j < pw; j++){ 00088 t[i*pw + j].parent = &t2[(i>>1)*w + (j>>1)]; 00089 } 00090 t = t2; 00091 } 00092 t[0].parent = NULL; 00093 return res; 00094 } 00095 00096 static void tag_tree_zero(J2kTgtNode *t, int w, int h) 00097 { 00098 int i, siz = tag_tree_size(w, h); 00099 00100 for (i = 0; i < siz; i++){ 00101 t[i].val = 0; 00102 t[i].vis = 0; 00103 } 00104 } 00105 00106 uint8_t ff_j2k_nbctxno_lut[256][4]; 00107 00108 static int getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol) 00109 { 00110 int h, v, d; 00111 00112 h = ((flag & J2K_T1_SIG_E) ? 1:0)+ 00113 ((flag & J2K_T1_SIG_W) ? 1:0); 00114 v = ((flag & J2K_T1_SIG_N) ? 1:0); 00115 if (!vert_causal_ctx_csty_symbol) 00116 v = v + ((flag & J2K_T1_SIG_S) ? 1:0); 00117 d = ((flag & J2K_T1_SIG_NE) ? 1:0)+ 00118 ((flag & J2K_T1_SIG_NW) ? 1:0); 00119 if (!vert_causal_ctx_csty_symbol) 00120 d = d + ((flag & J2K_T1_SIG_SE) ? 1:0)+ 00121 ((flag & J2K_T1_SIG_SW) ? 1:0); 00122 if (bandno < 3){ 00123 if (bandno == 1) 00124 FFSWAP(int, h, v); 00125 if (h == 2) return 8; 00126 if (h == 1){ 00127 if (v >= 1) return 7; 00128 if (d >= 1) return 6; 00129 return 5; 00130 } 00131 if (v == 2) return 4; 00132 if (v == 1) return 3; 00133 if (d >= 2) return 2; 00134 if (d == 1) return 1; 00135 return 0; 00136 } else{ 00137 if (d >= 3) return 8; 00138 if (d == 2){ 00139 if (h+v >= 1) return 7; 00140 return 6; 00141 } 00142 if (d == 1){ 00143 if (h+v >= 2) return 5; 00144 if (h+v == 1) return 4; 00145 return 3; 00146 } 00147 if (h+v >= 2) return 2; 00148 if (h+v == 1) return 1; 00149 return 0; 00150 } 00151 assert(0); 00152 } 00153 00154 uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16]; 00155 00156 static int getsgnctxno(int flag, uint8_t *xorbit) 00157 { 00158 int vcontrib, hcontrib; 00159 static const int contribtab[3][3] = {{0, -1, 1}, {-1, -1, 0}, {1, 0, 1}}; 00160 static const int ctxlbltab[3][3] = {{13, 12, 11}, {10, 9, 10}, {11, 12, 13}}; 00161 static const int xorbittab[3][3] = {{1, 1, 1,}, {1, 0, 0}, {0, 0, 0}}; 00162 00163 hcontrib = contribtab[flag & J2K_T1_SIG_E ? flag & J2K_T1_SGN_E ? 1:2:0] 00164 [flag & J2K_T1_SIG_W ? flag & J2K_T1_SGN_W ? 1:2:0]+1; 00165 vcontrib = contribtab[flag & J2K_T1_SIG_S ? flag & J2K_T1_SGN_S ? 1:2:0] 00166 [flag & J2K_T1_SIG_N ? flag & J2K_T1_SGN_N ? 1:2:0]+1; 00167 *xorbit = xorbittab[hcontrib][vcontrib]; 00168 return ctxlbltab[hcontrib][vcontrib]; 00169 } 00170 00171 void ff_j2k_init_tier1_luts(void) 00172 { 00173 int i, j; 00174 for (i = 0; i < 256; i++) 00175 for (j = 0; j < 4; j++) 00176 ff_j2k_nbctxno_lut[i][j] = getnbctxno(i, j, 0); 00177 for (i = 0; i < 16; i++) 00178 for (j = 0; j < 16; j++) 00179 ff_j2k_sgnctxno_lut[i][j] = getsgnctxno(i + (j << 8), &ff_j2k_xorbit_lut[i][j]); 00180 } 00181 00182 void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative) 00183 { 00184 x++; y++; 00185 t1->flags[y][x] |= J2K_T1_SIG; 00186 if (negative){ 00187 t1->flags[y][x+1] |= J2K_T1_SIG_W | J2K_T1_SGN_W; 00188 t1->flags[y][x-1] |= J2K_T1_SIG_E | J2K_T1_SGN_E; 00189 t1->flags[y+1][x] |= J2K_T1_SIG_N | J2K_T1_SGN_N; 00190 t1->flags[y-1][x] |= J2K_T1_SIG_S | J2K_T1_SGN_S; 00191 } else{ 00192 t1->flags[y][x+1] |= J2K_T1_SIG_W; 00193 t1->flags[y][x-1] |= J2K_T1_SIG_E; 00194 t1->flags[y+1][x] |= J2K_T1_SIG_N; 00195 t1->flags[y-1][x] |= J2K_T1_SIG_S; 00196 } 00197 t1->flags[y+1][x+1] |= J2K_T1_SIG_NW; 00198 t1->flags[y+1][x-1] |= J2K_T1_SIG_NE; 00199 t1->flags[y-1][x+1] |= J2K_T1_SIG_SW; 00200 t1->flags[y-1][x-1] |= J2K_T1_SIG_SE; 00201 } 00202 00203 int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy) 00204 { 00205 int reslevelno, bandno, gbandno = 0, ret, i, j, csize = 1; 00206 00207 if (ret=ff_j2k_dwt_init(&comp->dwt, comp->coord, codsty->nreslevels-1, codsty->transform)) 00208 return ret; 00209 for (i = 0; i < 2; i++) 00210 csize *= comp->coord[i][1] - comp->coord[i][0]; 00211 00212 comp->data = av_malloc(csize * sizeof(int)); 00213 if (!comp->data) 00214 return AVERROR(ENOMEM); 00215 comp->reslevel = av_malloc(codsty->nreslevels * sizeof(J2kResLevel)); 00216 00217 if (!comp->reslevel) 00218 return AVERROR(ENOMEM); 00219 for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ 00220 int declvl = codsty->nreslevels - reslevelno; 00221 J2kResLevel *reslevel = comp->reslevel + reslevelno; 00222 00223 for (i = 0; i < 2; i++) 00224 for (j = 0; j < 2; j++) 00225 reslevel->coord[i][j] = 00226 ff_j2k_ceildivpow2(comp->coord[i][j], declvl - 1); 00227 00228 if (reslevelno == 0) 00229 reslevel->nbands = 1; 00230 else 00231 reslevel->nbands = 3; 00232 00233 if (reslevel->coord[0][1] == reslevel->coord[0][0]) 00234 reslevel->num_precincts_x = 0; 00235 else 00236 reslevel->num_precincts_x = ff_j2k_ceildivpow2(reslevel->coord[0][1], codsty->log2_prec_width) 00237 - (reslevel->coord[0][0] >> codsty->log2_prec_width); 00238 00239 if (reslevel->coord[1][1] == reslevel->coord[1][0]) 00240 reslevel->num_precincts_y = 0; 00241 else 00242 reslevel->num_precincts_y = ff_j2k_ceildivpow2(reslevel->coord[1][1], codsty->log2_prec_height) 00243 - (reslevel->coord[1][0] >> codsty->log2_prec_height); 00244 00245 reslevel->band = av_malloc(reslevel->nbands * sizeof(J2kBand)); 00246 if (!reslevel->band) 00247 return AVERROR(ENOMEM); 00248 for (bandno = 0; bandno < reslevel->nbands; bandno++, gbandno++){ 00249 J2kBand *band = reslevel->band + bandno; 00250 int cblkno, precx, precy, precno; 00251 int x0, y0, x1, y1; 00252 int xi0, yi0, xi1, yi1; 00253 int cblkperprecw, cblkperprech; 00254 00255 if (qntsty->quantsty != J2K_QSTY_NONE){ 00256 const static uint8_t lut_gain[2][4] = {{0, 0, 0, 0}, {0, 1, 1, 2}}; 00257 int numbps; 00258 00259 numbps = cbps + lut_gain[codsty->transform][bandno + reslevelno>0]; 00260 band->stepsize = SHL(2048 + qntsty->mant[gbandno], 2 + numbps - qntsty->expn[gbandno]); 00261 } else 00262 band->stepsize = 1 << 13; 00263 00264 if (reslevelno == 0){ // the same everywhere 00265 band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width-1); 00266 band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height-1); 00267 for (i = 0; i < 2; i++) 00268 for (j = 0; j < 2; j++) 00269 band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], declvl-1); 00270 } else{ 00271 band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width); 00272 band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height); 00273 00274 for (i = 0; i < 2; i++) 00275 for (j = 0; j < 2; j++) 00276 band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j] - (((bandno+1>>i)&1) << declvl-1), declvl); 00277 } 00278 band->cblknx = ff_j2k_ceildiv(band->coord[0][1], band->codeblock_width) - band->coord[0][0] / band->codeblock_width; 00279 band->cblkny = ff_j2k_ceildiv(band->coord[1][1], band->codeblock_height) - band->coord[1][0] / band->codeblock_height; 00280 00281 for (j = 0; j < 2; j++) 00282 band->coord[0][j] = ff_j2k_ceildiv(band->coord[0][j], dx); 00283 for (j = 0; j < 2; j++) 00284 band->coord[1][j] = ff_j2k_ceildiv(band->coord[1][j], dy); 00285 00286 band->cblknx = ff_j2k_ceildiv(band->cblknx, dx); 00287 band->cblkny = ff_j2k_ceildiv(band->cblkny, dy); 00288 00289 band->cblk = av_malloc(band->cblknx * band->cblkny * sizeof(J2kCblk)); 00290 if (!band->cblk) 00291 return AVERROR(ENOMEM); 00292 band->prec = av_malloc(reslevel->num_precincts_x * reslevel->num_precincts_y * sizeof(J2kPrec)); 00293 if (!band->prec) 00294 return AVERROR(ENOMEM); 00295 00296 for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ 00297 J2kCblk *cblk = band->cblk + cblkno; 00298 cblk->zero = 0; 00299 cblk->lblock = 3; 00300 cblk->length = 0; 00301 cblk->lengthinc = 0; 00302 cblk->npasses = 0; 00303 } 00304 00305 y0 = band->coord[1][0]; 00306 y1 = ((band->coord[1][0] + (1<<codsty->log2_prec_height)) & ~((1<<codsty->log2_prec_height)-1)) - y0; 00307 yi0 = 0; 00308 yi1 = ff_j2k_ceildivpow2(y1 - y0, codsty->log2_cblk_height) << codsty->log2_cblk_height; 00309 yi1 = FFMIN(yi1, band->cblkny); 00310 cblkperprech = 1<<(codsty->log2_prec_height - codsty->log2_cblk_height); 00311 for (precy = 0, precno = 0; precy < reslevel->num_precincts_y; precy++){ 00312 for (precx = 0; precx < reslevel->num_precincts_x; precx++, precno++){ 00313 band->prec[precno].yi0 = yi0; 00314 band->prec[precno].yi1 = yi1; 00315 } 00316 yi1 += cblkperprech; 00317 yi0 = yi1 - cblkperprech; 00318 yi1 = FFMIN(yi1, band->cblkny); 00319 } 00320 x0 = band->coord[0][0]; 00321 x1 = ((band->coord[0][0] + (1<<codsty->log2_prec_width)) & ~((1<<codsty->log2_prec_width)-1)) - x0; 00322 xi0 = 0; 00323 xi1 = ff_j2k_ceildivpow2(x1 - x0, codsty->log2_cblk_width) << codsty->log2_cblk_width; 00324 xi1 = FFMIN(xi1, band->cblknx); 00325 00326 cblkperprecw = 1<<(codsty->log2_prec_width - codsty->log2_cblk_width); 00327 for (precx = 0, precno = 0; precx < reslevel->num_precincts_x; precx++){ 00328 for (precy = 0; precy < reslevel->num_precincts_y; precy++, precno = 0){ 00329 J2kPrec *prec = band->prec + precno; 00330 prec->xi0 = xi0; 00331 prec->xi1 = xi1; 00332 prec->cblkincl = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0, 00333 prec->yi1 - prec->yi0); 00334 prec->zerobits = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0, 00335 prec->yi1 - prec->yi0); 00336 if (!prec->cblkincl || !prec->zerobits) 00337 return AVERROR(ENOMEM); 00338 00339 } 00340 xi1 += cblkperprecw; 00341 xi0 = xi1 - cblkperprecw; 00342 xi1 = FFMIN(xi1, band->cblknx); 00343 } 00344 } 00345 } 00346 return 0; 00347 } 00348 00349 void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty) 00350 { 00351 int reslevelno, bandno, cblkno, precno; 00352 for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ 00353 J2kResLevel *rlevel = comp->reslevel + reslevelno; 00354 for (bandno = 0; bandno < rlevel->nbands; bandno++){ 00355 J2kBand *band = rlevel->band + bandno; 00356 for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){ 00357 J2kPrec *prec = band->prec + precno; 00358 tag_tree_zero(prec->zerobits, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0); 00359 tag_tree_zero(prec->cblkincl, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0); 00360 } 00361 for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ 00362 J2kCblk *cblk = band->cblk + cblkno; 00363 cblk->length = 0; 00364 cblk->lblock = 3; 00365 } 00366 } 00367 } 00368 } 00369 00370 void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty) 00371 { 00372 int reslevelno, bandno, precno; 00373 for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ 00374 J2kResLevel *reslevel = comp->reslevel + reslevelno; 00375 00376 for (bandno = 0; bandno < reslevel->nbands ; bandno++){ 00377 J2kBand *band = reslevel->band + bandno; 00378 for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ 00379 J2kPrec *prec = band->prec + precno; 00380 av_freep(&prec->zerobits); 00381 av_freep(&prec->cblkincl); 00382 } 00383 av_freep(&band->cblk); 00384 av_freep(&band->prec); 00385 } 00386 av_freep(&reslevel->band); 00387 } 00388 00389 ff_j2k_dwt_destroy(&comp->dwt); 00390 av_freep(&comp->reslevel); 00391 av_freep(&comp->data); 00392 }