00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/attributes.h"
00023 #include "dsputil.h"
00024 #include "dwt.h"
00025 #include "libavcodec/x86/dwt.h"
00026
00027 void ff_slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * base_buffer)
00028 {
00029 int i;
00030
00031 buf->base_buffer = base_buffer;
00032 buf->line_count = line_count;
00033 buf->line_width = line_width;
00034 buf->data_count = max_allocated_lines;
00035 buf->line = av_mallocz (sizeof(IDWTELEM *) * line_count);
00036 buf->data_stack = av_malloc (sizeof(IDWTELEM *) * max_allocated_lines);
00037
00038 for(i = 0; i < max_allocated_lines; i++){
00039 buf->data_stack[i] = av_malloc (sizeof(IDWTELEM) * line_width);
00040 }
00041
00042 buf->data_stack_top = max_allocated_lines - 1;
00043 }
00044
00045 IDWTELEM * ff_slice_buffer_load_line(slice_buffer * buf, int line)
00046 {
00047 IDWTELEM * buffer;
00048
00049 assert(buf->data_stack_top >= 0);
00050 if (buf->line[line])
00051 return buf->line[line];
00052
00053 buffer = buf->data_stack[buf->data_stack_top];
00054 buf->data_stack_top--;
00055 buf->line[line] = buffer;
00056
00057 return buffer;
00058 }
00059
00060 void ff_slice_buffer_release(slice_buffer * buf, int line)
00061 {
00062 IDWTELEM * buffer;
00063
00064 assert(line >= 0 && line < buf->line_count);
00065 assert(buf->line[line]);
00066
00067 buffer = buf->line[line];
00068 buf->data_stack_top++;
00069 buf->data_stack[buf->data_stack_top] = buffer;
00070 buf->line[line] = NULL;
00071 }
00072
00073 void ff_slice_buffer_flush(slice_buffer * buf)
00074 {
00075 int i;
00076 for(i = 0; i < buf->line_count; i++){
00077 if (buf->line[i])
00078 ff_slice_buffer_release(buf, i);
00079 }
00080 }
00081
00082 void ff_slice_buffer_destroy(slice_buffer * buf)
00083 {
00084 int i;
00085 ff_slice_buffer_flush(buf);
00086
00087 for(i = buf->data_count - 1; i >= 0; i--){
00088 av_freep(&buf->data_stack[i]);
00089 }
00090 av_freep(&buf->data_stack);
00091 av_freep(&buf->line);
00092 }
00093
00094 static inline int mirror(int v, int m){
00095 while((unsigned)v > (unsigned)m){
00096 v = -v;
00097 if(v < 0) v+= 2*m;
00098 }
00099 return v;
00100 }
00101
00102 static av_always_inline void
00103 lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
00104 int dst_step, int src_step, int ref_step,
00105 int width, int mul, int add, int shift,
00106 int highpass, int inverse){
00107 const int mirror_left = !highpass;
00108 const int mirror_right = (width & 1) ^ highpass;
00109 const int w = (width >> 1) - 1 + (highpass & width);
00110 int i;
00111
00112 #define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref)))
00113 if(mirror_left){
00114 dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
00115 dst += dst_step;
00116 src += src_step;
00117 }
00118
00119 for(i=0; i<w; i++){
00120 dst[i * dst_step] =
00121 LIFT(src[i * src_step],
00122 ((mul * (ref[i * ref_step] + ref[(i + 1) * ref_step]) + add) >> shift),
00123 inverse);
00124 }
00125
00126 if(mirror_right){
00127 dst[w * dst_step] =
00128 LIFT(src[w * src_step],
00129 ((mul * 2 * ref[w * ref_step] + add) >> shift),
00130 inverse);
00131 }
00132 }
00133
00134 static av_always_inline void
00135 inv_lift(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref,
00136 int dst_step, int src_step, int ref_step,
00137 int width, int mul, int add, int shift,
00138 int highpass, int inverse){
00139 const int mirror_left = !highpass;
00140 const int mirror_right = (width&1) ^ highpass;
00141 const int w = (width >> 1) - 1 + (highpass & width);
00142 int i;
00143
00144 #define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref)))
00145 if(mirror_left){
00146 dst[0] =
00147 LIFT(src[0],
00148 ((mul * 2 * ref[0] + add) >> shift),
00149 inverse);
00150 dst += dst_step;
00151 src += src_step;
00152 }
00153
00154 for(i = 0; i < w; i++){
00155 dst[i * dst_step] =
00156 LIFT(src[i * src_step],
00157 ((mul * (ref[i * ref_step] + ref[(i + 1) * ref_step]) + add) >> shift),
00158 inverse);
00159 }
00160
00161 if(mirror_right){
00162 dst[w * dst_step] =
00163 LIFT(src[w * src_step],
00164 ((mul * 2 * ref[w * ref_step] + add) >> shift),
00165 inverse);
00166 }
00167 }
00168
00169 #ifndef liftS
00170 static av_always_inline void
00171 liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
00172 int dst_step, int src_step, int ref_step,
00173 int width, int mul, int add, int shift,
00174 int highpass, int inverse){
00175 const int mirror_left = !highpass;
00176 const int mirror_right = (width&1) ^ highpass;
00177 const int w = (width >> 1) - 1 + (highpass & width);
00178 int i;
00179
00180 assert(shift == 4);
00181 #define LIFTS(src, ref, inv) \
00182 ((inv) ? \
00183 (src) + (((ref) + 4 * (src)) >> shift): \
00184 -((-16 * (src) + (ref) + add / 4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
00185 if(mirror_left){
00186 dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
00187 dst += dst_step;
00188 src += src_step;
00189 }
00190
00191 for(i = 0; i < w; i++){
00192 dst[i * dst_step] =
00193 LIFTS(src[i * src_step],
00194 mul * (ref[i * ref_step] + ref[(i+1) * ref_step]) + add,
00195 inverse);
00196 }
00197
00198 if(mirror_right){
00199 dst[w * dst_step] =
00200 LIFTS(src[w * src_step], mul * 2 * ref[w * ref_step] + add, inverse);
00201 }
00202 }
00203 static av_always_inline void
00204 inv_liftS(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref,
00205 int dst_step, int src_step, int ref_step,
00206 int width, int mul, int add, int shift,
00207 int highpass, int inverse){
00208 const int mirror_left = !highpass;
00209 const int mirror_right = (width&1) ^ highpass;
00210 const int w = (width >> 1) - 1 + (highpass & width);
00211 int i;
00212
00213 assert(shift == 4);
00214 #define LIFTS(src, ref, inv) \
00215 ((inv) ? \
00216 (src) + (((ref) + 4 * (src)) >> shift): \
00217 -((-16 * (src) + (ref) + add / 4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
00218 if(mirror_left){
00219 dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
00220 dst += dst_step;
00221 src += src_step;
00222 }
00223
00224 for(i = 0; i < w; i++){
00225 dst[i * dst_step] =
00226 LIFTS(src[i * src_step],
00227 mul * (ref[i * ref_step] + ref[(i+1) * ref_step]) + add,
00228 inverse);
00229 }
00230
00231 if(mirror_right){
00232 dst[w * dst_step] =
00233 LIFTS(src[w * src_step], mul * 2 * ref[w * ref_step] + add, inverse);
00234 }
00235 }
00236 #endif
00237
00238 static void horizontal_decompose53i(DWTELEM *b, int width){
00239 DWTELEM temp[width];
00240 const int width2 = width>>1;
00241 const int w2 = (width+1)>>1;
00242 int x;
00243
00244 for(x = 0; x < width2; x++){
00245 temp[x ] = b[2 * x ];
00246 temp[x+w2] = b[2 * x + 1];
00247 }
00248 if(width & 1)
00249 temp[x ] = b[2 * x ];
00250 #if 0
00251 {
00252 int A1,A2,A3,A4;
00253 A2 = temp[1 ];
00254 A4 = temp[0 ];
00255 A1 = temp[0+width2];
00256 A1 -= (A2 + A4) >> 1;
00257 A4 += (A1 + 1) >> 1;
00258 b[0 + width2] = A1;
00259 b[0 ] = A4;
00260 for(x = 1; x + 1 < width2; x += 2){
00261 A3 = temp[x + width2];
00262 A4 = temp[x + 1 ];
00263 A3 -= (A2 + A4) >> 1;
00264 A2 += (A1 + A3 + 2) >> 2;
00265 b[x + width2] = A3;
00266 b[x ] = A2;
00267
00268 A1 = temp[x + 1 + width2];
00269 A2 = temp[x + 2 ];
00270 A1 -= (A2 + A4) >> 1;
00271 A4 += (A1 + A3 + 2) >> 2;
00272 b[x + 1 + width2] = A1;
00273 b[x + 1 ] = A4;
00274 }
00275 A3 = temp[width - 1];
00276 A3 -= A2;
00277 A2 += (A1 + A3 + 2) >> 2;
00278 b[width -1] = A3;
00279 b[width2-1] = A2;
00280 }
00281 #else
00282 lift(b + w2, temp + w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
00283 lift(b , temp , b + w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
00284 #endif
00285 }
00286
00287 static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
00288 int i;
00289
00290 for(i = 0; i < width; i++){
00291 b1[i] -= (b0[i] + b2[i]) >> 1;
00292 }
00293 }
00294
00295 static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
00296 int i;
00297
00298 for(i = 0; i < width; i++){
00299 b1[i] += (b0[i] + b2[i] + 2) >> 2;
00300 }
00301 }
00302
00303 static void spatial_decompose53i(DWTELEM *buffer, int width, int height, int stride){
00304 int y;
00305 DWTELEM *b0 = buffer + mirror(-2 - 1, height-1)*stride;
00306 DWTELEM *b1 = buffer + mirror(-2 , height-1)*stride;
00307
00308 for(y = -2; y < height; y += 2){
00309 DWTELEM *b2 = buffer + mirror(y + 1, height-1) * stride;
00310 DWTELEM *b3 = buffer + mirror(y + 2, height-1) * stride;
00311
00312 if(y + 1 < (unsigned)height) horizontal_decompose53i(b2, width);
00313 if(y + 2 < (unsigned)height) horizontal_decompose53i(b3, width);
00314
00315 if(y + 1 < (unsigned)height) vertical_decompose53iH0(b1, b2, b3, width);
00316 if(y + 0 < (unsigned)height) vertical_decompose53iL0(b0, b1, b2, width);
00317
00318 b0 = b2;
00319 b1 = b3;
00320 }
00321 }
00322
00323 static void horizontal_decompose97i(DWTELEM *b, int width){
00324 DWTELEM temp[width];
00325 const int w2 = (width+1)>>1;
00326
00327 lift (temp + w2, b + 1 , b , 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
00328 liftS(temp , b , temp + w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
00329 lift (b + w2, temp + w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
00330 lift (b , temp , b + w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
00331 }
00332
00333
00334 static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
00335 int i;
00336
00337 for(i = 0; i < width; i++){
00338 b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
00339 }
00340 }
00341
00342 static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
00343 int i;
00344
00345 for(i=0; i < width; i++){
00346 b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
00347 }
00348 }
00349
00350 static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
00351 int i;
00352
00353 for(i = 0; i < width; i++){
00354 #ifdef liftS
00355 b1[i] -= (W_BM * (b0[i] + b2[i]) + W_BO) >> W_BS;
00356 #else
00357 b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) / (5 * 16) - (1 << 23);
00358 #endif
00359 }
00360 }
00361
00362 static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
00363 int i;
00364
00365 for(i = 0; i < width; i++){
00366 b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
00367 }
00368 }
00369
00370 static void spatial_decompose97i(DWTELEM *buffer, int width, int height, int stride){
00371 int y;
00372 DWTELEM *b0 = buffer + mirror(-4 - 1, height-1) * stride;
00373 DWTELEM *b1 = buffer + mirror(-4 , height-1) * stride;
00374 DWTELEM *b2 = buffer + mirror(-4 + 1, height-1) * stride;
00375 DWTELEM *b3 = buffer + mirror(-4 + 2, height-1) * stride;
00376
00377 for(y = -4; y < height; y += 2){
00378 DWTELEM *b4 = buffer + mirror(y + 3, height-1) * stride;
00379 DWTELEM *b5 = buffer + mirror(y + 4, height-1) * stride;
00380
00381 if(y + 3 < (unsigned)height) horizontal_decompose97i(b4, width);
00382 if(y + 4 < (unsigned)height) horizontal_decompose97i(b5, width);
00383
00384 if(y + 3 < (unsigned)height) vertical_decompose97iH0(b3, b4, b5, width);
00385 if(y + 2 < (unsigned)height) vertical_decompose97iL0(b2, b3, b4, width);
00386 if(y + 1 < (unsigned)height) vertical_decompose97iH1(b1, b2, b3, width);
00387 if(y + 0 < (unsigned)height) vertical_decompose97iL1(b0, b1, b2, width);
00388
00389 b0 = b2;
00390 b1 = b3;
00391 b2 = b4;
00392 b3 = b5;
00393 }
00394 }
00395
00396 void ff_spatial_dwt(DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
00397 int level;
00398
00399 for(level = 0; level < decomposition_count; level++){
00400 switch(type){
00401 case DWT_97: spatial_decompose97i(buffer, width >> level, height >> level, stride << level); break;
00402 case DWT_53: spatial_decompose53i(buffer, width >> level, height >> level, stride << level); break;
00403 }
00404 }
00405 }
00406
00407 static void horizontal_compose53i(IDWTELEM *b, int width){
00408 IDWTELEM temp[width];
00409 const int width2 = width >> 1;
00410 const int w2 = (width + 1) >> 1;
00411 int x;
00412
00413 for(x = 0; x < width2; x++){
00414 temp[2 * x ] = b[x ];
00415 temp[2 * x + 1] = b[x + w2];
00416 }
00417 if(width & 1)
00418 temp[2 * x ] = b[x ];
00419
00420 b[0] = temp[0] - ((temp[1] + 1) >> 1);
00421 for(x = 2; x < width - 1; x += 2){
00422 b[x ] = temp[x ] - ((temp[x - 1] + temp[x + 1] + 2) >> 2);
00423 b[x - 1] = temp[x - 1] + ((b [x - 2] + b [x ] + 1) >> 1);
00424 }
00425 if(width & 1){
00426 b[x ] = temp[x ] - ((temp[x - 1] + 1) >> 1);
00427 b[x - 1] = temp[x - 1] + ((b [x - 2] + b [x ] + 1) >> 1);
00428 }else
00429 b[x - 1] = temp[x - 1] + b[x - 2];
00430 }
00431
00432 static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
00433 int i;
00434
00435 for(i = 0; i < width; i++){
00436 b1[i] += (b0[i] + b2[i]) >> 1;
00437 }
00438 }
00439
00440 static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
00441 int i;
00442
00443 for(i = 0; i < width; i++){
00444 b1[i] -= (b0[i] + b2[i] + 2) >> 2;
00445 }
00446 }
00447
00448 static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer * sb, int height, int stride_line){
00449 cs->b0 = slice_buffer_get_line(sb, mirror(-1-1, height - 1) * stride_line);
00450 cs->b1 = slice_buffer_get_line(sb, mirror(-1 , height - 1) * stride_line);
00451 cs->y = -1;
00452 }
00453
00454 static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride){
00455 cs->b0 = buffer + mirror(-1-1, height - 1) * stride;
00456 cs->b1 = buffer + mirror(-1 , height - 1) * stride;
00457 cs->y = -1;
00458 }
00459
00460 static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line){
00461 int y = cs->y;
00462 IDWTELEM *b0 = cs->b0;
00463 IDWTELEM *b1 = cs->b1;
00464 IDWTELEM *b2 = slice_buffer_get_line(sb, mirror(y + 1, height-1) * stride_line);
00465 IDWTELEM *b3 = slice_buffer_get_line(sb, mirror(y + 2, height-1) * stride_line);
00466
00467 if(y + 1 < (unsigned)height && y < (unsigned)height){
00468 int x;
00469
00470 for(x = 0; x < width; x++){
00471 b2[x] -= (b1[x] + b3[x] + 2) >> 2;
00472 b1[x] += (b0[x] + b2[x]) >> 1;
00473 }
00474 }else{
00475 if(y + 1 < (unsigned)height) vertical_compose53iL0(b1, b2, b3, width);
00476 if(y + 0 < (unsigned)height) vertical_compose53iH0(b0, b1, b2, width);
00477 }
00478
00479 if(y - 1 <(unsigned)height) horizontal_compose53i(b0, width);
00480 if(y + 0 <(unsigned)height) horizontal_compose53i(b1, width);
00481
00482 cs->b0 = b2;
00483 cs->b1 = b3;
00484 cs->y += 2;
00485 }
00486
00487 static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride){
00488 int y = cs->y;
00489 IDWTELEM *b0 = cs->b0;
00490 IDWTELEM *b1 = cs->b1;
00491 IDWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
00492 IDWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
00493
00494 if(y + 1 < (unsigned)height) vertical_compose53iL0(b1, b2, b3, width);
00495 if(y + 0 < (unsigned)height) vertical_compose53iH0(b0, b1, b2, width);
00496
00497 if(y - 1 < (unsigned)height) horizontal_compose53i(b0, width);
00498 if(y + 0 < (unsigned)height) horizontal_compose53i(b1, width);
00499
00500 cs->b0 = b2;
00501 cs->b1 = b3;
00502 cs->y += 2;
00503 }
00504
00505 static void av_unused spatial_compose53i(IDWTELEM *buffer, int width, int height, int stride){
00506 DWTCompose cs;
00507 spatial_compose53i_init(&cs, buffer, height, stride);
00508 while(cs.y <= height)
00509 spatial_compose53i_dy(&cs, buffer, width, height, stride);
00510 }
00511
00512
00513 void ff_snow_horizontal_compose97i(IDWTELEM *b, int width){
00514 IDWTELEM temp[width];
00515 const int w2 = (width + 1) >> 1;
00516
00517 #if 0 //maybe more understadable but slower
00518 inv_lift (temp , b , b + w2, 2, 1, 1, width, W_DM, W_DO, W_DS, 0, 1);
00519 inv_lift (temp + 1, b + w2, temp , 2, 1, 2, width, W_CM, W_CO, W_CS, 1, 1);
00520
00521 inv_liftS(b ,temp ,temp + 1, 2, 2, 2, width, W_BM, W_BO, W_BS, 0, 1);
00522 inv_lift (b + 1 ,temp + 1,b , 2, 2, 2, width, W_AM, W_AO, W_AS, 1, 0);
00523 #else
00524 int x;
00525 temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
00526 for(x = 1; x < (width >> 1); x++){
00527 temp[2 * x ] = b[x ] - (( 3 * (b [ x + w2 - 1] + b[x + w2]) + 4) >> 3);
00528 temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
00529 }
00530 if(width & 1){
00531 temp[2*x ] = b[x ] - ((3*b [x+w2-1]+2)>>2);
00532 temp[2*x-1] = b[x+w2-1] - temp[2*x-2] - temp[2*x];
00533 }else
00534 temp[2*x-1] = b[x+w2-1] - 2*temp[2*x-2];
00535
00536 b[0] = temp[0] + ((2*temp[0] + temp[1]+4)>>3);
00537 for(x=2; x<width-1; x+=2){
00538 b[x ] = temp[x ] + ((4*temp[x ] + temp[x-1] + temp[x+1]+8)>>4);
00539 b[x-1] = temp[x-1] + ((3*(b [x-2] + b [x ] ))>>1);
00540 }
00541 if(width&1){
00542 b[x ] = temp[x ] + ((2*temp[x ] + temp[x-1]+4)>>3);
00543 b[x-1] = temp[x-1] + ((3*(b [x-2] + b [x ] ))>>1);
00544 }else
00545 b[x-1] = temp[x-1] + 3*b [x-2];
00546 #endif
00547 }
00548
00549 static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
00550 int i;
00551
00552 for(i=0; i<width; i++){
00553 b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
00554 }
00555 }
00556
00557 static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
00558 int i;
00559
00560 for(i=0; i<width; i++){
00561 b1[i] -= (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS;
00562 }
00563 }
00564
00565 static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
00566 int i;
00567
00568 for(i=0; i<width; i++){
00569 #ifdef liftS
00570 b1[i] += (W_BM*(b0[i] + b2[i])+W_BO)>>W_BS;
00571 #else
00572 b1[i] += (W_BM*(b0[i] + b2[i])+4*b1[i]+W_BO)>>W_BS;
00573 #endif
00574 }
00575 }
00576
00577 static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){
00578 int i;
00579
00580 for(i=0; i<width; i++){
00581 b1[i] -= (W_DM*(b0[i] + b2[i])+W_DO)>>W_DS;
00582 }
00583 }
00584
00585 void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){
00586 int i;
00587
00588 for(i=0; i<width; i++){
00589 b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS;
00590 b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS;
00591 #ifdef liftS
00592 b2[i] += (W_BM*(b1[i] + b3[i])+W_BO)>>W_BS;
00593 #else
00594 b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS;
00595 #endif
00596 b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
00597 }
00598 }
00599
00600 static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer * sb, int height, int stride_line){
00601 cs->b0 = slice_buffer_get_line(sb, mirror(-3-1, height-1) * stride_line);
00602 cs->b1 = slice_buffer_get_line(sb, mirror(-3 , height-1) * stride_line);
00603 cs->b2 = slice_buffer_get_line(sb, mirror(-3+1, height-1) * stride_line);
00604 cs->b3 = slice_buffer_get_line(sb, mirror(-3+2, height-1) * stride_line);
00605 cs->y = -3;
00606 }
00607
00608 static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride){
00609 cs->b0 = buffer + mirror(-3-1, height-1)*stride;
00610 cs->b1 = buffer + mirror(-3 , height-1)*stride;
00611 cs->b2 = buffer + mirror(-3+1, height-1)*stride;
00612 cs->b3 = buffer + mirror(-3+2, height-1)*stride;
00613 cs->y = -3;
00614 }
00615
00616 static void spatial_compose97i_dy_buffered(DWTContext *dsp, DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line){
00617 int y = cs->y;
00618
00619 IDWTELEM *b0= cs->b0;
00620 IDWTELEM *b1= cs->b1;
00621 IDWTELEM *b2= cs->b2;
00622 IDWTELEM *b3= cs->b3;
00623 IDWTELEM *b4= slice_buffer_get_line(sb, mirror(y + 3, height - 1) * stride_line);
00624 IDWTELEM *b5= slice_buffer_get_line(sb, mirror(y + 4, height - 1) * stride_line);
00625
00626 if(y>0 && y+4<height){
00627 dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
00628 }else{
00629 if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
00630 if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
00631 if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
00632 if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
00633 }
00634
00635 if(y-1<(unsigned)height) dsp->horizontal_compose97i(b0, width);
00636 if(y+0<(unsigned)height) dsp->horizontal_compose97i(b1, width);
00637
00638 cs->b0=b2;
00639 cs->b1=b3;
00640 cs->b2=b4;
00641 cs->b3=b5;
00642 cs->y += 2;
00643 }
00644
00645 static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride){
00646 int y = cs->y;
00647 IDWTELEM *b0= cs->b0;
00648 IDWTELEM *b1= cs->b1;
00649 IDWTELEM *b2= cs->b2;
00650 IDWTELEM *b3= cs->b3;
00651 IDWTELEM *b4= buffer + mirror(y+3, height-1)*stride;
00652 IDWTELEM *b5= buffer + mirror(y+4, height-1)*stride;
00653
00654 if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
00655 if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
00656 if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
00657 if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
00658
00659 if(y-1<(unsigned)height) ff_snow_horizontal_compose97i(b0, width);
00660 if(y+0<(unsigned)height) ff_snow_horizontal_compose97i(b1, width);
00661
00662 cs->b0=b2;
00663 cs->b1=b3;
00664 cs->b2=b4;
00665 cs->b3=b5;
00666 cs->y += 2;
00667 }
00668
00669 static void av_unused spatial_compose97i(IDWTELEM *buffer, int width, int height, int stride){
00670 DWTCompose cs;
00671 spatial_compose97i_init(&cs, buffer, height, stride);
00672 while(cs.y <= height)
00673 spatial_compose97i_dy(&cs, buffer, width, height, stride);
00674 }
00675
00676 void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line, int type, int decomposition_count){
00677 int level;
00678 for(level=decomposition_count-1; level>=0; level--){
00679 switch(type){
00680 case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
00681 case DWT_53: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
00682 }
00683 }
00684 }
00685
00686 void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs, slice_buffer * slice_buf, int width, int height, int stride_line, int type, int decomposition_count, int y){
00687 const int support = type==1 ? 3 : 5;
00688 int level;
00689 if(type==2) return;
00690
00691 for(level=decomposition_count-1; level>=0; level--){
00692 while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
00693 switch(type){
00694 case DWT_97: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
00695 break;
00696 case DWT_53: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
00697 break;
00698 }
00699 }
00700 }
00701 }
00702
00703 static void ff_spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
00704 int level;
00705 for(level=decomposition_count-1; level>=0; level--){
00706 switch(type){
00707 case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break;
00708 case DWT_53: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break;
00709 }
00710 }
00711 }
00712
00713 static void ff_spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count, int y){
00714 const int support = type==1 ? 3 : 5;
00715 int level;
00716 if(type==2) return;
00717
00718 for(level=decomposition_count-1; level>=0; level--){
00719 while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
00720 switch(type){
00721 case DWT_97: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
00722 break;
00723 case DWT_53: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
00724 break;
00725 }
00726 }
00727 }
00728 }
00729
00730 void ff_spatial_idwt(IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
00731 DWTCompose cs[MAX_DECOMPOSITIONS];
00732 int y;
00733 ff_spatial_idwt_init(cs, buffer, width, height, stride, type, decomposition_count);
00734 for(y=0; y<height; y+=4)
00735 ff_spatial_idwt_slice(cs, buffer, width, height, stride, type, decomposition_count, y);
00736 }
00737
00738 static inline int w_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int w, int h, int type){
00739 int s, i, j;
00740 const int dec_count= w==8 ? 3 : 4;
00741 int tmp[32*32];
00742 int level, ori;
00743 static const int scale[2][2][4][4]={
00744 {
00745 {
00746
00747 {268, 239, 239, 213},
00748 { 0, 224, 224, 152},
00749 { 0, 135, 135, 110},
00750 },{
00751
00752 {344, 310, 310, 280},
00753 { 0, 320, 320, 228},
00754 { 0, 175, 175, 136},
00755 { 0, 129, 129, 102},
00756 }
00757 },{
00758 {
00759
00760 {275, 245, 245, 218},
00761 { 0, 230, 230, 156},
00762 { 0, 138, 138, 113},
00763 },{
00764
00765 {352, 317, 317, 286},
00766 { 0, 328, 328, 233},
00767 { 0, 180, 180, 140},
00768 { 0, 132, 132, 105},
00769 }
00770 }
00771 };
00772
00773 for (i = 0; i < h; i++) {
00774 for (j = 0; j < w; j+=4) {
00775 tmp[32*i+j+0] = (pix1[j+0] - pix2[j+0])<<4;
00776 tmp[32*i+j+1] = (pix1[j+1] - pix2[j+1])<<4;
00777 tmp[32*i+j+2] = (pix1[j+2] - pix2[j+2])<<4;
00778 tmp[32*i+j+3] = (pix1[j+3] - pix2[j+3])<<4;
00779 }
00780 pix1 += line_size;
00781 pix2 += line_size;
00782 }
00783
00784 ff_spatial_dwt(tmp, w, h, 32, type, dec_count);
00785
00786 s=0;
00787 assert(w==h);
00788 for(level=0; level<dec_count; level++){
00789 for(ori= level ? 1 : 0; ori<4; ori++){
00790 int size= w>>(dec_count-level);
00791 int sx= (ori&1) ? size : 0;
00792 int stride= 32<<(dec_count-level);
00793 int sy= (ori&2) ? stride>>1 : 0;
00794
00795 for(i=0; i<size; i++){
00796 for(j=0; j<size; j++){
00797 int v= tmp[sx + sy + i*stride + j] * scale[type][dec_count-3][level][ori];
00798 s += FFABS(v);
00799 }
00800 }
00801 }
00802 }
00803 assert(s>=0);
00804 return s>>9;
00805 }
00806
00807 static int w53_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
00808 return w_c(v, pix1, pix2, line_size, 8, h, 1);
00809 }
00810
00811 static int w97_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
00812 return w_c(v, pix1, pix2, line_size, 8, h, 0);
00813 }
00814
00815 static int w53_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
00816 return w_c(v, pix1, pix2, line_size, 16, h, 1);
00817 }
00818
00819 static int w97_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
00820 return w_c(v, pix1, pix2, line_size, 16, h, 0);
00821 }
00822
00823 int ff_w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
00824 return w_c(v, pix1, pix2, line_size, 32, h, 1);
00825 }
00826
00827 int ff_w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){
00828 return w_c(v, pix1, pix2, line_size, 32, h, 0);
00829 }
00830
00831 void ff_dsputil_init_dwt(DSPContext *c)
00832 {
00833 c->w53[0]= w53_16_c;
00834 c->w53[1]= w53_8_c;
00835 c->w97[0]= w97_16_c;
00836 c->w97[1]= w97_8_c;
00837 }
00838
00839 void ff_dwt_init(DWTContext *c)
00840 {
00841 c->vertical_compose97i = ff_snow_vertical_compose97i;
00842 c->horizontal_compose97i = ff_snow_horizontal_compose97i;
00843 c->inner_add_yblock = ff_snow_inner_add_yblock;
00844
00845 if (HAVE_MMX) ff_dwt_init_x86(c);
00846 }
00847
00848
00849 static av_always_inline
00850 void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
00851 {
00852 int i;
00853 for (i = 0; i < w2; i++) {
00854 dst[2*i ] = (src0[i] + add) >> shift;
00855 dst[2*i+1] = (src1[i] + add) >> shift;
00856 }
00857 }
00858
00859 static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w)
00860 {
00861 const int w2 = w >> 1;
00862 int x;
00863
00864 temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
00865 for (x = 1; x < w2; x++) {
00866 temp[x ] = COMPOSE_53iL0 (b[x+w2-1], b[x ], b[x+w2]);
00867 temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
00868 }
00869 temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
00870
00871 interleave(b, temp, temp+w2, w2, 1, 1);
00872 }
00873
00874 static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
00875 {
00876 const int w2 = w >> 1;
00877 int x;
00878
00879 tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
00880 for (x = 1; x < w2; x++)
00881 tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
00882
00883
00884 tmp[-1] = tmp[0];
00885 tmp[w2+1] = tmp[w2] = tmp[w2-1];
00886
00887 for (x = 0; x < w2; x++) {
00888 b[2*x ] = (tmp[x] + 1)>>1;
00889 b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
00890 }
00891 }
00892
00893 static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
00894 {
00895 const int w2 = w >> 1;
00896 int x;
00897
00898 tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2 ], b[w2+1]);
00899 tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
00900 for (x = 2; x < w2-1; x++)
00901 tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
00902 tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
00903
00904
00905 tmp[-1] = tmp[0];
00906 tmp[w2+1] = tmp[w2] = tmp[w2-1];
00907
00908 for (x = 0; x < w2; x++) {
00909 b[2*x ] = (tmp[x] + 1)>>1;
00910 b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
00911 }
00912 }
00913
00914 static av_always_inline
00915 void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift)
00916 {
00917 const int w2 = w >> 1;
00918 int x;
00919
00920 for (x = 0; x < w2; x++) {
00921 temp[x ] = COMPOSE_HAARiL0(b[x ], b[x+w2]);
00922 temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
00923 }
00924
00925 interleave(b, temp, temp+w2, w2, shift, shift);
00926 }
00927
00928 static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w)
00929 {
00930 horizontal_compose_haari(b, temp, w, 0);
00931 }
00932
00933 static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w)
00934 {
00935 horizontal_compose_haari(b, temp, w, 1);
00936 }
00937
00938 static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w)
00939 {
00940 const int w2 = w >> 1;
00941 int i, x;
00942 IDWTELEM v[8];
00943
00944 for (x = 0; x < w2; x++) {
00945 for (i = 0; i < 8; i++)
00946 v[i] = b[av_clip(x-3+i, 0, w2-1)];
00947 tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
00948 }
00949
00950 for (x = 0; x < w2; x++) {
00951 for (i = 0; i < 8; i++)
00952 v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
00953 tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
00954 }
00955
00956 interleave(b, tmp+w2, tmp, w2, 0, 0);
00957 }
00958
00959 static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w)
00960 {
00961 const int w2 = w >> 1;
00962 int x, b0, b1, b2;
00963
00964 temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
00965 for (x = 1; x < w2; x++) {
00966 temp[x ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x ], b[x+w2]);
00967 temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
00968 }
00969 temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
00970
00971
00972 b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
00973 b[0] = (b0 + 1) >> 1;
00974 for (x = 1; x < w2; x++) {
00975 b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x ], temp[x+w2]);
00976 b1 = COMPOSE_DAUB97iH0( b0, temp[x+w2-1], b2 );
00977 b[2*x-1] = (b1 + 1) >> 1;
00978 b[2*x ] = (b2 + 1) >> 1;
00979 b0 = b2;
00980 }
00981 b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
00982 }
00983
00984 static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
00985 {
00986 int i;
00987
00988 for(i=0; i<width; i++){
00989 b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
00990 }
00991 }
00992
00993 static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
00994 IDWTELEM *b3, IDWTELEM *b4, int width)
00995 {
00996 int i;
00997
00998 for(i=0; i<width; i++){
00999 b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
01000 }
01001 }
01002
01003 static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
01004 IDWTELEM *b3, IDWTELEM *b4, int width)
01005 {
01006 int i;
01007
01008 for(i=0; i<width; i++){
01009 b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
01010 }
01011 }
01012
01013 static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
01014 {
01015 int i;
01016
01017 for (i = 0; i < width; i++) {
01018 b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
01019 b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
01020 }
01021 }
01022
01023 static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width)
01024 {
01025 int i;
01026
01027 for(i=0; i<width; i++){
01028 dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
01029 }
01030 }
01031
01032 static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width)
01033 {
01034 int i;
01035
01036 for(i=0; i<width; i++){
01037 dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
01038 }
01039 }
01040
01041 static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
01042 {
01043 int i;
01044
01045 for(i=0; i<width; i++){
01046 b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
01047 }
01048 }
01049
01050 static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
01051 {
01052 int i;
01053
01054 for(i=0; i<width; i++){
01055 b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
01056 }
01057 }
01058
01059 static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
01060 {
01061 int i;
01062
01063 for(i=0; i<width; i++){
01064 b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
01065 }
01066 }
01067
01068 static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
01069 {
01070 int i;
01071
01072 for(i=0; i<width; i++){
01073 b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
01074 }
01075 }
01076
01077
01078 static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
01079 {
01080 vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0;
01081 vertical_compose_5tap vertical_compose_h0 = d->vertical_compose_h0;
01082 DWTCompose *cs = d->cs + level;
01083
01084 int i, y = cs->y;
01085 IDWTELEM *b[8];
01086 for (i = 0; i < 6; i++)
01087 b[i] = cs->b[i];
01088 b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
01089 b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
01090
01091 if(y+5<(unsigned)height) vertical_compose_l0( b[5], b[6], b[7], width);
01092 if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
01093
01094 if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
01095 if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
01096
01097 for (i = 0; i < 6; i++)
01098 cs->b[i] = b[i+2];
01099 cs->y += 2;
01100 }
01101
01102 static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
01103 {
01104 vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0;
01105 vertical_compose_3tap vertical_compose_h0 = d->vertical_compose_h0;
01106 DWTCompose *cs = d->cs + level;
01107
01108 int y= cs->y;
01109 IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
01110 b[2] = d->buffer + mirror(y+1, height-1)*stride;
01111 b[3] = d->buffer + mirror(y+2, height-1)*stride;
01112
01113 if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
01114 if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
01115
01116 if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
01117 if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
01118
01119 cs->b[0] = b[2];
01120 cs->b[1] = b[3];
01121 cs->y += 2;
01122 }
01123
01124
01125 static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
01126 {
01127 vertical_compose_5tap vertical_compose_l0 = d->vertical_compose_l0;
01128 vertical_compose_5tap vertical_compose_h0 = d->vertical_compose_h0;
01129 DWTCompose *cs = d->cs + level;
01130
01131 int i, y = cs->y;
01132 IDWTELEM *b[10];
01133 for (i = 0; i < 8; i++)
01134 b[i] = cs->b[i];
01135 b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
01136 b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
01137
01138 if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
01139 if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
01140
01141 if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
01142 if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
01143
01144 for (i = 0; i < 8; i++)
01145 cs->b[i] = b[i+2];
01146 cs->y += 2;
01147 }
01148
01149
01150 static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
01151 {
01152 vertical_compose_2tap vertical_compose = d->vertical_compose;
01153 int y = d->cs[level].y;
01154 IDWTELEM *b0 = d->buffer + (y-1)*stride;
01155 IDWTELEM *b1 = d->buffer + (y )*stride;
01156
01157 vertical_compose(b0, b1, width);
01158 d->horizontal_compose(b0, d->temp, width);
01159 d->horizontal_compose(b1, d->temp, width);
01160
01161 d->cs[level].y += 2;
01162 }
01163
01164
01165
01166 static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
01167 {
01168 vertical_compose_9tap vertical_compose_l0 = d->vertical_compose_l0;
01169 vertical_compose_9tap vertical_compose_h0 = d->vertical_compose_h0;
01170 int i, y;
01171 IDWTELEM *b[8];
01172
01173 for (y = 1; y < height; y += 2) {
01174 for (i = 0; i < 8; i++)
01175 b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
01176 vertical_compose_h0(d->buffer + y*stride, b, width);
01177 }
01178
01179 for (y = 0; y < height; y += 2) {
01180 for (i = 0; i < 8; i++)
01181 b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
01182 vertical_compose_l0(d->buffer + y*stride, b, width);
01183 }
01184
01185 for (y = 0; y < height; y++)
01186 d->horizontal_compose(d->buffer + y*stride, d->temp, width);
01187
01188 d->cs[level].y = height+1;
01189 }
01190
01191 static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
01192 {
01193 vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0;
01194 vertical_compose_3tap vertical_compose_h0 = d->vertical_compose_h0;
01195 vertical_compose_3tap vertical_compose_l1 = d->vertical_compose_l1;
01196 vertical_compose_3tap vertical_compose_h1 = d->vertical_compose_h1;
01197 DWTCompose *cs = d->cs + level;
01198
01199 int i, y = cs->y;
01200 IDWTELEM *b[6];
01201 for (i = 0; i < 4; i++)
01202 b[i] = cs->b[i];
01203 b[4] = d->buffer + mirror(y+3, height-1)*stride;
01204 b[5] = d->buffer + mirror(y+4, height-1)*stride;
01205
01206 if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
01207 if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
01208 if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
01209 if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
01210
01211 if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
01212 if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
01213
01214 for (i = 0; i < 4; i++)
01215 cs->b[i] = b[i+2];
01216 cs->y += 2;
01217 }
01218
01219
01220 static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
01221 {
01222 cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
01223 cs->b[1] = buffer + mirror(-3 , height-1)*stride;
01224 cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
01225 cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
01226 cs->y = -3;
01227 }
01228
01229 static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
01230 {
01231 cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
01232 cs->b[1] = buffer + mirror(-1 , height-1)*stride;
01233 cs->y = -1;
01234 }
01235
01236 static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
01237 {
01238 cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
01239 cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride;
01240 cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
01241 cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
01242 cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
01243 cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
01244 cs->y = -5;
01245 }
01246
01247 static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
01248 {
01249 cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
01250 cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride;
01251 cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
01252 cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
01253 cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
01254 cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
01255 cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
01256 cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
01257 cs->y = -5;
01258 }
01259
01260 int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
01261 int stride, enum dwt_type type, int decomposition_count,
01262 IDWTELEM *temp)
01263 {
01264 int level;
01265
01266 d->buffer = buffer;
01267 d->width = width;
01268 d->height = height;
01269 d->stride = stride;
01270 d->decomposition_count = decomposition_count;
01271 d->temp = temp + 8;
01272
01273 for(level=decomposition_count-1; level>=0; level--){
01274 int hl = height >> level;
01275 int stride_l = stride << level;
01276
01277 switch(type){
01278 case DWT_DIRAC_DD9_7:
01279 spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
01280 break;
01281 case DWT_DIRAC_LEGALL5_3:
01282 spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
01283 break;
01284 case DWT_DIRAC_DD13_7:
01285 spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
01286 break;
01287 case DWT_DIRAC_HAAR0:
01288 case DWT_DIRAC_HAAR1:
01289 d->cs[level].y = 1;
01290 break;
01291 case DWT_DIRAC_DAUB9_7:
01292 spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
01293 break;
01294 default:
01295 d->cs[level].y = 0;
01296 break;
01297 }
01298 }
01299
01300 switch (type) {
01301 case DWT_DIRAC_DD9_7:
01302 d->spatial_compose = spatial_compose_dd97i_dy;
01303 d->vertical_compose_l0 = vertical_compose53iL0;
01304 d->vertical_compose_h0 = vertical_compose_dd97iH0;
01305 d->horizontal_compose = horizontal_compose_dd97i;
01306 d->support = 7;
01307 break;
01308 case DWT_DIRAC_LEGALL5_3:
01309 d->spatial_compose = spatial_compose_dirac53i_dy;
01310 d->vertical_compose_l0 = vertical_compose53iL0;
01311 d->vertical_compose_h0 = vertical_compose_dirac53iH0;
01312 d->horizontal_compose = horizontal_compose_dirac53i;
01313 d->support = 3;
01314 break;
01315 case DWT_DIRAC_DD13_7:
01316 d->spatial_compose = spatial_compose_dd137i_dy;
01317 d->vertical_compose_l0 = vertical_compose_dd137iL0;
01318 d->vertical_compose_h0 = vertical_compose_dd97iH0;
01319 d->horizontal_compose = horizontal_compose_dd137i;
01320 d->support = 7;
01321 break;
01322 case DWT_DIRAC_HAAR0:
01323 case DWT_DIRAC_HAAR1:
01324 d->spatial_compose = spatial_compose_haari_dy;
01325 d->vertical_compose = vertical_compose_haar;
01326 if (type == DWT_DIRAC_HAAR0)
01327 d->horizontal_compose = horizontal_compose_haar0i;
01328 else
01329 d->horizontal_compose = horizontal_compose_haar1i;
01330 d->support = 1;
01331 break;
01332 case DWT_DIRAC_FIDELITY:
01333 d->spatial_compose = spatial_compose_fidelity;
01334 d->vertical_compose_l0 = vertical_compose_fidelityiL0;
01335 d->vertical_compose_h0 = vertical_compose_fidelityiH0;
01336 d->horizontal_compose = horizontal_compose_fidelityi;
01337 break;
01338 case DWT_DIRAC_DAUB9_7:
01339 d->spatial_compose = spatial_compose_daub97i_dy;
01340 d->vertical_compose_l0 = vertical_compose_daub97iL0;
01341 d->vertical_compose_h0 = vertical_compose_daub97iH0;
01342 d->vertical_compose_l1 = vertical_compose_daub97iL1;
01343 d->vertical_compose_h1 = vertical_compose_daub97iH1;
01344 d->horizontal_compose = horizontal_compose_daub97i;
01345 d->support = 5;
01346 break;
01347 default:
01348 av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
01349 return -1;
01350 }
01351
01352 if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
01353
01354 return 0;
01355 }
01356
01357 void ff_spatial_idwt_slice2(DWTContext *d, int y)
01358 {
01359 int level, support = d->support;
01360
01361 for (level = d->decomposition_count-1; level >= 0; level--) {
01362 int wl = d->width >> level;
01363 int hl = d->height >> level;
01364 int stride_l = d->stride << level;
01365
01366 while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
01367 d->spatial_compose(d, level, wl, hl, stride_l);
01368 }
01369 }
01370
01371 int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride,
01372 enum dwt_type type, int decomposition_count, IDWTELEM *temp)
01373 {
01374 DWTContext d;
01375 int y;
01376
01377 if (ff_spatial_idwt_init2(&d, buffer, width, height, stride, type, decomposition_count, temp))
01378 return -1;
01379
01380 for (y = 0; y < d.height; y += 4)
01381 ff_spatial_idwt_slice2(&d, y);
01382
01383 return 0;
01384 }