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