Es posible calcular la transformada 2D a partir de la 1D usando la
propiedad de la separabilidad de la DWT. En concreto, la DWT 2D se
calcula aplicanto la DWT 1D primero a todas las filas de la imagen y
a continuación a todas las columnas. El orden (primero filas o primero
columnas) es irrelevante, siempre y cuando al descomprimir se realize en
el orden inverso.
/* Two "global" vectors of unsigned integers. */
uint32* in_line;
uint32* out_line;
/* Asign memory to those vectors taking into account the maximun
row or column size. */
line_allocation(uint32 width, uint32 height) {
uint32 max_length = 0;
if (max_length < width) {
max_length = width;
} else if (max_length < height) {
max_length = heidht;
}
in_line = memory_allocation(uint32, max_length);
out_line = memory_allocation(uint32, max_length);
}
/*
Structure in the memory of the matrix of pixels (that is, a vector of
pointers that points to vectors of pixels)):
+----> cols (columns)
image |
| v
v rows
+---------------+ +-------------+-------------+ +------------------+
| image[0] |--->| image[0][0] | image[0][1] | ... | image[0][cols-1] |
+---------------+ +-------------+-------------+ +------------------+
| image[1] |---> ...
+---------------+
: :
+---------------+ +------------------+ +-----------------------+
| image[rows-1] |--->| image[rows-1][0] | ... | image[rows-1][cols-1] |
+---------------+ +------------------+ +-----------------------+
*/
analyze_2d(int32** image, uint32 rows, uint32 cols, uint8 levels) {
for(uint8 l=0; l<levels; l++) {
uint32 x = cols;
cols /= 2;
if (cols == 0) cols = 0;
uint32 y = rows;
rows /= 2;
if (rows == 0) rows = 0;
/* Iterate over the columns */
if (x & 1) { /* There is a odd number of columns */
for(uint32 j = 0; j < y; j++) {
for(uint32 i = 0; i < x; i++) in_line[i] = image[j][i];
analyze_1d_odd(in_line, image[j], image[j] + width + 1, x);
}
} else { /* There is a even number of columns */
for(uint32 j = 0; j < y; j++) {
for(uint32 i = 0; i < x; i++) in_line[i] = image[j][i];
analyze_1d_even(in_line, image[j], image[j] + width, x);
}
}
/* Iterate over the rows */
if (y & 1) { /* There is a odd number of rows */
for(uint32 i = 0; i < x; i++) {
for(uint32 j = 0; j < y; j++) in_line[j] = image[j][i];
analyze_1d_odd(in_line, out_line, out_line+height+1, y);
for(uint32 j = 0; j < y; j++) image[j][i] = out_line[j];
}
} else { /* There is a even number of rows */
for(uint32 i=0; i<x; i++) {
for(uint32 j=0;j <y; j++) in_line[j]=image[j][i];
analyze_1d_even(in_line, out_line, out_line + height, y);
for(uint32 j=0;j <y; j++) image[j][i]=out_line[j];
}
}
}
}
synthesize_2d(int32 **image, uint32 width, uint32 height, uint8 levels) {
int nx, ny, lv;
int i,j;
uint32 x = width >> levels;
uint32 y = height >> levels;
for (uint8 lv = levels-1; lv >= 0; lv--) {
uint32 mx = x;
x = width >> lv;
if(x==0) x = 1;
uint32 my = y;
y = height >> lv;
if(y==0) y = 1;
/* Columns transformation */
if(y & 1) { /* Odd number of rows */
for(uint32 i = 0; i < x; i++) {
for(uint32 j = 0; j < y; j++) in_line[j] = image[j][i];
synthesize_1d_odd(out_line, in_line, in_line + my + 1, y);
for(uint32 j = 0; j < y; j++) image[j][i] = out_line[j];
}
} else { /* Even number of rows */
for(uint32 i = 0; i < x; i++) {
for(uint32 j = 0; j < y; j++) in_line[j] = image[j][i];
synthesize_1d_even(out_line, in_line, in_line + my, y);
for(uint32 j = 0; j < y; j++) image[j][i] = out_line[j];
}
}
/* Rows transformation */
if(x & 1) { /* Odd number of cols */
for(uint32 j = 0; j < y; j++) {
memcpy(in_line, image[j], x*sizeof(int32));
synthesize_1d_odd(image[j], in_line, in_line + mx + 1, x);
}
} else { /* N’umero par de columas */
for(j=0;j<ny;j++) {
memcpy(in_line, image[j], x*sizeof(int32));
synthesize_1d_even(image[j], in_line, in_line + mx, x);
}
}
}
}