wavelet.c

Go to the documentation of this file.
00001 /*                       W A V E L E T . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2004-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** \addtogroup wavelet */
00023 /*@{*/
00024 
00025 /** @file wavelet.c
00026  * @brief
00027  *  This is a standard wavelet library that takes a given data buffer of some data
00028  *  type and then performs a wavelet transform on that data.  
00029  *
00030  * The transform
00031  *  operations available are to either decompose or reconstruct a signal into it's
00032  *  corresponding wavelet form based on the haar wavelet.
00033  *
00034  *  Wavelet decompose/reconstruct operations
00035  *
00036  *      - bn_wlt_haar_1d_double_decompose(tbuffer, buffer, dimen, channels, limit)
00037  *      - bn_wlt_haar_1d_float_decompose (tbuffer, buffer, dimen, channels, limit)
00038  *      - bn_wlt_haar_1d_char_decompose  (tbuffer, buffer, dimen, channels, limit)
00039  *      - bn_wlt_haar_1d_short_decompose (tbuffer, buffer, dimen, channels, limit)
00040  *      - bn_wlt_haar_1d_int_decompose   (tbuffer, buffer, dimen, channels, limit)
00041  *      - bn_wlt_haar_1d_long_decompose  (tbuffer, buffer, dimen, channels, limit)
00042  *
00043  *      - bn_wlt_haar_1d_double_reconstruct(tbuffer, buffer, dimen, channels, sub_sz, limit)
00044  *      - bn_wlt_haar_1d_float_reconstruct (tbuffer, buffer, dimen, channels, sub_sz, limit)
00045  *      - bn_wlt_haar_1d_char_reconstruct  (tbuffer, buffer, dimen, channels, sub_sz, limit)
00046  *      - bn_wlt_haar_1d_short_reconstruct (tbuffer, buffer, dimen, channels, sub_sz, limit)
00047  *      - bn_wlt_haar_1d_int_reconstruct   (tbuffer, buffer, dimen, channels, sub_sz, limit)
00048  *      - bn_wlt_haar_1d_long_reconstruct  (tbuffer, buffer, dimen, channels, sub_sz, limit)
00049  *
00050  *      - bn_wlt_haar_2d_double_decompose(tbuffer, buffer, dimen, channels, limit)
00051  *      - bn_wlt_haar_2d_float_decompose (tbuffer, buffer, dimen, channels, limit)
00052  *      - bn_wlt_haar_2d_char_decompose  (tbuffer, buffer, dimen, channels, limit)
00053  *      - bn_wlt_haar_2d_short_decompose (tbuffer, buffer, dimen, channels, limit)
00054  *      - bn_wlt_haar_2d_int_decompose   (tbuffer, buffer, dimen, channels, limit)
00055  *      - bn_wlt_haar_2d_long_decompose  (tbuffer, buffer, dimen, channels, limit)
00056  *
00057  *      - bn_wlt_haar_2d_double_reconstruct(tbuffer, buffer, dimen, channels, sub_sz, limit)
00058  *      - bn_wlt_haar_2d_float_reconstruct (tbuffer, buffer, dimen, channels, sub_sz, limit)
00059  *      - bn_wlt_haar_2d_char_reconstruct  (tbuffer, buffer, dimen, channels, sub_sz, limit)
00060  *      - bn_wlt_haar_2d_short_reconstruct (tbuffer, buffer, dimen, channels, sub_sz, limit)
00061  *      - bn_wlt_haar_2d_int_reconstruct   (tbuffer, buffer, dimen, channels, sub_sz, limit)
00062  *      - bn_wlt_haar_2d_long_reconstruct  (tbuffer, buffer, dimen, channels, sub_sz, limit)
00063  *
00064  *      - bn_wlt_haar_2d_double_decompose2(tbuffer, buffer, width, height, channels, limit)
00065  *      - bn_wlt_haar_2d_float_decompose2 (tbuffer, buffer, width, height, channels, limit)
00066  *      - bn_wlt_haar_2d_char_decompose2  (tbuffer, buffer, width, height, channels, limit)
00067  *      - bn_wlt_haar_2d_short_decompose2 (tbuffer, buffer, width, height, channels, limit)
00068  *      - bn_wlt_haar_2d_int_decompose2   (tbuffer, buffer, width, height, channels, limit)
00069  *      - bn_wlt_haar_2d_long_decompose2  (tbuffer, buffer, width, height, channels, limit)
00070  *
00071  *      - bn_wlt_haar_2d_double_reconstruct2(tbuffer, buffer, width, height, channels, sub_sz, limit)
00072  *      - bn_wlt_haar_2d_float_reconstruct2 (tbuffer, buffer, width, height, channels, sub_sz, limit)
00073  *      - bn_wlt_haar_2d_char_reconstruct2  (tbuffer, buffer, width, height, channels, sub_sz, limit)
00074  *      - bn_wlt_haar_2d_short_reconstruct2 (tbuffer, buffer, width, height, channels, sub_sz, limit)
00075  *      - bn_wlt_haar_2d_int_reconstruct2   (tbuffer, buffer, width, height, channels, sub_sz, limit)
00076  *      - bn_wlt_haar_2d_long_reconstruct2  (tbuffer, buffer, width, height, channels, sub_sz, limit)
00077  *
00078  *
00079  *  For greatest accuracy, it is preferable to convert everything to "double"
00080  *  and decompose/reconstruct with that.  However, there are useful
00081  *  properties to performing the decomposition and/or reconstruction in
00082  *  various data types (most notably char).
00083  *
00084  *  Rather than define all of these routines explicitly, we define
00085  *  2 macros "decompose" and "reconstruct" which embody the structure of
00086  *  the function (which is common to all of them).  We then instatiate
00087  *  these macros once for each of the data types.  It's ugly, but it
00088  *  assures that a change to the structure of one operation type
00089  *  (decompose or reconstruct) occurs for all data types.
00090  *
00091  *
00092  *
00093  *
00094  *  bn_wlt_haar_1d_*_decompose(tbuffer, buffer, dimen, channels, limit)
00095  *  @par Parameters:
00096  *      - tbuffer     a temporary data buffer 1/2 as large as "buffer". See (1) below.
00097  *      - buffer      pointer to the data to be decomposed
00098  *      - dimen    the number of samples in the data buffer
00099  *      - channels the number of values per sample
00100  *      - limit    the extent of the decomposition
00101  *
00102  *  Perform a Haar wavelet decomposition on the data in buffer "buffer".  The
00103  *  decomposition is done "in place" on the data, hence the values in "buffer"
00104  *  are not preserved, but rather replaced by their decomposition.
00105  *  The number of original samples in the buffer (parameter "dimen") and the
00106  *  decomposition limit ("limit") must both be a power of 2 (e.g. 512, 1024).
00107  *  The buffer is decomposed into "average" and "detail" halves until the
00108  *  size of the "average" portion reaches "limit".  Simultaneous
00109  *  decomposition of multi-plane (e.g. pixel) data, can be performed by
00110  *  indicating the number of planes in the "channels" parameter.
00111  *
00112  *  (1) The process requires a temporary buffer which is 1/2 the size of the
00113  *  longest span to be decomposed.  If the "tbuffer" argument is non-null then
00114  *  it is a pointer to a temporary buffer.  If the pointer is NULL, then a
00115  *  local temporary buffer will be allocated (and freed).
00116  *
00117  *  @par Examples:
00118 @code
00119         double dbuffer[512], cbuffer[256];
00120         ...
00121         bn_wlt_haar_1d_double_decompose(cbuffer, dbuffer, 512, 1, 1);
00122 @endcode
00123  *
00124  *    performs complete decomposition on the data in array "dbuffer".
00125  *
00126 @code
00127         double buffer[3][512];   /_* 512 samples, 3 values/sample (e.g. RGB?)*_/
00128         double tbuffer[3][256];  /_* the temporary buffer *_/
00129         ...
00130         bn_wlt_haar_1d_double_decompose(tbuffer, buffer, 512, 3, 1);
00131 @endcode
00132  *
00133  *    This will completely decompose the data in buffer.  The first sample will
00134  *    be the average of all the samples.  Alternatively:
00135  *
00136  *      bn_wlt_haar_1d_double_decompose(tbuffer, buffer, 512, 3, 64);
00137  *
00138  *    decomposes buffer into a 64-sample "average image" and 3 "detail" sets.
00139  *
00140  *  bn_wlt_haar_1d_*_reconstruct(tbuffer, buffer, dimen, channels, sub_sz, limit)
00141  *
00142  *
00143  *  @author
00144  *      Lee A. Butler
00145  *
00146  *  @par Modifications
00147  *      Christopher Sean Morrison
00148  *
00149  *  @par Source -
00150  *      The U. S. Army Research Laboratory
00151  *@n    Aberdeen Proving Ground, Maryland  21005-5068  USA
00152  *
00153  */
00154 /*@}*/
00155 
00156 #include "common.h"
00157 
00158 #include <stdio.h>
00159 #ifdef HAVE_STRING_H
00160 #include <string.h>
00161 #endif
00162 
00163 #include "machine.h"
00164 #include "bu.h"
00165 #include "vmath.h"
00166 #include "bn.h"
00167 
00168 
00169 #ifdef __STDC__
00170 #define decompose_1d(DATATYPE) bn_wlt_haar_1d_ ## DATATYPE ## _decompose
00171 #else
00172 #define decompose_1d(DATATYPE) bn_wlt_haar_1d_/**/DATATYPE/**/_decompose
00173 #endif
00174 
00175 
00176 
00177 #define make_wlt_haar_1d_decompose(DATATYPE)  \
00178 void \
00179 decompose_1d(DATATYPE) \
00180 ( tbuffer, buffer, dimen, channels, limit ) \
00181 DATATYPE *tbuffer;              /* temporary buffer */ \
00182 DATATYPE *buffer;               /* data buffer */ \
00183 unsigned long dimen;    /* # of samples in data buffer */ \
00184 unsigned long channels; /* # of data values per sample */ \
00185 unsigned long limit;    /* extent of decomposition */ \
00186 { \
00187         register DATATYPE *detail; \
00188         register DATATYPE *avg; \
00189         unsigned long img_size; \
00190         unsigned long half_size; \
00191         int do_free = 0; \
00192         unsigned long x, x_tmp, d, i, j; \
00193         register fastf_t onehalf = (fastf_t)0.5; \
00194 \
00195         CK_POW_2( dimen ); \
00196 \
00197         if ( ! tbuffer ) { \
00198                 tbuffer = (DATATYPE *)bu_malloc( \
00199                                 (dimen/2) * channels * sizeof( *buffer ), \
00200                                 "1d wavelet buffer"); \
00201                 do_free = 1; \
00202         } \
00203 \
00204         /* each iteration of this loop decomposes the data into 2 halves: \
00205          * the "average image" and the "image detail" \
00206          */ \
00207         for (img_size = dimen ; img_size > limit ; img_size = half_size ){ \
00208 \
00209                 half_size = img_size/2; \
00210                  \
00211                 detail = tbuffer; \
00212                 avg = buffer; \
00213 \
00214                 for ( x=0 ; x < img_size ; x += 2 ) { \
00215                         x_tmp = x*channels; \
00216 \
00217                         for (d=0 ; d < channels ; d++, avg++, detail++) { \
00218                                 i = x_tmp + d; \
00219                                 j = i + channels; \
00220                                 *detail = (buffer[i] - buffer[j]) * onehalf; \
00221                                 *avg    = (buffer[i] + buffer[j]) * onehalf; \
00222                         } \
00223                 } \
00224 \
00225                 /* "avg" now points to the first element AFTER the "average \
00226                  * image" section, and hence is the START of the "image  \
00227                  * detail" portion.  Convenient, since we now want to copy \
00228                  * the contents of "tbuffer" (which holds the image detail) into \
00229                  * place. \
00230                  */ \
00231                 memcpy(avg, tbuffer, sizeof(*buffer) * channels * half_size); \
00232         } \
00233          \
00234         if (do_free) \
00235                 bu_free( (genptr_t)tbuffer, "1d wavelet buffer"); \
00236 }
00237 
00238 
00239 #if defined(__STDC__)
00240 #define reconstruct(DATATYPE ) bn_wlt_haar_1d_ ## DATATYPE ## _reconstruct
00241 #else
00242 #define reconstruct(DATATYPE) bn_wlt_haar_1d_/**/DATATYPE/**/_reconstruct
00243 #endif
00244 
00245 #define make_wlt_haar_1d_reconstruct( DATATYPE ) \
00246 void \
00247 reconstruct(DATATYPE) \
00248 ( tbuffer, buffer, dimen, channels, subimage_size, limit )\
00249 DATATYPE *tbuffer; \
00250 DATATYPE *buffer; \
00251 unsigned long dimen; \
00252 unsigned long channels; \
00253 unsigned long subimage_size; \
00254 unsigned long limit; \
00255 { \
00256         register DATATYPE *detail; \
00257         register DATATYPE *avg; \
00258         unsigned long img_size; \
00259         unsigned long dbl_size; \
00260         int do_free = 0; \
00261         unsigned long x_tmp, d, x, i, j; \
00262 \
00263         CK_POW_2( subimage_size ); \
00264         CK_POW_2( dimen ); \
00265         CK_POW_2( limit ); \
00266 \
00267         if ( ! (subimage_size < dimen) ) { \
00268                 bu_log("%s:%d Dimension %d should be greater than subimage size (%d)\n", \
00269                         __FILE__, __LINE__, dimen, subimage_size); \
00270                 bu_bomb("reconstruct"); \
00271         } \
00272 \
00273         if ( ! (subimage_size < limit) ) { \
00274                 bu_log("%s:%d Channels limit %d should be greater than subimage size (%d)\n", \
00275                         __FILE__, __LINE__, limit, subimage_size); \
00276                 bu_bomb("reconstruct"); \
00277         } \
00278 \
00279         if ( ! (limit <= dimen) ) { \
00280                 bu_log("%s:%d Dimension %d should be greater than or equal to the channels limit (%d)\n", \
00281                         __FILE__, __LINE__, dimen, limit); \
00282                 bu_bomb("reconstruct"); \
00283         } \
00284 \
00285 \
00286         if ( ! tbuffer ) { \
00287                 tbuffer = ( DATATYPE *)bu_malloc((dimen/2) * channels * sizeof( *buffer ), \
00288                                 "1d wavelet reconstruct tmp buffer"); \
00289                 do_free = 1; \
00290         } \
00291 \
00292         /* Each iteration of this loop reconstructs an image twice as \
00293          * large as the original using a "detail image". \
00294          */ \
00295         for (img_size=subimage_size ; img_size < limit ; img_size=dbl_size) { \
00296                 dbl_size = img_size * 2; \
00297 \
00298                 d = img_size * channels; \
00299                 detail = &buffer[ d ]; \
00300 \
00301                 /* copy the original or "average" data to temporary buffer */ \
00302                 avg = tbuffer; \
00303                 memcpy(avg, buffer, sizeof(*buffer) * d ); \
00304 \
00305 \
00306                 for (x=0 ; x < dbl_size ; x += 2 ) { \
00307                         x_tmp = x * channels; \
00308                         for (d=0 ; d < channels ; d++, avg++, detail++ ) { \
00309                                 i = x_tmp + d; \
00310                                 j = i + channels; \
00311                                 buffer[i] = *avg + *detail; \
00312                                 buffer[j] = *avg - *detail; \
00313                         } \
00314                 } \
00315         } \
00316 \
00317         if (do_free) \
00318                 bu_free( (genptr_t)tbuffer, \
00319                         "1d wavelet reconstruct tmp buffer"); \
00320 }
00321 
00322 /* Believe it or not, this is where the actual code is generated */
00323 
00324 make_wlt_haar_1d_decompose(double)
00325 make_wlt_haar_1d_reconstruct(double)
00326 
00327 make_wlt_haar_1d_decompose(float)
00328 make_wlt_haar_1d_reconstruct(float)
00329 
00330 make_wlt_haar_1d_decompose(char)
00331 make_wlt_haar_1d_reconstruct(char)
00332 
00333 make_wlt_haar_1d_decompose(int)
00334 make_wlt_haar_1d_reconstruct(int)
00335 
00336 make_wlt_haar_1d_decompose(short)
00337 make_wlt_haar_1d_reconstruct(short)
00338 
00339 make_wlt_haar_1d_decompose(long)
00340 make_wlt_haar_1d_reconstruct(long)
00341 
00342 
00343 #ifdef __STDC__
00344 #define decompose_2d( DATATYPE ) bn_wlt_haar_2d_ ## DATATYPE ## _decompose
00345 #else
00346 #define decompose_2d(DATATYPE) bn_wlt_haar_2d_/* */DATATYPE/* */_decompose
00347 #endif
00348 
00349 #define make_wlt_haar_2d_decompose(DATATYPE) \
00350 void \
00351 decompose_2d(DATATYPE) \
00352 (tbuffer, buffer, dimen, channels, limit) \
00353 DATATYPE *tbuffer; \
00354 DATATYPE *buffer; \
00355 unsigned long dimen; \
00356 unsigned long channels; \
00357 unsigned long limit; \
00358 { \
00359         register DATATYPE *detail; \
00360         register DATATYPE *avg; \
00361         unsigned long img_size; \
00362         unsigned long half_size; \
00363         unsigned long x, y, x_tmp, y_tmp, d, i, j; \
00364         register fastf_t onehalf = (fastf_t)0.5; \
00365 \
00366         CK_POW_2( dimen ); \
00367 \
00368         if ( ! tbuffer ) { \
00369                 tbuffer = (DATATYPE *)bu_malloc( \
00370                                 (dimen/2) * channels * sizeof( *buffer ), \
00371                                 "1d wavelet buffer"); \
00372         } \
00373 \
00374         /* each iteration of this loop decomposes the data into 4 quarters: \
00375          * the "average image", the horizontal detail, the vertical detail \
00376          * and the horizontal-vertical detail \
00377          */ \
00378         for (img_size = dimen ; img_size > limit ; img_size = half_size ) { \
00379                 half_size = img_size/2; \
00380 \
00381                 /* do a horizontal detail decomposition first */ \
00382                 for (y=0 ; y < img_size ; y++ ) { \
00383                         y_tmp = y * dimen * channels; \
00384 \
00385                         detail = tbuffer; \
00386                         avg = &buffer[y_tmp]; \
00387 \
00388                         for (x=0 ; x < img_size ; x += 2 ) { \
00389                                 x_tmp = x*channels + y_tmp; \
00390 \
00391                                 for (d=0 ; d < channels ; d++, avg++, detail++){ \
00392                                         i = x_tmp + d; \
00393                                         j = i + channels; \
00394                                         *detail = (buffer[i] - buffer[j]) * onehalf; \
00395                                         *avg    = (buffer[i] + buffer[j]) * onehalf; \
00396                                 } \
00397                         } \
00398                         /* "avg" now points to the first element AFTER the \
00399                          * "average image" section, and hence is the START \
00400                          * of the "image detail" portion.  Convenient, since \
00401                          * we now want to copy the contents of "tbuffer" (which \
00402                          * holds the image detail) into place. \
00403                          */ \
00404                         memcpy(avg, tbuffer, sizeof(*buffer) * channels * half_size); \
00405                 } \
00406 \
00407                 /* Now do the vertical decomposition */ \
00408                 for (x=0 ; x < img_size ; x ++ ) { \
00409                         x_tmp = x*channels; \
00410 \
00411                         detail = tbuffer; \
00412                         avg = &buffer[x_tmp]; \
00413 \
00414                         for (y=0 ; y < img_size ; y += 2) { \
00415                                 y_tmp =y*dimen*channels + x_tmp; \
00416 \
00417                                 for (d=0 ; d < channels ; d++, avg++, detail++) { \
00418                                         i = y_tmp + d; \
00419                                         j = i + dimen*channels; \
00420                                         *detail = (buffer[i] - buffer[j]) * onehalf; \
00421                                         *avg    = (buffer[i] + buffer[j]) * onehalf; \
00422                                 } \
00423                                 avg += (dimen-1)*channels; \
00424                         } \
00425 \
00426                         /* "avg" now points to the element ABOVE the \
00427                          * last "average image" pixel or the first "detail" \
00428                          * location in the user buffer. \
00429                          * \
00430                          * There is no memcpy for the columns, so we have to \
00431                          * copy the data back to the user buffer ourselves. \
00432                          */ \
00433                         detail = tbuffer; \
00434                         for (y=half_size ; y < img_size ; y++) { \
00435                                 for (d=0; d < channels ; d++) { \
00436                                         *avg++ = *detail++; \
00437                                 } \
00438                                 avg += (dimen-1)*channels; \
00439                         } \
00440                 } \
00441         } \
00442 }
00443 
00444 
00445 #ifdef __STDC__
00446 #define reconstruct_2d( DATATYPE ) bn_wlt_haar_2d_ ## DATATYPE ## _reconstruct
00447 #else
00448 #define reconstruct_2d(DATATYPE) bn_wlt_haar_2d_/* */DATATYPE/* */_reconstruct
00449 #endif
00450 
00451 #define make_wlt_haar_2d_reconstruct(DATATYPE) \
00452 void \
00453 reconstruct_2d(DATATYPE) \
00454 (tbuf, buf, width, channels, avg_size, limit) \
00455 DATATYPE *tbuf; \
00456 DATATYPE *buf; \
00457 unsigned long width; \
00458 unsigned long channels; \
00459 unsigned long avg_size; \
00460 unsigned long limit; \
00461 { \
00462         register DATATYPE *detail; \
00463         register DATATYPE *avg; \
00464         unsigned long img_size; \
00465         unsigned long dbl_size; \
00466         unsigned long x_tmp, d, x, i, j; \
00467         unsigned long y, row_len, row_start; \
00468  \
00469         CK_POW_2( avg_size ); \
00470         CK_POW_2( width ); \
00471         CK_POW_2( limit ); \
00472  \
00473         /* XXX check for: \
00474          * subimage_size < dimen && subimage_size < limit \
00475          * limit <= dimen \
00476          */ \
00477  \
00478  \
00479         if ( ! tbuf ) { \
00480                 tbuf = ( DATATYPE *)bu_malloc((width/2) * channels * sizeof( *buf ), \
00481                                 "1d wavelet reconstruct tmp buffer"); \
00482         } \
00483  \
00484         row_len = width * channels; \
00485  \
00486         /* Each iteration of this loop reconstructs an image twice as \
00487          * large as the original using a "detail image". \
00488          */ \
00489  \
00490         for (img_size = avg_size ; img_size < limit ; img_size = dbl_size) { \
00491                 dbl_size = img_size * 2; \
00492                  \
00493                  \
00494                 /* first is a vertical reconstruction */ \
00495                 for (x=0 ; x < dbl_size ; x++ ) { \
00496                         /* reconstruct column x */ \
00497  \
00498                         /* copy column of "average" data to tbuf */ \
00499                         x_tmp = x*channels; \
00500                         for (y=0 ; y < img_size ; y++) { \
00501                                 i = x_tmp + y*row_len; \
00502                                 j = y * channels; \
00503                                 for (d=0 ; d < channels ; d++) { \
00504                                         tbuf[j++] = buf[i++]; \
00505                                 } \
00506                         } \
00507                         avg = tbuf; \
00508                         detail = &buf[x_tmp + img_size*row_len]; \
00509  \
00510                         /* reconstruct column */ \
00511                         for (y=0 ; y < dbl_size ; y += 2) { \
00512  \
00513                                 i = x_tmp + y*row_len; \
00514                                 j = i + row_len; \
00515  \
00516                                 for (d=0 ; d < channels ; d++,avg++,detail++){ \
00517                                         buf[i++] = *avg + *detail; \
00518                                         buf[j++] = *avg - *detail; \
00519                                 } \
00520                                 detail += row_len - channels; \
00521                         } \
00522                 } \
00523  \
00524                 /* now a horizontal reconstruction */ \
00525                 for (y=0 ; y < dbl_size ; y++ ) { \
00526                         /* reconstruct row y */ \
00527  \
00528                         /* copy "average" row to tbuf and set pointer to \
00529                          * begining of "detail" \
00530                          */ \
00531                         d = img_size * channels; \
00532                         row_start = y*row_len; \
00533  \
00534  \
00535                         avg = &buf[ row_start ]; \
00536                         detail = &buf[ row_start + d]; \
00537  \
00538                         memcpy(tbuf, avg, sizeof(*buf) * d ); \
00539                         avg = tbuf; \
00540  \
00541                         /* reconstruct row */ \
00542                         for (x=0 ; x < dbl_size ; x += 2 ) { \
00543                                 x_tmp = x * channels; \
00544                                 i = row_start + x * channels; \
00545                                 j = i + channels; \
00546  \
00547                                 for (d=0 ; d < channels ; d++,avg++,detail++){ \
00548                                         buf[i++] = *avg + *detail; \
00549                                         buf[j++] = *avg - *detail; \
00550                                 } \
00551                         } \
00552                 } \
00553         } \
00554 }
00555 
00556 
00557 make_wlt_haar_2d_decompose(double)
00558 make_wlt_haar_2d_decompose(float)
00559 make_wlt_haar_2d_decompose(char)
00560 make_wlt_haar_2d_decompose(int)
00561 make_wlt_haar_2d_decompose(short)
00562 make_wlt_haar_2d_decompose(long)
00563 
00564 make_wlt_haar_2d_reconstruct(double)
00565 make_wlt_haar_2d_reconstruct(float)
00566 make_wlt_haar_2d_reconstruct(char)
00567 make_wlt_haar_2d_reconstruct(int)
00568 make_wlt_haar_2d_reconstruct(short)
00569 make_wlt_haar_2d_reconstruct(long)
00570 
00571 
00572 
00573 #ifdef __STDC__
00574 #define decompose_2d_2( DATATYPE ) bn_wlt_haar_2d_ ## DATATYPE ## _decompose2
00575 #else
00576 #define decompose_2d_2(DATATYPE) bn_wlt_haar_2d_/* */DATATYPE/* */_decompose2
00577 #endif
00578 
00579 #define make_wlt_haar_2d_decompose2(DATATYPE) \
00580 void \
00581 decompose_2d_2(DATATYPE) \
00582 (tbuffer, buffer, width, height, channels, limit) \
00583 DATATYPE *tbuffer; \
00584 DATATYPE *buffer; \
00585 unsigned long width; \
00586 unsigned long height; \
00587 unsigned long channels; \
00588 unsigned long limit; \
00589 { \
00590         register DATATYPE *detail; \
00591         register DATATYPE *avg; \
00592         unsigned long img_wsize; \
00593         unsigned long img_hsize; \
00594         unsigned long half_wsize; \
00595         unsigned long half_hsize; \
00596         unsigned long x, y, x_tmp, y_tmp, d, i, j; \
00597         register fastf_t onehalf = (fastf_t)0.5; \
00598 \
00599         CK_POW_2( width ); \
00600         CK_POW_2( height ); \
00601 \
00602         /* create a temp buffer the half the size of the larger dimension \
00603          */ \
00604         if ( ! tbuffer ) { \
00605                 tbuffer = (DATATYPE *)bu_malloc( \
00606                                 (((width>height)?width:height)/2) * channels * sizeof( *buffer ), \
00607                                 "1d wavelet buffer"); \
00608         } \
00609 \
00610         /* each iteration of this loop decomposes the data into 4 quarters: \
00611          * the "average image", the horizontal detail, the vertical detail \
00612          * and the horizontal-vertical detail \
00613          */ \
00614         for (img_wsize = width, img_hsize = height ; (img_wsize > limit) && (img_hsize > limit) ; img_wsize = half_wsize, img_hsize = half_hsize ) { \
00615                 half_wsize = img_wsize/2; \
00616                 half_hsize = img_hsize/2; \
00617 \
00618                 /* do a horizontal detail decomposition first */ \
00619                 for (y=0 ; y < img_hsize ; y++ ) { \
00620                         y_tmp = y * width * channels; \
00621 \
00622                         detail = tbuffer; \
00623                         avg = &buffer[y_tmp]; \
00624 \
00625                         for (x=0 ; x < img_wsize ; x += 2 ) { \
00626                                 x_tmp = x*channels + y_tmp; \
00627 \
00628                                 for (d=0 ; d < channels ; d++, avg++, detail++){ \
00629                                         i = x_tmp + d; \
00630                                         j = i + channels; \
00631                                         *detail = (buffer[i] - buffer[j]) * onehalf; \
00632                                         *avg    = (buffer[i] + buffer[j]) * onehalf; \
00633                                 } \
00634                         } \
00635                         /* "avg" now points to the first element AFTER the \
00636                          * "average image" section, and hence is the START \
00637                          * of the "image detail" portion.  Convenient, since \
00638                          * we now want to copy the contents of "tbuffer" (which \
00639                          * holds the image detail) into place. \
00640                          */ \
00641                         memcpy(avg, tbuffer, sizeof(*buffer) * channels * half_wsize); \
00642                 } \
00643 \
00644                 /* Now do the vertical decomposition */ \
00645                 for (x=0 ; x < img_wsize ; x ++ ) { \
00646                         x_tmp = x*channels; \
00647 \
00648                         detail = tbuffer; \
00649                         avg = &buffer[x_tmp]; \
00650 \
00651                         for (y=0 ; y < img_hsize ; y += 2) { \
00652                                 y_tmp =y*width*channels + x_tmp; \
00653 \
00654                                 for (d=0 ; d < channels ; d++, avg++, detail++) { \
00655                                         i = y_tmp + d; \
00656                                         j = i + width*channels; \
00657                                         *detail = (buffer[i] - buffer[j]) * onehalf; \
00658                                         *avg    = (buffer[i] + buffer[j]) * onehalf; \
00659                                 } \
00660                                 avg += (width-1)*channels; \
00661                         } \
00662 \
00663                         /* "avg" now points to the element ABOVE the \
00664                          * last "average image" pixel or the first "detail" \
00665                          * location in the user buffer. \
00666                          * \
00667                          * There is no memcpy for the columns, so we have to \
00668                          * copy the data back to the user buffer ourselves. \
00669                          */ \
00670                         detail = tbuffer; \
00671                         for (y=half_hsize ; y < img_hsize ; y++) { \
00672                                 for (d=0; d < channels ; d++) { \
00673                                         *avg++ = *detail++; \
00674                                 } \
00675                                 avg += (width-1)*channels; \
00676                         } \
00677                 } \
00678         } \
00679 }
00680 
00681 make_wlt_haar_2d_decompose2(double)
00682 make_wlt_haar_2d_decompose2(float)
00683 make_wlt_haar_2d_decompose2(char)
00684 make_wlt_haar_2d_decompose2(int)
00685 make_wlt_haar_2d_decompose2(short)
00686 make_wlt_haar_2d_decompose2(long)
00687 
00688 
00689 
00690 /*
00691  * Local Variables:
00692  * mode: C
00693  * tab-width: 8
00694  * c-basic-offset: 4
00695  * indent-tabs-mode: t
00696  * End:
00697  * ex: shiftwidth=4 tabstop=8
00698  */

Generated on Mon Sep 18 01:24:47 2006 for BRL-CAD by  doxygen 1.4.6