src/wavelet.c

Go to the documentation of this file.
00001 /*
00002    libit - Library for basic source and channel coding functions
00003    Copyright (C) 2005-2005 Vivien Chappelier, Herve Jegou
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 /*
00021   1D wavelet transform using lifting.
00022   Copyright (C) 2005 Vivien Chappelier, Herve Jegou
00023 */
00024 
00025 #include <it/types.h>
00026 #include <it/wavelet.h>
00027 #include <it/io.h>
00028 
00029 /* This computes the wavelet decomposition using the lifting implementation.
00030 */
00031 
00032 /* some predefined filters */
00033 static const double __it_wavelet_lifting_97_steps[] =
00034   { -1.586134342, -0.052980118, 0.882911075, 0.443506852 };
00035 static const it_wavelet_lifting_t __it_wavelet_lifting_97 = {
00036   4,
00037   1.149604398,
00038   __it_wavelet_lifting_97_steps
00039 };
00040 it_wavelet_lifting_t const *it_wavelet_lifting_97 = &__it_wavelet_lifting_97;
00041 
00042 static const double __it_wavelet_lifting_53_steps[] = { -0.5, 0.25 };
00043 static const it_wavelet_lifting_t __it_wavelet_lifting_53 = {
00044   2,
00045   1.41421,
00046   __it_wavelet_lifting_53_steps
00047 };
00048 it_wavelet_lifting_t const *it_wavelet_lifting_53 = &__it_wavelet_lifting_53;
00049 
00050 /*
00051   X[0] = X[0] + alpha * (X[-1] + X[1]); odd
00052   X[0] = X[0] + beta  * (X[-1] + X[1]);  even
00053   X[0] = X[0] + gamma * (X[-1] + X[1]); odd
00054   X[0] = X[0] + delta * (X[-1] + X[1]);  even
00055   X[0] = -scale * X[0];                 odd
00056   X[0] = X[0] / scale;                   even
00057 */
00058 
00059 #define shift_up(x, l) (((x) + ~(-1 << (l))) >> (l))
00060 
00061 /* compute the next level decomposition using the lifting method. */
00062 static int __wavelet_split (it_wavelet_t * wavelet)
00063 {
00064   int  i, j, l, h;
00065   int  length;
00066   int  level;
00067   int  levels;
00068   int  count;
00069   double s;
00070   double const *step;
00071   double scale;
00072   vec  v;
00073   vec  r;
00074 
00075   assert (wavelet);
00076 
00077   if (wavelet->level == wavelet->levels)
00078     return (-IT_EINVAL);
00079 
00080   v = wavelet->current;
00081   r = wavelet->next;
00082   length = wavelet->length;
00083   level = wavelet->level;
00084   levels = wavelet->levels;
00085   count = wavelet->lifting->count / 2;
00086   step = wavelet->lifting->step;
00087   scale = wavelet->lifting->scale;
00088 
00089   l = shift_up (length, level);
00090   h = shift_up (length, level + 1);
00091 
00092   /* lifting */
00093   for (j = 0; j < count; j++) {
00094     /* stage 1 : odd samples lifting */
00095     s = step[2 * j];
00096     if (l & 1) {
00097       for (i = 1; i < l - 1; i += 2)
00098   v[i] += s * (v[i - 1] + v[i + 1]);
00099     }
00100     else {
00101       for (i = 1; i < l - 1; i += 2)
00102   v[i] += s * (v[i - 1] + v[i + 1]);
00103       v[i] += s * 2 * v[i - 1];
00104     }
00105 
00106     /* stage 2 : even samples lifting */
00107     s = step[2 * j + 1];
00108     if (l & 1) {
00109       v[0] += s * 2 * v[1];
00110       for (i = 2; i < l - 1; i += 2)
00111   v[i] += s * (v[i - 1] + v[i + 1]);
00112       if (l > 2)
00113   v[i] += s * 2 * v[i - 1];
00114     }
00115     else {
00116       v[0] += s * 2 * v[1];
00117       for (i = 2; i < l - 1; i += 2)
00118   v[i] += s * (v[i - 1] + v[i + 1]);
00119     }
00120   }
00121 
00122   /* scale and demultiplex */
00123   for (i = 0; i < l - 1; i += 2) {
00124     r[(i >> 1)] = v[i] * scale;
00125     r[h + (i >> 1)] = v[i + 1] / scale;
00126   }
00127   if (l & 1)
00128     r[(i >> 1)] = v[i] * scale;
00129 
00130   /* swap the vectors */
00131   wavelet->current = r;
00132   wavelet->next = v;
00133 
00134   wavelet->level++;
00135 
00136   return (0);
00137 }
00138 
00139 /* reconstruct the previous level of decomposition
00140    by inverting the lifting steps. */
00141 static int __wavelet_merge (it_wavelet_t * wavelet)
00142 {
00143   int  i, j, l, h;
00144   int  length;
00145   int  level;
00146   int  levels;
00147   int  count;
00148   double const *step;
00149   double scale;
00150   double s;
00151   vec  v;
00152   vec  r;
00153 
00154   assert (wavelet);
00155 
00156   if (wavelet->level == 0)
00157     return (-IT_EINVAL);
00158 
00159   wavelet->level--;
00160 
00161   r = wavelet->current;
00162   v = wavelet->next;
00163   length = wavelet->length;
00164   level = wavelet->level;
00165   levels = wavelet->levels;
00166   count = wavelet->lifting->count / 2;
00167   step = wavelet->lifting->step;
00168   scale = wavelet->lifting->scale;
00169 
00170   l = shift_up (length, level);
00171   h = shift_up (length, level + 1);
00172 
00173   /* scale and multiplex */
00174   for (i = 0; i < l - 1; i += 2) {
00175     v[i] = r[(i >> 1)] / scale;
00176     v[i + 1] = r[h + (i >> 1)] * scale;
00177   }
00178   if (l & 1)
00179     v[i] = r[(i >> 1)] / scale;
00180 
00181   /* invert lifting */
00182   for (j = count - 1; j >= 0; j--) {
00183 
00184     /* stage 1 : even samples lifting */
00185     s = step[2 * j + 1];
00186     if (l & 1) {
00187       v[0] -= s * 2 * v[1];
00188       for (i = 2; i < l - 1; i += 2)
00189   v[i] -= s * (v[i - 1] + v[i + 1]);
00190       if (l > 2)
00191   v[i] -= s * 2 * v[i - 1];
00192     }
00193     else {
00194       v[0] -= s * 2 * v[1];
00195       for (i = 2; i < l - 1; i += 2)
00196   v[i] -= s * (v[i - 1] + v[i + 1]);
00197     }
00198 
00199     /* stage 2 : odd samples lifting */
00200     s = step[2 * j];
00201     if (l & 1) {
00202       for (i = 1; i < l - 1; i += 2)
00203   v[i] -= s * (v[i - 1] + v[i + 1]);
00204     }
00205     else {
00206       for (i = 1; i < l - 1; i += 2)
00207   v[i] -= s * (v[i - 1] + v[i + 1]);
00208       v[i] -= s * 2 * v[i - 1];
00209     }
00210   }
00211 
00212   /* swap the vectors */
00213   wavelet->current = v;
00214   wavelet->next = r;
00215 
00216   return (0);
00217 }
00218 
00219 static void __wavelet_pack (vec flat, vec current, vec next, int levels)
00220 {
00221   int  length;
00222   int  l;
00223   int  i;
00224   vec  v;
00225 
00226   /* merge the double buffer into a flat vector                       */
00227   /* with the lowest band stored in the 'current' buffer              */
00228   /* For example:                                                     */
00229   /* current: [ LLL | LLH |     ?     |           HHH           ]     */
00230   /* next   : [  ?  |  ?  |    LHH    |            ?            ]     */
00231   /* becomes                                                          */
00232   /* flat:    [ LLL | LLH |    LHH    |           HHH           ]     */
00233 
00234   length = vec_length (flat);
00235 
00236   /* low pass band */
00237   v = current;
00238   for (i = 0; i < shift_up (length, levels); i++)
00239     flat[i] = v[i];
00240 
00241   /* high pass bands */
00242   for (l = levels; l > 0; l--) {
00243     v = ((levels - l) & 1) ? next : current;
00244     for (; i < shift_up (length, l - 1); i++)
00245       flat[i] = v[i];
00246   }
00247 }
00248 
00249 static void __wavelet_unpack (vec flat, vec current, vec next, int levels)
00250 {
00251   int  length;
00252   int  l;
00253   int  i;
00254   vec  v;
00255 
00256   /* split the flat vector into the double buffer,                    */
00257   /* with the lowest band stored in the 'current' buffer              */
00258   /* For example:                                                     */
00259   /* flat:    [ LLL | LLH |    LHH    |           HHH           ]     */
00260   /* becomes                                                          */
00261   /* current: [ LLL | LLH |     ?     |           HHH           ]     */
00262   /* next   : [  ?  |  ?  |    LHH    |            ?            ]     */
00263   /* why bother and not copy flat into both buffers? .. efficiency :) */
00264 
00265   length = vec_length (flat);
00266 
00267   /* low pass band */
00268   v = current;
00269   for (i = 0; i < shift_up (length, levels); i++)
00270     v[i] = flat[i];
00271 
00272   /* high pass bands */
00273   for (l = levels; l > 0; l--) {
00274     v = ((levels - l) & 1) ? next : current;
00275     for (; i < shift_up (length, l - 1); i++)
00276       v[i] = flat[i];
00277   }
00278 }
00279 
00280 /* compute the wavelet transform of the image */
00281 static Vec __wavelet_transform (it_transform_t * transform, Vec __input)
00282 {
00283   it_wavelet_t *wavelet = IT_WAVELET (transform);
00284   vec  flat;
00285   idx_t length;
00286   vec  input = (vec) __input;
00287   int  free_on_exit = 0;
00288 
00289   assert (input);
00290   /* check the input is actually a vec */
00291   assert (Vec_header (input).element_size == sizeof (double));
00292 
00293   length = vec_length (input);
00294 
00295   if (!wavelet->length) {
00296     it_transform_set_size (wavelet, length);
00297     free_on_exit = 1;
00298   }
00299 
00300   assert (wavelet->length == length);
00301 
00302   wavelet->level = 0;
00303 
00304   flat = vec_new (wavelet->length);
00305 
00306   vec_copy (wavelet->current, input);
00307 
00308   while (wavelet->level < wavelet->levels)
00309     __wavelet_split (wavelet);
00310 
00311   __wavelet_pack (flat, wavelet->current, wavelet->next, wavelet->levels);
00312 
00313   if (free_on_exit)
00314     it_transform_clear_size (wavelet);
00315 
00316   return (flat);
00317 }
00318 
00319 /* compute the inverse wavelet transform of the coefficients */
00320 static Vec __wavelet_itransform (it_transform_t * transform, Vec __flat)
00321 {
00322   it_wavelet_t *wavelet = IT_WAVELET (transform);
00323   vec  output;
00324   idx_t length;
00325   vec  flat = (vec) __flat;
00326   int  free_on_exit = 0;
00327 
00328   assert (flat);
00329 
00330   /* check the input is actually a vec */
00331   assert (Vec_header (flat).element_size == sizeof (double));
00332 
00333   length = vec_length (flat);
00334 
00335   if (!wavelet->length) {
00336     it_transform_set_size (wavelet, length);
00337     free_on_exit = 1;
00338   }
00339 
00340   wavelet->length = length;
00341   wavelet->level = wavelet->levels;
00342 
00343   __wavelet_unpack (flat, wavelet->current, wavelet->next, wavelet->levels);
00344 
00345   while (wavelet->level)
00346     __wavelet_merge (wavelet);
00347 
00348   output = vec_clone (wavelet->current);
00349 
00350   if (free_on_exit)
00351     it_transform_clear_size (wavelet);
00352 
00353   return (output);
00354 }
00355 
00356 static void __wavelet_get_output_size (it_transform_t * transform,
00357                idx_t * input_size)
00358 {
00359   /* this transform is critically sampled */
00360 }
00361 
00362 static void __wavelet_set_size (it_transform_t * transform, idx_t length)
00363 {
00364   it_wavelet_t *wavelet = IT_WAVELET (transform);
00365 
00366   if (wavelet->length) {
00367     vec_delete (wavelet->current);
00368     vec_delete (wavelet->next);
00369   }
00370 
00371   if (length) {
00372     wavelet->current = vec_new (length);
00373     wavelet->next = vec_new (length);
00374   }
00375 
00376   wavelet->length = length;
00377 }
00378 
00379 static void __wavelet_get_size (it_transform_t * transform, idx_t * length)
00380 {
00381   it_wavelet_t *wavelet = IT_WAVELET (transform);
00382   *length = wavelet->length;
00383 }
00384 
00385 static void __wavelet_destructor (it_object_t * it_this)
00386 {
00387   it_wavelet_t *wavelet = IT_WAVELET (it_this);
00388 
00389   if (wavelet->length) {
00390     vec_delete (wavelet->current);
00391     vec_delete (wavelet->next);
00392   }
00393 
00394   /* call the parent destructor */
00395   wavelet->it_overloaded (destructor) (it_this);
00396 }
00397 
00398 it_instanciate (it_wavelet_t)
00399 {
00400   it_new_args_start ();
00401   it_construct (it_transform_t);
00402   it_set_magic (it_this, it_wavelet_t);
00403 
00404   /* overload the virtual destructor */
00405   it_overload (it_this, it_object_t, destructor, __wavelet_destructor);
00406 
00407   IT_TRANSFORM (it_this)->transform = __wavelet_transform;
00408   IT_TRANSFORM (it_this)->itransform = __wavelet_itransform;
00409   IT_TRANSFORM (it_this)->get_output_size = __wavelet_get_output_size;
00410   IT_TRANSFORM (it_this)->set_size = __wavelet_set_size;
00411   IT_TRANSFORM (it_this)->get_size = __wavelet_get_size;
00412 
00413   it_this->level = 0;
00414   it_this->lifting = it_new_args_next (it_wavelet_lifting_t *);
00415   it_this->levels = it_new_args_next (int);
00416   it_this->length = 0;
00417 
00418   it_new_args_stop ();
00419 
00420   return (it_this);
00421 }
00422 
00423 /*--------------------------------------------------------------------*/
00424 vec *it_wavelet_split (vec wav, int nb_levels)
00425 {
00426   int  mid, nb, l;
00427   vec *subbands;
00428 
00429   assert (wav);
00430 
00431   nb = vec_length (wav);
00432   mid = (nb + 1) / 2;
00433 
00434   subbands = (vec *) malloc (sizeof (vec) * (nb_levels + 1));
00435 
00436   for (l = nb_levels; l > 0; l--) {
00437     subbands[l] = vec_get_subvector (wav, mid, nb - 1);
00438     nb = mid;
00439     mid = (nb + 1) / 2;
00440   }
00441 
00442   subbands[0] = vec_get_subvector (wav, 0, nb - 1);
00443   return subbands;
00444 }
00445 
00446 vec it_wavelet_merge (vec * subbands, int nb_levels)
00447 {
00448   int  mid, nb, l;
00449   vec  wav;
00450   assert (subbands);
00451 
00452   nb = 0;
00453   for (l = 0; l <= nb_levels; l++)
00454     nb += vec_length (subbands[l]);
00455 
00456   wav = vec_new (nb);
00457   mid = (nb + 1) / 2;
00458 
00459   for (l = nb_levels; l > 0; l--) {
00460     vec_set_subvector (wav, subbands[l], mid);
00461     nb = mid;
00462     mid = (nb + 1) / 2;
00463   }
00464 
00465   vec_set_subvector (wav, subbands[0], 0);
00466   return wav;
00467 }
00468 
00469 vec it_dwt (vec v, it_wavelet_lifting_t const *lifting, int levels)
00470 {
00471   it_wavelet_t *wavelet;
00472   vec  t;
00473 
00474   wavelet = it_wavelet_new (lifting, levels);
00475 
00476   t = (vec) it_transform (wavelet, v);
00477 
00478   it_delete (wavelet);
00479 
00480   return (t);
00481 }
00482 
00483 vec it_idwt (vec t, it_wavelet_lifting_t const *lifting, int levels)
00484 {
00485   it_wavelet_t *wavelet;
00486   vec  v;
00487 
00488   wavelet = it_wavelet_new (lifting, levels);
00489 
00490   v = (vec) it_itransform (wavelet, t);
00491 
00492   it_delete (wavelet);
00493 
00494   return (v);
00495 }

Hosted by
Copyright (C) 2005-2006 Hervé Jégou
Vivien Chappelier
Francois Cayre
libit logo courtesy of Jonathan Delhumeau