00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <it/types.h>
00026 #include <it/wavelet.h>
00027 #include <it/wavelet2D.h>
00028 #include <it/io.h>
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #define reset_pointers() \
00089 do { \
00090 pixels = buffer + page; \
00091 low = buffer; \
00092 high = buffer + (page >> 1); \
00093 low_low = buffer + (page >> 1) + 0 * (page >> 2); \
00094 low_high = buffer + (page >> 1) + 1 * (page >> 2); \
00095 high_low = buffer + (page >> 1) + 2 * (page >> 2); \
00096 high_high = buffer + (page >> 1) + 3 * (page >> 2); \
00097 } while(0)
00098
00099 #define increment_pointers() \
00100 do { \
00101 pixels+=2; \
00102 low++; \
00103 high++; \
00104 high_low++; \
00105 high_high++; \
00106 low_high++; \
00107 low_low++; \
00108 } while(0)
00109
00110 #define adjust_pointers(odd) \
00111 do { \
00112 pixels+=odd; \
00113 if(odd == 1) low++; \
00114 if(odd == -1) high--; \
00115 } while(0)
00116
00117
00118 #define hlifting(dest, source, constant, alt_source_pre, alt_source, alt_source_post, w, h, odd) \
00119 do { \
00120 reset_pointers(); \
00121 for(y = 0; y < (h); y++) { \
00122 (dest) = (source) + (constant) * (alt_source_pre); \
00123 increment_pointers(); \
00124 \
00125 for(x = 1; x < (w)-1; x++) { \
00126 (dest) = (source) + (constant) * (alt_source); \
00127 increment_pointers(); \
00128 } \
00129 \
00130 (dest) = (source) + (constant) * (alt_source_post); \
00131 increment_pointers(); \
00132 adjust_pointers(odd); \
00133 } \
00134 } while(0)
00135
00136 #define hlifting(dest, source, constant, alt_source_pre, alt_source, alt_source_post, w, h, odd) \
00137 do { \
00138 reset_pointers(); \
00139 for(y = 0; y < (h); y++) { \
00140 (dest) = (source) + (constant) * (alt_source_pre); \
00141 increment_pointers(); \
00142 \
00143 for(x = 1; x < (w)-1; x++) { \
00144 (dest) = (source) + (constant) * (alt_source); \
00145 increment_pointers(); \
00146 } \
00147 \
00148 (dest) = (source) + (constant) * (alt_source_post); \
00149 increment_pointers(); \
00150 adjust_pointers(odd); \
00151 } \
00152 } while(0)
00153
00154 #define vlifting(dest, source, constant, alt_source_pre, alt_source, alt_source_post, line, w, h) \
00155 do { \
00156 reset_pointers(); \
00157 for(x = 0; x < w; x ++) { \
00158 (dest) = (source) + (constant) * (alt_source_pre); \
00159 increment_pointers(); \
00160 } \
00161 (line) += p; \
00162 for(y = 1; y < h-1; y ++) { \
00163 for(x = 0; x < w; x ++) { \
00164 (dest) = (source) + (constant) * (alt_source); \
00165 increment_pointers(); \
00166 } \
00167 (line) += p; \
00168 } \
00169 for(x = 0; x < w; x ++) { \
00170 (dest) = (source) + (constant) * (alt_source_post); \
00171 increment_pointers(); \
00172 } \
00173 } while(0)
00174
00175 #define scale(dest, scale, count) \
00176 do { \
00177 reset_pointers(); \
00178 for(x = 0; x < (count); x++) { \
00179 (dest)[0] *= (scale); \
00180 increment_pointers(); \
00181 } \
00182 } while(0)
00183
00184 #define shift_up(x, l) ((x + ~(-1 << l)) >> l)
00185 #define round_up(x, l) (shift_up(x, l) << l)
00186
00187
00188 static int __wavelet2D_split (it_wavelet2D_t * wavelet)
00189 {
00190 int i, x, y, w, h, p;
00191 int width;
00192 int height;
00193 int level;
00194 int levels;
00195 double *buffer;
00196 double *pixels;
00197 double *low, *high, *low_high, *low_low, *high_low, *high_high;
00198 int page;
00199 int count;
00200 double const *step;
00201 double scale;
00202
00203 assert (wavelet);
00204
00205 if (wavelet->level == wavelet->levels)
00206 return (-IT_EINVAL);
00207
00208 width = wavelet->width;
00209 height = wavelet->height;
00210 level = wavelet->level;
00211 levels = wavelet->levels;
00212 buffer = wavelet->buffer;
00213 count = wavelet->lifting->count / 2;
00214 step = wavelet->lifting->step;
00215 scale = wavelet->lifting->scale;
00216
00217 w = shift_up (width, level);
00218 h = shift_up (height, level);
00219 page = (round_up (width, levels) * round_up (height, levels)) >> level;
00220
00221
00222
00223
00224 if (w & 1) {
00225 hlifting (high[0], pixels[1], step[0],
00226 pixels[0] + pixels[2],
00227 pixels[0] + pixels[2], pixels[0] + pixels[2], w / 2, h, 1);
00228 }
00229 else {
00230 hlifting (high[0], pixels[1], step[0],
00231 pixels[0] + pixels[2],
00232 pixels[0] + pixels[2], pixels[0] + pixels[0], w / 2, h, 0);
00233 }
00234
00235
00236 if (w & 1) {
00237 hlifting (low[0], pixels[0], step[1],
00238 high[0] + high[0],
00239 high[-1] + high[0], high[-1] + high[-1], w / 2 + 1, h, -1);
00240 }
00241 else {
00242 hlifting (low[0], pixels[0], step[1],
00243 high[0] + high[0],
00244 high[-1] + high[0], high[-1] + high[0], w / 2, h, 0);
00245 }
00246
00247 reset_pointers ();
00248
00249 for (i = 1; i < count; i++) {
00250
00251 if (w & 1) {
00252 hlifting (high[0], high[0], step[2 * i],
00253 low[0] + low[1],
00254 low[0] + low[1], low[0] + low[1], w / 2, h, 1);
00255 }
00256 else {
00257 hlifting (high[0], high[0], step[2 * i],
00258 low[0] + low[1],
00259 low[0] + low[1], low[0] + low[0], w / 2, h, 0);
00260 }
00261
00262
00263 if (w & 1) {
00264 hlifting (low[0], low[0], step[2 * i + 1],
00265 high[0] + high[0],
00266 high[-1] + high[0], high[-1] + high[-1], w / 2 + 1, h, -1);
00267 }
00268 else {
00269 hlifting (low[0], low[0], step[2 * i + 1],
00270 high[0] + high[0],
00271 high[-1] + high[0], high[-1] + high[0], w / 2, h, 0);
00272 }
00273 }
00274
00275 scale (low, scale, ((w + 1) / 2) * h);
00276 scale (high, 1.0 / scale, (w / 2) * h);
00277
00278
00279 p = w / 2;
00280
00281 if (h & 1) {
00282 vlifting (high_high[0], high[p], step[0],
00283 high[0] + high[2 * p],
00284 high[0] + high[2 * p],
00285 high[0] + high[2 * p], high, w / 2, h / 2);
00286 }
00287 else {
00288 vlifting (high_high[0], high[p], step[0],
00289 high[0] + high[2 * p],
00290 high[0] + high[2 * p], high[0] + high[0], high, w / 2, h / 2);
00291 }
00292
00293
00294 if (h & 1) {
00295 vlifting (high_low[0], high[0], step[1],
00296 high_high[0] + high_high[0],
00297 high_high[-p] + high_high[0],
00298 high_high[-p] + high_high[-p], high, w / 2, h / 2 + 1);
00299 }
00300 else {
00301 vlifting (high_low[0], high[0], step[1],
00302 high_high[0] + high_high[0],
00303 high_high[-p] + high_high[0],
00304 high_high[-p] + high_high[0], high, w / 2, h / 2);
00305 }
00306
00307 for (i = 1; i < count; i++) {
00308
00309 if (h & 1) {
00310 vlifting (high_high[0], high_high[0], step[2 * i],
00311 high_low[0] + high_low[p],
00312 high_low[0] + high_low[p],
00313 high_low[0] + high_low[p], high, w / 2, h / 2);
00314 }
00315 else {
00316 vlifting (high_high[0], high_high[0], step[2 * i],
00317 high_low[0] + high_low[p],
00318 high_low[0] + high_low[p],
00319 high_low[0] + high_low[0], high, w / 2, h / 2);
00320 }
00321
00322
00323 if (h & 1) {
00324 vlifting (high_low[0], high_low[0], step[2 * i + 1],
00325 high_high[0] + high_high[0],
00326 high_high[-p] + high_high[0],
00327 high_high[-p] + high_high[-p], high, w / 2, h / 2 + 1);
00328 }
00329 else {
00330 vlifting (high_low[0], high_low[0], step[2 * i + 1],
00331 high_high[0] + high_high[0],
00332 high_high[-p] + high_high[0],
00333 high_high[-p] + high_high[0], high, w / 2, h / 2);
00334 }
00335 }
00336 scale (high_low, scale, p * (h + 1) / 2);
00337 scale (high_high, 1.0 / scale, p * (h + 1) / 2);
00338
00339
00340 p = (w + 1) / 2;
00341
00342 if (h & 1) {
00343 vlifting (low_high[0], low[p], step[0],
00344 low[0] + low[2 * p],
00345 low[0] + low[2 * p],
00346 low[0] + low[2 * p], low, (w + 1) / 2, h / 2);
00347 }
00348 else {
00349 vlifting (low_high[0], low[p], step[0],
00350 low[0] + low[2 * p],
00351 low[0] + low[2 * p], low[0] + low[0], low, (w + 1) / 2, h / 2);
00352 }
00353
00354
00355 if (h & 1) {
00356 vlifting (low_low[0], low[0], step[1],
00357 low_high[0] + low_high[0],
00358 low_high[-p] + low_high[0],
00359 low_high[-p] + low_high[-p], low, (w + 1) / 2, h / 2 + 1);
00360 }
00361 else {
00362 vlifting (low_low[0], low[0], step[1],
00363 low_high[0] + low_high[0],
00364 low_high[-p] + low_high[0],
00365 low_high[-p] + low_high[0], low, (w + 1) / 2, h / 2);
00366 }
00367
00368 for (i = 1; i < count; i++) {
00369
00370 if (h & 1) {
00371 vlifting (low_high[0], low_high[0], step[2 * i],
00372 low_low[0] + low_low[p],
00373 low_low[0] + low_low[p],
00374 low_low[0] + low_low[p], low, (w + 1) / 2, h / 2);
00375 }
00376 else {
00377 vlifting (low_high[0], low_high[0], step[2 * i],
00378 low_low[0] + low_low[p],
00379 low_low[0] + low_low[p],
00380 low_low[0] + low_low[0], low, (w + 1) / 2, h / 2);
00381 }
00382
00383
00384 if (h & 1) {
00385 vlifting (low_low[0], low_low[0], step[2 * i + 1],
00386 low_high[0] + low_high[0],
00387 low_high[-p] + low_high[0],
00388 low_high[-p] + low_high[-p], low, (w + 1) / 2, h / 2 + 1);
00389 }
00390 else {
00391 vlifting (low_low[0], low_low[0], step[2 * i + 1],
00392 low_high[0] + low_high[0],
00393 low_high[-p] + low_high[0],
00394 low_high[-p] + low_high[0], low, (w + 1) / 2, h / 2);
00395 }
00396 }
00397
00398 scale (low_low, scale, p * (h + 1) / 2);
00399 scale (low_high, 1.0 / scale, p * (h + 1) / 2);
00400
00401 wavelet->level++;
00402
00403 return (0);
00404 }
00405
00406
00407
00408 static int __wavelet2D_merge (it_wavelet2D_t * wavelet)
00409 {
00410 int i, x, y, w, h, p;
00411 int width;
00412 int height;
00413 int level;
00414 int levels;
00415 double *pixels;
00416 double *buffer;
00417 double *low, *high, *low_high, *low_low, *high_low, *high_high;
00418 int page;
00419 int count;
00420 double const *step;
00421 double scale;
00422
00423 assert (wavelet);
00424
00425 if (wavelet->level == 0)
00426 return (-IT_EINVAL);
00427
00428 wavelet->level--;
00429
00430 width = wavelet->width;
00431 height = wavelet->height;
00432 level = wavelet->level;
00433 levels = wavelet->levels;
00434 buffer = wavelet->buffer;
00435 count = wavelet->lifting->count / 2;
00436 step = wavelet->lifting->step;
00437 scale = wavelet->lifting->scale;
00438
00439 w = shift_up (width, level);
00440 h = shift_up (height, level);
00441 page = (round_up (width, levels) * round_up (height, levels)) >> level;
00442
00443
00444 p = (w + 1) / 2;
00445
00446 scale (low_low, 1.0 / scale, p * (h + 1) / 2);
00447 scale (low_high, scale, p * (h + 1) / 2);
00448
00449 for (i = 1; i < count; i++) {
00450
00451 if (h & 1) {
00452 vlifting (low_low[0], low_low[0], -step[2 * i + 1],
00453 low_high[0] + low_high[0],
00454 low_high[-p] + low_high[0],
00455 low_high[-p] + low_high[-p], low, (w + 1) / 2, h / 2 + 1);
00456 }
00457 else {
00458 vlifting (low_low[0], low_low[0], -step[2 * i + 1],
00459 low_high[0] + low_high[0],
00460 low_high[-p] + low_high[0],
00461 low_high[-p] + low_high[0], low, (w + 1) / 2, h / 2);
00462 }
00463
00464
00465 if (h & 1) {
00466 vlifting (low_high[0], low_high[0], -step[2 * i],
00467 low_low[0] + low_low[p],
00468 low_low[0] + low_low[p],
00469 low_low[0] + low_low[p], low, (w + 1) / 2, h / 2);
00470 }
00471 else {
00472 vlifting (low_high[0], low_high[0], -step[2 * i],
00473 low_low[0] + low_low[p],
00474 low_low[0] + low_low[p],
00475 low_low[0] + low_low[0], low, (w + 1) / 2, h / 2);
00476 }
00477 }
00478
00479
00480 if (h & 1) {
00481 vlifting (low[0], low_low[0], -step[1],
00482 low_high[0] + low_high[0],
00483 low_high[-p] + low_high[0],
00484 low_high[-p] + low_high[-p], low, (w + 1) / 2, h / 2 + 1);
00485 }
00486 else {
00487 vlifting (low[0], low_low[0], -step[1],
00488 low_high[0] + low_high[0],
00489 low_high[-p] + low_high[0],
00490 low_high[-p] + low_high[0], low, (w + 1) / 2, h / 2);
00491 }
00492
00493
00494 if (h & 1) {
00495 vlifting (low[p], low_high[0], -step[0],
00496 low[0] + low[2 * p],
00497 low[0] + low[2 * p],
00498 low[0] + low[2 * p], low, (w + 1) / 2, h / 2);
00499 }
00500 else {
00501 vlifting (low[p], low_high[0], -step[0],
00502 low[0] + low[2 * p],
00503 low[0] + low[2 * p], low[0] + low[0], low, (w + 1) / 2, h / 2);
00504 }
00505
00506
00507 p = w / 2;
00508
00509 scale (high_low, 1.0 / scale, p * (h + 1) / 2);
00510 scale (high_high, scale, p * (h + 1) / 2);
00511
00512 for (i = 1; i < count; i++) {
00513
00514 if (h & 1) {
00515 vlifting (high_low[0], high_low[0], -step[2 * i + 1],
00516 high_high[0] + high_high[0],
00517 high_high[-p] + high_high[0],
00518 high_high[-p] + high_high[-p], high, w / 2, h / 2 + 1);
00519 }
00520 else {
00521 vlifting (high_low[0], high_low[0], -step[2 * i + 1],
00522 high_high[0] + high_high[0],
00523 high_high[-p] + high_high[0],
00524 high_high[-p] + high_high[0], high, w / 2, h / 2);
00525 }
00526
00527
00528 if (h & 1) {
00529 vlifting (high_high[0], high_high[0], -step[2 * i],
00530 high_low[0] + high_low[p],
00531 high_low[0] + high_low[p],
00532 high_low[0] + high_low[p], high, w / 2, h / 2);
00533 }
00534 else {
00535 vlifting (high_high[0], high_high[0], -step[2 * i],
00536 high_low[0] + high_low[p],
00537 high_low[0] + high_low[p],
00538 high_low[0] + high_low[0], high, w / 2, h / 2);
00539 }
00540 }
00541
00542
00543 if (h & 1) {
00544 vlifting (high[0], high_low[0], -step[1],
00545 high_high[0] + high_high[0],
00546 high_high[-p] + high_high[0],
00547 high_high[-p] + high_high[-p], high, w / 2, h / 2 + 1);
00548 }
00549 else {
00550 vlifting (high[0], high_low[0], -step[1],
00551 high_high[0] + high_high[0],
00552 high_high[-p] + high_high[0],
00553 high_high[-p] + high_high[0], high, w / 2, h / 2);
00554 }
00555
00556
00557 if (h & 1) {
00558 vlifting (high[p], high_high[0], -step[0],
00559 high[0] + high[2 * p],
00560 high[0] + high[2 * p],
00561 high[0] + high[2 * p], high, w / 2, h / 2);
00562 }
00563 else {
00564 vlifting (high[p], high_high[0], -step[0],
00565 high[0] + high[2 * p],
00566 high[0] + high[2 * p], high[0] + high[0], high, w / 2, h / 2);
00567 }
00568
00569
00570 scale (low, 1.0 / scale, ((w + 1) / 2) * h);
00571 scale (high, scale, (w / 2) * h);
00572
00573 for (i = 1; i < count; i++) {
00574
00575 if (w & 1) {
00576 hlifting (low[0], low[0], -step[2 * i + 1],
00577 high[0] + high[0],
00578 high[-1] + high[0], high[-1] + high[-1], w / 2 + 1, h, -1);
00579 }
00580 else {
00581 hlifting (low[0], low[0], -step[2 * i + 1],
00582 high[0] + high[0],
00583 high[-1] + high[0], high[-1] + high[0], w / 2, h, 0);
00584 }
00585
00586
00587 if (w & 1) {
00588 hlifting (high[0], high[0], -step[2 * i],
00589 low[0] + low[1],
00590 low[0] + low[1], low[0] + low[1], w / 2, h, 1);
00591 }
00592 else {
00593 hlifting (high[0], high[0], -step[2 * i],
00594 low[0] + low[1],
00595 low[0] + low[1], low[0] + low[0], w / 2, h, 0);
00596 }
00597 }
00598
00599
00600 if (w & 1) {
00601 hlifting (pixels[0], low[0], -step[1],
00602 high[0] + high[0],
00603 high[-1] + high[0], high[-1] + high[-1], w / 2 + 1, h, -1);
00604 }
00605 else {
00606 hlifting (pixels[0], low[0], -step[1],
00607 high[0] + high[0],
00608 high[-1] + high[0], high[-1] + high[0], w / 2, h, 0);
00609 }
00610
00611
00612 if (w & 1) {
00613 hlifting (pixels[1], high[0], -step[0],
00614 pixels[0] + pixels[2],
00615 pixels[0] + pixels[2], pixels[0] + pixels[2], w / 2, h, 1);
00616 }
00617 else {
00618 hlifting (pixels[1], high[0], -step[0],
00619 pixels[0] + pixels[2],
00620 pixels[0] + pixels[2], pixels[0] + pixels[0], w / 2, h, 0);
00621 }
00622
00623 return (0);
00624 }
00625
00626
00627
00628 static int __wavelet_flatten (it_wavelet2D_t * it_this, mat image)
00629 {
00630 int x, y, wf, hf, wc, hc, ps;
00631 int width, height, level, page;
00632 int levels;
00633 double *band;
00634 double *buffer = it_this->buffer;
00635
00636 width = it_this->width;
00637 height = it_this->height;
00638 levels = it_this->levels;
00639 page = round_up (width, levels) * round_up (height, levels);
00640 buffer = it_this->buffer + page;
00641 ps = width;
00642
00643 if (width != mat_width (image))
00644 return (-IT_EINVAL);
00645 if (height != mat_height (image))
00646 return (-IT_EINVAL);
00647
00648 hc = height;
00649 wc = width;
00650
00651 for (level = 0; level < levels; level++) {
00652 page = (round_up (width, levels) * round_up (height, levels)) >> level;
00653 buffer = (it_this->buffer) + (page >> 1);
00654
00655 ps = (ps + 1) / 2;
00656 hf = hc / 2;
00657 hc = (hc + 1) / 2;
00658 wf = wc / 2;
00659 wc = (wc + 1) / 2;
00660
00661 band = buffer + 2 * (page >> 2);
00662 for (y = 0; y < hc; y++)
00663 for (x = 0; x < wf; x++)
00664 image[y][x + wc] = band[y * wf + x];
00665
00666 band = buffer + 1 * (page >> 2);
00667 for (y = 0; y < hf; y++)
00668 for (x = 0; x < wc; x++)
00669 image[y + hc][x] = band[y * wc + x];
00670
00671 band = buffer + 3 * (page >> 2);
00672 for (y = 0; y < hf; y++)
00673 for (x = 0; x < wf; x++)
00674 image[y + hc][x + wc] = band[y * wf + x];
00675 }
00676
00677 band = buffer;
00678 for (y = 0; y < hc; y++)
00679 for (x = 0; x < wc; x++)
00680 image[y][x] = band[y * wc + x];
00681
00682 return (0);
00683 }
00684
00685
00686
00687 static int __wavelet_unflatten (it_wavelet2D_t * it_this, mat image)
00688 {
00689 int x, y, wf, hf, wc, hc, ps;
00690 int width, height, level, page;
00691 int levels;
00692 double *band;
00693 double *buffer = it_this->buffer;
00694
00695 width = it_this->width;
00696 height = it_this->height;
00697 levels = it_this->levels;
00698 page = round_up (width, levels) * round_up (height, levels);
00699 buffer = it_this->buffer + page;
00700 ps = width;
00701
00702 if (width != mat_width (image))
00703 return (-IT_EINVAL);
00704 if (height != mat_height (image))
00705 return (-IT_EINVAL);
00706
00707
00708 it_this->level = levels;
00709 hc = height;
00710 wc = width;
00711
00712 for (level = 0; level < levels; level++) {
00713 page = (round_up (width, levels) * round_up (height, levels)) >> level;
00714 buffer = (it_this->buffer) + (page >> 1);
00715
00716 ps = (ps + 1) / 2;
00717 hf = hc / 2;
00718 hc = (hc + 1) / 2;
00719 wf = wc / 2;
00720 wc = (wc + 1) / 2;
00721
00722 band = buffer + 2 * (page >> 2);
00723 for (y = 0; y < hc; y++)
00724 for (x = 0; x < wf; x++)
00725 band[y * wf + x] = image[y][x + wc];
00726
00727 band = buffer + 1 * (page >> 2);
00728 for (y = 0; y < hf; y++)
00729 for (x = 0; x < wc; x++)
00730 band[y * wc + x] = image[y + hc][x];
00731
00732 band = buffer + 3 * (page >> 2);
00733 for (y = 0; y < hf; y++)
00734 for (x = 0; x < wf; x++)
00735 band[y * wf + x] = image[y + hc][x + wc];
00736 }
00737
00738 band = buffer;
00739 for (y = 0; y < hc; y++)
00740 for (x = 0; x < wc; x++)
00741 band[y * wc + x] = image[y][x];
00742
00743 return (0);
00744 }
00745
00746
00747 static Mat __it_wavelet2D_transform (it_transform2D_t * transform,
00748 Mat __image)
00749 {
00750 it_wavelet2D_t *wavelet = IT_WAVELET2D (transform);
00751 int x, y;
00752 int width, height;
00753 int page;
00754 int levels;
00755 double *buffer;
00756 mat flat;
00757 mat image = (mat) __image;
00758 int free_on_exit = 0;
00759
00760 assert (image);
00761
00762
00763 assert (Vec_header (image[0]).element_size == sizeof (double));
00764
00765 width = mat_width (image);
00766 height = mat_height (image);
00767
00768 if (!wavelet->width || !wavelet->height) {
00769 it_transform2D_set_size (wavelet, width, height);
00770 free_on_exit = 1;
00771 }
00772
00773 flat = mat_new (height, width);
00774 levels = wavelet->levels;
00775 page = round_up (width, levels) * round_up (height, levels);
00776 buffer = wavelet->buffer + page;
00777
00778 for (y = 0; y < height; y++)
00779 for (x = 0; x < width; x++)
00780 buffer[y * width + x] = image[y][x];
00781
00782 while (wavelet->level < levels)
00783 __wavelet2D_split (wavelet);
00784
00785 __wavelet_flatten (IT_WAVELET2D (transform), flat);
00786
00787 if (free_on_exit)
00788 it_transform2D_clear_size (wavelet);
00789
00790 return ((Mat) flat);
00791 }
00792
00793
00794 static Mat __it_wavelet2D_itransform (it_transform2D_t * transform,
00795 Mat __flat)
00796 {
00797 it_wavelet2D_t *wavelet = IT_WAVELET2D (transform);
00798 int width, height;
00799 int x, y;
00800 int page;
00801 int levels;
00802 double *buffer;
00803 mat image;
00804 mat flat = (mat) __flat;
00805 int free_on_exit = 0;
00806
00807 assert (flat);
00808
00809
00810 assert (Vec_header (flat[0]).element_size == sizeof (double));
00811
00812 width = mat_width (flat);
00813 height = mat_height (flat);
00814
00815 if (!wavelet->width || !wavelet->height) {
00816 it_transform2D_set_size (wavelet, width, height);
00817 free_on_exit = 1;
00818 }
00819
00820 image = mat_new (height, width);
00821 levels = wavelet->levels;
00822 page = round_up (width, levels) * round_up (height, levels);
00823 buffer = wavelet->buffer + page;
00824
00825 __wavelet_unflatten (IT_WAVELET2D (transform), flat);
00826
00827 while (wavelet->level)
00828 __wavelet2D_merge (wavelet);
00829
00830 for (y = 0; y < height; y++)
00831 for (x = 0; x < width; x++)
00832 image[y][x] = buffer[y * width + x];
00833
00834 if (free_on_exit)
00835 it_transform2D_clear_size (wavelet);
00836
00837 return ((Mat) image);
00838 }
00839
00840 static int __it_wavelet2D_copy (it_wavelet2D_t * it_this,
00841 it_wavelet2D_t * source)
00842 {
00843 assert (it_this->levels == source->levels);
00844
00845 if (source->width && source->height) {
00846 it_transform2D_set_size (it_this, source->width, source->height);
00847 vec_copy (it_this->buffer, source->buffer);
00848 }
00849
00850 return (0);
00851 }
00852
00853 static void __wavelet2D_get_output_size (it_transform2D_t * transform,
00854 idx_t * width, idx_t * height)
00855 {
00856
00857 }
00858
00859 static void __wavelet2D_set_size (it_transform2D_t * transform,
00860 idx_t width, idx_t height)
00861 {
00862 it_wavelet2D_t *wavelet = IT_WAVELET2D (transform);
00863 int levels = wavelet->levels;
00864
00865 if (wavelet->width && wavelet->height)
00866 vec_delete (wavelet->buffer);
00867
00868 if (width && height)
00869 wavelet->buffer =
00870 vec_new (2 * round_up (width, levels) * round_up (height, levels));
00871
00872 wavelet->width = width;
00873 wavelet->height = height;
00874 }
00875
00876 static void __wavelet2D_get_size (it_transform2D_t * transform,
00877 idx_t * width, idx_t * height)
00878 {
00879 it_wavelet2D_t *wavelet = IT_WAVELET2D (transform);
00880
00881 *width = wavelet->width;
00882 *height = wavelet->height;
00883 }
00884
00885 static void __wavelet2D_destructor (it_object_t * it_this)
00886 {
00887 it_wavelet2D_t *wavelet = IT_WAVELET2D (it_this);
00888
00889 if (wavelet->width && wavelet->height)
00890 vec_delete (wavelet->buffer);
00891
00892
00893 wavelet->it_overloaded (destructor) (it_this);
00894 }
00895
00896 it_instanciate (it_wavelet2D_t)
00897 {
00898 it_new_args_start ();
00899 it_construct (it_transform2D_t);
00900 it_set_magic (it_this, it_wavelet2D_t);
00901
00902
00903 it_overload (it_this, it_object_t, destructor, __wavelet2D_destructor);
00904
00905 IT_TRANSFORM2D (it_this)->transform = __it_wavelet2D_transform;
00906 IT_TRANSFORM2D (it_this)->itransform = __it_wavelet2D_itransform;
00907 IT_TRANSFORM2D (it_this)->get_output_size = __wavelet2D_get_output_size;
00908 IT_TRANSFORM2D (it_this)->set_size = __wavelet2D_set_size;
00909 IT_TRANSFORM2D (it_this)->get_size = __wavelet2D_get_size;
00910
00911 it_this->copy = __it_wavelet2D_copy;
00912
00913 it_this->level = 0;
00914 it_this->lifting = it_new_args_next (it_wavelet_lifting_t *);
00915 it_this->levels = it_new_args_next (int);
00916 it_this->width = 0;
00917 it_this->height = 0;
00918
00919 it_new_args_stop ();
00920
00921 return (it_this);
00922 }
00923
00924
00925 mat *it_wavelet2D_split (mat wav, int nb_levels)
00926 {
00927 int mid_row, mid_col, nb_row, nb_col, l;
00928 mat *subbands;
00929
00930 assert (wav);
00931
00932 nb_row = mat_height (wav);
00933 nb_col = mat_width (wav);
00934 mid_row = (nb_row + 1) / 2;
00935 mid_col = (nb_col + 1) / 2;
00936
00937 subbands = (mat *) malloc (sizeof (mat) * (3 * nb_levels + 1));
00938
00939 for (l = nb_levels; l > 0; l--) {
00940 subbands[l * 3 - 2] =
00941 mat_get_submatrix (wav, 0, mid_col, mid_row - 1, nb_col - 1);
00942 subbands[l * 3 - 1] =
00943 mat_get_submatrix (wav, mid_row, 0, nb_row - 1, mid_col - 1);
00944 subbands[l * 3] =
00945 mat_get_submatrix (wav, mid_row, mid_col, nb_row - 1, nb_col - 1);
00946
00947 nb_row = mid_row;
00948 nb_col = mid_col;
00949 mid_row = (nb_row + 1) / 2;
00950 mid_col = (nb_col + 1) / 2;
00951 }
00952
00953 subbands[0] = mat_get_submatrix (wav, 0, 0, nb_row -1 , nb_col -1);
00954 return subbands;
00955 }
00956
00957 mat it_wavelet2D_merge (mat * subbands, int nb_levels)
00958 {
00959 int mid_row, mid_col, nb_row, nb_col, l;
00960 mat wav;
00961
00962 assert (subbands);
00963
00964 wav = mat_new (mat_height (subbands[nb_levels * 3])
00965 + mat_height (subbands[nb_levels * 3 - 2]),
00966 mat_width (subbands[nb_levels * 3])
00967 + mat_width (subbands[nb_levels * 3 - 1]));
00968
00969 nb_row = mat_height (wav);
00970 nb_col = mat_width (wav);
00971 mid_row = (nb_row + 1) / 2;
00972 mid_col = (nb_col + 1) / 2;
00973
00974 for (l = nb_levels; l > 0; l--) {
00975 mat_set_submatrix (wav, subbands[l * 3 - 2], 0, mid_col);
00976 mat_set_submatrix (wav, subbands[l * 3 - 1], mid_row, 0);
00977 mat_set_submatrix (wav, subbands[l * 3], mid_row, mid_col);
00978
00979 nb_row = mid_row;
00980 nb_col = mid_col;
00981 mid_row = (nb_row + 1) / 2;
00982 mid_col = (nb_col + 1) / 2;
00983 }
00984
00985 mat_set_submatrix (wav, subbands[0], 0, 0);
00986 return wav;
00987 }
00988
00989 mat it_dwt2D (mat m, it_wavelet_lifting_t const *lifting, int levels)
00990 {
00991 it_wavelet2D_t *wavelet;
00992 mat t;
00993
00994 wavelet = it_wavelet2D_new (lifting, levels);
00995
00996 t = (mat) it_transform2D (wavelet, m);
00997
00998 it_delete (wavelet);
00999
01000 return (t);
01001 }
01002
01003 mat it_idwt2D (mat t, it_wavelet_lifting_t const *lifting, int levels)
01004 {
01005 it_wavelet2D_t *wavelet;
01006 mat m;
01007
01008 wavelet = it_wavelet2D_new (lifting, levels);
01009
01010 m = (mat) it_itransform2D (wavelet, t);
01011
01012 it_delete (wavelet);
01013
01014 return (m);
01015 }