waili-gpl-19990723/ 40755 24520 25417 0 6746056437 12244 5ustar geertnatwwaili-gpl-19990723/lib/ 40755 24520 25417 0 6746056434 13007 5ustar geertnatwwaili-gpl-19990723/lib/Channel.C100640 24520 25417 11010 6745120265 14556 0ustar geertnatw// // Channel Class // // $Id: Channel.C,v 4.4.2.2.2.1 1999/07/20 16:15:49 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include const char *Channel::rcsid = "$Id: Channel.C,v 4.4.2.2.2.1 1999/07/20 16:15:49 geert Exp $"; // ---------------------------------------------------------------------------- // // Channel Abstract Base Class // // ---------------------------------------------------------------------------- Channel *Channel::CreateFromDescriptor(u_int cols, u_int rows, const TransformDescriptor transform[], u_int depth, int offsetx, int offsety) { if (depth == 0) return new NTChannel(cols, rows, offsetx, offsety); else { const Wavelet *wavelet = Wavelet::CreateFromID(transform->filter); LChannel *ch = NULL; switch (transform->type) { case TT_ColsRows: ch = new LChannelCR(*wavelet, cols, rows, offsetx, offsety); break; case TT_Cols: ch = new LChannelC(*wavelet, cols, rows, offsetx, offsety); break; case TT_Rows: ch = new LChannelR(*wavelet, cols, rows, offsetx, offsety); break; } delete wavelet; Channel *ch2 = ch->SubBands[0]; cols = ch2->GetCols(); rows = ch2->GetRows(); offsetx = ch2->GetOffsetX(); offsety = ch2->GetOffsetY(); delete ch2; ch->SubBands[0] = CreateFromDescriptor(cols, rows, transform+1, depth-1, offsetx, offsety); return ch; } } double Channel::Psnr(const Channel &channel, PixType maxval) const { if (maxval < 0) maxval = -maxval; if (Cols != channel.GetCols() || Rows != channel.GetRows()) return(-DBL_MAX); u64 ss = 0; for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) { int d = (*this)(c, r)-channel(c, r); ss += d*d; } if (ss == 0) return(DBL_MAX); double rmse = sqrt((double)ss/(double)(Cols*Rows)); double psnr = 20.0*log10(maxval/rmse); return(psnr); } double Channel::Entropy(void) const { PixType min, max; u64 n; u64 *histogram = FullHistogram(min, max, n); double logn = log(double(n)); double entropy = 0; for (int i = 0; i < max-min+1; i++) if (histogram[i]) { double x = double(histogram[i]); entropy -= x*(log(x)-logn); } entropy /= double(n); entropy *= M_LOG2E; delete [] histogram; return(entropy); } Channel *Channel::UpScale(u_int s, const Wavelet &wavelet) { if (s > 1) { LChannelCR *channel = new LChannelCR(wavelet); channel->Cols = Cols<<1; channel->Rows = Rows<<1; channel->OffsetX = OffsetX<<1; channel->OffsetY = OffsetY<<1; channel->SubBands[SubBand_LH] = new NTChannel(Cols, Rows, OffsetX, OffsetY); channel->SubBands[SubBand_HL] = new NTChannel(Cols, Rows, OffsetX, OffsetY); channel->SubBands[SubBand_HH] = new NTChannel(Cols, Rows, OffsetX, OffsetY); ((NTChannel*)channel->SubBands[SubBand_LH])->Clear(); ((NTChannel*)channel->SubBands[SubBand_HL])->Clear(); ((NTChannel*)channel->SubBands[SubBand_HH])->Clear(); channel->SubBands[SubBand_LL] = this->Clone(); Destroy(); return(channel->UpScale(GetEven(s), wavelet)); } else { Channel *channel = this->Clone(); Destroy(); return(channel); } } Channel *Channel::Scale(f32 s, const Wavelet &wavelet) { u_int cols = (int)floor(Cols*s); u_int rows = (int)floor(Rows*s); Channel *channel; if (s < 1) channel = DownScale((u_int)floor(1/s), wavelet); else channel = UpScale((u_int)ceil(s), wavelet); if (channel->GetCols() != cols || channel->GetRows() != rows) { s = (f32)cols / (f32)channel->GetCols(); if (channel->IsLifted()) { NTChannel *ch = ((LChannel*)channel)->IFwt(); delete channel; ch->Interpolate(s); channel = ch; ch = NULL; } else ((NTChannel*)channel)->Interpolate(s); } return(channel); } waili-gpl-19990723/lib/Color.C100640 24520 25417 16535 6745120265 14305 0ustar geertnatw// // Color Spaces // // $Id: Color.C,v 4.0.2.1.2.1 1999/07/20 16:15:49 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include const char *ColorSpace::rcsid = "$Id: Color.C,v 4.0.2.1.2.1 1999/07/20 16:15:49 geert Exp $"; static f32 DefaultPrimChroma[6] = { 0.6400, 0.3300, 0.3000, 0.6000, 0.1500, 0.0600 }; static f32 DefaultWhitePoint[2] = { 0.3127, 0.3290 }; ColorSpace::ColorSpace(void) { SetPrimChroma(DefaultPrimChroma, 0); SetWhitePoint(DefaultWhitePoint, 1); } void ColorSpace::SetPrimChroma(const f32 chroma[6], int immediate) { PrimChroma[0].x = chroma[0]; PrimChroma[0].y = chroma[1]; PrimChroma[0].z = 1.0-PrimChroma[0].x-PrimChroma[0].y; PrimChroma[1].x = chroma[2]; PrimChroma[1].y = chroma[3]; PrimChroma[1].z = 1.0-PrimChroma[1].x-PrimChroma[1].y; PrimChroma[2].x = chroma[4]; PrimChroma[2].y = chroma[5]; PrimChroma[2].z = 1.0-PrimChroma[2].x-PrimChroma[2].y; if (immediate) CalcConvMat(); } void ColorSpace::GetPrimChroma(f32 chroma[6]) const { chroma[0] = PrimChroma[0].x; chroma[1] = PrimChroma[0].y; chroma[2] = PrimChroma[1].x; chroma[3] = PrimChroma[1].y; chroma[4] = PrimChroma[2].x; chroma[5] = PrimChroma[2].y; } void ColorSpace::SetWhitePoint(const f32 wp[2], int immediate) { WhitePoint.x = wp[0]/wp[1]; WhitePoint.y = 1.0; WhitePoint.z = (1.0-wp[0]-wp[1])/wp[1]; if (immediate) CalcConvMat(); } void ColorSpace::GetWhitePoint(f32 wp[2]) const { wp[1] = 1.0/(1.0+WhitePoint.x+WhitePoint.z); wp[0] = WhitePoint.x*wp[1]; } void ColorSpace::CalcConvMat(void) { f32 mat[3][3], white[3], scale[3], c; int ind[3], t; u_int i, j, k; // Normalized white point white[0] = WhitePoint.x; white[1] = WhitePoint.y; white[2] = WhitePoint.z; for (i = 0; i < 3; i++) { mat[0][i] = PrimChroma[i].x; mat[1][i] = PrimChroma[i].y; mat[2][i] = PrimChroma[i].z; ind[i] = i; } // Gaussian elimination with partial pivoting for (i = 0; i < 2; i++) { for (j = i+1; j < 3; j++) if (fabs(mat[ind[j]][i]) > fabs(mat[ind[i]][i])) { t = ind[j]; ind[j] = ind[i]; ind[i] = t; } if (fabs(mat[ind[i]][i]) < EPS) Die("%s: Matrix is singular\n", __FUNCTION__); for (j = i+1; j < 3; j++) { c = mat[ind[j]][i]/mat[ind[i]][i]; for (k = i+1; k < 3; k++) mat[ind[j]][k] -= c*mat[ind[i]][k]; white[ind[j]] -= c*white[ind[i]]; } } if (fabs(mat[ind[2]][2]) < EPS) Die("%s: Matrix is singular\n", __FUNCTION__); // Back substitution to solve for scale scale[ind[2]] = white[ind[2]]/mat[ind[2]][2]; scale[ind[1]] = (white[ind[1]]-(mat[ind[1]][2]*scale[ind[2]]))/ mat[ind[1]][1]; scale[ind[0]] = (white[ind[0]]-(mat[ind[0]][1]*scale[ind[1]])- (mat[ind[0]][2]*scale[ind[2]]))/mat[ind[0]][0]; // Build matrix RGB->XYZ for (i = 0; i < 3; i++) { RGB2XYZ[0][i] = scale[i]*PrimChroma[i].x; RGB2XYZ[1][i] = scale[i]*PrimChroma[i].y; RGB2XYZ[2][i] = scale[i]*PrimChroma[i].z; } for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) { mat[i][j] = RGB2XYZ[i][j]; XYZ2RGB[i][j] = i == j ? 1.0 : 0.0; } for (i = 0; i < 3; i++) { for (j = i+1, k = i; j < 3; j++) if (fabs(mat[j][i]) > fabs(mat[k][i])) k = j; // Check for singularity if (fabs(mat[k][i]) < EPS) Die("%s: Matrix is singular\n", __FUNCTION__); // Pivot - switch rows k and i if (k != i) for (j = 0; j < 3; j++) { c = mat[i][j]; mat[i][j] = mat[k][j]; mat[k][j] = c; c = XYZ2RGB[i][j]; XYZ2RGB[i][j] = XYZ2RGB[k][j]; XYZ2RGB[k][j] = c; } // Normalize the row - make the diagonal 1 c = 1.0/mat[i][i]; for (j = 0; j < 3; j++) { if (j != i) mat[i][j] *= c; else mat[i][j] = 1.0; XYZ2RGB[i][j] *= c; } // Zero the non-diagonal terms in this column for (j = 0; j < 3; j++) if (j != i) { c = -mat[j][i]; for (k = 0; k < 3; k++) { mat[j][k] += c*mat[i][k]; XYZ2RGB[j][k] += c*XYZ2RGB[i][k]; } } } } // Color Conversions void ColorSpace::Convert(const Color_RGB &rgb, Color_XYZ &xyz) const { xyz.x = RGB2XYZ[0][0]*rgb.r+RGB2XYZ[0][1]*rgb.g+RGB2XYZ[0][2]*rgb.b; xyz.y = RGB2XYZ[1][0]*rgb.r+RGB2XYZ[1][1]*rgb.g+RGB2XYZ[1][2]*rgb.b; xyz.z = RGB2XYZ[2][0]*rgb.r+RGB2XYZ[2][1]*rgb.g+RGB2XYZ[2][2]*rgb.b; } void ColorSpace::Convert(const Color_XYZ &xyz, Color_RGB &rgb) const { rgb.r = XYZ2RGB[0][0]*xyz.x+XYZ2RGB[0][1]*xyz.y+XYZ2RGB[0][2]*xyz.z; rgb.g = XYZ2RGB[1][0]*xyz.x+XYZ2RGB[1][1]*xyz.y+XYZ2RGB[1][2]*xyz.z; rgb.b = XYZ2RGB[2][0]*xyz.x+XYZ2RGB[2][1]*xyz.y+XYZ2RGB[2][2]*xyz.z; } #define DARK_XYZ_VALUE (0.008856) #define DARK_L_VALUE (7.999625) #define DARK_AB_VALUE (0.206893) void ColorSpace::Convert(const Color_XYZ &xyz, Color_LAB &lab) const { f32 x, y, z; x = xyz.x/WhitePoint.x; y = xyz.y; z = xyz.z/WhitePoint.z; if (y <= DARK_XYZ_VALUE) { lab.l = 903.3*y; y = pow(7.787*y+16.0/116.0, 1.0/3.0); } else { y = pow(y, 1.0/3.0); lab.l = 116.0*y-16; } #if 0 if (x <= DARK_XYZ_VALUE) x = 7.787*x+16.0/116.0; if (z <= DARK_XYZ_VALUE) z = 7.787*z+16.0/116.0; #endif x = pow(x, 1.0/3.0); z = pow(z, 1.0/3.0); lab.a = 500*(x-y); lab.b = 200*(y-z); } void ColorSpace::Convert(const Color_LAB &lab, Color_XYZ &xyz) const { f32 x, y, z, t; if (lab.l <= DARK_L_VALUE) { y = lab.l/903.3; t = pow(7.787*y+16.0/116.0, 1.0/3.0); } else { t = (lab.l+16.0)/116.0; y = pow(t, 3.0); } x = pow(lab.a/500.0+t, 3.0); z = pow(t-lab.b/200.0, 3.0); #if 0 if (x <= DARK_AB_VALUE) x = (x-16.0/116.0)/7.787; if (y <= DARK_AB_VALUE) y = (y-16.0/116.0)/7.787; #endif xyz.x = x*WhitePoint.x; xyz.y = y; xyz.z = z*WhitePoint.z; } // Color to Gray Conversions void ColorSpace::Convert(const Color_RGB &rgb, Color_CIEY &y) const { y.y = RGB2XYZ[1][0]*rgb.r+RGB2XYZ[1][1]*rgb.g+RGB2XYZ[1][2]*rgb.b; } // Gray Conversions void ColorSpace::Convert(const Color_CIEY &y, Color_CIEL &l) { if (y.y <= DARK_XYZ_VALUE) l.l = 903.3*y.y; else l.l = 116.0*pow(y.y, 1.0/3.0)-16; } void ColorSpace::Convert(const Color_CIEL &l, Color_CIEY &y) { if (l.l <= DARK_L_VALUE) y.y = l.l/903.3; else y.y = pow((l.l+16.0)/116.0, 3.0); } // Color Conversions (16 bit) void ColorSpace::Convert(const Color_RGB16 &rgb, Color_YUVr16 &yuvr) { yuvr.yr = (rgb.r+2*rgb.g+rgb.b)>>2; yuvr.ur = rgb.r-rgb.g; yuvr.vr = rgb.b-rgb.g; } void ColorSpace::Convert(const Color_YUVr16 &yuvr, Color_RGB16 &rgb) { rgb.g = yuvr.yr-((yuvr.ur+yuvr.vr)>>2); rgb.r = yuvr.ur+rgb.g; rgb.b = yuvr.vr+rgb.g; } waili-gpl-19990723/lib/Image.C100640 24520 25417 47460 6745120265 14252 0ustar geertnatw// // Image Class // // $Id: Image.C,v 4.4.2.4.2.1 1999/07/20 16:15:49 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include #include #include #include #ifdef SUPPORT_TIFF #include #endif // SUPPORT_TIFF const char *Image::rcsid = "$Id: Image.C,v 4.4.2.4.2.1 1999/07/20 16:15:49 geert Exp $"; Image::Image(u_int cols, u_int rows, u_int channels) : NumChannels(channels), Channels(NULL) { Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = new NTChannel(cols, rows); } Image::Image(const u_int cols[], const u_int rows[], u_int channels) : NumChannels(channels), Channels(NULL) { Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = new NTChannel(cols[ch], rows[ch]); } Image::Image(const Channel &channel, u_int channels = 1) : NumChannels(channels), Channels(NULL) { Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = channel.Clone(); } Image::Image(const Channel *channel[], u_int channels) : NumChannels(channels), Channels(NULL) { Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = channel[ch]->Clone(); } Image::Image(const Image &im) : NumChannels(im.NumChannels), Channels(NULL) { Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = im.Channels[ch]->Clone(); } Image::Image(u_int cols, u_int rows, const TransformDescriptor transform[], u_int depth, u_int channels) : NumChannels(channels), Channels(NULL) { Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = Channel::CreateFromDescriptor(cols, rows, transform, depth); } Image::~Image() { if (Channels) for (u_int ch = 0; ch < NumChannels; ch++) delete Channels[ch]; delete[] Channels; } // ---------------------------------------------------------------------------- // // Generic Routines // // ---------------------------------------------------------------------------- // Import/Export of Graphics Files ImageType Image::Import(const char *filename, ImageFormat type) { ImageType res = IT_Unknown; switch (type) { case IF_AUTO: #ifdef SUPPORT_TIFF if (strstr(filename, "tif")) res = ImportTIFF(filename); else #endif // SUPPORT_TIFF res = ImportPNM(filename); break; case IF_PNMASCII: case IF_PNMRAW: res = ImportPNM(filename); break; #ifdef SUPPORT_TIFF case IF_TIFF: res = ImportTIFF(filename); break; #endif // SUPPORT_TIFF } return(res); } void Image::Export(const char *filename, ImageFormat type) { switch (type) { case IF_AUTO: #ifdef SUPPORT_TIFF if (strstr(filename, "tif")) Die("%s: Export to TIFF isn't implemented yet!\n", __FUNCTION__); else #endif // SUPPORT_TIFF ExportPNM(filename, 1); break; case IF_PNMASCII: ExportPNM(filename, 0); break; case IF_PNMRAW: ExportPNM(filename, 1); break; #ifdef SUPPORT_TIFF case IF_TIFF: Die("%s: Export to TIFF isn't implemented yet!\n", __FUNCTION__); break; #endif // SUPPORT_TIFF } } // Static Routines static u8 GetRealChar(Stream &stream); static u_int GetNumber(Stream &stream); // Import an Image from a File in the PNM (PGM or PPM) Format ImageType Image::ImportPNM(const char *filename) { ImageType res; Stream stream(filename, "r"); u_int cols, rows, channels; u_int c, r, ch; u8 d, magic; int raw = 0; stream.Read(magic); if (magic != 'P') Die("%s: Not a PNM file\n", __FUNCTION__); stream.Read(magic); switch (magic) { case '1': // PBM ASCII case '4': // PBM Raw Die("%s: PBM is not supported\n", __FUNCTION__); break; case '5': // PGM Raw raw = 1; case '2': // PGM ASCII channels = 1; res = IT_CIEY; break; case '6': // PPM Raw raw = 1; case '3': // PPM ASCII channels = 3; res = IT_RGB; break; default: Die("%s: Not a PNM file\n", __FUNCTION__); break; } cols = GetNumber(stream); rows = GetNumber(stream); GetNumber(stream); Resize(cols, rows, channels); if (raw) for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) for (ch = 0; ch < channels; ch++) { stream.Read(d); (*this)(c, r, ch) = (PixType)(d-128); } else for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) for (ch = 0; ch < channels; ch++) (*this)(c, r, ch) = (PixType)(GetNumber(stream)-128); return(res); } #ifdef SUPPORT_TIFF // Import an Image from a File in the TIFF Format ImageType Image::ImportTIFF(const char *filename) { ImageType res; TIFF *tif; u_short bps, spp, photomet; u_int tiffmaxval, sign, bitsleft; u_int cols, rows, channels; u_int r, c, ch; int sample; u_char *buf, *p; if (!(tif = TIFFOpen(filename, "r"))) Die("%s: TIFFOpen() failed: %s\n", __FUNCTION__, strerror(errno)); if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bps)) bps = 1; if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp)) spp = 1; if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photomet)) Die("%s: Can't get photometric\n", __FUNCTION__); switch (spp) { case 1: case 3: case 4: break; default: Die("%s: cannot handle %d samples per pixel\n", __FUNCTION__, spp); } channels = spp; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &cols); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &rows); tiffmaxval = (1<>bitsleft) & tiffmaxval; \ } for (r = 0; r < rows; r++) { if (TIFFReadScanline(tif, buf, r, 0) < 0) Die("%s: TIFFReadScanline() failed: %s\n", __FUNCTION__, strerror(errno)); p = buf; bitsleft = 8; switch (photomet) { case PHOTOMETRIC_MINISBLACK: case PHOTOMETRIC_RGB: for (c = 0; c < cols; c++) for (ch = 0; ch < channels; ch++) { NEXTSAMPLE (*this)(c, r, ch) = (PixType)(sample-128); } break; case PHOTOMETRIC_CIELAB: for (c = 0; c < cols; c++) { NEXTSAMPLE // L* (*this)(c, r, 0) = (PixType)(sample-128); if (channels == 1) continue; NEXTSAMPLE // a* if (sample & sign) sample -= 2*sign; (*this)(c, r, 2) = (PixType)(sample-128); NEXTSAMPLE // b* if (sample & sign) sample -= 2*sign; (*this)(c, r, 2) = (PixType)(sample-128); if (channels == 4) NEXTSAMPLE // Alpha } break; case PHOTOMETRIC_MINISWHITE: for (c = 0; c < cols; c++) { NEXTSAMPLE sample = tiffmaxval - sample; (*this)(c, r, 0) = (PixType)(sample-128); } break; } } delete[] buf; TIFFClose(tif); return(res); } #endif // SUPPORT_TIFF // Export an Image to a File in the PNM (PGM or PPM) Format void Image::ExportPNM(const char *filename, int raw) { Stream stream(filename, "w"); u8 magic, d; PixType val; u_int cols = GetCols(0); u_int rows = GetRows(0); u_int channels = GetChannels(); for (u_int ch = 1; ch < channels; ch++) if (cols != GetCols(ch) || rows != GetRows(ch)) Die("%s: All channels must have the same size\n", __FUNCTION__); switch (channels) { case 1: magic = '2'; break; case 3: magic = '3'; break; default: Die("%s: Unsupported number of channels %d\n", __FUNCTION__, channels); } if (raw) magic += 3; stream.Printf("P%c\n%d %d\n255", magic, cols, rows); if (raw) { stream.Write((u8)'\n'); for (u_int r = 0; r < rows; r++) for (u_int c = 0; c < cols; c++) for (u_int ch = 0; ch < channels; ch++) { val = (*this)(c, r, ch)+128; if (val < 0) d = 0; else if (val > 255) d = 255; else d = (u8)val; stream.Write(d); } } else { u_int l = 70; for (u_int r = 0; r < rows; r++) for (u_int c = 0; c < cols; c++) for (u_int ch = 0; ch < channels; ch++) { val = (*this)(c, r, ch)+128; if (val < 0) d = 0; else if (val > 255) d = 255; else d = (u8)val; l += 4; if (l >= 70) { stream.Printf("\n%4d", (u_int)d); l = 3; } else stream.Printf(" %4d", (u_int)d); } stream.Write((u8)'\n'); } } // ---------------------------------------------------------------------------- // Image Conversion static u_int type2numchannels(ImageType t) { switch (t) { case IT_Mono: case IT_CIEY: case IT_CIEL: return 1; case IT_RGB: case IT_CIEXYZ: case IT_CIELab: case IT_YUV: case IT_YUVr: return 3; case IT_Unknown: default: return 0; } } void Image::Convert(ImageType from, ImageType to) { u_int c, r; ColorSpace color; u_int cols = GetCols(0); u_int rows = GetRows(0); u_int channels = GetChannels(); for (u_int ch = 1; ch < channels; ch++) if (cols != GetCols(ch) || rows != GetRows(ch)) Die("%s: All channels must have the same size\n", __FUNCTION__); if (NumChannels < type2numchannels(from) || NumChannels < type2numchannels(to)) Die("%s: Not enough channels for the specified conversion types\n", __FUNCTION__); switch (from) { case IT_RGB: switch (to) { case IT_RGB: // Trivial break; case IT_CIEXYZ: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_RGB rgb; Color_XYZ xyz; rgb.r = (*this)(c, r, 0); rgb.g = (*this)(c, r, 1); rgb.b = (*this)(c, r, 2); color.Convert(rgb, xyz); (*this)(c, r, 0) = (PixType)(xyz.x+0.5); (*this)(c, r, 1) = (PixType)(xyz.y+0.5); (*this)(c, r, 2) = (PixType)(xyz.z+0.5); } break; case IT_CIELab: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_RGB rgb; Color_LAB lab; rgb.r = (*this)(c, r, 0)/255.0; rgb.g = (*this)(c, r, 1)/255.0; rgb.b = (*this)(c, r, 2)/255.0; color.Convert(rgb, lab); (*this)(c, r, 0) = (PixType)(lab.l*255.0/100.0+0.5); if (lab.a < -128.0) lab.a = -128.0; else if (lab.a > 127.0) lab.a = 127.0; if (lab.b < -128.0) lab.b = -128.0; else if (lab.b > 127.0) lab.b = 127.0; (*this)(c, r, 1) = (PixType)(lab.a+0.5); (*this)(c, r, 2) = (PixType)(lab.b+0.5); } break; case IT_YUVr: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_RGB16 rgb; Color_YUVr16 yuvr; rgb.r = (*this)(c, r, 0); rgb.g = (*this)(c, r, 1); rgb.b = (*this)(c, r, 2); ColorSpace::Convert(rgb, yuvr); (*this)(c, r, 0) = yuvr.yr; (*this)(c, r, 1) = yuvr.ur; (*this)(c, r, 2) = yuvr.vr; } break; default: goto conversion_not_supported; } break; case IT_CIEXYZ: switch (to) { case IT_RGB: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_XYZ xyz; Color_RGB rgb; xyz.x = (*this)(c, r, 0); xyz.y = (*this)(c, r, 1); xyz.z = (*this)(c, r, 2); color.Convert(xyz, rgb); (*this)(c, r, 0) = (PixType)(rgb.r+0.5); (*this)(c, r, 1) = (PixType)(rgb.g+0.5); (*this)(c, r, 2) = (PixType)(rgb.b+0.5); } break; case IT_CIEXYZ: // Trivial break; case IT_CIELab: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_XYZ xyz; Color_LAB lab; xyz.x = (*this)(c, r, 0)/255.0; xyz.y = (*this)(c, r, 1)/255.0; xyz.z = (*this)(c, r, 2)/255.0; color.Convert(xyz, lab); (*this)(c, r, 0) = (PixType)(lab.l*255.0/100.0+0.5); if (lab.a < -128.0) lab.a = -128.0; else if (lab.a > 127.0) lab.a = 127.0; if (lab.b < -128.0) lab.b = -128.0; else if (lab.b > 127.0) lab.b = 127.0; (*this)(c, r, 1) = (PixType)(lab.a+0.5); (*this)(c, r, 2) = (PixType)(lab.b+0.5); } break; default: goto conversion_not_supported; } break; case IT_CIELab: switch (to) { case IT_RGB: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_LAB lab; Color_RGB rgb; lab.l = (*this)(c, r, 0)*100.0/255.0; lab.a = (*this)(c, r, 1); lab.b = (*this)(c, r, 2); color.Convert(lab, rgb); (*this)(c, r, 0) = (PixType)(rgb.r*255.0+0.5); (*this)(c, r, 1) = (PixType)(rgb.g*255.0+0.5); (*this)(c, r, 2) = (PixType)(rgb.b*255.0+0.5); } break; case IT_CIEXYZ: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_LAB lab; Color_XYZ xyz; lab.l = (*this)(c, r, 0)*100.0/255.0; lab.a = (*this)(c, r, 1); lab.b = (*this)(c, r, 2); color.Convert(lab, xyz); (*this)(c, r, 0) = (PixType)(xyz.x*255.0+0.5); (*this)(c, r, 1) = (PixType)(xyz.y*255.0+0.5); (*this)(c, r, 2) = (PixType)(xyz.z*255.0+0.5); } break; case IT_CIELab: // Trivial break; default: goto conversion_not_supported; } break; case IT_YUVr: switch (to) { case IT_YUVr: // Trivial break; case IT_RGB: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_YUVr16 yuvr; Color_RGB16 rgb; yuvr.yr = (*this)(c, r, 0); yuvr.ur = (*this)(c, r, 1); yuvr.vr = (*this)(c, r, 2); ColorSpace::Convert(yuvr, rgb); (*this)(c, r, 0) = rgb.r; (*this)(c, r, 1) = rgb.g; (*this)(c, r, 2) = rgb.b; } break; default: goto conversion_not_supported; } break; case IT_CIEY: switch (to) { case IT_CIEY: // Trivial break; case IT_CIEL: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_CIEY y; Color_CIEL l; y.y = (*this)(c, r, 0)*255.0; color.Convert(y, l); (*this)(c, r, 0) = (PixType)(l.l*255.0/100.0+0.5); }; break; default: goto conversion_not_supported; } break; case IT_CIEL: switch (to) { case IT_CIEY: for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) { Color_CIEL l; Color_CIEY y; l.l = (*this)(c, r, 0)*100.0/255.0; color.Convert(l, y); (*this)(c, r, 0) = (PixType)(y.y*255.0+0.5); }; break; case IT_CIEL: // Trivial break; default: goto conversion_not_supported; } break; default: conversion_not_supported: Die("%s: Conversion from type %d to type %d is not supported\n", __FUNCTION__, from, to); } } // Read the Next Character from a PNM File and Care about Comments static u8 GetRealChar(Stream &stream) { u8 c; for (stream.Read(c); c == '#'; stream.Read(c)) do stream.Read(c); while (c != '\n'); return(c); } // Skip Leading Whitespace and Read an ASCII Number from a PNM File static u_int GetNumber(Stream &stream) { u_int value = 0; u8 c; do c = GetRealChar(stream); while ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')); while (1) { if ((c >= '0') && (c <= '9')) { value = 10*value+(c-'0'); c = GetRealChar(stream); continue; } if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) break; Die("%s: Not a number\n", __FUNCTION__); } return(value); } // --------------------------------------------------------------------------- // Manipulation void Image::Resize(u_int cols, u_int rows, u_int channels) { for (u_int ch = 0; ch < NumChannels; ch++) delete Channels[ch]; delete[] Channels; NumChannels = channels; Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = new NTChannel(cols, rows); } Image& Image::operator=(const Image &im) { if (this != &im) { for (u_int ch = 0; ch < NumChannels; ch++) delete Channels[ch]; delete[] Channels; NumChannels = im.NumChannels; Channels = new (Channel *)[NumChannels]; for (u_int ch = 0; ch < NumChannels; ch++) Channels[ch] = im[ch]->Clone(); } return(*this); } void Image::InsertChannel(const Channel &data, u_int channel) { Channel **newChannels = new (Channel *)[++NumChannels]; for (u_int ch = 0; ch < channel; ch++) newChannels[ch] = Channels[ch]; for (u_int ch = channel+1; ch < NumChannels; ch++) newChannels[ch] = Channels[ch-1]; newChannels[channel] = data.Clone(); delete[] Channels; Channels = newChannels; } void Image::DeleteChannel(u_int channel) { Channel **newChannels = new (Channel *)[--NumChannels]; for (u_int ch = 0; ch < channel; ch++) newChannels[ch] = Channels[ch]; for (u_int ch = channel; ch < NumChannels; ch++) newChannels[ch] = Channels[ch+1]; delete Channels[channel]; delete[] Channels; Channels = newChannels; } // Wavelet Transforms void Image::Fwt(const TransformDescriptor transform[], u_int depth) { for (u_int ch = 0; ch < NumChannels; ch++) { assert(!(*this)[ch]->IsLifted()); LChannel *channel = ((NTChannel *)((*this)[ch]))->Fwt(transform, depth); if (channel) { delete Channels[ch]; Channels[ch] = channel; } } } void Image::IFwt(void) { for (u_int ch = 0; ch < NumChannels; ch++) if ((*this)[ch]->IsLifted()) { NTChannel *channel = ((LChannel *)((*this)[ch]))->IFwt(); if (channel) { delete Channels[ch]; Channels[ch] = channel; } } } void Image::RedundantFwt(const Wavelet &wavelet, TransformType type) { for (u_int ch = 0; ch < NumChannels; ch++) { assert(!(*this)[ch]->IsLifted()); LChannel *channel = NULL; switch (type) { case TT_ColsRows: channel = ((NTChannel*)(*this)[ch])->RedundantFwtCR(wavelet); break; case TT_Cols: channel = ((NTChannel*)(*this)[ch])->RedundantFwtC(wavelet); break; case TT_Rows: channel = ((NTChannel*)(*this)[ch])->RedundantFwtR(wavelet); break; } if (channel) { delete Channels[ch]; Channels[ch] = channel; } } } // Wavelet Based Operations void Image::Scale(f32 scale, const Wavelet &wavelet) { for (u_int ch = 0; ch < NumChannels; ch++) { Channel *channel = (*this)[ch]->Scale(scale, wavelet); if (channel) { delete Channels[ch]; Channels[ch] = channel; } } } waili-gpl-19990723/lib/LChannel.C100640 24520 25417 15306 6745120265 14706 0ustar geertnatw// // LChannel Class // // $Id: LChannel.C,v 4.5.2.2.2.1 1999/07/20 16:15:49 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include const char *LChannel::rcsid = "$Id: LChannel.C,v 4.5.2.2.2.1 1999/07/20 16:15:49 geert Exp $"; // ---------------------------------------------------------------------------- // // Lifted Channel Abstract Base Class // // ---------------------------------------------------------------------------- LChannel::LChannel(const Wavelet &filter, u_int numsubbands, u_int cols, u_int rows) : Channel(cols, rows), NumSubBands(0), SubBands(NULL), Filter(NULL), Shifts(NULL) { if (numsubbands) { SubBands = new Channel*[numsubbands]; ::Clear(SubBands, numsubbands); Shifts = new int[numsubbands]; ::Clear(Shifts, numsubbands); } NumSubBands = numsubbands; Filter = filter.Clone(); } LChannel::LChannel(const LChannel &channel) : Channel(channel.Cols, channel.Rows, channel.OffsetX, channel.OffsetY), NumSubBands(0), SubBands(NULL), Filter(NULL), Shifts(NULL) { u_int numsubbands = channel.NumSubBands; if (numsubbands) { SubBands = new Channel*[numsubbands]; Shifts = new int[numsubbands]; for (u_int i = 0; i < numsubbands; i++) { if (channel.SubBands[i]) SubBands[i] = channel.SubBands[i]->Clone(); else SubBands[i] = NULL; Shifts[i] = channel.Shifts[i]; } } NumSubBands = numsubbands; Filter = channel.Filter->Clone(); } LChannel::~LChannel() { delete Filter; if (SubBands) { for (u_int i = 0; i < NumSubBands; i++) delete SubBands[i]; delete[] SubBands; } } TransformDescriptor *LChannel::GetTransform(void) const { u_int depth = GetDepth(); TransformDescriptor *transform = new TransformDescriptor[depth]; const LChannel *lchannel = this; for (u_int level = 0; level < depth; level++) { transform[level].type = lchannel->GetTransformType(); transform[level].filter = lchannel->Filter->GetID(); if (lchannel->SubBands[0]->IsLifted()) lchannel = (LChannel*)lchannel->SubBands[0]; } return(transform); } u64 *LChannel::FullHistogram(PixType &min, PixType &max, u64 &numpixels) const { numpixels = 0; PixType minima[NumSubBands], maxima[NumSubBands]; u64 *histograms[NumSubBands]; for (u_int i = 0; i < NumSubBands; i++) { u64 *hist = NULL; if (SubBands[i]) { u64 n; if ((hist = SubBands[i]->FullHistogram(minima[i], maxima[i], n))) { if (!numpixels) { min = minima[i]; max = maxima[i]; } else { min = Min(min, minima[i]); max = Max(max, maxima[i]); } numpixels += n; } } histograms[i] = hist; } if (!numpixels) return(NULL); u64 *histogram = new u64[max-min+1]; ::Clear(histogram, max-min+1); u64 *hz = histogram-min; for (u_int i = 0; i < NumSubBands; i++) if (histograms[i]) { u64 *hz2 = histograms[i]-minima[i]; for (PixType j = Max(min, minima[i]); j <= Min(max, maxima[i]); j++) hz[j] += hz2[j]; delete [] histograms[i]; } return(histogram); } void LChannel::Clear(void) { for (u_int i = 0; i < NumSubBands; i++) if (SubBands[i]) SubBands[i]->Clear(); } void LChannel::Enhance(f32 m) { for (u_int i = 1; i < NumSubBands; i++) if (SubBands[i]) SubBands[i]->Enhance(m); } void LChannel::Enhance(int m, u_int shift) { for (u_int i = 1; i < NumSubBands; i++) if (SubBands[i]) SubBands[i]->Enhance(m, shift); } u64 LChannel::Threshold(double threshold, int soft) { u64 cnt = 0; for (u_int i = 0; i < NumSubBands; i++) if (SubBands[i]) { double subthresh = threshold; int shift = Shifts[i]; if (shift > 0) { while (shift >= 2) { subthresh *= 0.5; shift -= 2; } if (shift) subthresh *= M_SQRT1_2; } else if (shift < 0) { while (shift <= -2) { subthresh *= 2; shift += 2; } if (shift) subthresh *= M_SQRT2; } cnt += SubBands[i]->Threshold(subthresh, soft); } return(cnt); } NTChannel *LChannel::IFwtStep(void) { NTChannel *dest = new NTChannel(Cols, Rows, GetOffsetX(), GetOffsetY()); ICakeWalk(); ILazy(*dest); Destroy(); return(dest); } NTChannel *LChannel::IFwt(void) { if (SubBands[0]->IsLifted()) { NTChannel *dest = ((LChannel *)SubBands[0])->IFwt(); delete SubBands[0]; SubBands[0] = dest; } return(IFwtStep()); } LChannel *LChannel::PushFwtStepCR(const Wavelet &wavelet) { Channel *channel = NULL; if (SubBands[0] && (channel = SubBands[0]->PushFwtStepCR(wavelet))) { if (channel != SubBands[0]) { delete SubBands[0]; SubBands[0] = channel; } channel = this; } return((LChannel *)channel); } LChannel *LChannel::PushFwtStepC(const Wavelet &wavelet) { Channel *channel = NULL; if (SubBands[0] && (channel = SubBands[0]->PushFwtStepC(wavelet))) { if (channel != SubBands[0]) { delete SubBands[0]; SubBands[0] = channel; } channel = this; } return((LChannel *)channel); } LChannel *LChannel::PushFwtStepR(const Wavelet &wavelet) { Channel *channel = NULL; if (SubBands[0] && (channel = SubBands[0]->PushFwtStepR(wavelet))) { if (channel != SubBands[0]) { delete SubBands[0]; SubBands[0] = channel; } channel = this; } return((LChannel *)channel); } Channel *LChannel::PopFwtStep(void) { Channel *channel = NULL; if (SubBands[0]) if (SubBands[0]->IsLifted()) { channel = SubBands[0]->PopFwtStep(); if (channel != SubBands[0]) { delete SubBands[0]; SubBands[0] = channel; } channel = this; } else { NTChannel *dest = new NTChannel(Cols, Rows, GetOffsetX(), GetOffsetY()); ICakeWalk(); ILazy(*dest); Destroy(); channel = dest; } return(channel); } void LChannel::Destroy(void) { for (u_int i = 0; i < NumSubBands; i++) { delete SubBands[i]; SubBands[i] = NULL; } delete Filter; Filter = NULL; Cols = Rows = OffsetX = OffsetY = 0; } waili-gpl-19990723/lib/LChannelC.C100640 24520 25417 52507 6745120265 15015 0ustar geertnatw// // LChannelC Class // // $Id: LChannelC.C,v 4.6.2.1.2.1 1999/07/20 16:15:49 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include const char *LChannelC::rcsid = "$Id: LChannelC.C,v 4.6.2.1.2.1 1999/07/20 16:15:49 geert Exp $"; // ---------------------------------------------------------------------------- // // Lifted Channel Abstract Base Class (lifted Cols) // // ---------------------------------------------------------------------------- LChannelC::LChannelC(const Wavelet &filter, u_int cols, u_int rows, int offx, int offy) : LChannel(filter, 2, cols, rows) { OffsetX = offx; OffsetY = offy; int offy_l = GetEven(OffsetY); int offy_h = GetOdd(OffsetY); u_int rlow = Even(OffsetY)? GetEven(Rows): GetOdd(Rows); u_int rhigh = Rows - rlow; SubBands[SubBand_L] = new NTChannel(Cols, rlow, OffsetX, offy_l); SubBands[SubBand_H] = new NTChannel(Cols, rhigh, OffsetX, offy_h); Shifts[SubBand_L] = filter.GetShiftL(); Shifts[SubBand_H] = filter.GetShiftH(); } LChannelC::LChannelC(const LChannelC &channel) : LChannel(channel) { } void LChannelC::GetMask(u_int &maskx, u_int &masky) const { SubBands[SubBand_L]->GetMask(maskx, masky); masky = masky<<1 | 1; } void LChannelC::Resize(u_int cols, u_int rows) { Channel::Resize(cols, rows); u_int rlow = Even(OffsetY)? GetEven(Rows): GetOdd(Rows); u_int rhigh = Rows - rlow; if (SubBands[SubBand_L]) SubBands[SubBand_L]->Resize(Cols, rlow); if (SubBands[SubBand_H]) SubBands[SubBand_H]->Resize(Cols, rhigh); } void LChannelC::SetOffsetX(int offx) { OffsetX = offx; SubBands[SubBand_L]->SetOffsetX(offx); SubBands[SubBand_H]->SetOffsetX(offx); } void LChannelC::SetOffsetY(int offy) { if (Even(offy) != Even(OffsetY)) { TransformDescriptor *transform = GetTransform(); u_int depth = GetDepth(); NTChannel *ntchannel = LChannel::IFwt(); ntchannel->SetOffsetY(offy); LChannel *lchannel = ntchannel->Fwt(transform, depth); delete ntchannel; Cols = lchannel->Cols; Rows = lchannel->Rows; OffsetX = lchannel->OffsetX; OffsetY = lchannel->OffsetY; SubBands[SubBand_L] = lchannel->SubBands[SubBand_L]; SubBands[SubBand_H] = lchannel->SubBands[SubBand_H]; Filter = lchannel->Filter; lchannel->SubBands[SubBand_L] = NULL; lchannel->SubBands[SubBand_H] = NULL; lchannel->Filter = NULL; delete lchannel; } else { OffsetY = offy; SubBands[SubBand_L]->SetOffsetY(GetEven(offy)); SubBands[SubBand_H]->SetOffsetY(GetOdd(offy)); } } void LChannelC::Add(const Channel &channel) { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_Cols); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); SubBands[SubBand_L]->Add(*((LChannel&)channel)[SubBand_L]); SubBands[SubBand_H]->Add(*((LChannel&)channel)[SubBand_H]); } void LChannelC::Subtract(const Channel &channel) { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_Cols); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); SubBands[SubBand_L]->Subtract(*((LChannel&)channel)[SubBand_L]); SubBands[SubBand_H]->Subtract(*((LChannel&)channel)[SubBand_H]); } LChannelC *LChannelC::Diff(const Channel &channel) const { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_Cols); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); LChannelC *diff = new LChannelC(*Filter); diff->Cols = Cols; diff->Rows = Rows; diff->OffsetX = OffsetX; diff->OffsetY = OffsetY; diff->SubBands[SubBand_L] = SubBands[SubBand_L]-> Diff(*((LChannel&)channel)[SubBand_L]); diff->SubBands[SubBand_H] = SubBands[SubBand_H]-> Diff(*((LChannel&)channel)[SubBand_H]); return(diff); } void LChannelC::Lazy(const NTChannel &source) { assert(source.Data != NULL); const PixType *data = source.Data; assert(SubBands[SubBand_L] != NULL); assert(SubBands[SubBand_H] != NULL); assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); assert(((NTChannel *)SubBands[SubBand_L])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_H])->Data != NULL); PixType *l = ((NTChannel *)SubBands[SubBand_L])->Data; PixType *h = ((NTChannel *)SubBands[SubBand_H])->Data; u_int low = GetRlow(); u_int high = GetRhigh(); if (Even(OffsetY)) { for (u_int r = 0; r < high; r++) { Copy(data, l, Cols); data += Cols; l += Cols; Copy(data, h, Cols); data += Cols; h += Cols; } if (low != high) Copy(data, l, Cols); } else { for (u_int r = 0; r < low; r++) { Copy(data, h, Cols); data += Cols; h += Cols; Copy(data, l, Cols); data += Cols; l += Cols; } if (low != high) Copy(data, h, Cols); } } void LChannelC::ILazy(NTChannel &dest) const { assert(dest.Data != NULL); PixType *data = dest.Data; assert(SubBands[SubBand_L] != NULL); assert(SubBands[SubBand_H] != NULL); assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); assert(((NTChannel *)SubBands[SubBand_L])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_H])->Data != NULL); const PixType *l = ((NTChannel *)SubBands[SubBand_L])->Data; const PixType *h = ((NTChannel *)SubBands[SubBand_H])->Data; u_int low = GetRlow(); u_int high = GetRhigh(); if (Even(OffsetY)) { for (u_int r = 0; r < high; r++) { Copy(l, data, Cols); data += Cols; l += Cols; Copy(h, data, Cols); data += Cols; h += Cols; } if (low != high) Copy(l, data, Cols); } else { for (u_int r = 0; r < low; r++) { Copy(h, data, Cols); data += Cols; h += Cols; Copy(l, data, Cols); data += Cols; l += Cols; } if (low != high) Copy(h, data, Cols); } } void LChannelC::CakeWalk(void) { assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); LiftChannelC lifting((NTChannel *)SubBands[SubBand_L], (NTChannel *)SubBands[SubBand_H]); Filter->CakeWalk(lifting); } void LChannelC::ICakeWalk(void) { assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); LiftChannelC lifting((NTChannel *)SubBands[SubBand_L], (NTChannel *)SubBands[SubBand_H]); Filter->ICakeWalk(lifting); } void LChannelC::Zip(const LChannelC &channel) { LChannelC *dest = new LChannelC(*Filter, Cols, Rows<<1, OffsetX, OffsetY<<1); LChannelC *subband = new LChannelC(*Filter); subband->Cols = Cols; subband->Rows = Rows; subband->OffsetX = OffsetX; subband->OffsetY = OffsetY; subband->SubBands[SubBand_L] = SubBands[SubBand_L]; subband->SubBands[SubBand_H] = channel.SubBands[SubBand_L]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_L]); subband->SubBands[SubBand_L] = channel.SubBands[SubBand_H]; subband->SubBands[SubBand_H] = SubBands[SubBand_H]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_H]); subband->SubBands[SubBand_L] = NULL; subband->SubBands[SubBand_H] = NULL; delete subband; Rows = dest->Rows; OffsetY = dest->OffsetY; SubBands[SubBand_L] = dest->SubBands[SubBand_L]; SubBands[SubBand_H] = dest->SubBands[SubBand_H]; dest->SubBands[SubBand_L] = NULL; dest->SubBands[SubBand_H] = NULL; delete dest; } NTChannel *LChannelC::IFwt(int x1, int y1, int x2, int y2) const { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); // Calculate new coordinates taking account of the needed borders int yb1 = Max((int)y1-bw-1, OffsetY); int yb2 = Min((int)y2+bw+1, OffsetY+(int)Rows-1); LChannelC *lchannel = new LChannelC(*Filter); lchannel->Cols = x2-x1+1; lchannel->Rows = yb2-yb1+1; lchannel->OffsetX = x1; lchannel->OffsetY = yb1; int yb1_l = GetEven(yb1); int yb1_h = GetOdd(yb1); int yb2_l = GetOdd(yb2); int yb2_h = GetOdd(yb2-1); // Crop subimages of all subbands if (SubBands[SubBand_L]->IsLifted()) lchannel->SubBands[SubBand_L] = ((LChannel*)SubBands[SubBand_L])-> IFwt(x1, yb1_l, x2, yb2_l); else lchannel->SubBands[SubBand_L] = SubBands[SubBand_L]->Crop(x1, yb1_l, x2, yb2_l); lchannel->SubBands[SubBand_H] = SubBands[SubBand_H]->Crop(x1, yb1_h, x2, yb2_h); // Apply invers transform and crop redundant borders NTChannel *ntchannel = lchannel->IFwtStep(); NTChannel *channel = ntchannel->Crop(x1, y1, x2, y2); delete lchannel; delete ntchannel; return(channel); } NTChannel *LChannelC::CropMergeH(LChannelC *channel, int x1, int y1_l, int y1_h, int x2, int y2_l, int y2_h) { assert(x1 <= x2); assert(y1_l <= y2_l); assert(y1_h <= y2_h); // Crop the specified subimages of both subbands // None of the subbands is tranformed!!!!! NTChannel *channel_l = ((NTChannel*)channel->SubBands[SubBand_L])-> Crop(x1, y1_l, x2, y2_l); NTChannel *channel_h = ((NTChannel*)channel->SubBands[SubBand_H])-> Crop(x1, y1_h, x2, y2_h); // Merge high-pass subband in the subband of the current channel SubBands[SubBand_H]->Merge(*channel_h); delete channel; delete channel_h; return(channel_l); } LChannelC *LChannelC::Crop_rec(int x1, int y1, int x2, int y2, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) const { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); LChannelC *channel; int y1_l = GetEven(y1); int y1_h = GetOdd(y1); int y2_l = GetOdd(y2); int y2_h = GetOdd(y2-1); // Calculate new coordinates taking account of the needed borders int y2_tb = top? y1+(bw<<1)+(int)top->Rows: y1+(bw<<1); int y1_bb = bottom? y2-(bw<<1)-(int)bottom->Rows: y2-(bw<<1); if (y1_bb-y2_tb > 1) { channel = new LChannelC(*Filter); channel->Cols = x2-x1+1; channel->Rows = y2-y1+1; channel->OffsetX = x1; channel->OffsetY = y1; // Crop the high-pass subband (without borders) channel->SubBands[SubBand_H] = SubBands[SubBand_H]->Crop(x1, y1_h, x2, y2_h); // Adjust top border according to the higher resolution level NTChannel *nttop = IFwt(x1, y1, x2, y2_tb); if (top) nttop->Merge(*top); if (left) CopyRect(left->Data, left->Cols, 0, 0, nttop->Data, nttop->Cols, 0, 0, left->Cols, nttop->Rows); if (right) CopyRect(right->Data, right->Cols, 0, 0, nttop->Data, nttop->Cols, nttop->Cols-right->Cols, 0, right->Cols, nttop->Rows); LChannelC *ltop = nttop->PushFwtStepC(*Filter); delete nttop; y2_tb -= bw; int y2_tb_l = GetOdd(y2_tb); int y2_tb_h = GetOdd(y2_tb-1); NTChannel *top_l = channel->CropMergeH(ltop, x1, y1_l, y1_h, x2, y2_tb_l, y2_tb_h); // Adjust bottom border according to the higher resolution level NTChannel *ntbottom = IFwt(x1, y1_bb, x2, y2); if (bottom) ntbottom->Merge(*bottom); if (left) CopyRect(left->Data, left->Cols, 0, left->Rows-ntbottom->Rows, ntbottom->Data, ntbottom->Cols, 0, 0, left->Cols, ntbottom->Rows); if (right) CopyRect(right->Data, right->Cols, 0, right->Rows-ntbottom->Rows, ntbottom->Data, ntbottom->Cols, ntbottom->Cols-right->Cols, 0, right->Cols, ntbottom->Rows); LChannelC *lbottom = ntbottom->PushFwtStepC(*Filter); delete ntbottom; y1_bb += bw; int y1_bb_l = GetEven(y1_bb); int y1_bb_h = GetOdd(y1_bb); NTChannel *bottom_l = channel->CropMergeH(lbottom, x1, y1_bb_l, y1_bb_h, x2, y2_l, y2_h); // Adjust left border according to the higher resolution level NTChannel *left_l = NULL; if (left) { LChannelC *lleft = left->PushFwtStepC(*Filter); left_l = (NTChannel*)lleft->SubBands[SubBand_L]; lleft->SubBands[SubBand_L] = NULL; channel->SubBands[SubBand_H]-> Merge(*(NTChannel*)lleft->SubBands[SubBand_H]); delete lleft; } // Adjust right border according to the higher resolution level NTChannel *right_l = NULL; if (right) { LChannelC *lright = right->PushFwtStepC(*Filter); right_l = (NTChannel*)lright->SubBands[SubBand_L]; lright->SubBands[SubBand_L] = NULL; channel->SubBands[SubBand_H]-> Merge(*(NTChannel*)lright->SubBands[SubBand_H]); delete lright; } if (SubBands[SubBand_L]->IsLifted()) // Crop coarser level taking account of new borders channel->SubBands[SubBand_L] = ((LChannel*)SubBands[SubBand_L])-> Crop_rec(x1, y1_l, x2, y2_l, top_l, bottom_l, left_l, right_l); else { // Crop low-pass subband taking account of new borders channel->SubBands[SubBand_L] = SubBands[SubBand_L]-> Crop(x1, y1_l, x2, y2_l); channel->SubBands[SubBand_L]->Merge(*top_l); channel->SubBands[SubBand_L]->Merge(*bottom_l); if (left_l) channel->SubBands[SubBand_L]->Merge(*left_l); if (right_l) channel->SubBands[SubBand_L]->Merge(*right_l); } delete top_l; delete bottom_l; if (left_l) delete left_l; if (right_l) delete right_l; } else { // Crop after applying a full IFwt of the subimage and by // reconstructing the original structure. This is only the case // for one of the most coarse levels. TransformDescriptor *transform = GetTransform(); u_int depth = GetDepth(); NTChannel* ntchannel = IFwt(x1, y1, x2, y2); if (top) ntchannel->Merge(*top); if (bottom) ntchannel->Merge(*bottom); if (left) ntchannel->Merge(*left); if (right) ntchannel->Merge(*right); channel = (LChannelC*)ntchannel->Fwt(transform, depth); delete[] transform; delete ntchannel; } return(channel); } void LChannelC::Merge_rec(const Channel *channel, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); int ch_x1 = channel->GetOffsetX(); int ch_y1 = channel->GetOffsetY(); int ch_x2 = ch_x1+(int)channel->GetCols()-1; int ch_y2 = ch_y1+(int)channel->GetRows()-1; int x1, y1, x2, y2, y1_tb, y2_tb, y1_bb, y2_bb; // Calculate inner and outer border coordinates if (top) { y1 = top->OffsetY; y1_tb = y1-(bw<<1)-1; y2_tb = y1+(int)top->Rows-1+(bw<<1); } else { y1 = ch_y1; y1_tb = y1-(bw<<1)-1; y2_tb = y1+(bw<<1); } if (bottom) { y2 = bottom->OffsetY+(int)bottom->Rows-1; y1_bb = y2-(int)bottom->Rows+1-(bw<<1); y2_bb = y2+(bw<<1)+1; } else { y2 = ch_y2; y1_bb = y2-(bw<<1); y2_bb = y2+(bw<<1)+1; } x1 = left? left->OffsetX: ch_x1; x2 = right? right->OffsetX+(int)right->Cols-1: ch_x2; y1_tb = Max(y1_tb, OffsetY); y2_bb = Min(y2_bb, OffsetY+(int)Rows-1); if (y1_bb-y2_tb > 1 && channel->IsLifted() && ((LChannel*)channel)->GetTransformType() == TT_Cols) { // Adjust top border according to the higher resolution level NTChannel *nttop = IFwt(x1, y1_tb, x2, y2_tb); NTChannel *ntch_top = ((LChannel*)channel)-> IFwt(ch_x1, ch_y1, ch_x2, y2_tb); nttop->Merge(*ntch_top); delete ntch_top; if (top) nttop->Merge(*top); if (left) CopyRect(left->Data, left->Cols, 0, 0, nttop->Data, nttop->Cols, 0, y1-y1_tb, left->Cols, y2_tb-y1+1); if (right) CopyRect(right->Data, right->Cols, 0, 0, nttop->Data, nttop->Cols, x2-right->Cols+1-x1, y1-y1_tb, right->Cols, y2_tb-y1+1); LChannelC *ltop = nttop->PushFwtStepC(*Filter); delete nttop; // Adjust bottom border according to the higher resolution level NTChannel *ntbottom = IFwt(x1, y1_bb, x2, y2_bb); NTChannel *ntch_bottom = ((LChannel*)channel)-> IFwt(ch_x1, y1_bb, ch_x2, ch_y2); ntbottom->Merge(*ntch_bottom); delete ntch_bottom; if (bottom) ntbottom->Merge(*bottom); if (left) CopyRect(left->Data, left->Cols, 0, y1_bb-y1, ntbottom->Data, ntbottom->Cols, 0, 0, left->Cols, y2-y1_bb+1); if (right) CopyRect(right->Data, right->Cols, 0, y1_bb-y1, ntbottom->Data, ntbottom->Cols, x2-right->Cols+1-x1, 0, right->Cols, y2-y1_bb+1); LChannelC *lbottom = ntbottom->PushFwtStepC(*Filter); delete ntbottom; // Adjust left border according to the higher resolution level LChannelC *lleft = NULL; if (left) { NTChannel *ntleft = IFwt(x1, y1_tb, x1+(int)left->Cols-1, y2_bb); ntleft->Merge(*left); lleft = ntleft->PushFwtStepC(*Filter); delete ntleft; } // Adjust right border according to the higher resolution level LChannelC *lright = NULL; if (right) { NTChannel *ntright = IFwt(x2-(int)right->Cols+1, y1_tb, x2, y2_bb); ntright->Merge(*right); lright = ntright->PushFwtStepC(*Filter); delete ntright; } // Merge the high-pass border-independent (center) subimage part SubBands[SubBand_H]-> Merge(*((LChannelC*)channel)->SubBands[SubBand_H]); // Recalculate inner and outer border coordinates // (without redundant border) y1_tb = Max(y1-bw-1, OffsetY); int y1_tb_l = GetEven(y1_tb); int y1_tb_h = GetOdd(y1_tb); y2_bb = Min(y2+bw+1, OffsetY+(int)Rows-1); int y2_bb_l = GetOdd(y2_bb); int y2_bb_h = GetOdd(y2_bb-1); y2_tb -= bw; int y2_tb_l = GetOdd(y2_tb); int y2_tb_h = GetOdd(y2_tb-1); y1_bb += bw; int y1_bb_l = GetEven(y1_bb); int y1_bb_h = GetOdd(y1_bb); // Merge specified border parts for the high-pass subimage and // crop the low-pass parts NTChannel *top_l = CropMergeH(ltop, x1, y1_tb_l, y1_tb_h, x2, y2_tb_l, y2_tb_h); NTChannel *bottom_l = CropMergeH(lbottom, x1, y1_bb_l, y1_bb_h, x2, y2_bb_l, y2_bb_h); NTChannel *left_l = lleft? CropMergeH(lleft, x1, y1_tb_l, y1_tb_h, x1+(int)lleft->Cols-1, y2_bb_l, y2_bb_h) : (NTChannel*)NULL; NTChannel *right_l = lright? CropMergeH(lright, x2-(int)lright->Cols+1, y1_tb_l, y1_tb_h, x2, y2_bb_l, y2_bb_h) : (NTChannel*)NULL; if (SubBands[SubBand_L]->IsLifted()) // Merge coarser level taking account of new borders ((LChannel*)SubBands[SubBand_L])-> Merge_rec(((LChannelC*)channel)->SubBands[SubBand_L], top_l, bottom_l, left_l, right_l); else { // Merge low-pass subband taking account of new borders SubBands[SubBand_L]-> Merge(*((LChannelC*)channel)->SubBands[SubBand_L]); SubBands[SubBand_L]->Merge(*top_l); SubBands[SubBand_L]->Merge(*bottom_l); if (lleft) SubBands[SubBand_L]->Merge(*left_l); if (lright) SubBands[SubBand_L]->Merge(*right_l); } delete top_l; delete bottom_l; if (lleft) delete left_l; if (lright) delete right_l; } else { // Merge after applying a full IFwt of the subimage and by // reconstructing the original structure. This is only the case // for one of the most coarse levels. NTChannel* ntchannel = IFwt(x1, y1_tb, x2, y2_bb); ntchannel->Merge(*channel); if (top) ntchannel->Merge(*top); if (bottom) ntchannel->Merge(*bottom); if (left) ntchannel->Merge(*left); if (right) ntchannel->Merge(*right); LChannelC *lchannel = ntchannel->PushFwtStepC(*Filter); delete ntchannel; y1_tb = Max(y1-bw-1, OffsetY); int y1_tb_l = GetEven(y1_tb); int y1_tb_h = GetOdd(y1_tb); y2_bb = Min(y2+bw+1, OffsetY+(int)Rows-1); int y2_bb_l = GetOdd(y2_bb); int y2_bb_h = GetOdd(y2_bb-1); NTChannel *lchannel_l = CropMergeH(lchannel, x1, y1_tb_l, y1_tb_h, x2, y2_bb_l, y2_bb_h); SubBands[SubBand_L]->Merge(*lchannel_l); delete lchannel_l; } } Channel *LChannelC::DownScale(u_int s, const Wavelet &wavelet) { assert(s != 0); if (s > 1) { Channel *channel; if (SubBands[SubBand_L]->IsLifted()) if (((LChannel*)SubBands[SubBand_L])-> GetTransformType() == TT_Rows) { channel = ((LChannel*)SubBands[SubBand_L])->SubBands[SubBand_L]; ((LChannel*)SubBands[SubBand_L])->SubBands[SubBand_L] = NULL; } else { NTChannel *ntchannel = ((LChannel*)SubBands[SubBand_L])->IFwt(); LChannelR *lchannel = ntchannel->PushFwtStepR(wavelet); channel = lchannel->SubBands[SubBand_L]; lchannel->SubBands[SubBand_L] = NULL; delete ntchannel; delete lchannel; } else { LChannelR *lchannel = ((NTChannel*)SubBands[SubBand_L])-> PushFwtStepR(wavelet); channel = lchannel->SubBands[SubBand_L]; lchannel->SubBands[SubBand_L] = NULL; delete lchannel; } Destroy(); return(channel->DownScale(GetOdd(s), wavelet)); } else { LChannelC *channel = this->Clone(); Destroy(); return(channel); } } waili-gpl-19990723/lib/LChannelCR.C100640 24520 25417 102573 6745120266 15157 0ustar geertnatw// // LChannelCR Class // // $Id: LChannelCR.C,v 4.6.2.1.2.1 1999/07/20 16:15:50 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include const char *LChannelCR::rcsid = "$Id: LChannelCR.C,v 4.6.2.1.2.1 1999/07/20 16:15:50 geert Exp $"; // ---------------------------------------------------------------------------- // // Lifted Channel Abstract Base Class (lifted Cols and Rows) // // ---------------------------------------------------------------------------- LChannelCR::LChannelCR(const Wavelet &filter, u_int cols, u_int rows, int offx, int offy) : LChannel(filter, 4, cols, rows) { OffsetX = offx; OffsetY = offy; int offx_l = GetEven(OffsetX); int offx_h = GetOdd(OffsetX); int offy_l = GetEven(OffsetY); int offy_h = GetOdd(OffsetY); u_int clow = Even(OffsetX)? GetEven(Cols): GetOdd(Cols); u_int chigh = Cols - clow; u_int rlow = Even(OffsetY)? GetEven(Rows): GetOdd(Rows); u_int rhigh = Rows - rlow; SubBands[SubBand_LL] = new NTChannel(clow, rlow, offx_l, offy_l); SubBands[SubBand_LH] = new NTChannel(chigh, rlow, offx_h, offy_l); SubBands[SubBand_HL] = new NTChannel(clow, rhigh, offx_l, offy_h); SubBands[SubBand_HH] = new NTChannel(chigh, rhigh, offx_h, offy_h); int lshift = filter.GetShiftL(); int hshift = filter.GetShiftH(); Shifts[SubBand_LL] = lshift+lshift; Shifts[SubBand_LH] = Shifts[SubBand_HL] = hshift+lshift; Shifts[SubBand_HH] = hshift+hshift; } LChannelCR::LChannelCR(const LChannelCR &channel) : LChannel(channel) { } void LChannelCR::GetMask(u_int &maskx, u_int &masky) const { SubBands[SubBand_LL]->GetMask(maskx, masky); maskx = maskx<<1 | 1; masky = masky<<1 | 1; } void LChannelCR::Resize(u_int cols, u_int rows) { Channel::Resize(cols, rows); u_int clow = Even(OffsetX)? GetEven(Cols): GetOdd(Cols); u_int chigh = Cols - clow; u_int rlow = Even(OffsetY)? GetEven(Rows): GetOdd(Rows); u_int rhigh = Rows - rlow; if (SubBands[SubBand_LL]) SubBands[SubBand_LL]->Resize(clow, rlow); if (SubBands[SubBand_LH]) SubBands[SubBand_LH]->Resize(chigh, rlow); if (SubBands[SubBand_HL]) SubBands[SubBand_HL]->Resize(clow, rhigh); if (SubBands[SubBand_HH]) SubBands[SubBand_HH]->Resize(chigh, rhigh); } void LChannelCR::SetOffsetX(int offx) { if (Even(offx) != Even(OffsetX)) { TransformDescriptor *transform = GetTransform(); u_int depth = GetDepth(); NTChannel *ntchannel = LChannel::IFwt(); ntchannel->SetOffsetX(offx); LChannel *lchannel = ntchannel->Fwt(transform, depth); delete ntchannel; Cols = lchannel->Cols; Rows = lchannel->Rows; OffsetX = lchannel->OffsetX; OffsetY = lchannel->OffsetY; SubBands[SubBand_LL] = lchannel->SubBands[SubBand_LL]; SubBands[SubBand_LH] = lchannel->SubBands[SubBand_LH]; SubBands[SubBand_HL] = lchannel->SubBands[SubBand_HL]; SubBands[SubBand_HH] = lchannel->SubBands[SubBand_HH]; Filter = lchannel->Filter; lchannel->SubBands[SubBand_LL] = NULL; lchannel->SubBands[SubBand_LH] = NULL; lchannel->SubBands[SubBand_HL] = NULL; lchannel->SubBands[SubBand_HH] = NULL; lchannel->Filter = NULL; delete lchannel; } else { OffsetX = offx; SubBands[SubBand_LL]->SetOffsetX(GetEven(offx)); SubBands[SubBand_LH]->SetOffsetX(GetOdd(offx)); SubBands[SubBand_HL]->SetOffsetX(GetEven(offx)); SubBands[SubBand_HH]->SetOffsetX(GetOdd(offx)); } } void LChannelCR::SetOffsetY(int offy) { if (Even(offy) != Even(OffsetY)) { TransformDescriptor *transform = GetTransform(); u_int depth = GetDepth(); NTChannel *ntchannel = LChannel::IFwt(); ntchannel->SetOffsetY(offy); LChannel *lchannel = ntchannel->Fwt(transform, depth); delete ntchannel; Cols = lchannel->Cols; Rows = lchannel->Rows; OffsetX = lchannel->OffsetX; OffsetY = lchannel->OffsetY; SubBands[SubBand_LL] = lchannel->SubBands[SubBand_LL]; SubBands[SubBand_LH] = lchannel->SubBands[SubBand_LH]; SubBands[SubBand_HL] = lchannel->SubBands[SubBand_HL]; SubBands[SubBand_HH] = lchannel->SubBands[SubBand_HH]; Filter = lchannel->Filter; lchannel->SubBands[SubBand_LL] = NULL; lchannel->SubBands[SubBand_LH] = NULL; lchannel->SubBands[SubBand_HL] = NULL; lchannel->SubBands[SubBand_HH] = NULL; lchannel->Filter = NULL; delete lchannel; } else { OffsetY = offy; SubBands[SubBand_LL]->SetOffsetY(GetEven(offy)); SubBands[SubBand_LH]->SetOffsetY(GetEven(offy)); SubBands[SubBand_HL]->SetOffsetY(GetOdd(offy)); SubBands[SubBand_HH]->SetOffsetY(GetOdd(offy)); } } void LChannelCR::Add(const Channel &channel) { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_ColsRows); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); SubBands[SubBand_LL]->Add(*((LChannel&)channel)[SubBand_LL]); SubBands[SubBand_LH]->Add(*((LChannel&)channel)[SubBand_LH]); SubBands[SubBand_HL]->Add(*((LChannel&)channel)[SubBand_HL]); SubBands[SubBand_HH]->Add(*((LChannel&)channel)[SubBand_HH]); } void LChannelCR::Subtract(const Channel &channel) { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_ColsRows); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); SubBands[SubBand_LL]->Subtract(*((LChannel&)channel)[SubBand_LL]); SubBands[SubBand_LH]->Subtract(*((LChannel&)channel)[SubBand_LH]); SubBands[SubBand_HL]->Subtract(*((LChannel&)channel)[SubBand_HL]); SubBands[SubBand_HH]->Subtract(*((LChannel&)channel)[SubBand_HH]); } LChannelCR *LChannelCR::Diff(const Channel &channel) const { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_ColsRows); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); LChannelCR *diff = new LChannelCR(*Filter); diff->Cols = Cols; diff->Rows = Rows; diff->OffsetX = OffsetX; diff->OffsetY = OffsetY; diff->SubBands[SubBand_LL] = SubBands[SubBand_LL]-> Diff(*((LChannel&)channel)[SubBand_LL]); diff->SubBands[SubBand_LH] = SubBands[SubBand_LH]-> Diff(*((LChannel&)channel)[SubBand_LH]); diff->SubBands[SubBand_HL] = SubBands[SubBand_HL]-> Diff(*((LChannel&)channel)[SubBand_HL]); diff->SubBands[SubBand_HH] = SubBands[SubBand_HH]-> Diff(*((LChannel&)channel)[SubBand_HH]); return(diff); } void LChannelCR::Lazy(const NTChannel &source) { assert(source.Data != NULL); const PixType *data = source.Data; assert(SubBands[SubBand_LL] != NULL); assert(SubBands[SubBand_LH] != NULL); assert(SubBands[SubBand_HL] != NULL); assert(SubBands[SubBand_HH] != NULL); assert(SubBands[SubBand_LL]->IsLifted() == 0); assert(SubBands[SubBand_LH]->IsLifted() == 0); assert(SubBands[SubBand_HL]->IsLifted() == 0); assert(SubBands[SubBand_HH]->IsLifted() == 0); assert(((NTChannel *)SubBands[SubBand_LL])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_LH])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_HL])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_HH])->Data != NULL); PixType *ll = ((NTChannel *)SubBands[SubBand_LL])->Data; PixType *lh = ((NTChannel *)SubBands[SubBand_LH])->Data; PixType *hl = ((NTChannel *)SubBands[SubBand_HL])->Data; PixType *hh = ((NTChannel *)SubBands[SubBand_HH])->Data; u_int clow = GetClow(); u_int chigh = GetChigh(); u_int rlow = GetRlow(); u_int rhigh = GetRhigh(); if (Even(OffsetX)) if (Even(OffsetY)) { for (u_int r = 0; r < rhigh; r++) { for (u_int c = 0; c < chigh; c++) { *ll++ = *data++; *lh++ = *data++; } if (clow != chigh) *ll++ = *data++; for (u_int c = 0; c < chigh; c++) { *hl++ = *data++; *hh++ = *data++; } if (clow != chigh) *hl++ = *data++; } if (rlow != rhigh) { for (u_int c = 0; c < chigh; c++) { *ll++ = *data++; *lh++ = *data++; } if (clow != chigh) *ll++ = *data++; } } else { for (u_int r = 0; r < rlow; r++) { for (u_int c = 0; c < chigh; c++) { *hl++ = *data++; *hh++ = *data++; } if (clow != chigh) *hl++ = *data++; for (u_int c = 0; c < chigh; c++) { *ll++ = *data++; *lh++ = *data++; } if (clow != chigh) *ll++ = *data++; } if (rlow != rhigh) { for (u_int c = 0; c < chigh; c++) { *hl++ = *data++; *hh++ = *data++; } if (clow != chigh) *hl++ = *data++; } } else if (Even(OffsetY)) { for (u_int r = 0; r < rhigh; r++) { for (u_int c = 0; c < clow; c++) { *lh++ = *data++; *ll++ = *data++; } if (clow != chigh) *lh++ = *data++; for (u_int c = 0; c < clow; c++) { *hh++ = *data++; *hl++ = *data++; } if (clow != chigh) *hh++ = *data++; } if (rlow != rhigh) { for (u_int c = 0; c < clow; c++) { *lh++ = *data++; *ll++ = *data++; } if (clow != chigh) *lh++ = *data++; } } else { for (u_int r = 0; r < rlow; r++) { for (u_int c = 0; c < clow; c++) { *hh++ = *data++; *hl++ = *data++; } if (clow != chigh) *hh++ = *data++; for (u_int c = 0; c < clow; c++) { *lh++ = *data++; *ll++ = *data++; } if (clow != chigh) *lh++ = *data++; } if (rlow != rhigh) { for (u_int c = 0; c < clow; c++) { *hh++ = *data++; *hl++ = *data++; } if (clow != chigh) *hh++ = *data++; } } } void LChannelCR::ILazy(NTChannel &dest) const { assert(dest.Data != NULL); PixType *data = dest.Data; assert(SubBands[SubBand_LL] != NULL); assert(SubBands[SubBand_LH] != NULL); assert(SubBands[SubBand_HL] != NULL); assert(SubBands[SubBand_HH] != NULL); assert(SubBands[SubBand_LL]->IsLifted() == 0); assert(SubBands[SubBand_LH]->IsLifted() == 0); assert(SubBands[SubBand_HL]->IsLifted() == 0); assert(SubBands[SubBand_HH]->IsLifted() == 0); assert(((NTChannel *)SubBands[SubBand_LL])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_LH])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_HL])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_HH])->Data != NULL); const PixType *ll = ((NTChannel *)SubBands[SubBand_LL])->Data; const PixType *lh = ((NTChannel *)SubBands[SubBand_LH])->Data; const PixType *hl = ((NTChannel *)SubBands[SubBand_HL])->Data; const PixType *hh = ((NTChannel *)SubBands[SubBand_HH])->Data; u_int clow = GetClow(); u_int chigh = GetChigh(); u_int rlow = GetRlow(); u_int rhigh = GetRhigh(); if (Even(OffsetX)) if (Even(OffsetY)) { for (u_int r = 0; r < rhigh; r++) { for (u_int c = 0; c < chigh; c++) { *data++ = *ll++; *data++ = *lh++; } if (clow != chigh) *data++ = *ll++; for (u_int c = 0; c < chigh; c++) { *data++ = *hl++; *data++ = *hh++; } if (clow != chigh) *data++ = *hl++; } if (rlow != rhigh) { for (u_int c = 0; c < chigh; c++) { *data++ = *ll++; *data++ = *lh++; } if (clow != chigh) *data++ = *ll++; } } else { for (u_int r = 0; r < rlow; r++) { for (u_int c = 0; c < chigh; c++) { *data++ = *hl++; *data++ = *hh++; } if (clow != chigh) *data++ = *hl++; for (u_int c = 0; c < chigh; c++) { *data++ = *ll++; *data++ = *lh++; } if (clow != chigh) *data++ = *ll++; } if (rlow != rhigh) { for (u_int c = 0; c < chigh; c++) { *data++ = *hl++; *data++ = *hh++; } if (clow != chigh) *data++ = *hl++; } } else if (Even(OffsetY)) { for (u_int r = 0; r < rhigh; r++) { for (u_int c = 0; c < clow; c++) { *data++ = *lh++; *data++ = *ll++; } if (clow != chigh) *data++ = *lh++; for (u_int c = 0; c < clow; c++) { *data++ = *hh++; *data++ = *hl++; } if (clow != chigh) *data++ = *hh++; } if (rlow != rhigh) { for (u_int c = 0; c < clow; c++) { *data++ = *lh++; *data++ = *ll++; } if (clow != chigh) *data++ = *lh++; } } else { for (u_int r = 0; r < rlow; r++) { for (u_int c = 0; c < clow; c++) { *data++ = *hh++; *data++ = *hl++; } if (clow != chigh) *data++ = *hh++; for (u_int c = 0; c < clow; c++) { *data++ = *lh++; *data++ = *ll++; } if (clow != chigh) *data++ = *lh++; } if (rlow != rhigh) { for (u_int c = 0; c < clow; c++) { *data++ = *hh++; *data++ = *hl++; } if (clow != chigh) *data++ = *hh++; } } } void LChannelCR::CakeWalk(void) { assert(SubBands[SubBand_LL]->IsLifted() == 0); assert(SubBands[SubBand_LH]->IsLifted() == 0); assert(SubBands[SubBand_HL]->IsLifted() == 0); assert(SubBands[SubBand_HH]->IsLifted() == 0); LiftChannelR rowsl((NTChannel *)SubBands[SubBand_LL], (NTChannel *)SubBands[SubBand_LH]); LiftChannelR rowsh((NTChannel *)SubBands[SubBand_HL], (NTChannel *)SubBands[SubBand_HH]); LiftChannelC colsl((NTChannel *)SubBands[SubBand_LL], (NTChannel *)SubBands[SubBand_HL]); LiftChannelC colsh((NTChannel *)SubBands[SubBand_LH], (NTChannel *)SubBands[SubBand_HH]); // Transform the Rows Filter->CakeWalk(rowsl); Filter->CakeWalk(rowsh); // Transform the Columns Filter->CakeWalk(colsl); Filter->CakeWalk(colsh); } void LChannelCR::ICakeWalk(void) { assert(SubBands[SubBand_LL]->IsLifted() == 0); assert(SubBands[SubBand_LH]->IsLifted() == 0); assert(SubBands[SubBand_HL]->IsLifted() == 0); assert(SubBands[SubBand_HH]->IsLifted() == 0); LiftChannelR rowsl((NTChannel *)SubBands[SubBand_LL], (NTChannel *)SubBands[SubBand_LH]); LiftChannelR rowsh((NTChannel *)SubBands[SubBand_HL], (NTChannel *)SubBands[SubBand_HH]); LiftChannelC colsl((NTChannel *)SubBands[SubBand_LL], (NTChannel *)SubBands[SubBand_HL]); LiftChannelC colsh((NTChannel *)SubBands[SubBand_LH], (NTChannel *)SubBands[SubBand_HH]); // Transform the Columns Filter->ICakeWalk(colsl); Filter->ICakeWalk(colsh); // Transform the Rows Filter->ICakeWalk(rowsl); Filter->ICakeWalk(rowsh); } void LChannelCR::Zip(const LChannelCR &channel_lh, const LChannelCR &channel_hl, const LChannelCR &channel_hh) { LChannelCR *dest = new LChannelCR(*Filter, Cols<<1, Rows<<1, OffsetX<<1, OffsetY<<1); LChannelCR *subband = new LChannelCR(*Filter); subband->Cols = Cols; subband->Rows = Rows; subband->OffsetX = OffsetX; subband->OffsetY = OffsetY; subband->SubBands[SubBand_LL] = SubBands[SubBand_LL]; subband->SubBands[SubBand_LH] = channel_lh.SubBands[SubBand_LL]; subband->SubBands[SubBand_HL] = channel_hl.SubBands[SubBand_LL]; subband->SubBands[SubBand_HH] = channel_hh.SubBands[SubBand_LL]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_LL]); subband->SubBands[SubBand_LL] = channel_lh.SubBands[SubBand_LH]; subband->SubBands[SubBand_LH] = SubBands[SubBand_LH]; subband->SubBands[SubBand_HL] = channel_hh.SubBands[SubBand_LH]; subband->SubBands[SubBand_HH] = channel_hl.SubBands[SubBand_LH]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_LH]); subband->SubBands[SubBand_LL] = channel_hl.SubBands[SubBand_HL]; subband->SubBands[SubBand_LH] = channel_hh.SubBands[SubBand_HL]; subband->SubBands[SubBand_HL] = SubBands[SubBand_HL]; subband->SubBands[SubBand_HH] = channel_lh.SubBands[SubBand_HL]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_HL]); subband->SubBands[SubBand_LL] = channel_hh.SubBands[SubBand_HH]; subband->SubBands[SubBand_LH] = channel_hl.SubBands[SubBand_HH]; subband->SubBands[SubBand_HL] = channel_lh.SubBands[SubBand_HH]; subband->SubBands[SubBand_HH] = SubBands[SubBand_HH]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_HH]); subband->SubBands[SubBand_LL] = NULL; subband->SubBands[SubBand_LH] = NULL; subband->SubBands[SubBand_HL] = NULL; subband->SubBands[SubBand_HH] = NULL; delete subband; Cols = dest->Cols; Rows = dest->Rows; OffsetX = dest->OffsetX; OffsetY = dest->OffsetY; SubBands[SubBand_LL] = dest->SubBands[SubBand_LL]; SubBands[SubBand_LH] = dest->SubBands[SubBand_LH]; SubBands[SubBand_HL] = dest->SubBands[SubBand_HL]; SubBands[SubBand_HH] = dest->SubBands[SubBand_HH]; dest->SubBands[SubBand_LL] = NULL; dest->SubBands[SubBand_LH] = NULL; dest->SubBands[SubBand_HL] = NULL; dest->SubBands[SubBand_HH] = NULL; delete dest; } NTChannel *LChannelCR::IFwt(int x1, int y1, int x2, int y2) const { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); // Calculate new coordinates taking account of the needed borders int xb1 = Max((int)x1-bw-1, OffsetX); int yb1 = Max((int)y1-bw-1, OffsetY); int xb2 = Min((int)x2+bw+1, OffsetX+(int)Cols-1); int yb2 = Min((int)y2+bw+1, OffsetY+(int)Rows-1); LChannelCR *lchannel = new LChannelCR(*Filter); lchannel->Cols = xb2-xb1+1; lchannel->Rows = yb2-yb1+1; lchannel->OffsetX = xb1; lchannel->OffsetY = yb1; int xb1_l = GetEven(xb1); int yb1_l = GetEven(yb1); int xb1_h = GetOdd(xb1); int yb1_h = GetOdd(yb1); int xb2_l = GetOdd(xb2); int yb2_l = GetOdd(yb2); int xb2_h = GetOdd(xb2-1); int yb2_h = GetOdd(yb2-1); // Crop subimages of all subbands if (SubBands[SubBand_LL]->IsLifted()) lchannel->SubBands[SubBand_LL] = ((LChannel*)SubBands[SubBand_LL])-> IFwt(xb1_l, yb1_l, xb2_l, yb2_l); else lchannel->SubBands[SubBand_LL] = SubBands[SubBand_LL]->Crop(xb1_l, yb1_l, xb2_l, yb2_l); lchannel->SubBands[SubBand_LH] = SubBands[SubBand_LH]->Crop(xb1_h, yb1_l, xb2_h, yb2_l); lchannel->SubBands[SubBand_HL] = SubBands[SubBand_HL]->Crop(xb1_l, yb1_h, xb2_l, yb2_h); lchannel->SubBands[SubBand_HH] = SubBands[SubBand_HH]->Crop(xb1_h, yb1_h, xb2_h, yb2_h); // Apply invers transform and crop redundant borders NTChannel *ntchannel = lchannel->IFwtStep(); NTChannel *channel = ntchannel->Crop(x1, y1, x2, y2); delete lchannel; delete ntchannel; return(channel); } NTChannel *LChannelCR::CropMergeH(LChannelCR *channel, int x1_l, int x1_h, int y1_l, int y1_h, int x2_l, int x2_h, int y2_l, int y2_h) { assert(x1_l <= x2_l); assert(x1_h <= x2_h); assert(y1_l <= y2_l); assert(y1_h <= y2_h); // Crop the specified subimages of all subbands // None of the subbands is tranformed!!!!! NTChannel *channel_ll = ((NTChannel*)channel->SubBands[SubBand_LL])-> Crop(x1_l, y1_l, x2_l, y2_l); NTChannel *channel_lh = ((NTChannel*)channel->SubBands[SubBand_LH])-> Crop(x1_h, y1_l, x2_h, y2_l); NTChannel *channel_hl = ((NTChannel*)channel->SubBands[SubBand_HL])-> Crop(x1_l, y1_h, x2_l, y2_h); NTChannel *channel_hh = ((NTChannel*)channel->SubBands[SubBand_HH])-> Crop(x1_h, y1_h, x2_h, y2_h); // Merge high-pass subbands in the subbands of the current channel SubBands[SubBand_LH]->Merge(*channel_lh); SubBands[SubBand_HL]->Merge(*channel_hl); SubBands[SubBand_HH]->Merge(*channel_hh); delete channel; delete channel_lh; delete channel_hl; delete channel_hh; return(channel_ll); } LChannelCR *LChannelCR::Crop_rec(int x1, int y1, int x2, int y2, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) const { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); LChannelCR *channel; int x1_l = GetEven(x1); int y1_l = GetEven(y1); int x1_h = GetOdd(x1); int y1_h = GetOdd(y1); int x2_l = GetOdd(x2); int y2_l = GetOdd(y2); int x2_h = GetOdd(x2-1); int y2_h = GetOdd(y2-1); // Calculate new coordinates taking account of the needed borders int y2_tb = top? y1+(bw<<1)+(int)top->Rows: y1+(bw<<1); int y1_bb = bottom? y2-(bw<<1)-(int)bottom->Rows: y2-(bw<<1); int x2_lb = left? x1+(bw<<1)+(int)left->Cols: x1+(bw<<1); int x1_rb = right? x2-(bw<<1)-(int)right->Cols: x2-(bw<<1); if (y1_bb-y2_tb > 1 && x1_rb-x2_lb > 1) { channel = new LChannelCR(*Filter); channel->Cols = x2-x1+1; channel->Rows = y2-y1+1; channel->OffsetX = x1; channel->OffsetY = y1; // Crop all high-pass subbands (without borders) channel->SubBands[SubBand_LH] = SubBands[SubBand_LH]->Crop(x1_h, y1_l, x2_h, y2_l); channel->SubBands[SubBand_HL] = SubBands[SubBand_HL]->Crop(x1_l, y1_h, x2_l, y2_h); channel->SubBands[SubBand_HH] = SubBands[SubBand_HH]->Crop(x1_h, y1_h, x2_h, y2_h); // Adjust top border according to the higher resolution level NTChannel *nttop = IFwt(x1, y1, x2, y2_tb); if (top) nttop->Merge(*top); if (left) CopyRect(left->Data, left->Cols, 0, 0, nttop->Data, nttop->Cols, 0, 0, left->Cols, nttop->Rows); if (right) CopyRect(right->Data, right->Cols, 0, 0, nttop->Data, nttop->Cols, nttop->Cols-right->Cols, 0, right->Cols, nttop->Rows); LChannelCR *ltop = nttop->PushFwtStepCR(*Filter); delete nttop; y2_tb -= bw; int y2_tb_l = GetOdd(y2_tb); int y2_tb_h = GetOdd(y2_tb-1); NTChannel *top_ll = channel->CropMergeH(ltop, x1_l, x1_h, y1_l, y1_h, x2_l, x2_h, y2_tb_l, y2_tb_h); // Adjust bottom border according to the higher resolution level NTChannel *ntbottom = IFwt(x1, y1_bb, x2, y2); if (bottom) ntbottom->Merge(*bottom); if (left) CopyRect(left->Data, left->Cols, 0, left->Rows-ntbottom->Rows, ntbottom->Data, ntbottom->Cols, 0, 0, left->Cols, ntbottom->Rows); if (right) CopyRect(right->Data, right->Cols, 0, right->Rows-ntbottom->Rows, ntbottom->Data, ntbottom->Cols, ntbottom->Cols-right->Cols, 0, right->Cols, ntbottom->Rows); LChannelCR *lbottom = ntbottom->PushFwtStepCR(*Filter); delete ntbottom; y1_bb += bw; int y1_bb_l = GetEven(y1_bb); int y1_bb_h = GetOdd(y1_bb); NTChannel *bottom_ll = channel->CropMergeH(lbottom, x1_l, x1_h, y1_bb_l, y1_bb_h, x2_l, x2_h, y2_l, y2_h); // Adjust left border according to the higher resolution level NTChannel *ntleft = IFwt(x1, y1, x2_lb, y2); if (left) ntleft->Merge(*left); if (top) CopyRect(top->Data, top->Cols, 0, 0, ntleft->Data, ntleft->Cols, 0, 0, ntleft->Cols, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, 0, 0, ntleft->Data, ntleft->Cols, 0, ntleft->Rows-bottom->Rows, ntleft->Cols, bottom->Rows); LChannelCR *lleft = ntleft->PushFwtStepCR(*Filter); delete ntleft; x2_lb -= bw; int x2_lb_l = GetOdd(x2_lb); int x2_lb_h = GetOdd(x2_lb-1); NTChannel *left_ll = channel->CropMergeH(lleft, x1_l, x1_h, y1_l, y1_h, x2_lb_l, x2_lb_h, y2_l, y2_h); // Adjust right border according to the higher resolution level NTChannel *ntright = IFwt(x1_rb, y1, x2, y2); if (right) ntright->Merge(*right); if (top) CopyRect(top->Data, top->Cols, top->Cols-ntright->Cols, 0, ntright->Data, ntright->Cols, 0, 0, ntright->Cols, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, bottom->Cols-ntright->Cols, 0, ntright->Data, ntright->Cols, 0, ntright->Rows-bottom->Rows, ntright->Cols, bottom->Rows); LChannelCR *lright = ntright->PushFwtStepCR(*Filter); delete ntright; x1_rb += bw; int x1_rb_l = GetEven(x1_rb); int x1_rb_h = GetOdd(x1_rb); NTChannel *right_ll = channel->CropMergeH(lright, x1_rb_l, x1_rb_h, y1_l, y1_h, x2_l, x2_h, y2_l, y2_h); if (SubBands[SubBand_LL]->IsLifted()) // Crop coarser level taking account of new borders channel->SubBands[SubBand_LL] = ((LChannel*)SubBands[SubBand_LL])-> Crop_rec(x1_l, y1_l, x2_l, y2_l, top_ll, bottom_ll, left_ll, right_ll); else { // Crop low-pass subband taking account of new borders channel->SubBands[SubBand_LL] = SubBands[SubBand_LL]-> Crop(x1_l, y1_l, x2_l, y2_l); channel->SubBands[SubBand_LL]->Merge(*top_ll); channel->SubBands[SubBand_LL]->Merge(*bottom_ll); channel->SubBands[SubBand_LL]->Merge(*left_ll); channel->SubBands[SubBand_LL]->Merge(*right_ll); } delete top_ll; delete bottom_ll; delete left_ll; delete right_ll; } else { // Crop after applying a full IFwt of the subimage and by // reconstructing the original structure. This is only the case // for one of the most coarse levels. TransformDescriptor *transform = GetTransform(); u_int depth = GetDepth(); NTChannel* ntchannel = IFwt(x1, y1, x2, y2); if (top) ntchannel->Merge(*top); if (bottom) ntchannel->Merge(*bottom); if (left) ntchannel->Merge(*left); if (right) ntchannel->Merge(*right); channel = (LChannelCR*)ntchannel->Fwt(transform, depth); delete[] transform; delete ntchannel; } return(channel); } void LChannelCR::Merge_rec(const Channel *channel, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); int ch_x1 = channel->GetOffsetX(); int ch_y1 = channel->GetOffsetY(); int ch_x2 = ch_x1+(int)channel->GetCols()-1; int ch_y2 = ch_y1+(int)channel->GetRows()-1; int x1, y1, x2, y2, y1_tb, y2_tb, y1_bb, y2_bb, x1_lb, x2_lb, x1_rb, x2_rb; // Calculate inner and outer border coordinates if (top) { y1 = top->OffsetY; y1_tb = y1-(bw<<1)-1; y2_tb = y1+(int)top->Rows+(bw<<1); } else { y1 = ch_y1; y1_tb = y1-(bw<<1)-1; y2_tb = y1+(bw<<1); } if (bottom) { y2 = bottom->OffsetY+(int)bottom->Rows-1; y1_bb = y2-(int)bottom->Rows-(bw<<1); y2_bb = y2+(bw<<1)+1; } else { y2 = ch_y2; y1_bb = y2-(bw<<1); y2_bb = y2+(bw<<1)+1; } if (left) { x1 = left->OffsetX; x1_lb = x1-(bw<<1)-1; x2_lb = x1+(int)left->Cols+(bw<<1); } else { x1 = ch_x1; x1_lb = x1-(bw<<1)-1; x2_lb = x1+(bw<<1); } if (right) { x2 = right->OffsetX+(int)right->Cols-1; x1_rb = x2-(int)right->Cols-(bw<<1); x2_rb = x2+(bw<<1)+1; } else { x2 = ch_x2; x1_rb = x2-(bw<<1); x2_rb = x2+(bw<<1)+1; } y1_tb = Max(y1_tb, OffsetY); y2_bb = Min(y2_bb, OffsetY+(int)Rows-1); x1_lb = Max(x1_lb, OffsetX); x2_rb = Min(x2_rb, OffsetX+(int)Cols-1); if (y1_bb-y2_tb > 1 && x1_rb-x2_lb > 1 && channel->IsLifted() && ((LChannel*)channel)->GetTransformType() == TT_ColsRows) { // Adjust top border according to the higher resolution level NTChannel *nttop = IFwt(x1_lb, y1_tb, x2_rb, y2_tb); NTChannel *ntch_top = ((LChannel*)channel)-> IFwt(ch_x1, ch_y1, ch_x2, y2_tb); nttop->Merge(*ntch_top); delete ntch_top; if (top) nttop->Merge(*top); if (left) CopyRect(left->Data, left->Cols, 0, 0, nttop->Data, nttop->Cols, x1-x1_lb, y1-y1_tb, left->Cols, y2_tb-y1+1); if (right) CopyRect(right->Data, right->Cols, 0, 0, nttop->Data, nttop->Cols, x2-right->Cols+1-x1_lb, y1-y1_tb, right->Cols, y2_tb-y1+1); LChannelCR *ltop = nttop->PushFwtStepCR(*Filter); delete nttop; // Adjust bottom border according to the higher resolution level NTChannel *ntbottom = IFwt(x1_lb, y1_bb, x2_rb, y2_bb); NTChannel *ntch_bottom = ((LChannel*)channel)-> IFwt(ch_x1, y1_bb, ch_x2, ch_y2); ntbottom->Merge(*ntch_bottom); delete ntch_bottom; if (bottom) ntbottom->Merge(*bottom); if (left) CopyRect(left->Data, left->Cols, 0, y1_bb-y1, ntbottom->Data, ntbottom->Cols, x1-x1_lb, 0, left->Cols, y2-y1_bb+1); if (right) CopyRect(right->Data, right->Cols, 0, y1_bb-y1, ntbottom->Data, ntbottom->Cols, x2-right->Cols+1-x1_lb, 0, right->Cols, y2-y1_bb+1); LChannelCR *lbottom = ntbottom->PushFwtStepCR(*Filter); delete ntbottom; // Adjust left border according to the higher resolution level NTChannel *ntleft = IFwt(x1_lb, y1_tb, x2_lb, y2_bb); NTChannel *ntch_left = ((LChannel*)channel)-> IFwt(ch_x1, ch_y1, x2_lb, ch_y2); ntleft->Merge(*ntch_left); delete ntch_left; if (left) ntleft->Merge(*left); if (top) CopyRect(top->Data, top->Cols, 0, 0, ntleft->Data, ntleft->Cols, x1-x1_lb, y1-y1_tb, x2_lb-x1+1, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, 0, 0, ntleft->Data, ntleft->Cols, x1-x1_lb, y2-bottom->Rows+1-y1_tb, x2_lb-x1+1, bottom->Rows); LChannelCR *lleft = ntleft->PushFwtStepCR(*Filter); delete ntleft; // Adjust right border according to the higher resolution level NTChannel *ntright = IFwt(x1_rb, y1_tb, x2_rb, y2_bb); NTChannel *ntch_right = ((LChannel*)channel)-> IFwt(x1_rb, ch_y1, ch_x2, ch_y2); ntright->Merge(*ntch_right); delete ntch_right; if (right) ntright->Merge(*right); if (top) CopyRect(top->Data, top->Cols, x1_rb-x1, 0, ntright->Data, ntright->Cols, 0, y1-y1_tb, x2-x1_rb+1, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, x1_rb-x1, 0, ntright->Data, ntright->Cols, 0, y2-bottom->Rows+1-y1_tb, x2-x1_rb+1, bottom->Rows); LChannelCR *lright = ntright->PushFwtStepCR(*Filter); delete ntright; // Merge the high-pass border-independent (center) subimage parts SubBands[SubBand_LH]-> Merge(*((LChannelCR*)channel)->SubBands[SubBand_LH]); SubBands[SubBand_HL]-> Merge(*((LChannelCR*)channel)->SubBands[SubBand_HL]); SubBands[SubBand_HH]-> Merge(*((LChannelCR*)channel)->SubBands[SubBand_HH]); // Recalculate inner and outer border coordinates // (without redundant border) y1_tb = Max(y1-bw-1, OffsetY); int y1_tb_l = GetEven(y1_tb); int y1_tb_h = GetOdd(y1_tb); y2_bb = Min(y2+bw+1, OffsetY+(int)Rows-1); int y2_bb_l = GetOdd(y2_bb); int y2_bb_h = GetOdd(y2_bb-1); x1_lb = Max(x1-bw-1, OffsetX); int x1_lb_l = GetEven(x1_lb); int x1_lb_h = GetOdd(x1_lb); x2_rb = Min(x2+bw+1, OffsetX+(int)Cols-1); int x2_rb_l = GetOdd(x2_rb); int x2_rb_h = GetOdd(x2_rb-1); y2_tb -= bw; int y2_tb_l = GetOdd(y2_tb); int y2_tb_h = GetOdd(y2_tb-1); y1_bb += bw; int y1_bb_l = GetEven(y1_bb); int y1_bb_h = GetOdd(y1_bb); x2_lb -= bw; int x2_lb_l = GetOdd(x2_lb); int x2_lb_h = GetOdd(x2_lb-1); x1_rb += bw; int x1_rb_l = GetEven(x1_rb); int x1_rb_h = GetOdd(x1_rb); // Merge specified border parts for the high-pass subimages and // crop the low-pass parts NTChannel *top_ll = CropMergeH(ltop, x1_lb_l, x1_lb_h, y1_tb_l, y1_tb_h, x2_rb_l, x2_rb_h, y2_tb_l, y2_tb_h); NTChannel *bottom_ll = CropMergeH(lbottom, x1_lb_l, x1_lb_h, y1_bb_l, y1_bb_h, x2_rb_l, x2_rb_h, y2_bb_l, y2_bb_h); NTChannel *left_ll = CropMergeH(lleft, x1_lb_l, x1_lb_h, y1_tb_l, y1_tb_h, x2_lb_l, x2_lb_h, y2_bb_l, y2_bb_h); NTChannel *right_ll = CropMergeH(lright, x1_rb_l, x1_rb_h, y1_tb_l, y1_tb_h, x2_rb_l, x2_rb_h, y2_bb_l, y2_bb_h); if (SubBands[SubBand_LL]->IsLifted()) // Merge coarser level taking account of new borders ((LChannel*)SubBands[SubBand_LL])-> Merge_rec(((LChannelCR*)channel)->SubBands[SubBand_LL], top_ll, bottom_ll, left_ll, right_ll); else { // Merge low-pass subband taking account of new borders SubBands[SubBand_LL]-> Merge(*((LChannelCR*)channel)->SubBands[SubBand_LL]); SubBands[SubBand_LL]->Merge(*top_ll); SubBands[SubBand_LL]->Merge(*bottom_ll); SubBands[SubBand_LL]->Merge(*left_ll); SubBands[SubBand_LL]->Merge(*right_ll); } delete top_ll; delete bottom_ll; delete left_ll; delete right_ll; } else { // Merge after applying a full IFwt of the subimage and by // reconstructing the original structure. This is only the case // for one of the most coarse levels. NTChannel* ntchannel = IFwt(x1_lb, y1_tb, x2_rb, y2_bb); ntchannel->Merge(*channel); if (top) ntchannel->Merge(*top); if (bottom) ntchannel->Merge(*bottom); if (left) ntchannel->Merge(*left); if (right) ntchannel->Merge(*right); LChannelCR *lchannel = ntchannel->PushFwtStepCR(*Filter); delete ntchannel; y1_tb = Max(y1-bw-1, OffsetY); int y1_tb_l = GetEven(y1_tb); int y1_tb_h = GetOdd(y1_tb); y2_bb = Min(y2+bw+1, OffsetY+(int)Rows-1); int y2_bb_l = GetOdd(y2_bb); int y2_bb_h = GetOdd(y2_bb-1); x1_lb = Max(x1-bw-1, OffsetX); int x1_lb_l = GetEven(x1_lb); int x1_lb_h = GetOdd(x1_lb); x2_rb = Min(x2+bw+1, OffsetX+(int)Cols-1); int x2_rb_l = GetOdd(x2_rb); int x2_rb_h = GetOdd(x2_rb-1); NTChannel *lchannel_ll = CropMergeH(lchannel, x1_lb_l, x1_lb_h, y1_tb_l, y1_tb_h, x2_rb_l, x2_rb_h, y2_bb_l, y2_bb_h); SubBands[SubBand_LL]->Merge(*lchannel_ll); delete lchannel_ll; } } Channel *LChannelCR::DownScale(u_int s, const Wavelet &wavelet) { assert(s != 0); if (s > 1) { Channel *channel; channel = SubBands[SubBand_LL]; SubBands[SubBand_LL] = NULL; Destroy(); return(channel->DownScale(GetOdd(s), wavelet)); } else { LChannelCR *channel = this->Clone(); Destroy(); return(channel); } } waili-gpl-19990723/lib/LChannelR.C100640 24520 25417 52210 6745120267 15025 0ustar geertnatw// // LChannelR Class // // $Id: LChannelR.C,v 4.6.2.1.2.1 1999/07/20 16:15:51 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include const char *LChannelR::rcsid = "$Id: LChannelR.C,v 4.6.2.1.2.1 1999/07/20 16:15:51 geert Exp $"; // ---------------------------------------------------------------------------- // // Lifted Channel Abstract Base Class (lifted Rows) // // ---------------------------------------------------------------------------- LChannelR::LChannelR(const Wavelet &filter, u_int cols, u_int rows, int offx, int offy) : LChannel(filter, 2, cols, rows) { OffsetX = offx; OffsetY = offy; int offx_l = GetEven(OffsetX); int offx_h = GetOdd(OffsetX); u_int clow = Even(OffsetX)? GetEven(Cols): GetOdd(Cols); u_int chigh = Cols - clow; SubBands[SubBand_L] = new NTChannel(clow, Rows, offx_l, OffsetY); SubBands[SubBand_H] = new NTChannel(chigh, Rows, offx_h, OffsetY); Shifts[SubBand_L] = filter.GetShiftL(); Shifts[SubBand_H] = filter.GetShiftH(); } LChannelR::LChannelR(const LChannelR &channel) : LChannel(channel) { } void LChannelR::GetMask(u_int &maskx, u_int &masky) const { SubBands[SubBand_L]->GetMask(maskx, masky); maskx = maskx<<1 | 1; } void LChannelR::Resize(u_int cols, u_int rows) { Channel::Resize(cols, rows); u_int clow = Even(OffsetX)? GetEven(Cols): GetOdd(Cols); u_int chigh = Cols - clow; if (SubBands[SubBand_L]) SubBands[SubBand_L]->Resize(clow, Rows); if (SubBands[SubBand_H]) SubBands[SubBand_H]->Resize(chigh, Rows); } void LChannelR::SetOffsetX(int offx) { if (Even(offx) != Even(OffsetX)) { TransformDescriptor *transform = GetTransform(); u_int depth = GetDepth(); NTChannel *ntchannel = LChannel::IFwt(); ntchannel->SetOffsetX(offx); LChannel *lchannel = ntchannel->Fwt(transform, depth); delete ntchannel; Cols = lchannel->Cols; Rows = lchannel->Rows; OffsetX = lchannel->OffsetX; OffsetY = lchannel->OffsetY; SubBands[SubBand_L] = lchannel->SubBands[SubBand_L]; SubBands[SubBand_H] = lchannel->SubBands[SubBand_H]; Filter = lchannel->Filter; lchannel->SubBands[SubBand_L] = NULL; lchannel->SubBands[SubBand_H] = NULL; lchannel->Filter = NULL; delete lchannel; } else { OffsetX = offx; SubBands[SubBand_L]->SetOffsetX(GetEven(offx)); SubBands[SubBand_H]->SetOffsetX(GetOdd(offx)); } } void LChannelR::SetOffsetY(int offy) { OffsetY = offy; SubBands[SubBand_L]->SetOffsetY(offy); SubBands[SubBand_H]->SetOffsetY(offy); } void LChannelR::Add(const Channel &channel) { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_Rows); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); SubBands[SubBand_L]->Add(*((LChannel&)channel)[SubBand_L]); SubBands[SubBand_H]->Add(*((LChannel&)channel)[SubBand_H]); } void LChannelR::Subtract(const Channel &channel) { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_Rows); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); SubBands[SubBand_L]->Subtract(*((LChannel&)channel)[SubBand_L]); SubBands[SubBand_H]->Subtract(*((LChannel&)channel)[SubBand_H]); } LChannelR *LChannelR::Diff(const Channel &channel) const { assert(channel.IsLifted()); assert(((LChannel&)channel).GetTransformType() == TT_Rows); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); LChannelR *diff = new LChannelR(*Filter); diff->Cols = Cols; diff->Rows = Rows; diff->OffsetX = OffsetX; diff->OffsetY = OffsetY; diff->SubBands[SubBand_L] = SubBands[SubBand_L]-> Diff(*((LChannel&)channel)[SubBand_L]); diff->SubBands[SubBand_H] = SubBands[SubBand_H]-> Diff(*((LChannel&)channel)[SubBand_H]); return(diff); } void LChannelR::Lazy(const NTChannel &source) { assert(source.Data != NULL); const PixType *data = source.Data; assert(SubBands[SubBand_L] != NULL); assert(SubBands[SubBand_H] != NULL); assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); assert(((NTChannel *)SubBands[SubBand_L])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_H])->Data != NULL); PixType *l = ((NTChannel *)SubBands[SubBand_L])->Data; PixType *h = ((NTChannel *)SubBands[SubBand_H])->Data; u_int low = GetClow(); u_int high = GetChigh(); if (Even(OffsetX)) for (u_int r = 0; r < Rows; r++) { for (u_int c = 0; c < high; c++) { *l++ = *data++; *h++ = *data++; } if (low != high) *l++ = *data++; } else for (u_int r = 0; r < Rows; r++) { for (u_int c = 0; c < low; c++) { *h++ = *data++; *l++ = *data++; } if (low != high) *h++ = *data++; } } void LChannelR::ILazy(NTChannel &dest) const { assert(dest.Data != NULL); PixType *data = dest.Data; assert(SubBands[SubBand_L] != NULL); assert(SubBands[SubBand_H] != NULL); assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); assert(((NTChannel *)SubBands[SubBand_L])->Data != NULL); assert(((NTChannel *)SubBands[SubBand_H])->Data != NULL); const PixType *l = ((NTChannel *)SubBands[SubBand_L])->Data; const PixType *h = ((NTChannel *)SubBands[SubBand_H])->Data; u_int low = GetClow(); u_int high = GetChigh(); if (Even(OffsetX)) for (u_int r = 0; r < Rows; r++) { for (u_int c = 0; c < high; c++) { *data++ = *l++; *data++ = *h++; } if (low != high) *data++ = *l++; } else for (u_int r = 0; r < Rows; r++) { for (u_int c = 0; c < low; c++) { *data++ = *h++; *data++ = *l++; } if (low != high) *data++ = *h++; } } void LChannelR::CakeWalk(void) { assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); LiftChannelR lifting((NTChannel *)SubBands[SubBand_L], (NTChannel *)SubBands[SubBand_H]); Filter->CakeWalk(lifting); } void LChannelR::ICakeWalk(void) { assert(SubBands[SubBand_L]->IsLifted() == 0); assert(SubBands[SubBand_H]->IsLifted() == 0); LiftChannelR lifting((NTChannel *)SubBands[SubBand_L], (NTChannel *)SubBands[SubBand_H]); Filter->ICakeWalk(lifting); } void LChannelR::Zip(const LChannelR &channel) { LChannelR *dest = new LChannelR(*Filter, Cols<<1, Rows, OffsetX<<1, OffsetY); LChannelR *subband = new LChannelR(*Filter); subband->Cols = Cols; subband->Rows = Rows; subband->OffsetX = OffsetX; subband->OffsetY = OffsetY; subband->SubBands[SubBand_L] = SubBands[SubBand_L]; subband->SubBands[SubBand_H] = channel.SubBands[SubBand_L]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_L]); subband->SubBands[SubBand_L] = channel.SubBands[SubBand_H]; subband->SubBands[SubBand_H] = SubBands[SubBand_H]; subband->ILazy(*(NTChannel*)dest->SubBands[SubBand_H]); subband->SubBands[SubBand_L] = NULL; subband->SubBands[SubBand_H] = NULL; delete subband; Cols = dest->Cols; OffsetX = dest->OffsetX; SubBands[SubBand_L] = dest->SubBands[SubBand_L]; SubBands[SubBand_H] = dest->SubBands[SubBand_H]; dest->SubBands[SubBand_L] = NULL; dest->SubBands[SubBand_H] = NULL; delete dest; } NTChannel *LChannelR::IFwt(int x1, int y1, int x2, int y2) const { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); // Calculate new coordinates taking account of the needed borders int xb1 = Max((int)x1-bw-1, OffsetX); int xb2 = Min((int)x2+bw+1, OffsetX+(int)Cols-1); LChannelR *lchannel = new LChannelR(*Filter); lchannel->Cols = xb2-xb1+1; lchannel->Rows = y2-y1+1; lchannel->OffsetX = xb1; lchannel->OffsetY = y1; int xb1_l = GetEven(xb1); int xb1_h = GetOdd(xb1); int xb2_l = GetOdd(xb2); int xb2_h = GetOdd(xb2-1); // Crop subimages of all subbands if (SubBands[SubBand_L]->IsLifted()) lchannel->SubBands[SubBand_L] = ((LChannel*)SubBands[SubBand_L])-> IFwt(xb1_l, y1, xb2_l, y2); else lchannel->SubBands[SubBand_L] = SubBands[SubBand_L]->Crop(xb1_l, y1, xb2_l, y2); lchannel->SubBands[SubBand_H] = SubBands[SubBand_H]->Crop(xb1_h, y1, xb2_h, y2); // Apply invers transform and crop redundant borders NTChannel *ntchannel = lchannel->IFwtStep(); NTChannel *channel = ntchannel->Crop(x1, y1, x2, y2); delete lchannel; delete ntchannel; return(channel); } NTChannel *LChannelR::CropMergeH(LChannelR *channel, int x1_l, int x1_h, int y1, int x2_l, int x2_h, int y2) { assert(x1_l <= x2_l); assert(x1_h <= x2_h); assert(y1 <= y2); // Crop the specified subimages of both subbands // None of the subbands is tranformed!!!!! NTChannel *channel_l = ((NTChannel*)channel->SubBands[SubBand_L])-> Crop(x1_l, y1, x2_l, y2); NTChannel *channel_h = ((NTChannel*)channel->SubBands[SubBand_H])-> Crop(x1_h, y1, x2_h, y2); // Merge high-pass subband in the subband of the current channel SubBands[SubBand_H]->Merge(*channel_h); delete channel; delete channel_h; return(channel_l); } LChannelR *LChannelR::Crop_rec(int x1, int y1, int x2, int y2, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) const { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); LChannelR *channel; int x1_l = GetEven(x1); int x1_h = GetOdd(x1); int x2_l = GetOdd(x2); int x2_h = GetOdd(x2-1); // Calculate new coordinates taking account of the needed borders int x2_lb = left? x1+(bw<<1)+(int)left->Cols: x1+(bw<<1); int x1_rb = right? x2-(bw<<1)-(int)right->Cols: x2-(bw<<1); if (x1_rb-x2_lb > 1) { channel = new LChannelR(*Filter); channel->Cols = x2-x1+1; channel->Rows = y2-y1+1; channel->OffsetX = x1; channel->OffsetY = y1; // Crop the high-pass subband (without borders) channel->SubBands[SubBand_H] = SubBands[SubBand_H]->Crop(x1_h, y1, x2_h, y2); // Adjust left border according to the higher resolution level NTChannel *ntleft = IFwt(x1, y1, x2_lb, y2); if (left) ntleft->Merge(*left); if (top) CopyRect(top->Data, top->Cols, 0, 0, ntleft->Data, ntleft->Cols, 0, 0, ntleft->Cols, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, 0, 0, ntleft->Data, ntleft->Cols, 0, ntleft->Rows-bottom->Rows, ntleft->Cols, bottom->Rows); LChannelR *lleft = ntleft->PushFwtStepR(*Filter); delete ntleft; x2_lb -= bw; int x2_lb_l = GetOdd(x2_lb); int x2_lb_h = GetOdd(x2_lb-1); NTChannel *left_l = channel->CropMergeH(lleft, x1_l, x1_h, y1, x2_lb_l, x2_lb_h, y2); // Adjust right border according to the higher resolution level NTChannel *ntright = IFwt(x1_rb, y1, x2, y2); if (right) ntright->Merge(*right); if (top) CopyRect(top->Data, top->Cols, top->Cols-ntright->Cols, 0, ntright->Data, ntright->Cols, 0, 0, ntright->Cols, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, bottom->Cols-ntright->Cols, 0, ntright->Data, ntright->Cols, 0, ntright->Rows-bottom->Rows, ntright->Cols, bottom->Rows); LChannelR *lright = ntright->PushFwtStepR(*Filter); delete ntright; x1_rb += bw; int x1_rb_l = GetEven(x1_rb); int x1_rb_h = GetOdd(x1_rb); NTChannel *right_l = channel->CropMergeH(lright, x1_rb_l, x1_rb_h, y1, x2_l, x2_h, y2); // Adjust top border according to the higher resolution level NTChannel *top_l = NULL; if (top) { LChannelR *ltop = top->PushFwtStepR(*Filter); top_l = (NTChannel*)ltop->SubBands[SubBand_L]; ltop->SubBands[SubBand_L] = NULL; channel->SubBands[SubBand_H]-> Merge(*(NTChannel*)ltop->SubBands[SubBand_H]); delete ltop; } // Adjust bottom border according to the higher resolution level NTChannel *bottom_l = NULL; if (bottom) { LChannelR *lbottom = bottom->PushFwtStepR(*Filter); bottom_l = (NTChannel*)lbottom->SubBands[SubBand_L]; lbottom->SubBands[SubBand_L] = NULL; channel->SubBands[SubBand_H]-> Merge(*(NTChannel*)lbottom->SubBands[SubBand_H]); delete lbottom; } if (SubBands[SubBand_L]->IsLifted()) // Crop coarser level taking account of new borders channel->SubBands[SubBand_L] = ((LChannel*)SubBands[SubBand_L])-> Crop_rec(x1_l, y1, x2_l, y2, top_l, bottom_l, left_l, right_l); else { // Crop low-pass subband taking account of new borders channel->SubBands[SubBand_L] = SubBands[SubBand_L]-> Crop(x1_l, y1, x2_l, y2); channel->SubBands[SubBand_L]->Merge(*left_l); channel->SubBands[SubBand_L]->Merge(*right_l); if (top_l) channel->SubBands[SubBand_L]->Merge(*top_l); if (bottom_l) channel->SubBands[SubBand_L]->Merge(*bottom_l); } delete left_l; delete right_l; if (top_l) delete top_l; if (bottom_l) delete bottom_l; } else { // Crop after applying a full IFwt of the subimage and by // reconstructing the original structure. This is only the case // for one of the most coarse levels. TransformDescriptor *transform = GetTransform(); u_int depth = GetDepth(); NTChannel* ntchannel = IFwt(x1, y1, x2, y2); if (top) ntchannel->Merge(*top); if (bottom) ntchannel->Merge(*bottom); if (left) ntchannel->Merge(*left); if (right) ntchannel->Merge(*right); channel = (LChannelR*)ntchannel->Fwt(transform, depth); delete[] transform; delete ntchannel; } return(channel); } void LChannelR::Merge_rec(const Channel *channel, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) { int bwstart = Min(Filter->GetHStart(), Filter->GetGStart()); int bwend = Max(Filter->GetHEnd(), Filter->GetGEnd()); int bw = Max(-bwstart, bwend); int ch_x1 = channel->GetOffsetX(); int ch_y1 = channel->GetOffsetY(); int ch_x2 = ch_x1+(int)channel->GetCols()-1; int ch_y2 = ch_y1+(int)channel->GetRows()-1; int x1, y1, x2, y2, x1_lb, x2_lb, x1_rb, x2_rb; // Calculate inner and outer border coordinates y1 = top? top->OffsetY: ch_y1; y2 = bottom? bottom->OffsetY+(int)bottom->Rows-1: ch_y2; if (left) { x1 = left->OffsetX; x1_lb = x1-(bw<<1)-1; x2_lb = x1+(int)left->Cols+(bw<<1); } else { x1 = ch_x1; x1_lb = x1-(bw<<1)-1; x2_lb = x1+(bw<<1); } if (right) { x2 = right->OffsetX+(int)right->Cols-1; x1_rb = x2-(int)right->Cols-(bw<<1); x2_rb = x2+(bw<<1)+1; } else { x2 = ch_x2; x1_rb = x2-(bw<<1); x2_rb = x2+(bw<<1)+1; } x1_lb = Max(x1_lb, OffsetX); x2_rb = Min(x2_rb, OffsetX+(int)Cols-1); if (x1_rb-x2_lb > 1 && channel->IsLifted() && ((LChannel*)channel)->GetTransformType() == TT_Rows) { // Adjust left border according to the higher resolution level NTChannel *ntleft = IFwt(x1_lb, y1, x2_lb, y2); NTChannel *ntch_left = ((LChannel*)channel)-> IFwt(ch_x1, ch_y1, x2_lb, ch_y2); ntleft->Merge(*ntch_left); delete ntch_left; if (left) ntleft->Merge(*left); if (top) CopyRect(top->Data, top->Cols, 0, 0, ntleft->Data, ntleft->Cols, x1-x1_lb, 0, x2_lb-x1+1, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, 0, 0, ntleft->Data, ntleft->Cols, x1-x1_lb, y2-bottom->Rows+1-y1, x2_lb-x1+1, bottom->Rows); LChannelR *lleft = ntleft->PushFwtStepR(*Filter); delete ntleft; // Adjust right border according to the higher resolution level NTChannel *ntright = IFwt(x1_rb, y1, x2_rb, y2); NTChannel *ntch_right = ((LChannel*)channel)-> IFwt(x1_rb, ch_y1, ch_x2, ch_y2); ntright->Merge(*ntch_right); delete ntch_right; if (right) ntright->Merge(*right); if (top) CopyRect(top->Data, top->Cols, x1_rb-x1, 0, ntright->Data, ntright->Cols, 0, 0, x2-x1_rb+1, top->Rows); if (bottom) CopyRect(bottom->Data, bottom->Cols, x1_rb-x1, 0, ntright->Data, ntright->Cols, 0, y2-bottom->Rows+1-y1, x2-x1_rb+1, bottom->Rows); LChannelR *lright = ntright->PushFwtStepR(*Filter); delete ntright; // Adjust top border according to the higher resolution level LChannelR *ltop = NULL; if (top) { NTChannel *nttop = IFwt(x1_lb, y1, x2_rb, y1+(int)top->Rows-1); nttop->Merge(*top); ltop = nttop->PushFwtStepR(*Filter); delete nttop; } // Adjust bottom border according to the higher resolution level LChannelR *lbottom = NULL; if (bottom) { NTChannel *ntbottom = IFwt(x1_lb, y2-(int)bottom->Rows+1, x2_rb, y2); ntbottom->Merge(*bottom); lbottom = ntbottom->PushFwtStepR(*Filter); delete ntbottom; } // Merge the high-pass border-independent (center) subimage part SubBands[SubBand_H]-> Merge(*((LChannelR*)channel)->SubBands[SubBand_H]); // Recalculate inner and outer border coordinates // (without redundant border) x1_lb = Max(x1-bw-1, OffsetX); int x1_lb_l = GetEven(x1_lb); int x1_lb_h = GetOdd(x1_lb); x2_rb = Min(x2+bw+1, OffsetX+(int)Cols-1); int x2_rb_l = GetOdd(x2_rb); int x2_rb_h = GetOdd(x2_rb-1); x2_lb -= bw; int x2_lb_l = GetOdd(x2_lb); int x2_lb_h = GetOdd(x2_lb-1); x1_rb += bw; int x1_rb_l = GetEven(x1_rb); int x1_rb_h = GetOdd(x1_rb); // Merge specified border parts for the high-pass subimage and // crop the low-pass parts NTChannel *left_l = CropMergeH(lleft, x1_lb_l, x1_lb_h, y1, x2_lb_l, x2_lb_h, y2); NTChannel *right_l = CropMergeH(lright, x1_rb_l, x1_rb_h, y1, x2_rb_l, x2_rb_h, y2); NTChannel *top_l = ltop? CropMergeH(ltop, x1_lb_l, x1_lb_h, y1, x2_rb_l, x2_rb_h, y1+(int)ltop->Rows-1) : (NTChannel*)NULL; NTChannel *bottom_l = lbottom? CropMergeH(lbottom, x1_lb_l, x1_lb_h, y2-(int)lbottom->Rows+1, x2_rb_l, x2_rb_h, y2) : (NTChannel*)NULL; if (SubBands[SubBand_L]->IsLifted()) // Merge coarser level taking account of new borders ((LChannel*)SubBands[SubBand_L])-> Merge_rec(((LChannelR*)channel)->SubBands[SubBand_L], top_l, bottom_l, left_l, right_l); else { // Merge low-pass subband taking account of new borders SubBands[SubBand_L]-> Merge(*((LChannelR*)channel)->SubBands[SubBand_L]); SubBands[SubBand_L]->Merge(*left_l); SubBands[SubBand_L]->Merge(*right_l); if (ltop) SubBands[SubBand_L]->Merge(*top_l); if (lbottom) SubBands[SubBand_L]->Merge(*bottom_l); } delete left_l; delete right_l; if (ltop) delete top_l; if (lbottom) delete bottom_l; } else { // Merge after applying a full IFwt of the subimage and by // reconstructing the original structure. This is only the case // for one of the most coarse levels. NTChannel* ntchannel = IFwt(x1_lb, y1, x2_rb, y2); ntchannel->Merge(*channel); if (top) ntchannel->Merge(*top); if (bottom) ntchannel->Merge(*bottom); if (left) ntchannel->Merge(*left); if (right) ntchannel->Merge(*right); LChannelR *lchannel = ntchannel->PushFwtStepR(*Filter); delete ntchannel; x1_lb = Max(x1-bw-1, OffsetX); int x1_lb_l = GetEven(x1_lb); int x1_lb_h = GetOdd(x1_lb); x2_rb = Min(x2+bw+1, OffsetX+(int)Cols-1); int x2_rb_l = GetOdd(x2_rb); int x2_rb_h = GetOdd(x2_rb-1); NTChannel *lchannel_l = CropMergeH(lchannel, x1_lb_l, x1_lb_h, y1, x2_rb_l, x2_rb_h, y2); SubBands[SubBand_L]->Merge(*lchannel_l); delete lchannel_l; } } Channel *LChannelR::DownScale(u_int s, const Wavelet &wavelet) { assert(s != 0); if (s > 1) { Channel *channel; if (SubBands[SubBand_L]->IsLifted()) if (((LChannel*)SubBands[SubBand_L])-> GetTransformType() == TT_Cols) { channel = ((LChannel*)SubBands[SubBand_L])->SubBands[SubBand_L]; ((LChannel*)SubBands[SubBand_L])->SubBands[SubBand_L] = NULL; } else { NTChannel *ntchannel = ((LChannel*)SubBands[SubBand_L])->IFwt(); LChannelC *lchannel = ntchannel->PushFwtStepC(wavelet); channel = lchannel->SubBands[SubBand_L]; lchannel->SubBands[SubBand_L] = NULL; delete ntchannel; delete lchannel; } else { LChannelC *lchannel = ((NTChannel*)SubBands[SubBand_L])-> PushFwtStepC(wavelet); channel = lchannel->SubBands[SubBand_L]; lchannel->SubBands[SubBand_L] = NULL; delete lchannel; } Destroy(); return(channel->DownScale(GetOdd(s), wavelet)); } else { LChannelR *channel = this->Clone(); Destroy(); return(channel); } } waili-gpl-19990723/lib/Lifting.C100640 24520 25417 144217 6745120267 14644 0ustar geertnatw// // Integer Lifting Operations // // $Id: Lifting.C,v 4.5.2.1.2.1 1999/07/20 16:15:51 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include const char *Lifting::rcsid = "$Id: Lifting.C,v 4.5.2.1.2.1 1999/07/20 16:15:51 geert Exp $"; // Clipping with symmetric signal extension static inline int clip_11(int idx, u_int len) { if (idx < 0) idx = -idx; idx %= 2*(len-1); if ((u_int)idx >= len) idx = 2*len-idx-2; return(idx); } static inline int clip_12(int idx, u_int len) { if (idx < 0) idx = -idx; idx %= 2*len-1; if ((u_int)idx >= len) idx = 2*len-idx-1; return(idx); } static inline int clip_21(int idx, u_int len) { if (idx < 0) idx = -idx-1; idx %= 2*len-1; if ((u_int)idx >= len) idx = 2*len-idx-2; return(idx); } static inline int clip_22(int idx, u_int len) { if (idx < 0) idx = -idx-1; idx %= 2*len; if ((u_int)idx >= len) idx = 2*len-idx-1; return(idx); } // Integer division with rounding template static inline Type divrnd(Type p, u_int d) { int d2 = d>>1; if (p < 0) d2 = -d2; p += d2; return(p/(int)d); } // ---------------------------------------------------------------------------- // // Integer Lifting Operations on the Rows of NTChannels // // ---------------------------------------------------------------------------- // Lifting Steps (Full Rounding) void LiftChannelR::Lift_L1R1_FR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) for (u_int i = 0; i < Rows; i++) { even[0] += divrnd((b[0]+b[1])*odd[0], a); for (u_int j = 1; j < Codd; j++) even[j] += divrnd(b[0]*odd[j-1]+b[1]*odd[j], a); if (Ceven != Codd) even[Ceven-1] += divrnd((b[0]+b[1])*odd[Codd-1], a); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] += divrnd(b[0]*even[j]+b[1]*even[j+1], a); if (Ceven == Codd) odd[Codd-1] += divrnd((b[0]+b[1])*even[Ceven-1], a); even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_FR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) for (u_int i = 0; i < Rows; i++) { even[0] -= divrnd((b[0]+b[1])*odd[0], a); for (u_int j = 1; j < Codd; j++) even[j] -= divrnd(b[0]*odd[j-1]+b[1]*odd[j], a); if (Ceven != Codd) even[Ceven-1] -= divrnd((b[0]+b[1])*odd[Codd-1], a); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] -= divrnd(b[0]*even[j]+b[1]*even[j+1], a); if (Ceven == Codd) odd[Codd-1] -= divrnd((b[0]+b[1])*even[Ceven-1], a); even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L2R2_FR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { srclen = Codd; src = Odd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] += divrnd(b[0]*src[clip(equal_idx_left+j-2, srclen)]+ b[1]*src[clip(equal_idx_left+j-1, srclen)]+ b[2]*src[clip(equal_idx_left+j, srclen)]+ b[3]*src[clip(equal_idx_left+j+1, srclen)], a); dst += dstlen; src += srclen; } } void LiftChannelR::ILift_L2R2_FR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] -= divrnd(b[0]*src[clip(equal_idx_left+j-2, srclen)]+ b[1]*src[clip(equal_idx_left+j-1, srclen)]+ b[2]*src[clip(equal_idx_left+j, srclen)]+ b[3]*src[clip(equal_idx_left+j+1, srclen)], a); dst += dstlen; src += srclen; } } void LiftChannelR::Lift_L3R3_FR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] += divrnd(b[0]*src[clip(equal_idx_left+j-3, srclen)]+ b[1]*src[clip(equal_idx_left+j-2, srclen)]+ b[2]*src[clip(equal_idx_left+j-1, srclen)]+ b[3]*src[clip(equal_idx_left+j, srclen)]+ b[4]*src[clip(equal_idx_left+j+1, srclen)]+ b[5]*src[clip(equal_idx_left+j+2, srclen)], a); dst += dstlen; src += srclen; } } void LiftChannelR::ILift_L3R3_FR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] -= divrnd(b[0]*src[clip(equal_idx_left+j-3, srclen)]+ b[1]*src[clip(equal_idx_left+j-2, srclen)]+ b[2]*src[clip(equal_idx_left+j-1, srclen)]+ b[3]*src[clip(equal_idx_left+j, srclen)]+ b[4]*src[clip(equal_idx_left+j+1, srclen)]+ b[5]*src[clip(equal_idx_left+j+2, srclen)], a); dst += dstlen; src += srclen; } } // Lifting Steps (No Rounding) void LiftChannelR::Lift_L1R1_NR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) for (u_int i = 0; i < Rows; i++) { even[0] = a*even[0]+(b[0]+b[1])*odd[0]; for (u_int j = 1; j < Codd; j++) even[j] = a*even[j]+b[0]*odd[j-1]+b[1]*odd[j]; if (Ceven != Codd) even[Ceven-1] = a*even[Ceven-1]+(b[0]+b[1])*odd[Codd-1]; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] = a*odd[j]+b[0]*even[j]+b[1]*even[j+1]; if (Ceven == Codd) odd[Codd-1] = a*odd[Codd-1]+(b[0]+b[1])*even[Ceven-1]; even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_NR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) for (u_int i = 0; i < Rows; i++) { even[0] = (even[0]-(b[0]+b[1])*odd[0])/a; for (u_int j = 1; j < Codd; j++) even[j] = (even[j]-b[0]*odd[j-1]-b[1]*odd[j])/a; if (Ceven != Codd) even[Ceven-1] = (even[Ceven-1]-(b[0]+b[1])*odd[Codd-1])/a; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] = (odd[j]-b[0]*even[j]-b[1]*even[j+1])/a; if (Ceven == Codd) odd[Codd-1] = (odd[Codd-1]-(b[0]+b[1])*even[Ceven-1])/a; even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L2R2_NR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = a*dst[j]+b[0]*src[clip(equal_idx_left+j-2, srclen)]+ b[1]*src[clip(equal_idx_left+j-1, srclen)]+ b[2]*src[clip(equal_idx_left+j, srclen)]+ b[3]*src[clip(equal_idx_left+j+1, srclen)]; dst += dstlen; src += srclen; } } void LiftChannelR::ILift_L2R2_NR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = (dst[j]-(b[0]*src[clip(equal_idx_left+j-2, srclen)]+ b[1]*src[clip(equal_idx_left+j-1, srclen)]+ b[2]*src[clip(equal_idx_left+j, srclen)]+ b[3]*src[clip(equal_idx_left+j+1, srclen)]))/a; dst += dstlen; src += srclen; } } void LiftChannelR::Lift_L3R3_NR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = a*dst[j]+b[0]*src[clip(equal_idx_left+j-3, srclen)]+ b[1]*src[clip(equal_idx_left+j-2, srclen)]+ b[2]*src[clip(equal_idx_left+j-1, srclen)]+ b[3]*src[clip(equal_idx_left+j, srclen)]+ b[4]*src[clip(equal_idx_left+j+1, srclen)]+ b[5]*src[clip(equal_idx_left+j+2, srclen)]; dst += dstlen; src += srclen; } } void LiftChannelR::ILift_L3R3_NR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = (dst[j]-(b[0]*src[clip(equal_idx_left+j-3, srclen)]+ b[1]*src[clip(equal_idx_left+j-2, srclen)]+ b[2]*src[clip(equal_idx_left+j-1, srclen)]+ b[3]*src[clip(equal_idx_left+j, srclen)]+ b[4]*src[clip(equal_idx_left+j+1, srclen)]+ b[5]*src[clip(equal_idx_left+j+2, srclen)]))/a; dst += dstlen; src += srclen; } } // Lifting Steps (Mixed) void LiftChannelR::Lift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) for (u_int i = 0; i < Rows; i++) { even[0] = a1*even[0]+divrnd((b[0]+b[1])*odd[0], a2); for (u_int j = 1; j < Codd; j++) even[j] = a1*even[j]+divrnd(b[0]*odd[j-1]+b[1]*odd[j], a2); if (Ceven != Codd) even[Ceven-1] = a1*even[Ceven-1]+ divrnd((b[0]+b[1])*odd[Codd-1], a2); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] = a1*odd[j]+divrnd(b[0]*even[j]+b[1]*even[j+1], a2); if (Ceven == Codd) odd[Codd-1] = a1*odd[Codd-1]+ divrnd((b[0]+b[1])*even[Ceven-1], a2); even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) for (u_int i = 0; i < Rows; i++) { even[0] = (even[0]-divrnd((b[0]+b[1])*odd[0], a2))/a1; for (u_int j = 1; j < Codd; j++) even[j] = (even[j]-divrnd(b[0]*odd[j-1]+b[1]*odd[j], a2))/a1; if (Ceven != Codd) even[Ceven-1] = (even[Ceven-1]- divrnd((b[0]+b[1])*odd[Codd-1], a2))/a1; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] = (odd[j]-divrnd(b[0]*even[j]+b[1]*even[j+1], a2))/a1; if (Ceven == Codd) odd[Codd-1] = (odd[Codd-1]- divrnd((b[0]+b[1])*even[Ceven-1], a2))/a1; even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = a1*dst[j]+ divrnd(b[0]*src[clip(equal_idx_left+j-2, srclen)]+ b[1]*src[clip(equal_idx_left+j-1, srclen)]+ b[2]*src[clip(equal_idx_left+j, srclen)]+ b[3]*src[clip(equal_idx_left+j+1, srclen)], a2); dst += dstlen; src += srclen; } } void LiftChannelR::ILift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = (dst[j]- divrnd(b[0]*src[clip(equal_idx_left+j-2, srclen)]+ b[1]*src[clip(equal_idx_left+j-1, srclen)]+ b[2]*src[clip(equal_idx_left+j, srclen)]+ b[3]*src[clip(equal_idx_left+j+1, srclen)], a2))/ a1; dst += dstlen; src += srclen; } } void LiftChannelR::Lift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = a1*dst[j]+ divrnd(b[0]*src[clip(equal_idx_left+j-3, srclen)]+ b[1]*src[clip(equal_idx_left+j-2, srclen)]+ b[2]*src[clip(equal_idx_left+j-1, srclen)]+ b[3]*src[clip(equal_idx_left+j, srclen)]+ b[4]*src[clip(equal_idx_left+j+1, srclen)]+ b[5]*src[clip(equal_idx_left+j+2, srclen)], a2); dst += dstlen; src += srclen; } } void LiftChannelR::ILift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Codd; dst = Even; dstlen = Ceven; equal_idx_left = 0; clip = Ceven == Codd ? clip_21 : clip_22; } else { src = Even; srclen = Ceven; dst = Odd; dstlen = Codd; equal_idx_left = 1; clip = Ceven == Codd ? clip_12 : clip_11; } for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < dstlen; j++) dst[j] = (dst[j]- divrnd(b[0]*src[clip(equal_idx_left+j-3, srclen)]+ b[1]*src[clip(equal_idx_left+j-2, srclen)]+ b[2]*src[clip(equal_idx_left+j-1, srclen)]+ b[3]*src[clip(equal_idx_left+j, srclen)]+ b[4]*src[clip(equal_idx_left+j+1, srclen)]+ b[5]*src[clip(equal_idx_left+j+2, srclen)], a2))/ a1; dst += dstlen; src += srclen; } } // Optimized functions for specific wavelet transforms void LiftChannelR::Lift_L1R1_NR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) for (u_int i = 0; i < Rows; i++) { even[0] = (even[0]-odd[0])<<1; for (u_int j = 1; j < Codd; j++) even[j] = (even[j]<<1)-odd[j-1]-odd[j]; if (Ceven != Codd) even[Ceven-1] = (even[Ceven-1]-odd[Codd-1])<<1; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] = (odd[j]<<1)-even[j]-even[j+1]; if (Ceven == Codd) odd[Codd-1] = (odd[Codd-1]-even[Ceven-1])<<1; even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_NR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) for (u_int i = 0; i < Rows; i++) { even[0] = (even[0]>>1)+odd[0]; for (u_int j = 1; j < Codd; j++) even[j] = (even[j]+odd[j-1]+odd[j])>>1; if (Ceven != Codd) even[Ceven-1] = (even[Ceven-1]>>1)+odd[Codd-1]; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] = (odd[j]+even[j]+even[j+1])>>1; if (Ceven == Codd) odd[Codd-1] = (odd[Codd-1]>>1)+even[Ceven-1]; even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L1R1_FR_1_1_1_8(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) for (u_int i = 0; i < Rows; i++) { even[0] += divrnd(odd[0], 4); for (u_int j = 1; j < Codd; j++) even[j] += divrnd(odd[j-1]+odd[j], 8); if (Ceven != Codd) even[Ceven-1] += divrnd(odd[Codd-1], 4); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] += divrnd(even[j]+even[j+1], 8); if (Ceven == Codd) odd[Codd-1] += divrnd(even[Ceven-1], 4); even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_FR_1_1_1_8(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) for (u_int i = 0; i < Rows; i++) { even[0] -= divrnd(odd[0], 4); for (u_int j = 1; j < Codd; j++) even[j] -= divrnd(odd[j-1]+odd[j], 8); if (Ceven != Codd) even[Ceven-1] -= divrnd(odd[Codd-1], 4); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] -= divrnd(even[j]+even[j+1], 8); if (Ceven == Codd) odd[Codd-1] -= divrnd(even[Ceven-1], 4); even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L1R1_FR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) for (u_int i = 0; i < Rows; i++) { even[0] -= odd[0]; for (u_int j = 1; j < Codd; j++) even[j] += divrnd(-odd[j-1]-odd[j], 2); if (Ceven != Codd) even[Ceven-1] -= odd[Codd-1]; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] += divrnd(-even[j]-even[j+1], 2); if (Ceven == Codd) odd[Codd-1] -= even[Ceven-1]; even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_FR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) for (u_int i = 0; i < Rows; i++) { even[0] += odd[0]; for (u_int j = 1; j < Codd; j++) even[j] -= divrnd(-odd[j-1]-odd[j], 2); if (Ceven != Codd) even[Ceven-1] += odd[Codd-1]; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] -= divrnd(-even[j]-even[j+1], 2); if (Ceven == Codd) odd[Codd-1] += even[Ceven-1]; even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L1R1_FR_1_1_1_4(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) for (u_int i = 0; i < Rows; i++) { even[0] += divrnd(odd[0], 2); for (u_int j = 1; j < Codd; j++) even[j] += divrnd(odd[j-1]+odd[j], 4); if (Ceven != Codd) even[Ceven-1] += divrnd(odd[Codd-1], 2); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] += divrnd(even[j]+even[j+1], 4); if (Ceven == Codd) odd[Codd-1] += divrnd(even[Ceven-1], 2); even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_FR_1_1_1_4(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) for (u_int i = 0; i < Rows; i++) { even[0] -= divrnd(odd[0], 2); for (u_int j = 1; j < Codd; j++) even[j] -= divrnd(odd[j-1]+odd[j], 4); if (Ceven != Codd) even[Ceven-1] -= divrnd(odd[Codd-1], 2); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] -= divrnd(even[j]+even[j+1], 4); if (Ceven == Codd) odd[Codd-1] -= divrnd(even[Ceven-1], 2); even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L1R1_FR_0_m1_0_1(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) for (u_int i = 0; i < Rows; i++) { even[0] -= odd[0]; for (u_int j = 1; j < Codd; j++) even[j] -= odd[j-1]; if (Ceven != Codd) even[Ceven-1] -= odd[Codd-1]; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] -= even[j]; if (Ceven == Codd) odd[Codd-1] -= even[Ceven-1]; even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_FR_0_m1_0_1(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) for (u_int i = 0; i < Rows; i++) { even[0] += odd[0]; for (u_int j = 1; j < Codd; j++) even[j] += odd[j-1]; if (Ceven != Codd) even[Ceven-1] += odd[Codd-1]; even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] += even[j]; if (Ceven == Codd) odd[Codd-1] += even[Ceven-1]; even += Ceven; odd += Codd; } } void LiftChannelR::Lift_L1R1_FR_1_0_1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) for (u_int i = 0; i < Rows; i++) { even[0] += divrnd(odd[0], 2); for (u_int j = 1; j < Codd; j++) even[j] += divrnd(odd[j], 2); if (Ceven != Codd) even[Ceven-1] += divrnd(odd[Codd-1], 2); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] += divrnd(even[j+1], 2); if (Ceven == Codd) odd[Codd-1] += divrnd(even[Ceven-1], 2); even += Ceven; odd += Codd; } } void LiftChannelR::ILift_L1R1_FR_1_0_1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) for (u_int i = 0; i < Rows; i++) { even[0] -= divrnd(odd[0], 2); for (u_int j = 1; j < Codd; j++) even[j] -= divrnd(odd[j], 2); if (Ceven != Codd) even[Ceven-1] -= divrnd(odd[Codd-1], 2); even += Ceven; odd += Codd; } else for (u_int i = 0; i < Rows; i++) { for (u_int j = 0; j < Ceven-1; j++) odd[j] -= divrnd(even[j+1], 2); if (Ceven == Codd) odd[Codd-1] -= divrnd(even[Ceven-1], 2); even += Ceven; odd += Codd; } } // ---------------------------------------------------------------------------- // // Integer Lifting Operations on the Columns of NTChannels // // ---------------------------------------------------------------------------- // Lifting Steps (Full Rounding) void LiftChannelC::Lift_L1R1_FR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) { for (u_int i = 0; i < Cols; i++) even[i] += divrnd((b[0]+b[1])*odd[i], a); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] += divrnd(b[0]*odd[int(j-Cols)]+b[1]*odd[j], a); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] += divrnd((b[0]+b[1])*odd[int(i-Cols)], a); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(b[0]*even[j]+b[1]*even[j+Cols], a); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] += divrnd((b[0]+b[1])*even[j], a); } } void LiftChannelC::ILift_L1R1_FR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) { for (u_int i = 0; i < Cols; i++) even[i] -= divrnd((b[0]+b[1])*odd[i], a); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] -= divrnd(b[0]*odd[int(j-Cols)]+b[1]*odd[j], a); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] -= divrnd((b[0]+b[1])*odd[int(i-Cols)], a); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(b[0]*even[j]+b[1]*even[j+Cols], a); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd((b[0]+b[1])*even[j], a); } } void LiftChannelC::Lift_L2R2_FR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] += divrnd(b[0]*src[il2+j]+ b[1]*src[il1+j]+ b[2]*src[ir1+j]+ b[3]*src[ir2+j], a); dst += Cols; } } void LiftChannelC::ILift_L2R2_FR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] -= divrnd(b[0]*src[il2+j]+ b[1]*src[il1+j]+ b[2]*src[ir1+j]+ b[3]*src[ir2+j], a); dst += Cols; } } void LiftChannelC::Lift_L3R3_FR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il3 = clip(equal_idx_left+i-3, srclen)*Cols; u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; u_int ir3 = clip(equal_idx_left+i+2, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] += divrnd(b[0]*src[il3+j]+ b[1]*src[il2+j]+ b[2]*src[il1+j]+ b[3]*src[ir1+j]+ b[4]*src[ir2+j]+ b[5]*src[ir3+j], a); dst += Cols; } } void LiftChannelC::ILift_L3R3_FR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il3 = clip(equal_idx_left+i-3, srclen)*Cols; u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; u_int ir3 = clip(equal_idx_left+i+2, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] -= divrnd(b[0]*src[il3+j]+ b[1]*src[il2+j]+ b[2]*src[il1+j]+ b[3]*src[ir1+j]+ b[4]*src[ir2+j]+ b[5]*src[ir3+j], a); dst += Cols; } } // ---------------------------------------------------------------------------- // Lifting Steps (No Rounding) void LiftChannelC::Lift_L1R1_NR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) { for (u_int i = 0; i < Cols; i++) even[i] = a*even[i]+(b[0]+b[1])*odd[i]; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] = a*even[j]+b[0]*odd[int(j-Cols)]+b[1]*odd[j]; even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] = a*even[i]+(b[0]+b[1])*odd[int(i-Cols)]; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] = a*odd[j]+b[0]*even[j]+b[1]*even[j+Cols]; even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] = a*odd[j]+(b[0]+b[1])*even[j]; } } void LiftChannelC::ILift_L1R1_NR(int primal, const s16 b[2], const u16 a) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) { for (u_int i = 0; i < Cols; i++) even[i] = (even[i]-(b[0]+b[1])*odd[i])/a; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] = (even[j]-b[0]*odd[int(j-Cols)]-b[1]*odd[j])/a; even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] = (even[i]-(b[0]+b[1])*odd[int(i-Cols)])/a; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]-b[0]*even[j]-b[1]*even[j+Cols])/a; even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]-(b[0]+b[1])*even[j])/a; } } void LiftChannelC::Lift_L2R2_NR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = a*dst[j]+b[0]*src[il2+j]+ b[1]*src[il1+j]+ b[2]*src[ir1+j]+ b[3]*src[ir2+j]; dst += Cols; } } void LiftChannelC::ILift_L2R2_NR(int primal, const s16 b[4], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = (dst[j]-(b[0]*src[il2+j]+ b[1]*src[il1+j]+ b[2]*src[ir1+j]+ b[3]*src[ir2+j]))/a; dst += Cols; } } void LiftChannelC::Lift_L3R3_NR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il3 = clip(equal_idx_left+i-3, srclen)*Cols; u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; u_int ir3 = clip(equal_idx_left+i+2, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = a*dst[j]+b[0]*src[il3+j]+ b[1]*src[il2+j]+ b[2]*src[il1+j]+ b[3]*src[ir1+j]+ b[4]*src[ir2+j]+ b[5]*src[ir3+j]; dst += Cols; } } void LiftChannelC::ILift_L3R3_NR(int primal, const s16 b[6], const u16 a) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il3 = clip(equal_idx_left+i-3, srclen)*Cols; u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; u_int ir3 = clip(equal_idx_left+i+2, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = (a*dst[j]-(b[0]*src[il3+j]+ b[1]*src[il2+j]+ b[2]*src[il1+j]+ b[3]*src[ir1+j]+ b[4]*src[ir2+j]+ b[5]*src[ir3+j]))/a; dst += Cols; } } // ---------------------------------------------------------------------------- // Lifting Steps (Mixed) void LiftChannelC::Lift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) { for (u_int i = 0; i < Cols; i++) even[i] = a1*even[i]+divrnd((b[0]+b[1])*odd[i], a2); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] = a1*even[j]+divrnd(b[0]*odd[int(j-Cols)]+b[1]*odd[j], a2); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] = a1*even[i]+divrnd((b[0]+b[1])*odd[int(i-Cols)], a2); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] = a1*odd[j]+divrnd(b[0]*even[j]+b[1]*even[j+Cols], a2); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] = a1*odd[j]+divrnd((b[0]+b[1])*even[j], a2); } } void LiftChannelC::ILift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const { PixType *even = Even; PixType *odd = Odd; if (primal ^ Parity) { for (u_int i = 0; i < Cols; i++) even[i] = (even[i]-divrnd((b[0]+b[1])*odd[i], a2))/a1; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] = (even[j]-divrnd(b[0]*odd[int(j-Cols)]+b[1]*odd[j], a2))/a1; even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] = (even[i]-divrnd((b[0]+b[1])*odd[int(i-Cols)], a2))/ a1; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]-divrnd(b[0]*even[j]+b[1]*even[j+Cols], a2))/a1; even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]-divrnd((b[0]+b[1])*even[j], a2))/a1; } } void LiftChannelC::Lift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = a1*dst[j]+divrnd(b[0]*src[il2+j]+ b[1]*src[il1+j]+ b[2]*src[ir1+j]+ b[3]*src[ir2+j], a2); dst += Cols; } } void LiftChannelC::ILift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = (dst[j]-divrnd(b[0]*src[il2+j]+ b[1]*src[il1+j]+ b[2]*src[ir1+j]+ b[3]*src[ir2+j], a2))/a1; dst += Cols; } } void LiftChannelC::Lift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il3 = clip(equal_idx_left+i-3, srclen)*Cols; u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; u_int ir3 = clip(equal_idx_left+i+2, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = a1*dst[j]+divrnd(b[0]*src[il3+j]+ b[1]*src[il2+j]+ b[2]*src[il1+j]+ b[3]*src[ir1+j]+ b[4]*src[ir2+j]+ b[5]*src[ir3+j], a2); dst += Cols; } } void LiftChannelC::ILift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const { PixType *src, *dst; u_int srclen, dstlen; int equal_idx_left; int (*clip)(int idx, u_int len); if (primal ^ Parity) { src = Odd; srclen = Rodd; dst = Even; dstlen = Reven; equal_idx_left = 0; clip = Reven == Rodd ? clip_21 : clip_22; } else { src = Even; srclen = Reven; dst = Odd; dstlen = Rodd; equal_idx_left = 1; clip = Reven == Rodd ? clip_12 : clip_11; } for (u_int i = 0; i < dstlen; i++) { u_int il3 = clip(equal_idx_left+i-3, srclen)*Cols; u_int il2 = clip(equal_idx_left+i-2, srclen)*Cols; u_int il1 = clip(equal_idx_left+i-1, srclen)*Cols; u_int ir1 = clip(equal_idx_left+i, srclen)*Cols; u_int ir2 = clip(equal_idx_left+i+1, srclen)*Cols; u_int ir3 = clip(equal_idx_left+i+2, srclen)*Cols; for (u_int j = 0; j < Cols; j++) dst[j] = (dst[j]-divrnd(b[0]*src[il3+j]+ b[1]*src[il2+j]+ b[2]*src[il1+j]+ b[3]*src[ir1+j]+ b[4]*src[ir2+j]+ b[5]*src[ir3+j], a2))/a1; dst += Cols; } } // Optimized functions for specific wavelet transforms void LiftChannelC::Lift_L1R1_NR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) { for (u_int i = 0; i < Cols; i++) even[i] = (even[i]-odd[i])<<1; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] = (even[j]<<1)-odd[int(j-Cols)]-odd[j]; even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] = (even[i]-odd[int(i-Cols)])<<1; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]<<1)-even[j]-even[j+Cols]; even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]-even[j])<<1; } } void LiftChannelC::ILift_L1R1_NR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) { for (u_int i = 0; i < Cols; i++) even[i] = (even[i]>>1)+odd[i]; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] = (even[j]+odd[int(j-Cols)]+odd[j])>>1; even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] = (even[i]>>1)+odd[int(i-Cols)]; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]+even[j]+even[j+Cols])>>1; even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] = (odd[j]>>1)+even[j]; } } void LiftChannelC::Lift_L1R1_FR_1_1_1_8(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) { for (u_int i = 0; i < Cols; i++) even[i] += divrnd(odd[i], 4); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] += divrnd(odd[int(j-Cols)]+odd[j], 8); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] += divrnd(odd[int(i-Cols)], 4); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(even[j]+even[j+Cols], 8); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(even[j], 4); } } void LiftChannelC::ILift_L1R1_FR_1_1_1_8(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) { for (u_int i = 0; i < Cols; i++) even[i] -= divrnd(odd[i], 4); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] -= divrnd(odd[int(j-Cols)]+odd[j], 8); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] -= divrnd(odd[int(i-Cols)], 4); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(even[j]+even[j+Cols], 8); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(even[j], 4); } } void LiftChannelC::Lift_L1R1_FR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) { for (u_int i = 0; i < Cols; i++) even[i] -= odd[i]; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] += divrnd(-odd[int(j-Cols)]-odd[j], 2); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] -= odd[int(i-Cols)]; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(-even[j]-even[j+Cols], 2); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] -= even[j]; } } void LiftChannelC::ILift_L1R1_FR_0_m1_m1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) { for (u_int i = 0; i < Cols; i++) even[i] += odd[i]; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] -= divrnd(-odd[int(j-Cols)]-odd[j], 2); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] += odd[int(i-Cols)]; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(-even[j]-even[j+Cols], 2); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] += even[j]; } } void LiftChannelC::Lift_L1R1_FR_1_1_1_4(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) { for (u_int i = 0; i < Cols; i++) even[i] += divrnd(odd[i], 2); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] += divrnd(odd[int(j-Cols)]+odd[j], 4); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] += divrnd(odd[int(i-Cols)], 2); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(even[j]+even[j+Cols], 4); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(even[j], 2); } } void LiftChannelC::ILift_L1R1_FR_1_1_1_4(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) { for (u_int i = 0; i < Cols; i++) even[i] -= divrnd(odd[i], 2); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] -= divrnd(odd[int(j-Cols)]+odd[j], 4); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] -= divrnd(odd[int(i-Cols)], 2); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(even[j]+even[j+Cols], 4); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(even[j], 2); } } void LiftChannelC::Lift_L1R1_FR_0_m1_0_1(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) { for (u_int i = 0; i < Cols; i++) even[i] -= odd[i]; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] -= odd[int(j-Cols)]; even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] -= odd[int(i-Cols)]; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] -= even[j]; even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] -= even[j]; } } void LiftChannelC::ILift_L1R1_FR_0_m1_0_1(void) const { PixType *even = Even; PixType *odd = Odd; if (Parity) { for (u_int i = 0; i < Cols; i++) even[i] += odd[i]; even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] += odd[int(j-Cols)]; even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] += odd[int(i-Cols)]; } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] += even[j]; even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] += even[j]; } } void LiftChannelC::Lift_L1R1_FR_1_0_1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) { for (u_int i = 0; i < Cols; i++) even[i] += divrnd(odd[i], 2); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] += divrnd(odd[j], 2); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] += divrnd(odd[int(i-Cols)], 2); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(even[j+Cols], 2); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] += divrnd(even[j], 2); } } void LiftChannelC::ILift_L1R1_FR_1_0_1_2(void) const { PixType *even = Even; PixType *odd = Odd; if (!Parity) { for (u_int i = 0; i < Cols; i++) even[i] -= divrnd(odd[i], 2); even += Cols; odd += Cols; for (u_int i = 1; i < Rodd; i++) { for (u_int j = 0; j < Cols; j++) even[j] -= divrnd(odd[j], 2); even += Cols; odd += Cols; } if (Reven != Rodd) for (u_int i = 0; i < Cols; i++) even[i] -= divrnd(odd[int(i-Cols)], 2); } else { for (u_int i = 0; i < Reven-1; i++) { for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(even[j+Cols], 2); even += Cols; odd += Cols; } if (Reven == Rodd) for (u_int j = 0; j < Cols; j++) odd[j] -= divrnd(even[j], 2); } } waili-gpl-19990723/lib/Makefile100640 24520 25417 2555 6745120267 14542 0ustar geertnatw# # Makefile for lib # # $Id: Makefile,v 4.0.2.2.2.1 1999/07/20 16:15:51 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # include ../Rules.config LIBOBJS = Channel.o Color.o Image.o LChannel.o LChannelC.o LChannelCR.o \ LChannelR.o Lifting.o NTChannel.o Storage.o Timer.o Util.o \ Wavelet.o Wavelet_CDF_1_x.o Wavelet_CDF_2_x.o \ Wavelet_CDF_4_x.o Wavelet_JPEG2000.o LIB = libwaili.a All: $(LIB) $(LIB): $(LIBOBJS) rm -f $(LIB) $(AR) rc $(LIB) $(LIBOBJS) $(RANLIB) $(LIB) depend: rm -f .depend $(CXX) $(CFLAGS) -M -E *.C > .depend clean: rm -f .depend *.o *.a include ../Rules.make waili-gpl-19990723/lib/NTChannel.C100640 24520 25417 32426 6745120267 15040 0ustar geertnatw// // NTChannel Class // // $Id: NTChannel.C,v 4.12.2.3.2.1 1999/07/20 16:15:51 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include const char *NTChannel::rcsid = "$Id: NTChannel.C,v 4.12.2.3.2.1 1999/07/20 16:15:51 geert Exp $"; // ---------------------------------------------------------------------------- // // Non-Transformed Channel Class // // ---------------------------------------------------------------------------- NTChannel::NTChannel(u_int cols, u_int rows, int offx, int offy) : Channel(cols, rows, offx, offy), Data(NULL) { Data = new PixType[Cols*Rows]; } NTChannel::NTChannel(const NTChannel &channel) : Channel(channel.Cols, channel.Rows, channel.OffsetX, channel.OffsetY), Data(NULL) { Data = new PixType[Cols*Rows]; Copy(channel.Data, Data, Cols*Rows); } NTChannel::~NTChannel() { delete[] Data; } void NTChannel::Clear(void) { ::Clear(Data, Cols*Rows); } void NTChannel::Resize(u_int cols, u_int rows) { PixType *data = new PixType[cols*rows]; Cols = cols; Rows = rows; delete[] Data; Data = data; } NTChannel *NTChannel::Crop(int x1, int y1, int x2, int y2) const { assert(x1 >= OffsetX); assert(y1 >= OffsetY); assert(x2 < OffsetX+(int)Cols); assert(y2 < OffsetY+(int)Rows); assert(x2 >= x1); assert(y2 >= y1); u_int cols = x2-x1+1; u_int rows = y2-y1+1; NTChannel *ntch = new NTChannel(cols, rows, x1, y1); CopyRect(Data, Cols, x1-OffsetX, y1-OffsetY, ntch->Data, cols, 0, 0, cols, rows); return(ntch); } void NTChannel::Merge(const Channel &channel) { int x = channel.GetOffsetX()-OffsetX; int y = channel.GetOffsetY()-OffsetY; assert(x+channel.GetCols() <= Cols); assert(y+channel.GetRows() <= Rows); Channel *ch = channel.Clone(); NTChannel *ntch; if (ch->IsLifted()) { ntch = ((LChannel*)ch)->IFwt(); delete ch; } else ntch = (NTChannel*)ch; CopyRect(ntch->Data, ntch->Cols, 0, 0, Data, Cols, x, y, ntch->Cols, ntch->Rows); delete ntch; } void NTChannel::Add(const Channel &channel) { assert(!channel.IsLifted()); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) (*this)(c, r) += channel(c, r); } void NTChannel::Subtract(const Channel &channel) { assert(!channel.IsLifted()); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) (*this)(c, r) -= channel(c, r); } NTChannel *NTChannel::Diff(const Channel &channel) const { assert(!channel.IsLifted()); assert(channel.GetRows() == Rows); assert(channel.GetCols() == Cols); assert(channel.GetOffsetX() == OffsetX); assert(channel.GetOffsetY() == OffsetY); NTChannel *diff = new NTChannel(Cols, Rows, OffsetX, OffsetY); for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) (*diff)(c, r) = (*this)(c, r) == channel(c, r)? -128: 127; return(diff); } s32 *NTChannel::Correlate(const NTChannel &channel, u_int diff) const { s32 *cor = new s32[Cols*Rows]; NTChannel *scaled = channel.DupliScale((u_int)pow(2.0, (double)diff)); int dx = scaled->OffsetX-OffsetX; int dy = scaled->OffsetY-OffsetY; for (u_int j = 0; j < Rows; j++) if ((int)j < dy || j > dy+scaled->Rows-1) for (u_int i = 0; i < Cols; i++) cor[j*Cols+i] = 0; else for (u_int i = 0; i < Cols; i++) if ((int)i < dx || i > dx+scaled->Cols-1) cor[j*Cols+i] = 0; else cor[j*Cols+i] = (*this)(i,j)*(*scaled)(i-dx,j-dy); delete scaled; return(cor); } void NTChannel::Enhance(f32 m) { for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) (*this)(c, r) = PixType(m*(*this)(c, r)); } void NTChannel::Enhance(int m, u_int shift) { for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) (*this)(c, r) = PixType(int(m*(*this)(c, r))>>shift); } LChannelCR *NTChannel::PushFwtStepCR(const Wavelet &wavelet) { if (Cols < 2 || Rows < 2) return(NULL); LChannelCR *lifted = new LChannelCR(wavelet, Cols, Rows, OffsetX, OffsetY); lifted->Lazy(*this); Destroy(); lifted->CakeWalk(); return(lifted); } LChannelC *NTChannel::PushFwtStepC(const Wavelet &wavelet) { if (Rows < 2) return(NULL); LChannelC *lifted = new LChannelC(wavelet, Cols, Rows, OffsetX, OffsetY); lifted->Lazy(*this); Destroy(); lifted->CakeWalk(); return(lifted); } LChannelR *NTChannel::PushFwtStepR(const Wavelet &wavelet) { if (Cols < 2) return(NULL); LChannelR *lifted = new LChannelR(wavelet, Cols, Rows, OffsetX, OffsetY); lifted->Lazy(*this); Destroy(); lifted->CakeWalk(); return(lifted); } LChannel *NTChannel::Fwt(const TransformDescriptor transform[], u_int depth) { LChannel *channel = NULL; if (depth) { const Wavelet *wavelet = Wavelet::CreateFromID(transform->filter); switch (transform->type) { case TT_ColsRows: channel = PushFwtStepCR(*wavelet); break; case TT_Cols: channel = PushFwtStepC(*wavelet); break; case TT_Rows: channel = PushFwtStepR(*wavelet); break; } delete wavelet; if (channel) { Destroy(); assert(!channel->SubBands[0]->IsLifted()); NTChannel *ch1 = (NTChannel *)channel->SubBands[0]; LChannel *ch2 = ch1->Fwt(++transform, --depth); if (ch2) { delete channel->SubBands[0]; channel->SubBands[0] = ch2; } } } return(channel); } LChannelCR *NTChannel::RedundantFwtCR(const Wavelet &wavelet) { if (Cols < 2 || Rows < 2) return(NULL); LChannelCR *lifted = new LChannelCR(wavelet, Cols, Rows, OffsetX, OffsetY); lifted->Lazy(*this); LChannelCR *red_lh = new LChannelCR(wavelet, Cols, Rows, OffsetX+1, OffsetY); red_lh->Lazy(*this); LChannelCR *red_hl = new LChannelCR(wavelet, Cols, Rows, OffsetX, OffsetY+1); red_hl->Lazy(*this); LChannelCR *red_hh = new LChannelCR(wavelet, Cols, Rows, OffsetX+1, OffsetY+1); red_hh->Lazy(*this); Destroy(); lifted->CakeWalk(); red_lh->CakeWalk(); red_hl->CakeWalk(); red_hh->CakeWalk(); lifted->Zip(*red_lh, *red_hl, *red_hh); delete lifted->SubBands[SubBand_LL]; lifted->SubBands[SubBand_LL] = this->Clone(); return(lifted); } LChannelC *NTChannel::RedundantFwtC(const Wavelet &wavelet) { if (Rows < 2) return(NULL); LChannelC *lifted = new LChannelC(wavelet, Cols, Rows, OffsetX, OffsetY); lifted->Lazy(*this); LChannelC *redundant = new LChannelC(wavelet, Cols, Rows, OffsetX, OffsetY+1); redundant->Lazy(*this); Destroy(); lifted->CakeWalk(); redundant->CakeWalk(); lifted->Zip(*redundant); return(lifted); } LChannelR *NTChannel::RedundantFwtR(const Wavelet &wavelet) { if (Cols < 2) return(NULL); LChannelR *lifted = new LChannelR(wavelet, Cols, Rows, OffsetX, OffsetY); lifted->Lazy(*this); LChannelR *redundant = new LChannelR(wavelet, Cols, Rows, OffsetX+1, OffsetY); redundant->Lazy(*this); Destroy(); lifted->CakeWalk(); redundant->CakeWalk(); lifted->Zip(*redundant); return(lifted); } NTChannel *NTChannel::DownScale(u_int s, const Wavelet &wavelet) { if (s > 1) if (Cols > 1 && Rows > 1) { LChannelCR *channel = PushFwtStepCR(wavelet); ((NTChannel*)channel->SubBands[SubBand_LH])->Destroy(); ((NTChannel*)channel->SubBands[SubBand_HL])->Destroy(); ((NTChannel*)channel->SubBands[SubBand_HH])->Destroy(); return(((NTChannel*)channel->SubBands[SubBand_LL])-> DownScale(GetOdd(s), wavelet)); } else return(NULL); else { NTChannel *channel = this->Clone(); Destroy(); return(channel); } } NTChannel *NTChannel::DupliScale(u_int s) const { u_int cols = Cols*s; NTChannel *channel = new NTChannel(cols, Rows*s, OffsetX*(int)s, OffsetY*(int)s); PixType *src, *dst; src = dst = channel->Data; u_int js = 0; for (u_int j = 0; j < Rows; j++) { u_int is = 0; for (u_int i = 0; i < Cols; i++) { for (u_int p = 0; p < s; p++) (*channel)(is+p, js) = (*this)(i, j); is += s; } for (u_int q = 1; q < s; q++) { dst += cols; Copy(src, dst, cols); } src = dst += cols; js += s; } return(channel); } void NTChannel::Interpolate(f32 s) { u_int cols = (int)floor(Cols*s); u_int rows = (int)floor(Rows*s); f32 step, x = 0; NTChannel *channel = new NTChannel(cols, Rows, OffsetX, OffsetY); step = (f32)(Cols-1)/(f32)(cols-1); for (u_int c = 0; c < cols; c++) { u_int x1 = (int)floor(x); u_int x2 = Min(x1+1, Cols-1); f32 dx = x-(f32)x1; for (u_int r = 0; r < Rows; r++) (*channel)(c, r) = Interpolate((*this)(x1, r), (*this)(x2, r), dx); x += step; } step = (f32)(Rows-1)/(f32)(rows-1); x = 0; u_int oldRows = Rows; this->Resize(cols, rows); for (u_int r = 0; r < rows; r++) { u_int x1 = (int)floor(x); u_int x2 = Min(x1+1, oldRows-1); f32 dx = x-(f32)x1; for (u_int c = 0; c < cols; c++) (*this)(c, r) = Interpolate((*channel)(c, x1), (*channel)(c, x2), dx); x += step; } delete channel; } void NTChannel::Destroy(void) { delete[] Data; Data = 0; Cols = Rows = OffsetX = OffsetY = 0; } void NTChannel::GetMinMax(PixType &min, PixType &max, u_int smoothing = 0) const { if (smoothing != 0) Die("%s: Smoothing isn't implemented yet!\n", __FUNCTION__); min = max = (*this)(0, 0); for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) if ((*this)(c, r) < min) min = (*this)(c, r); else if ((*this)(c, r) > max) max = (*this)(c, r); } u64 *NTChannel::Histogram(PixType min, PixType max) const { u64 *histogram = new u64[max-min+1]; ::Clear(histogram, max-min+1); u64 *hz = histogram-min; for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) { PixType val = (*this)(c, r); if (val < min) val = min; else if (val > max) val = max; hz[val]++; } return(histogram); } u64 *NTChannel::FullHistogram(PixType &min, PixType &max, u64 &numpixels) const { GetMinMax(min, max); u64 *histogram = Histogram(min, max); numpixels = Cols*Rows; return(histogram); } u64 NTChannel::ThresholdHard(u_int threshold) { u64 cnt = 0; for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) if ((u_int)Abs((*this)(c, r)) < threshold) { (*this)(c, r) = 0; cnt++; } return(cnt); } u64 NTChannel::ThresholdSoft(u_int threshold) { u64 cnt = 0; for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) if ((u_int)Abs((*this)(c, r)) < threshold) { (*this)(c, r) = 0; cnt++; } else if ((*this)(c, r) > 0) (*this)(c, r) -= threshold; else (*this)(c, r) += threshold; return(cnt); } // Generalized Cross Validation u_int NTChannel::OptimalGCVThreshold(void) const { PixType min, max; u_int threshold, first, last, u, v; double minimum, ffirst, flast, fu, fv; GetMinMax(min, max); last = Max(Abs(min), Abs(max)); if (last > 20) last /= 5; if (!last) last = 1; first = u_int(last/50); if (!first) first = 1; u_int f0 = 1; u_int f1 = 1; u_int f2 = 2; while (last-first > f2) { f0 = f1; f1 = f2; f2 = f0+f1; } ffirst = GCV(first); flast = GCV(last); u = first+f0; fu = GCV(u); v = first+f1; fv = GCV(v); while (last-first > 3) { if (fu > fv) { first = u; ffirst = fu; u = v; fu = fv; v = first+last-u; if (v <= u) if (last > u+1) v = (u+last)/2; else v = last; fv = GCV(v); } else { last = v; flast = fv; v = u; fv = fu; u = first+last-v; if (u >= v) if (first < v-1) u = (first+v)/2; else u = first; fu = GCV(u); } } threshold = first; minimum = ffirst; if (fu < minimum) { threshold = u; minimum = fu; } if (fv < minimum) { threshold = v; minimum = fv; } if (flast < minimum) { threshold = last; minimum = flast; } return(threshold); } double NTChannel::GCV(u_int threshold) const { u_int cnt = 0; u64 quadsum = 0; u_int quadthresh = threshold*threshold; double gcv; for (u_int r = 0; r < Rows; r++) for (u_int c = 0; c < Cols; c++) if ((u_int)Abs((*this)(c, r)) < threshold) { cnt++; quadsum += (*this)(c, r)*(*this)(c, r); } else quadsum += quadthresh; gcv = (double)Cols*(double)Rows*(double)quadsum/((double)cnt*(double)cnt); return(gcv); } waili-gpl-19990723/lib/Storage.C100640 24520 25417 12744 6745120270 14625 0ustar geertnatw// // Data Storage Class // // $Id: Storage.C,v 4.0.2.2.2.1 1999/07/20 16:15:52 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include const char *Stream::rcsid = "$Id: Storage.C,v 4.0.2.2.2.1 1999/07/20 16:15:52 geert Exp $"; // Create a Stream Stream::Stream(const char *name, const char *mode) : File(NULL) { Open(name, mode); } // Delete a Stream Stream::~Stream() { if (File) Close(); } // Open a Stream void Stream::Open(const char *name, const char *mode) { if (File) Die("%s: Stream `%s' already opened\n", __FUNCTION__, Name); u_int nlen = strlen(name); if ((nlen > 3) && !strncmp(&name[nlen-3], ".gz", 3)) { Compressed = 1; char *cmd; char *pmode; if (!strcmp(mode, "r")) { cmd = new char[nlen+6]; pmode = "r"; sprintf(cmd, "zcat %s", name); } else if (!strcmp(mode, "w")) { cmd = new char[nlen+8]; pmode = "w"; sprintf(cmd, "gzip > %s", name); } else if (!strcmp(mode, "a")) { cmd = new char[nlen+8]; pmode = "w"; sprintf(cmd, "gzip >> %s", name); } else Die("%s: Invalid mode `%s' for a compressed stream\n", __FUNCTION__, mode); if (!(File = popen(cmd, pmode))) Die("%s: popen() failed for `%s': %s\n", __FUNCTION__, name, strerror(errno)); delete[] cmd; } else { Compressed = 0; if (!(File = fopen(name, mode))) Die("%s: fopen() failed for `%s': %s\n", __FUNCTION__, name, strerror(errno)); } Name = new char[nlen+1]; strcpy(Name, name); Mode = new char[strlen(mode)+1]; strcpy(Mode, mode); } // Close a Stream void Stream::Close(void) { if (!File) Die("%s: Stream not opened yet\n", __FUNCTION__); if (Compressed) pclose(File); else fclose(File); File = NULL; delete[] Name; delete[] Mode; } // Read Raw Data from a Stream void Stream::RawRead(void *data, int size) { if (fread((char *)data, size, 1, File) != 1) Die("%s: fread() on `%s' failed: %s\n", __FUNCTION__, Name, strerror(errno)); } // Write Raw Data to a Stream void Stream::RawWrite(const void *data, int size) { if (fwrite((char *)data, size, 1, File) != 1) Die("%s: fwrite() on `%s' failed: %s\n", __FUNCTION__, Name, strerror(errno)); } // Format and Write a String to a Stream void Stream::Printf(const char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(File, fmt, args); va_end(args); } // Endianness-aware Routines #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN) #if BYTE_ORDER == BIG_ENDIAN #define WAILI_BIG_ENDIAN #elif BYTE_ORDER == LITTLE_ENDIAN #define WAILI_LITTLE_ENDIAN #endif #elif defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) #define WAILI_BIG_ENDIAN #elif defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN) #define WAILI_LITTLE_ENDIAN #endif #if !defined(WAILI_BIG_ENDIAN) && !defined(WAILI_LITTLE_ENDIAN) #error Please fix me #endif static inline u64 ntohll(u64 x) { #ifdef WAILI_BIG_ENDIAN return x; #else u64 hi = ntohl(x & 0xffffffff); u64 lo = ntohl(x >> 32); return hi<<32 | lo; #endif } static inline u64 htonll(u64 x) { #ifdef WAILI_BIG_ENDIAN return x; #else u64 hi = htonl(x & 0xffffffff); u64 lo = htonl(x >> 32); return hi<<32 | lo; #endif } void Stream::Read(u16 *x, u_int cnt) { RawRead(x, cnt*sizeof(*x)); for (u_int i = 0; i < cnt; i++) x[i] = ntohs(x[i]); } void Stream::Read(u32 *x, u_int cnt) { RawRead(x, cnt*sizeof(*x)); for (u_int i = 0; i < cnt; i++) x[i] = ntohl(x[i]); } void Stream::Read(u64 *x, u_int cnt) { RawRead(x, cnt*sizeof(*x)); for (u_int i = 0; i < cnt; i++) x[i] = ntohll(x[i]); } #define TMP_CONVERT_LEN_S 512 #define TMP_CONVERT_LEN_L 256 #define TMP_CONVERT_LEN_LL 128 static union { u16 s[TMP_CONVERT_LEN_S]; u32 l[TMP_CONVERT_LEN_L]; u64 ll[TMP_CONVERT_LEN_LL]; } tmp_convert; void Stream::Write(const u16 *x, u_int cnt) { while (cnt > 0) { u_int cnt2 = Min(cnt, (u_int)TMP_CONVERT_LEN_S); for (u_int i = 0; i < cnt2; i++) tmp_convert.s[i] = htons(x[i]); RawWrite(tmp_convert.s, cnt2*sizeof(*x)); x += cnt2; cnt -= cnt2; } } void Stream::Write(const u32 *x, u_int cnt) { while (cnt > 0) { u_int cnt2 = Min(cnt, (u_int)TMP_CONVERT_LEN_L); for (u_int i = 0; i < cnt2; i++) tmp_convert.l[i] = htonl(x[i]); RawWrite(tmp_convert.l, cnt2*sizeof(*x)); x += cnt2; cnt -= cnt2; } } void Stream::Write(const u64 *x, u_int cnt) { while (cnt > 0) { u_int cnt2 = Min(cnt, (u_int)TMP_CONVERT_LEN_LL); for (u_int i = 0; i < cnt2; i++) tmp_convert.ll[i] = htonll(x[i]); RawWrite(tmp_convert.ll, cnt2*sizeof(*x)); x += cnt2; cnt -= cnt2; } } waili-gpl-19990723/lib/Timer.C100640 24520 25417 10117 6745120270 14271 0ustar geertnatw// // Timer Class // // $Id: Timer.C,v 4.0.4.1 1999/07/20 16:15:52 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #if defined(sun) && !defined(CLK_TCK) // SunOS #define CLK_TCK 60 #endif const char *Timer::rcsid = "$Id: Timer.C,v 4.0.4.1 1999/07/20 16:15:52 geert Exp $"; static inline void CurrentTime(time_t &real, time_t &user, time_t &system) { struct tms tms; real = times(&tms); user = tms.tms_utime; system = tms.tms_stime; } // Start the Timer void Timer::Start(void) { time_t real, user, system; if (!Running) { CurrentTime(real, user, system); Running = 1; Real = real-Real; User = user-User; System = system-System; } } // Stop the Timer void Timer::Stop(void) { time_t real, user, system; if (Running) { CurrentTime(real, user, system); Running = 0; Real = real-Real; User = user-User; System = system-System; } } // Reset the Timer void Timer::Reset(void) { Running = 0; Real = 0; User = 0; System = 0; } // Get the Real part of the Timer f32 Timer::GetReal(void) const { time_t real, user, system; if (Running) { CurrentTime(real, user, system); real -= Real; } else real = Real; return((f32)real/CLK_TCK); } // Get the User part of the Timer f32 Timer::GetUser(void) const { time_t real, user, system; if (Running) { CurrentTime(real, user, system); user -= User; } else user = User; return((f32)user/CLK_TCK); } // Get the System part of the Timer f32 Timer::GetSystem(void) const { time_t real, user, system; if (Running) { CurrentTime(real, user, system); system -= System; } else system = System; return((f32)system/CLK_TCK); } // Get a Time Stamp copy of the Timer Timer Timer::GetStamp(void) const { Timer t; time_t real, user, system; if (Running) { CurrentTime(real, user, system); t.Real = real-Real; t.User = user-User; t.System = system-System; } else { t.Real = Real; t.User = User; t.System = System; } return(t); } // Reset and Start the Timer void Timer::Tic(void) { CurrentTime(Real, User, System); Running = 1; } // Dump the current Timer values void Timer::Toc(void) { Timer t; t = GetStamp(); fprintf(stderr, "Real = %10.3f User = %10.3f System = %10.3f\n", (f32)t.Real/CLK_TCK, (f32)t.User/CLK_TCK, (f32)t.System/CLK_TCK); } // Timer math Timer Timer::operator+(const Timer &t) { Timer res; assert(!Running && !t.Running); res.Real = Real+t.Real; res.User = User+t.User; res.System = System+t.System; return(res); } Timer Timer::operator-(const Timer &t) { Timer res; assert(!Running && !t.Running); res.Real = Real-t.Real; res.User = User-t.User; res.System = System-t.System; return(res); } void Timer::operator+=(const Timer &t) { assert(!t.Running); if (Running) { Real -= t.Real; User -= t.User; System -= t.System; } else { Real += t.Real; User += t.User; System += t.System; } } void Timer::operator-=(const Timer &t) { assert(!t.Running); if (Running) { Real += t.Real; User += t.User; System += t.System; } else { Real -= t.Real; User -= t.User; System -= t.System; } } waili-gpl-19990723/lib/Util.C100640 24520 25417 7643 6745120270 14120 0ustar geertnatw// // Utility Routines // // $Id: Util.C,v 4.0.2.2.2.1 1999/07/20 16:15:52 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include #include #include #include // Program Failure void Die(const char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); exit(1); } // ---------------------------------------------------------------------------- #ifdef TRACK_MEMORY // Memory Tracking #define MAX_HASH (31) #define MEMTRACK_MAGIC (0x4d74724d) // MtrM struct MemChunk { u32 Magic; struct MemChunk *Next; size_t Size; bool IsArray; // sizeof(struct MemChunk) == 16 u_char Address[0]; }; static struct MemChunk *MemChunks[MAX_HASH] = { 0, }; static size_t AllocatedMemory = 0; static void AddMemChunk(struct MemChunk *chunk) { u_int hash = (u_int)chunk % MAX_HASH; chunk->Magic = MEMTRACK_MAGIC; chunk->Next = MemChunks[hash]; MemChunks[hash] = chunk; AllocatedMemory += chunk->Size; } static void RemMemChunk(struct MemChunk *chunk) { u_int hash = (u_int)chunk % MAX_HASH; struct MemChunk **p = &MemChunks[hash]; const char *msg; switch (chunk->Magic) { case MEMTRACK_MAGIC: for (p = &MemChunks[hash]; *p; p = &(*p)->Next) if (*p == chunk) { *p = chunk->Next; chunk->Magic = ~MEMTRACK_MAGIC; AllocatedMemory -= chunk->Size; return; } msg = "Not on list"; break; case ~MEMTRACK_MAGIC: msg = "Freed twice"; break; default: msg = "No magic"; break; } fprintf(stderr, "Warning: trying to delete unallocated block of size %d at" " %p (%s)\n", chunk->Size, chunk->Address, msg); } static void *TrackedMalloc(size_t size, bool is_array) { struct MemChunk *chunk; if (!(chunk = (struct MemChunk *)malloc(sizeof(struct MemChunk)+size))) Die("Fatal Error: Can't allocate %d bytes\n", size); else { chunk->Size = size; chunk->IsArray = is_array; AddMemChunk(chunk); return(chunk->Address); } } static void TrackedFree(void *p, bool is_array) { struct MemChunk *chunk; if (p) { chunk = (struct MemChunk *)(p-sizeof(struct MemChunk)); if (chunk->IsArray != is_array) fprintf(stderr, "Warning: using delete%s on a block allocated with" " new%s (%d bytes at %p)\n", is_array ? " []" : "", is_array ? "" : " []", chunk->Size, chunk->Address); RemMemChunk(chunk); free(chunk); } } void *operator new(size_t size) { return(TrackedMalloc(size, 0)); } void *operator new[](size_t size) { return(TrackedMalloc(size, 1)); } void operator delete(void *p) { TrackedFree(p, 0); } void operator delete[](void *p) { TrackedFree(p, 1); } void DumpMemoryStatus(void) { struct MemChunk *chunk; if (AllocatedMemory) { fprintf(stderr, "%d bytes allocated:\n", AllocatedMemory); for (u_int i = 0; i < MAX_HASH; i++) for (chunk = MemChunks[i]; chunk; chunk = chunk->Next) fprintf(stderr, " %p: %d bytes%s\n", chunk->Address, chunk->Size, chunk->IsArray ? " []" : ""); } else fputs("No memory allocated\n", stderr); } #endif /* TRACK_MEMORY */ waili-gpl-19990723/lib/Wavelet.C100640 24520 25417 27070 6745120270 14626 0ustar geertnatw// // Integer Wavelet Classes // // $Id: Wavelet.C,v 4.1.2.3.2.1 1999/07/20 16:15:52 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include #include // // Biorthogonal Cohen-Daubechies-Feauveau Wavelet Filters // // // D = detail (high freqency) // S = signal (low freqency) // // // (1,1): g~ = ( 1 -1 ) / 2 // start = 0 // h~ = ( 1 1 ) / 2 // start = 0 // // D1 = ( -1 0 ) // S1 = ( 0 1 ) / 2 // // NS = 1 // ND = -1/2 // // // (1,3): g~ = ( 1 -1 ) / 2 // start = 0 // h~ = ( -1 1 8 8 1 -1 ) / 16 // start = -2 // // D1 = ( -1 0 ) // S1 = ( 0 1 8 -1 ) / 16 // // NS = 1 // ND = -1/2 // // // (1,5): g~ = ( 1 -1 ) / 2 // start = 0 // h~ = ( 3 -3 -22 22 128 128 22 -22 -3 3 ) / 256 // start = -4 // // D1 = ( -1 0 ) // S1 = ( 0 -3 22 128 -22 3 ) / 256 // // NS = 1 // ND = -1/2 // // ---------------------------------------------------------------------------- // // (2,2): g~ = ( 1 -2 1 ) / 4 // start = 0 // h~ = ( -1 2 6 2 -1 ) / 8 // start = -2 // // D1 = ( -1 -1 ) / 2 // S1 = ( 1 1) / 4 // // NS = 1 // ND = -1/2 // // // (2,4): g~ = ( 1 -2 1 ) / 4 // start = 0 // h~ = ( 3 -6 -16 38 90 38 -16 -6 3 ) / 128 // start = -4 // // D1 = ( -1 -1 ) / 2 // S1 = ( -3 19 19 -3 ) / 64 // // NS = 1 // ND = -1/2 // // // (2,6): g~ = ( 1 -2 1 ) / 4 // start = 0 // h~ = ( -5 10 34 -78 -123 324 700 324 -123 -78 34 10 -5) / 1024 // start = -6 // // D1 = ( -1 -1 ) / 2 // S1 = ( 5 -39 162 162 -39 5 ) / 512 // // NS = 1 // ND = -1/2 // // ---------------------------------------------------------------------------- // // (3,1): g~ = ( -1 3 -3 1 ) / 8 // start = -1 // h~ = ( -1 3 3 -1 ) / 4 // start = -1 // // S1 = ( -1 0 ) / 3 // D1 = ( -9 -3 ) / 8 // S2 = ( 0 4 ) / 9 // // NS = 3/2 // ND = -1/3 // // // (3,3): g~ = ( -1 3 -3 1 ) / 8 // start = -1 // h~ = ( 3 -9 -7 45 45 -7 -9 3 ) / 64 // start = -3 // // S1 = ( -1 0 ) / 3 // D1 = ( -9 -3 ) / 8 // S2 = ( 0 3 16 -3 ) / 36 // // NS = 3/2 // ND = -1/3 // // // (3,5): g~ = ( -1 3 -3 1 ) / 8 // start = -1 // h~ = ( -5 15 19 -97 -26 350 350 -26 -97 19 15 -5 ) / 512 // start = -5 // // S1 = ( -1 0 ) / 3 // D1 = ( -9 -3 ) / 8 // S2 = ( 0 -5 34 128 -34 5 ) / 288 // // NS = 3/2 // ND = -1/3 // // // ---------------------------------------------------------------------------- // // (4,2): g~ = ( -1 4 -6 4 -1 ) / 16 // start = -1 // h~ = ( 3 -12 5 40 5 -12 3 ) / 32 // start = -3 // // S1 = ( -1 -1 ) / 4 // D1 = ( -1 -1 ) // S2 = ( 3 3 ) / 16 // // NS = 2 // ND = -1/4 // // // (4,4): g~ = ( -1 4 -6 4 -1 ) / 16 // start = -1 // h~ = ( -10 40 -2 -192 140 560 140 -192 -2 40 -10 ) / 512 // start = -5 // // S1 = ( -1 -1 ) / 4 // D1 = ( -1 -1 ) // S2 = ( -5 29 29 -5 ) / 128 // // NS = 2 // ND = -1/4 // // // (4,6): g~ = ( -1 4 -6 4 -1 ) / 16 // start = -1 // h~ = ( 35 -140 -55 920 -557 -2932 2625 8400 2625 -2932 // -557 920 -55 -140 35) / 8192 // start = -7 // // S1 = ( -1 -1 ) / 4 // D1 = ( -1 -1 ) // S2 = ( 35 -265 998 998 -265 35) / 4096 // // NS = 2 // ND = -1/4 // // ---------------------------------------------------------------------------- // // (5,1): g~ = ( 1 -5 10 -10 5 -1 ) / 32 // start = -2 // h~ = ( 3 -15 20 20 -15 3 ) / 16 // start = -2 // // D1 = ( -1 0 ) / 5 // S1 = ( -15 -5 ) / 24 // D2 = ( -15 -9 ) / 10 // S2 = ( 0 1 ) / 3 // // NS = 3 // ND = -1/6 // // // (5,3): g~ = ( 1 -5 10 -10 5 -1 ) / 32 // start = -2 // h~ = ( -5 25 -26 -70 140 140 -70 -26 25 -5 ) / 128 // start = -4 // // D1 = ( -1 0 ) / 5 // S1 = ( -15 -5 ) / 24 // D2 = ( -15 -9 ) / 10 // S2 = ( 0 5 24 -5 ) / 72 // // NS = 3 // ND = -1/6 // // // (5,5): g~ = ( 1 -5 10 -10 5 -1 ) / 32 // start = -2 // h~ = ( 35 -175 120 800 -1357 -1575 4200 4200 -1575 -1357 800 // 120 -175 35 ) / 4096 // start = -6 // // D1 = ( -1 0 ) / 5 // S1 = ( -15 -5 ) / 24 // D2 = ( -15 -9 ) / 10 // S2 = ( 0 -35 230 768 -230 35 ) / 2304 // // NS = 3 // ND = -1/6 // // // ---------------------------------------------------------------------------- // // (6,2): g~ = ( 1 -6 15 -20 15 -6 1 ) / 64 // start = -2 // h~ = ( -5 30 -56 -14 154 -14 -56 30 -5 ) / 64 // start = -4 // // D1 = ( -1 -1 ) / 6 // S1 = ( -9 -9 ) / 16 // D2 = ( -4 -4 ) / 3 // S2 = ( 5 5 ) / 32 // // NS = 4 // ND = -1/8 // // // (6,4): g~ = ( 1 -6 15 -20 15 -6 1 ) / 64 // start = -2 // h~ = ( 35 -210 330 470 -1827 252 3948 252 -1827 470 330 -210 // 35 ) / 2048 // start = -6 // // D1 = ( -1 -1 ) / 6 // S1 = ( -9 -9 ) / 16 // D2 = ( -4 -4 ) / 3 // S2 = ( -35 195 195 -35 ) / 1024 // // NS = 4 // ND = -1/8 // // // (6,6): g~ = ( 1 -6 15 -20 15 -6 1 ) / 64 // start = -2 // h~ = ( -63 378 -476 -1554 4404 1114 -13860 4158 28182 4158 // -13860 1114 4404 -1554 -476 378 -63 ) / 16384 // start = -8 // // D1 = ( -1 -1 ) / 6 // S1 = ( -9 -9 ) / 16 // D2 = ( -4 -4 ) / 3 // S2 = ( 63 -469 1686 1686 -469 63 ) / 8192 // // NS = 4 // ND = -1/8 // // // ---------------------------------------------------------------------------- // // // Some more wavelets used by JPEG2000 // // Biorthogonal CRF (13, 7): // // g~ = ( 1 0 -9 16 -9 0 1 ) / 16 // start = -4 // h~ = ( -1 0 14 -16 -31 80 164 80 -31 -16 14 0 -1 ) / 256 // start = -6 // // D1 = ( 1 -9 -9 1 ) / 16 // S1 = ( -1 5 5 -1 ) / 16 // // NS = 1 // ND = 1 // // // Biorthogonal SWE (13, 7): // // g~ = ( 1 0 -9 16 -9 0 1 ) / 16 // start = -4 // h~ = ( -1 0 18 -16 -63 144 348 144 -63 -16 18 0 -1 ) / 512 // start = -6 // // D1 = ( 1 -9 -9 1 ) / 16 // S1 = ( -1, 9, 9, -1 ) / 32 // // NS = 1 // ND = 1 // // // ---------------------------------------------------------------------------- // // Growth of the wavelet coefficients for 8-bit (-128..127) input data // (obtained by experiments) // // // CDF (1, 1): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -128..127 -255..255 // 2 -128..127 -255..255 // 3 -128..127 -255..255 // 4 -128..127 -255..255 // 5 -128..127 -255..255 // 6 -128..127 -255..255 // 7 -128..127 -255..255 // 8 -128..127 -255..255 // 9 -128..127 -255..255 // 10 -128..127 -255..255 // // CDF (1, 3): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -159..159 -255..255 // 2 -162..163 -286..286 // 3 -164..165 -291..291 // 4 -164..165 -293..293 // 5 -164..165 -293..293 // 6 -164..165 -293..293 // 7 -165..166 -293..293 // 8 -164..166 -293..293 // 9 -165..166 -293..293 // 10 -165..166 -293..293 // // CDF (1, 5): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -177..177 -255..255 // 2 -179..180 -310..310 // 3 -182..184 -315..315 // 4 -182..184 -319..319 // 5 -183..184 -319..319 // 6 -183..184 -319..319 // 7 -183..184 -319..319 // 8 -182..184 -319..319 // 9 -183..184 -319..319 // // CDF (2, 2): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -191..191 -510..510 // 2 -206..207 -636..638 // 3 -214..214 -700..698 // 4 -215..216 -712..714 // 5 -217..217 -718..718 // 6 -218..218 -724..720 // 7 -217..218 -724..722 // 8 -217..218 -724..720 // 9 -218..218 -724..726 // 10 -216..218 -722..724 // // CDF (2, 4): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -215..215 -510..510 // 2 -222..223 -708..708 // 3 -232..232 -776..776 // 4 -232..234 -796..800 // 5 -232..234 -802..802 // 6 -233..234 -804..804 // 7 -233..234 -804..804 // 8 -233..234 -802..802 // 9 -233..234 -804..806 // 10 -233..234 -804..804 // // CDF (2, 6): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -230..230 -510..510 // 2 -236..237 -758..758 // 3 -245..246 -828..828 // 4 -245..248 -848..848 // 5 -245..247 -852..856 // 6 -246..247 -854..856 // // CDF (4, 2): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -318..319 -1020..1018 // 2 -524..527 -2096..2094 // 3 -949..951 -3498..3496 // 4 -1580..1586 -6890..6880 // 5 -2726..2731 -11102..11094 // 6 -4623..4629 -19380..19380 // 7 -7928..7933 -32482..32488 // 8 -13522..13530 -55888..55892 // 9 -23105..23116 -94794..94794 // 10 -39428..39438 -162448..162446 // // CDF (4, 4): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -330..331 -1020..1018 // 2 -456..456 -2238..2236 // 3 -583..587 -3410..3410 // 4 -713..715 -4212..4216 // 5 -859..865 -5212..5210 // 6 -1015..1019 -6274..6272 // 7 -1180..1187 -7300..7304 // 8 -1370..1377 -8574..8566 // 9 -1582..1590 -9948..9948 // 10 -1819..1829 -11434..11450 // // CDF (4, 6): # levels Low-Pass High-Pass // -------- -------- --------- // 1 -356..357 -1020..1018 // 2 -463..464 -2388..2386 // 3 -499..502 -3366..3364 // 4 -539..544 -3742..3746 // 5 -563..568 -3980..3978 // 6 -576..582 -4148..4136 // 7 -583..589 -4228..4228 // const char *Wavelet::rcsid = "$Id: Wavelet.C,v 4.1.2.3.2.1 1999/07/20 16:15:52 geert Exp $"; // Biorthogonal Cohen-Daubechies-Feauveau Wavelet *Wavelet::CreateCDF(u_int np, u_int nd) { switch (np) { case 0: switch (nd) { case 0: return(new Wavelet_Lazy); } break; case 1: switch (nd) { case 1: return(new Wavelet_CDF_1_1); case 3: return(new Wavelet_CDF_1_3); case 5: return(new Wavelet_CDF_1_5); } break; case 2: switch (nd) { case 2: return(new Wavelet_CDF_2_2); case 4: return(new Wavelet_CDF_2_4); case 6: return(new Wavelet_CDF_2_6); } break; case 4: switch (nd) { case 2: return(new Wavelet_CDF_4_2); case 4: return(new Wavelet_CDF_4_4); case 6: return(new Wavelet_CDF_4_6); } break; } if ((np & 1) == (nd & 1)) Die("%s: Cohen-Daubechies-Feauveau (%d, %d) wasn't implemented\n", __FUNCTION__, np, nd); else Die("%s: Cohen-Daubechies-Feauveau (%d, %d) does not exist\n", __FUNCTION__, np, nd); } // Create a Wavelet from an ID Wavelet *Wavelet::CreateFromID(u8 id) { switch (id) { case ID_CDF_1_1: return new Wavelet_CDF_1_1; case ID_CDF_1_3: return new Wavelet_CDF_1_3; case ID_CDF_1_5: return new Wavelet_CDF_1_5; case ID_CDF_2_2: return new Wavelet_CDF_2_2; case ID_CDF_2_4: return new Wavelet_CDF_2_4; case ID_CDF_2_6: return new Wavelet_CDF_2_6; case ID_CDF_4_2: return new Wavelet_CDF_4_2; case ID_CDF_4_4: return new Wavelet_CDF_4_4; case ID_CDF_4_6: return new Wavelet_CDF_4_6; case ID_CRF_13_7: return new Wavelet_CRF_13_7; case ID_SWE_13_7: return new Wavelet_SWE_13_7; default: Die("%s: Illegal ID %u\n", __FUNCTION__, id); } } waili-gpl-19990723/lib/Wavelet_CDF_1_x.C100640 24520 25417 6443 6745120270 16032 0ustar geertnatw// // Integer Wavelet Classes // // Biorthogonal Cohen-Daubechies-Feauveau (1, x) // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // $Id: Wavelet_CDF_1_x.C,v 4.1.4.1 1999/07/20 16:15:52 geert Exp $ // #include #include const char *Wavelet_CDF_1_x::rcsid = "$Id: Wavelet_CDF_1_x.C,v 4.1.4.1 1999/07/20 16:15:52 geert Exp $"; const s16 LiftCoef_CDF_1_x::D1b[2] = { -1, 0 }; const u16 LiftCoef_CDF_1_x::D1a = 1; // Biorthogonal Cohen-Daubechies-Feauveau (1, 1) const s16 LiftCoef_CDF_1_1::P2b[2] = { 0, 1 }; const u16 LiftCoef_CDF_1_1::P2a = 2; void Wavelet_CDF_1_1::CakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR_0_m1_0_1(); lifting.Lift_L1R1_FR_1_0_1_2(); #else // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR(0, D1b, D1a); lifting.Lift_L1R1_FR(1, P2b, P2a); #endif // !LIFTING_OPTIMIZE_STEPS } void Wavelet_CDF_1_1::ICakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR_1_0_1_2(); lifting.ILift_L1R1_FR_0_m1_0_1(); #else // !LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR(1, P2b, P2a); lifting.ILift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS } // Biorthogonal Cohen-Daubechies-Feauveau (1, 3) const s16 LiftCoef_CDF_1_3::P2b[4] = { 0, 1, 8, -1 }; const u16 LiftCoef_CDF_1_3::P2a = 16; void Wavelet_CDF_1_3::CakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR_0_m1_0_1(); #else // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L2R2_FR(1, P2b, P2a); } void Wavelet_CDF_1_3::ICakeWalk(Lifting &lifting) const { lifting.ILift_L2R2_FR(1, P2b, P2a); #if LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR_0_m1_0_1(); #else // !LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS } // Biorthogonal Cohen-Daubechies-Feauveau (1, 5) const s16 LiftCoef_CDF_1_5::P2b[6] = { 0, -3, 22, 128, -22, 3 }; const u16 LiftCoef_CDF_1_5::P2a = 256; void Wavelet_CDF_1_5::CakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR_0_m1_0_1(); #else // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L3R3_FR(1, P2b, P2a); } void Wavelet_CDF_1_5::ICakeWalk(Lifting &lifting) const { lifting.ILift_L3R3_FR(1, P2b, P2a); #if LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR_0_m1_0_1(); #else // !LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS } waili-gpl-19990723/lib/Wavelet_CDF_2_x.C100640 24520 25417 6715 6745120270 16035 0ustar geertnatw// // Integer Wavelet Classes // // Biorthogonal Cohen-Daubechies-Feauveau (2, x) // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // $Id: Wavelet_CDF_2_x.C,v 4.2.2.1.2.1 1999/07/20 16:15:52 geert Exp $ // #include #include const char *Wavelet_CDF_2_x::rcsid = "$Id: Wavelet_CDF_2_x.C,v 4.2.2.1.2.1 1999/07/20 16:15:52 geert Exp $"; const s16 LiftCoef_CDF_2_x::D1b[2] = { -1, -1 }; const u16 LiftCoef_CDF_2_x::D1a = 2; // Biorthogonal Cohen-Daubechies-Feauveau (2, 2) const s16 LiftCoef_CDF_2_2::P2b[2] = { 1, 1 }; const u16 LiftCoef_CDF_2_2::P2a = 4; void Wavelet_CDF_2_2::CakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS // Optimized version lifting.Lift_L1R1_FR_0_m1_m1_2(); lifting.Lift_L1R1_FR_1_1_1_4(); #else // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR(0, D1b, D1a); lifting.Lift_L1R1_FR(1, P2b, P2a); #endif // !LIFTING_OPTIMIZE_STEPS } void Wavelet_CDF_2_2::ICakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS // Optimized version lifting.ILift_L1R1_FR_1_1_1_4(); lifting.ILift_L1R1_FR_0_m1_m1_2(); #else // !LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR(1, P2b, P2a); lifting.ILift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS } // Biorthogonal Cohen-Daubechies-Feauveau (2, 4) const s16 LiftCoef_CDF_2_4::P2b[4] = { -3, 19, 19, -3 }; const u16 LiftCoef_CDF_2_4::P2a = 64; void Wavelet_CDF_2_4::CakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS // Optimized version lifting.Lift_L1R1_FR_0_m1_m1_2(); #else // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L2R2_FR(1, P2b, P2a); } void Wavelet_CDF_2_4::ICakeWalk(Lifting &lifting) const { lifting.ILift_L2R2_FR(1, P2b, P2a); #if LIFTING_OPTIMIZE_STEPS // Optimized version lifting.ILift_L1R1_FR_0_m1_m1_2(); #else // !LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS } // Biorthogonal Cohen-Daubechies-Feauveau (2, 6) const s16 LiftCoef_CDF_2_6::P2b[6] = { 5, -39, 162, 162, -39, 5 }; const u16 LiftCoef_CDF_2_6::P2a = 512; void Wavelet_CDF_2_6::CakeWalk(Lifting &lifting) const { #if LIFTING_OPTIMIZE_STEPS // Optimized version lifting.Lift_L1R1_FR_0_m1_m1_2(); #else // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS lifting.Lift_L3R3_FR(1, P2b, P2a); } void Wavelet_CDF_2_6::ICakeWalk(Lifting &lifting) const { lifting.ILift_L3R3_FR(1, P2b, P2a); #if LIFTING_OPTIMIZE_STEPS // Optimized version lifting.ILift_L1R1_FR_0_m1_m1_2(); #else // !LIFTING_OPTIMIZE_STEPS lifting.ILift_L1R1_FR(0, D1b, D1a); #endif // !LIFTING_OPTIMIZE_STEPS } waili-gpl-19990723/lib/Wavelet_CDF_4_x.C100640 24520 25417 5555 6745120270 16040 0ustar geertnatw// // Integer Wavelet Classes // // Biorthogonal Cohen-Daubechies-Feauveau (4, x) // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // $Id: Wavelet_CDF_4_x.C,v 4.2.2.1.2.1 1999/07/20 16:15:52 geert Exp $ // #include #include const char *Wavelet_CDF_4_x::rcsid = "$Id: Wavelet_CDF_4_x.C,v 4.2.2.1.2.1 1999/07/20 16:15:52 geert Exp $"; const s16 LiftCoef_CDF_4_x::P1b[2] = { -1, -1 }; const u16 LiftCoef_CDF_4_x::P1a1 = 2; const u16 LiftCoef_CDF_4_x::P1a2 = 2; const s16 LiftCoef_CDF_4_x::D2b[2] = { -1, -1 }; const u16 LiftCoef_CDF_4_x::D2a = 2; // Biorthogonal Cohen-Daubechies-Feauveau (4, 2) const s16 LiftCoef_CDF_4_2::P3b[2] = { 3, 3 }; const u16 LiftCoef_CDF_4_2::P3a = 8; void Wavelet_CDF_4_2::CakeWalk(Lifting &lifting) const { lifting.Lift_L1R1_MX(1, P1b, P1a1, P1a2); lifting.Lift_L1R1_FR(0, D2b, D2a); lifting.Lift_L1R1_FR(1, P3b, P3a); } void Wavelet_CDF_4_2::ICakeWalk(Lifting &lifting) const { lifting.ILift_L1R1_FR(1, P3b, P3a); lifting.ILift_L1R1_FR(0, D2b, D2a); lifting.ILift_L1R1_MX(1, P1b, P1a1, P1a2); } // Biorthogonal Cohen-Daubechies-Feauveau (4, 4) const s16 LiftCoef_CDF_4_4::P3b[4] = { -5, 29, 29, -5 }; const u16 LiftCoef_CDF_4_4::P3a = 64; void Wavelet_CDF_4_4::CakeWalk(Lifting &lifting) const { lifting.Lift_L1R1_MX(1, P1b, P1a1, P1a2); lifting.Lift_L1R1_FR(0, D2b, D2a); lifting.Lift_L2R2_FR(1, P3b, P3a); } void Wavelet_CDF_4_4::ICakeWalk(Lifting &lifting) const { lifting.ILift_L2R2_FR(1, P3b, P3a); lifting.ILift_L1R1_FR(0, D2b, D2a); lifting.ILift_L1R1_MX(1, P1b, P1a1, P1a2); } // Biorthogonal Cohen-Daubechies-Feauveau (4, 6) const s16 LiftCoef_CDF_4_6::P3b[6] = { 35, -265, 998, 998, -265, 35 }; const u16 LiftCoef_CDF_4_6::P3a = 2048; void Wavelet_CDF_4_6::CakeWalk(Lifting &lifting) const { lifting.Lift_L1R1_MX(1, P1b, P1a1, P1a2); lifting.Lift_L1R1_FR(0, D2b, D2a); lifting.Lift_L3R3_FR(1, P3b, P3a); } void Wavelet_CDF_4_6::ICakeWalk(Lifting &lifting) const { lifting.ILift_L3R3_FR(1, P3b, P3a); lifting.ILift_L1R1_FR(0, D2b, D2a); lifting.ILift_L1R1_MX(1, P1b, P1a1, P1a2); } waili-gpl-19990723/lib/Wavelet_JPEG2000.C100644 24520 25417 4256 6745120271 15723 0ustar geertnatw// // Integer Wavelet Classes // // Some more wavelets used by JPEG2000 // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // $Id: Wavelet_JPEG2000.C,v 5.1.2.1.2.1 1999/07/20 16:15:53 geert Exp $ // #include // Biorthogonal CRF (13, 7) const char *Wavelet_CRF_13_7::rcsid = "$Id: Wavelet_JPEG2000.C,v 5.1.2.1.2.1 1999/07/20 16:15:53 geert Exp $"; const s16 Wavelet_CRF_13_7::D1b[4] = { 1, -9, -9, 1 }; const u16 Wavelet_CRF_13_7::D1a = 16; const s16 Wavelet_CRF_13_7::P2b[4] = { -1, 5, 5, -1 }; const u16 Wavelet_CRF_13_7::P2a = 16; void Wavelet_CRF_13_7::CakeWalk(Lifting &lifting) const { lifting.Lift_L2R2_FR(0, D1b, D1a); lifting.Lift_L2R2_FR(1, P2b, P2a); } void Wavelet_CRF_13_7::ICakeWalk(Lifting &lifting) const { lifting.ILift_L2R2_FR(1, P2b, P2a); lifting.ILift_L2R2_FR(0, D1b, D1a); } // Biorthogonal SWE (13, 7) const char *Wavelet_SWE_13_7::rcsid = "$Id: Wavelet_JPEG2000.C,v 5.1.2.1.2.1 1999/07/20 16:15:53 geert Exp $"; const s16 Wavelet_SWE_13_7::D1b[4] = { 1, -9, -9, 1 }; const u16 Wavelet_SWE_13_7::D1a = 16; const s16 Wavelet_SWE_13_7::P2b[4] = { -1, 9, 9, -1 }; const u16 Wavelet_SWE_13_7::P2a = 32; void Wavelet_SWE_13_7::CakeWalk(Lifting &lifting) const { lifting.Lift_L2R2_FR(0, D1b, D1a); lifting.Lift_L2R2_FR(1, P2b, P2a); } void Wavelet_SWE_13_7::ICakeWalk(Lifting &lifting) const { lifting.ILift_L2R2_FR(1, P2b, P2a); lifting.ILift_L2R2_FR(0, D1b, D1a); } waili-gpl-19990723/Makefile100640 24520 25417 2605 6745120241 13760 0ustar geertnatw# # Root Makefile # # $Id: Makefile,v 4.2.2.1.2.1 1999/07/20 16:15:29 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # SUBDIRS = include lib test ifeq (man,$(wildcard man)) SUBDIRS += man endif All: Rules.config .depend set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done Rules.config: $(MAKE) -C config clean: rm -f .depend set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i clean; done distclean: clean rm -f Rules.config config: dummy rm -f Rules.config $(MAKE) Rules.config .depend: set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i depend; done touch .depend depend: rm -f .depend $(MAKE) .depend dummy: waili-gpl-19990723/README.GPL100644 24520 25417 43127 6745120241 13651 0ustar geertnatw GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. waili-gpl-19990723/Rules.make100640 24520 25417 1743 6745120241 14253 0ustar geertnatw# # Default rules # # $Id: Rules.make,v 4.0.4.1 1999/07/20 16:15:29 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # %.o: %.C $(CXX) $(CFLAGS) -c $< -o $@ ifeq (.depend,$(wildcard .depend)) include .depend endif waili-gpl-19990723/config/ 40755 24520 25417 0 6746056432 13504 5ustar geertnatwwaili-gpl-19990723/config/Configure100750 24520 25417 2555 6745120251 15440 0ustar geertnatw#!/bin/sh # # Simple configuration script # # $Id: Configure,v 4.2.4.1 1999/07/20 16:15:37 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # arch=`uname` compiler=g++ # We always assume the GNU compiler case $arch in Linux) # ix86-linux, m68k-linux etc. system=Linux; ;; *) # sparc-sun-solaris etc. system=UNIX; ;; esac echo echo " Configuring for $system" echo if [ "$PWD" != "" ]; then topdir=$PWD; else topdir=`pwd`; fi topdir=`echo $topdir | sed -e 's@/config$@@'` rm -f ../Rules.config sed -e "s@-top-dir-here-@$topdir@" < Rules.$system.$compiler > ../Rules.config exit 0 waili-gpl-19990723/config/Makefile100640 24520 25417 1632 6745120251 15225 0ustar geertnatw# # Makefile for config # # $Id: Makefile,v 4.0.2.1.2.1 1999/07/20 16:15:37 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # All: ./Configure waili-gpl-19990723/config/Rules.Linux.g++100640 24520 25417 2730 6745120251 16253 0ustar geertnatw# # Configuration for Linux 2.0.x and g++ 2.7.2 # # Tested on: # # PC (Intel Pentium, Linux/i386 2.0.x, g++ 2.7.2) # Amiga (Motorola 68040, Linux/m68k 2.0.x, g++ 2.7.2) # # $Id: Rules.Linux.g++,v 4.1.4.1 1999/07/20 16:15:37 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # CXX = g++ TOPDIR = -top-dir-here- TIFFDEF = -DSUPPORT_TIFF #TIFFDIR = ../libtiff #TIFFINC = -I$(TIFFDIR) #TIFFLIB = -L$(TIFFDIR) -ltiff TIFFLIB = -ltiff OPTFLAGS = -O3 -fomit-frame-pointer #DEBUGFLAGS = -DTRACK_MEMORY -DBOUNDS_CHECK -g CFLAGS = -Wall -I$(TOPDIR)/include $(TIFFINC) $(TIFFDEF) $(OPTFLAGS) \ $(DEBUGFLAGS) LFLAGS = -L$(TOPDIR)/lib -lm -lwaili $(TIFFLIB) AR = ar RANLIB = ranlib DEPLIBS = $(TOPDIR)/lib/libwaili.a waili-gpl-19990723/config/Rules.UNIX.g++100640 24520 25417 3174 6745120251 15742 0ustar geertnatw# # Configuration for UNIX and g++ 2.7.2 # # Tested on: # # PC (Intel Pentium, Linux/i386 2.0.x, g++ 2.7.2) # Amiga (Motorola 68040, Linux/m68k 2.0.x, g++ 2.7.2) # Sun-4u (Sun UltraSPARC, Solaris 2.5, g++ 2.7.2) # Sun-4c (Sun SPARC, SunOS 4.1.3, g++ 2.7.2) # IBM SP2 (IBM POWER2, AIX 4.1.4, g++ 2.7.2) # DECstation 5000 (MIPS R3000, Ultrix 4.4, g++ 2.7.2) # # $Id: Rules.UNIX.g++,v 4.1.4.1 1999/07/20 16:15:37 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # CXX = g++ TOPDIR = -top-dir-here- #TIFFDEF = -DSUPPORT_TIFF #TIFFDIR = ../libtiff #TIFFINC = -I$(TIFFDIR) #TIFFLIB = -L$(TIFFDIR) -ltiff OPTFLAGS = -O3 -fomit-frame-pointer #DEBUGFLAGS = -DTRACK_MEMORY -DBOUNDS_CHECK -g CFLAGS = -Wall -I$(TOPDIR)/include $(TIFFINC) $(TIFFDEF) $(OPTFLAGS) \ $(DEBUGFLAGS) LFLAGS = -L$(TOPDIR)/lib -lm -lwaili $(TIFFLIB) AR = ar RANLIB = ranlib DEPLIBS = $(TOPDIR)/lib/libwaili.a waili-gpl-19990723/include/ 40755 24520 25417 0 6746056432 13662 5ustar geertnatwwaili-gpl-19990723/include/Makefile100640 24520 25417 2220 6745120254 15400 0ustar geertnatw# # Makefile for include # # $Id: Makefile,v 4.0.4.1 1999/07/20 16:15:40 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # include ../Rules.config SUBDIRS = waili All: set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done clean: set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i clean; done depend: set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i depend; done include ../Rules.make waili-gpl-19990723/include/waili/ 40755 24520 25417 0 6746056433 14770 5ustar geertnatwwaili-gpl-19990723/include/waili/Blit.h100640 24520 25417 5570 6745120257 16126 0ustar geertnatw// // Low-Level Block Operations // // $Id: Blit.h,v 4.0.4.1 1999/07/20 16:15:43 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_BLIT_H #define WAILI_BLIT_H #include "Types.h" #include // Copy a Block of Data template inline void Copy(const Type *src, Type *dst, u_int len) { memmove(dst, src, len*sizeof(Type)); } template inline void Copy(const Type *src, Type *dst) { memmove(dst, src, sizeof(Type)); } // Fill a Block of Data template inline void Fill(Type *dst, u_int len, Type value) { for (u_int i = 0; i < len; i++) dst[i] = value; } // Clear a Block of Data template inline void Clear(Type *dst, u_int len) { memset(dst, 0, len*sizeof(Type)); } template inline void Clear(Type *dst) { memset(dst, 0, sizeof(Type)); } // Copy a Rectangular Block template inline void CopyRect(const Type *src, u_int sw, Type *dst, u_int dw, u_int cols, u_int rows) { for (u_int r = 0; r < rows; r++) { Copy(src, dst, cols); src += sw; dst += dw; } } template inline void CopyRect(const Type *src, u_int sw, u_int sx, u_int sy, Type *dst, u_int dw, u_int dx, u_int dy, u_int cols, u_int rows) { CopyRect(src+sy*sw+sx, sw, dst+dy*dw+dx, dw, cols, rows); } // Fill a Rectangular Block template inline void FillRect(Type *dst, u_int dw, u_int cols, u_int rows, Type value) { for (u_int r = 0; r < rows; r++) { Fill(dst, cols, value); dst += dw; } } template inline void FillRect(Type *dst, u_int dw, u_int dx, u_int dy, u_int cols, u_int rows, Type value) { FillRect(dst+dy*dw+dx, dw, cols, rows, value); } // Clear a Rectangular Block template inline void ClearRect(Type *dst, u_int dw, u_int cols, u_int rows) { for (u_int r = 0; r < rows; r++) { Clear(dst, cols); dst += dw; } } template inline void ClearRect(Type *dst, u_int dw, u_int dx, u_int dy, u_int cols, u_int rows) { ClearRect(dst+dy*dw+dx, dw, cols, rows, value); } #endif // WAILI_BLIT_H waili-gpl-19990723/include/waili/Channel.h100640 24520 25417 11436 6745120257 16622 0ustar geertnatw// // Channel Class // // $Id: Channel.h,v 4.5.2.3.2.1 1999/07/20 16:15:43 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_CHANNEL_H #define WAILI_CHANNEL_H #include #include "Wavelet.h" #include "Blit.h" enum TransformType { TT_ColsRows, TT_Cols, TT_Rows }; struct TransformDescriptor { u8 type; // TransformType u8 filter; // Wavelet_IDs }; // Channel Abstract Base Class class LChannel; // class LChannelCR; class Channel { friend class LChannelCR; friend class LChannelC; friend class LChannelR; public: // Construction/Destruction Channel(); Channel(u_int cols, u_int rows, int offx = 0, int offy = 0); Channel(const Channel &channel); virtual ~Channel(); static Channel *CreateFromDescriptor(u_int cols, u_int rows, const TransformDescriptor transform[], u_int depth, int offsetx = 0, int offsety = 0); // Properties u_int GetCols(void) const; u_int GetRows(void) const; int GetOffsetX(void) const; int GetOffsetY(void) const; virtual void GetMask(u_int &maskx, u_int &masky) const = 0; virtual u_int GetDepth(void) const = 0; virtual double Psnr(const Channel &channel, PixType maxval = 255) const; virtual u64 *FullHistogram(PixType &min, PixType &max, u64 &numpixels) const = 0; double Entropy(void) const; // Manipulation virtual PixType &operator()(u_int c, u_int r) = 0; virtual PixType operator()(u_int c, u_int r) const = 0; virtual void Clear(void) = 0; virtual void Resize(u_int cols, u_int rows); virtual Channel *Clone(void) const = 0; virtual void SetOffsetX(int offx) = 0; virtual void SetOffsetY(int offy) = 0; virtual Channel *Crop(int x1, int y1, int x2, int y2) const = 0; virtual void Merge(const Channel &channel) = 0; virtual void Add(const Channel &channel) = 0; virtual void Subtract(const Channel &channel) = 0; virtual Channel *Diff(const Channel &channel) const = 0; virtual void Enhance(f32 m) = 0; virtual void Enhance(int m, u_int shift) = 0; // Wavelet Transforms virtual LChannel *PushFwtStepCR(const Wavelet &wavelet) = 0; virtual LChannel *PushFwtStepC(const Wavelet &wavelet) = 0; virtual LChannel *PushFwtStepR(const Wavelet &wavelet) = 0; virtual Channel *PopFwtStep(void) = 0; // Thresholding virtual u64 Threshold(double threshold, int soft = 0) = 0; // This should be removed later!! The user doesn't need to know // what's the internal representation of the channel virtual int IsLifted(void) const = 0; // Wavelet Based Operations Channel *Scale(f32 s, const Wavelet &wavelet); protected: virtual void Destroy(void) = 0; // Wavelet Based Operations virtual Channel *DownScale(u_int s, const Wavelet &wavelet) = 0; Channel *UpScale(u_int s, const Wavelet &wavelet); static int GetEven(int len); static int GetOdd(int len); protected: u_int Cols, Rows; int OffsetX, OffsetY; private: static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// inline Channel::Channel() : Cols(0), Rows(0), OffsetX(0), OffsetY(0) {} inline Channel::Channel(u_int cols, u_int rows, int offx, int offy) : Cols(cols), Rows(rows), OffsetX(offx), OffsetY(offy) {} inline Channel::Channel(const Channel &channel) : Cols(channel.Cols), Rows(channel.Rows), OffsetX(channel.OffsetX), OffsetY(channel.OffsetY) {} inline Channel::~Channel() {} inline u_int Channel::GetCols(void) const { return(Cols); } inline u_int Channel::GetRows(void) const { return(Rows); } inline int Channel::GetOffsetX(void) const { return(OffsetX); } inline int Channel::GetOffsetY(void) const { return(OffsetY); } inline void Channel::Resize(u_int cols, u_int rows) { Cols = cols; Rows = rows; } inline int Channel::GetEven(int len) { return((len+(len>=0))/2); } inline int Channel::GetOdd(int len) { return((len-(len<0))/2); } // Include derived classes #include "LChannel.h" #include "NTChannel.h" #endif // WAILI_CHANNEL_H waili-gpl-19990723/include/waili/Color.h100640 24520 25417 10636 6745120260 16323 0ustar geertnatw// // Color Spaces // // $Id: Color.h,v 4.0.2.1.2.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_COLOR_H #define WAILI_COLOR_H #include "Types.h" class Color_RGB8; class Color_XYZ8; class Color_LAB8; class Color_RGB { public: Color_RGB() {} Color_RGB(const Color_RGB8 &rgb8); f32 r, g, b; }; class Color_XYZ { public: Color_XYZ() {} Color_XYZ(const Color_XYZ8 &xyz8); f32 x, y, z; }; class Color_LAB { public: Color_LAB() {} Color_LAB(const Color_LAB8 &lab8); f32 l, a, b; }; class Color_RGB8 { public: Color_RGB8() {} Color_RGB8(const Color_RGB &rgb); u8 r, g, b; }; class Color_XYZ8 { public: Color_XYZ8() {} Color_XYZ8(const Color_XYZ &xyz); u8 x, y, z; }; class Color_LAB8 { public: Color_LAB8() {} Color_LAB8(const Color_LAB &lab); u8 l; s8 a, b; }; class Color_CIEY { public: Color_CIEY() {} f32 y; }; class Color_CIEL { public: Color_CIEL() {} f32 l; }; class Color_RGB16 { public: Color_RGB16() {} s16 r, g, b; }; class Color_YUVr16 { public: Color_YUVr16() {} s16 yr, ur, vr; }; class ColorSpace { public: ColorSpace(void); void SetPrimChroma(const f32 chroma[6], int immediate = 1); void GetPrimChroma(f32 chroma[6]) const; void SetWhitePoint(const f32 wp[2], int immediate = 1); void GetWhitePoint(f32 wp[2]) const; // Color Conversions (f32) void Convert(const Color_RGB &rgb, Color_XYZ &xyz) const; void Convert(const Color_XYZ &xyz, Color_RGB &rgb) const; void Convert(const Color_XYZ &xyz, Color_LAB &lab) const; void Convert(const Color_LAB &lab, Color_XYZ &xyz) const; void Convert(const Color_RGB &rgb, Color_LAB &lab) const; void Convert(const Color_LAB &lab, Color_RGB &rgb) const; // Color to Gray Conversions (f32) void Convert(const Color_RGB &rgb, Color_CIEY &y) const; void Convert(const Color_XYZ &xyz, Color_CIEY &y) const; void Convert(const Color_RGB &rgb, Color_CIEL &l) const; void Convert(const Color_XYZ &xyz, Color_CIEL &l) const; // Gray Conversions (f32) static void Convert(const Color_CIEY &y, Color_CIEL &l); static void Convert(const Color_CIEL &l, Color_CIEY &y); // Color Conversions (8 bit) void Convert(const Color_RGB8 &rgb, Color_XYZ8 &xyz) const; void Convert(const Color_XYZ8 &xyz, Color_RGB8 &rgb) const; void Convert(const Color_XYZ8 &xyz, Color_LAB8 &lab) const; void Convert(const Color_LAB8 &lab, Color_XYZ8 &xyz) const; void Convert(const Color_RGB8 &rgb, Color_LAB8 &lab) const; void Convert(const Color_LAB8 &lab, Color_RGB8 &rgb) const; // Color Conversions (16 bit) static void Convert(const Color_RGB16 &rgb, Color_YUVr16 &yuvr); static void Convert(const Color_YUVr16 &yuvr, Color_RGB16 &rgb); protected: void CalcConvMat(void); private: Color_XYZ PrimChroma[3]; Color_XYZ WhitePoint; f32 RGB2XYZ[3][3]; f32 XYZ2RGB[3][3]; private: static const char *rcsid; }; // ---------------------------------------------------------------------------- // Inline Class Member Functions inline void ColorSpace::Convert(const Color_RGB &rgb, Color_LAB &lab) const { Color_XYZ xyz; Convert(rgb, xyz); Convert(xyz, lab); } inline void ColorSpace::Convert(const Color_LAB &lab, Color_RGB &rgb) const { Color_XYZ xyz; Convert(lab, xyz); Convert(xyz, rgb); } inline void ColorSpace::Convert(const Color_XYZ &xyz, Color_CIEY &y) const { y.y = xyz.y; } inline void ColorSpace::Convert(const Color_RGB &rgb, Color_CIEL &l) const { Color_CIEY y; Convert(rgb, y); Convert(y, l); } inline void ColorSpace::Convert(const Color_XYZ &xyz, Color_CIEL &l) const { Color_CIEY y; Convert(xyz, y); Convert(y, l); } #endif // WAILI_COLOR_H waili-gpl-19990723/include/waili/Compiler.h100640 24520 25417 2154 6745120260 16773 0ustar geertnatw// // Compiler Dependent Definitions // // $Id: Compiler.h,v 4.1.4.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_COMPILER_H #define WAILI_COMPILER_H // GNU G++ #ifdef __GNUG__ // Make sure we always use the pretty version #define __FUNCTION__ __PRETTY_FUNCTION__ #endif // __GNUG__ #endif // WAILI_COMPILER_H waili-gpl-19990723/include/waili/Image.h100640 24520 25417 15102 6745120260 16260 0ustar geertnatw// // Image Class // // $Id: Image.h,v 4.6.2.3.2.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_IMAGE_H #define WAILI_IMAGE_H #include #include #include "Channel.h" #include "Util.h" // Image Types and File Types enum ImageType { IT_Unknown, IT_Mono, IT_CIEY, IT_CIEL, IT_RGB, IT_CIEXYZ, IT_CIELab, IT_YUV, IT_YUVr }; enum ImageFormat { IF_AUTO, IF_PNMASCII, IF_PNMRAW #ifdef SUPPORT_TIFF , IF_TIFF #endif // SUPPORT_TIFF }; // Image Class class Image { public: // Construction/Destruction Image(); Image(u_int channels); Image(u_int cols, u_int rows, u_int channels = 1); Image(const u_int cols[], const u_int rows[], u_int channels); Image(const Channel &channel, u_int channels = 1); Image(const Channel *channel[], u_int channels); Image(const Image &im); Image(u_int cols, u_int rows, const TransformDescriptor transform[], u_int depth, u_int channels = 1); ~Image(); // Import/Export of Images ImageType Import(const char *filename, ImageFormat type = IF_AUTO); void Export(const char *filename, ImageFormat type = IF_AUTO); // Image Conversion void Convert(ImageType from, ImageType to); // Properties u_int GetChannels(void) const; u_int GetCols(u_int channel) const; u_int GetRows(u_int channel) const; int GetOffsetX(void) const; int GetOffsetY(void) const; // Manipulation Channel*& operator[](u_int channel); const Channel*& operator[](u_int channel) const; PixType& operator()(u_int c, u_int r, u_int ch = 0); const PixType operator()(u_int c, u_int r, u_int ch = 0) const; void Clear(void); void Resize(u_int cols, u_int rows); void Resize(u_int cols, u_int rows, u_int channels); Image& operator=(const Image &im); Image *Clone(void) const; void SetOffsetX(int offx); void SetOffsetY(int offy); Image *Crop(int x1, int y1, int x2, int y2) const; void Merge(const Image &im); void Add(const Image &im); void Subtract(const Image &im); Image *Diff(const Image &im) const; void InsertChannel(const Channel &data, u_int ch); void DeleteChannel(u_int channel); // Wavelet Transforms void Fwt(const TransformDescriptor transform[], u_int depth); void IFwt(void); void RedundantFwt(const Wavelet &wavelet, TransformType type); // Wavelet Based Operations void Scale(f32 scale, const Wavelet &wavelet); private: // Low-level Image Import/Export ImageType ImportPNM(const char *filename); ImageType ImportTIFF(const char *filename); void ExportPNM(const char *filename, int raw); protected: u_int NumChannels; Channel **Channels; private: static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// inline Image::Image() : NumChannels(0), Channels(NULL) {} inline Image::Image(u_int channels) : NumChannels(channels), Channels(NULL) { Channels = new (Channel *)[NumChannels]; ::Clear(Channels, NumChannels); } inline Channel*& Image::operator[](u_int channel) { #ifdef BOUNDS_CHECK assert(channel < NumChannels); #endif // BOUNDS_CHECK return(Channels[channel]); } inline const Channel*& Image::operator[](u_int channel) const { #ifdef BOUNDS_CHECK assert(channel < NumChannels); #endif // BOUNDS_CHECK return(Channels[channel]); } inline u_int Image::GetChannels(void) const { return(NumChannels); } inline u_int Image::GetCols(u_int channel) const { #ifdef BOUNDS_CHECK assert(channel < NumChannels); #endif // BOUNDS_CHECK assert(Channels[channel] != NULL); return(Channels[channel]->GetCols()); } inline u_int Image::GetRows(u_int channel) const { #ifdef BOUNDS_CHECK assert(channel < NumChannels); #endif // BOUNDS_CHECK assert(Channels[channel] != NULL); return(Channels[channel]->GetRows()); } inline int Image::GetOffsetX(void) const { assert(Channels[0] != NULL); return(Channels[0]->GetOffsetX()); } inline int Image::GetOffsetY(void) const { assert(Channels[0] != NULL); return(Channels[0]->GetOffsetY()); } inline PixType& Image::operator()(u_int c, u_int r, u_int ch) { return((*(*this)[ch])(c, r)); } inline const PixType Image::operator()(u_int c, u_int r, u_int ch) const { return((*(*this)[ch])(c, r)); } inline void Image::Clear(void) { for (u_int ch = 0; ch < NumChannels; ch++) (*this)[ch]->Clear(); } inline void Image::Resize(u_int cols, u_int rows) { for (u_int ch = 0; ch < NumChannels; ch++) (*this)[ch]->Resize(cols, rows); } inline Image *Image::Clone(void) const { return(new Image(*this)); } inline void Image::SetOffsetX(int offx) { for (u_int ch = 0; ch < NumChannels; ch++) (*this)[ch]->SetOffsetX(offx); } inline void Image::SetOffsetY(int offy) { for (u_int ch = 0; ch < NumChannels; ch++) (*this)[ch]->SetOffsetY(offy); } inline Image *Image::Crop(int x1, int y1, int x2, int y2) const { Image *im = new Image(NumChannels); for (u_int ch = 0; ch < NumChannels; ch++) (*im)[ch] = (*this)[ch]->Crop(x1, y1, x2, y2); return(im); } inline void Image::Merge(const Image &im) { assert(im.GetChannels() == NumChannels); for (u_int ch = 0; ch < NumChannels; ch++) (*this)[ch]->Merge(*im[ch]); } inline void Image::Add(const Image &im) { assert(im.GetChannels() == NumChannels); for (u_int ch = 0; ch < NumChannels; ch++) (*this)[ch]->Add(*im[ch]); } inline void Image::Subtract(const Image &im) { assert(im.GetChannels() == NumChannels); for (u_int ch = 0; ch < NumChannels; ch++) (*this)[ch]->Subtract(*im[ch]); } inline Image *Image::Diff(const Image &im) const { assert(im.GetChannels() == NumChannels); Image *diff = new Image(NumChannels); for (u_int ch = 0; ch < NumChannels; ch++) (*diff)[ch] = (*this)[ch]->Diff(*im[ch]); return(diff); } #endif // WAILI_IMAGE_H waili-gpl-19990723/include/waili/LChannel.h100640 24520 25417 11603 6745120260 16724 0ustar geertnatw// // LChannel Class // // $Id: LChannel.h,v 4.3.2.2.2.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_LCHANNEL_H #define WAILI_LCHANNEL_H #include #include "Blit.h" // Lifted Channel Abstract Base Class enum SubBand { SubBand_LL = 0, SubBand_LH = 1, SubBand_HL = 2, SubBand_HH = 3, SubBand_L = SubBand_LL, SubBand_H = SubBand_LH }; class LChannelCR; class LChannelC; class LChannelR; class LChannel : public Channel { friend class Channel; friend class NTChannel; friend class LChannelCR; friend class LChannelC; friend class LChannelR; public: // Construction/Destruction LChannel(const LChannel &channel); virtual ~LChannel(); // Properties virtual u_int GetDepth(void) const; virtual TransformType GetTransformType(void) const = 0; TransformDescriptor *GetTransform(void) const; virtual u64 *FullHistogram(PixType &min, PixType &max, u64 &numpixels) const; int GetShift(SubBand band); // Manipulation virtual void Clear(void); Channel* &operator[](SubBand band); const Channel* &operator[](SubBand band) const; virtual LChannel *Clone(void) const = 0; // Wavelet Transforms NTChannel *IFwt(void); virtual NTChannel *IFwt(int x1, int y1, int x2, int y2) const = 0; virtual LChannel *PushFwtStepCR(const Wavelet &wavelet); virtual LChannel *PushFwtStepC(const Wavelet &wavelet); virtual LChannel *PushFwtStepR(const Wavelet &wavelet); virtual Channel *PopFwtStep(void); // Wavelet Based Operations virtual LChannel *Crop(int x1, int y1, int x2, int y2) const; virtual void Merge(const Channel &channel); virtual void Enhance(f32 m); virtual void Enhance(int m, u_int shift); // Thresholding virtual u64 Threshold(double threshold, int soft = 0); // This should be removed later!! The user doesn't need to know // what's the internal representation of the channel virtual int IsLifted(void) const; protected: LChannel(const Wavelet &filter, u_int numsubbands, u_int cols = 0, u_int rows = 0); virtual void Destroy(void); // Internal Wavelet Transform Steps virtual NTChannel *IFwtStep(void); virtual void Lazy(const NTChannel &source) = 0; virtual void ILazy(NTChannel &dest) const = 0; virtual void CakeWalk(void) = 0; virtual void ICakeWalk(void) = 0; // Wavelet Based Operations virtual LChannel *Crop_rec(int x1, int y1, int x2, int y2, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) const = 0; virtual void Merge_rec(const Channel *channel, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) = 0; virtual Channel *DownScale(u_int s, const Wavelet &wavelet) = 0; protected: u_int NumSubBands; Channel **SubBands; const Wavelet *Filter; int *Shifts; private: static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// // inline LChannel::LChannel(const Wavelet &filter) // : Channel(), Filter(NULL) // { // ::Clear(SubBands, NumSubBands); // Is niet correct voor C and R !!!!!!! // Filter = filter.Clone(); // } inline u_int LChannel::GetDepth(void) const { return(1+SubBands[0]->GetDepth()); } inline int LChannel::GetShift(SubBand band) { assert((u_int)band < NumSubBands); return(Shifts[band]); } inline Channel* &LChannel::operator[](SubBand band) { assert((u_int)band < NumSubBands); assert(SubBands[band] != NULL); return(SubBands[band]); } inline const Channel* &LChannel::operator[](SubBand band) const { assert((u_int)band < NumSubBands); assert(SubBands[band] != NULL); return(SubBands[band]); } inline LChannel *LChannel::Crop(int x1, int y1, int x2, int y2) const { return(Crop_rec(x1, y1, x2, y2, NULL, NULL, NULL, NULL)); } inline void LChannel::Merge(const Channel &channel) { Merge_rec(&channel, NULL, NULL, NULL, NULL); } inline int LChannel::IsLifted(void) const { return(1); } // Include derived classes #include "LChannelCR.h" #include "LChannelC.h" #include "LChannelR.h" #endif // WAILI_LCHANNEL_H waili-gpl-19990723/include/waili/LChannelC.h100640 24520 25417 10435 6745120260 17031 0ustar geertnatw// // LChannelC Class // // $Id: LChannelC.h,v 4.3.2.1.2.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_LCHANNELC_H #define WAILI_LCHANNELC_H #include #include "Blit.h" // Lifted Channel Class (lifted Cols) class LChannelC : public LChannel { friend class NTChannel; public: // Construction/Destruction LChannelC(const Wavelet &filter); LChannelC(const Wavelet &filter, u_int cols, u_int rows, int offx, int offy); LChannelC(const LChannelC &channel); // Properties virtual void GetMask(u_int &maskx, u_int &masky) const; virtual TransformType GetTransformType(void) const; u_int GetRlow(void) const; u_int GetRhigh(void) const; // Manipulation virtual PixType &operator()(u_int c, u_int r); virtual PixType operator()(u_int c, u_int r) const; virtual void Resize(u_int cols, u_int rows); virtual LChannelC *Clone(void) const; virtual void SetOffsetX(int offx); virtual void SetOffsetY(int offy); virtual void Add(const Channel &channel); virtual void Subtract(const Channel &channel); virtual LChannelC *Diff(const Channel &channel) const; // Wavelet Transforms virtual NTChannel *IFwt(int x1, int y1, int x2, int y2) const; protected: // Internal Wavelet Transform Steps virtual void Lazy(const NTChannel &source); virtual void ILazy(NTChannel &dest) const; virtual void CakeWalk(void); virtual void ICakeWalk(void); void Zip(const LChannelC &channel); // Wavelet Based Operations virtual LChannelC *Crop_rec(int x1, int y1, int x2, int y2, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) const; virtual void Merge_rec(const Channel *channel, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right); virtual Channel *DownScale(u_int s, const Wavelet &wavelet); private: NTChannel *CropMergeH(LChannelC *channel, int x1, int y1_l, int y1_h, int x2, int y2_l, int y2_h); static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// inline LChannelC::LChannelC(const Wavelet &filter) : LChannel(filter, 2) { Shifts[SubBand_L] = filter.GetShiftL(); Shifts[SubBand_H] = filter.GetShiftH(); } inline TransformType LChannelC::GetTransformType(void) const { return(TT_Cols); } inline u_int LChannelC::GetRlow(void) const { assert(SubBands[SubBand_L] != NULL); return(SubBands[SubBand_L]->GetRows()); } inline u_int LChannelC::GetRhigh(void) const { assert(SubBands[SubBand_H] != NULL); return(SubBands[SubBand_H]->GetRows()); } inline PixType &LChannelC::operator()(u_int c, u_int r) { Channel *channel; #ifdef BOUNDS_CHECK assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK if (r < GetRlow()) channel = SubBands[0]; else { r -= GetRlow(); channel = SubBands[1]; } #ifdef BOUNDS_CHECK assert(channel != NULL); #endif // BOUNDS_CHECK return((*channel)(c, r)); } inline PixType LChannelC::operator()(u_int c, u_int r) const { Channel *channel; #ifdef BOUNDS_CHECK assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK if (r < GetRlow()) channel = SubBands[0]; else { r -= GetRlow(); channel = SubBands[1]; } #ifdef BOUNDS_CHECK assert(channel != NULL); #endif // BOUNDS_CHECK return((*channel)(c, r)); } inline LChannelC *LChannelC::Clone(void) const { return(new LChannelC(*this)); } #endif // WAILI_LCHANNELC_H waili-gpl-19990723/include/waili/LChannelCR.h100640 24520 25417 12143 6745120260 17151 0ustar geertnatw// // LChannelCR Class // // $Id: LChannelCR.h,v 4.3.2.1.2.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_LCHANNELCR_H #define WAILI_LCHANNELCR_H #include #include "Blit.h" // Lifted Channel Class (lifted Cols and Rows) class LChannelCR : public LChannel { friend class NTChannel; friend class LChannelC; friend class LChannelR; public: // Construction/Destruction LChannelCR(const Wavelet &filter); LChannelCR(const Wavelet &filter, u_int cols, u_int rows, int offx, int offy); LChannelCR(const LChannelCR &channel); // Properties virtual void GetMask(u_int &maskx, u_int &masky) const; virtual TransformType GetTransformType(void) const; u_int GetClow(void) const; u_int GetChigh(void) const; u_int GetRlow(void) const; u_int GetRhigh(void) const; // Manipulation virtual PixType &operator()(u_int c, u_int r); virtual PixType operator()(u_int c, u_int r) const; virtual void Resize(u_int cols, u_int rows); virtual LChannelCR *Clone(void) const; virtual void SetOffsetX(int offx); virtual void SetOffsetY(int offy); virtual void Add(const Channel &channel); virtual void Subtract(const Channel &channel); virtual LChannelCR *Diff(const Channel &channel) const; // Wavelet Transforms virtual NTChannel *IFwt(int x1, int y1, int x2, int y2) const; protected: // Internal Wavelet Transform Steps virtual void Lazy(const NTChannel &source); virtual void ILazy(NTChannel &dest) const; virtual void CakeWalk(void); virtual void ICakeWalk(void); void Zip(const LChannelCR &channel_lh, const LChannelCR &channel_hl, const LChannelCR &channel_hh); // Wavelet Based Operations virtual LChannelCR *Crop_rec(int x1, int y1, int x2, int y2, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) const; virtual void Merge_rec(const Channel *channel, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right); virtual Channel *DownScale(u_int s, const Wavelet &wavelet); private: NTChannel *CropMergeH(LChannelCR *channel, int x1_l, int x1_h, int y1_l, int y1_h, int x2_l, int x2_h, int y2_l, int y2_h); static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// inline LChannelCR::LChannelCR(const Wavelet &filter) : LChannel(filter, 4) { int lshift = filter.GetShiftL(); int hshift = filter.GetShiftH(); Shifts[SubBand_LL] = lshift+lshift; Shifts[SubBand_LH] = Shifts[SubBand_HL] = hshift+lshift; Shifts[SubBand_HH] = hshift+hshift; } inline TransformType LChannelCR::GetTransformType(void) const { return(TT_ColsRows); } inline u_int LChannelCR::GetClow(void) const { assert(SubBands[SubBand_LL] != NULL); return(SubBands[SubBand_LL]->GetCols()); } inline u_int LChannelCR::GetChigh(void) const { assert(SubBands[SubBand_HH] != NULL); return(SubBands[SubBand_HH]->GetCols()); } inline u_int LChannelCR::GetRlow(void) const { assert(SubBands[SubBand_LL] != NULL); return(SubBands[SubBand_LL]->GetRows()); } inline u_int LChannelCR::GetRhigh(void) const { assert(SubBands[SubBand_HH] != NULL); return(SubBands[SubBand_HH]->GetRows()); } inline PixType &LChannelCR::operator()(u_int c, u_int r) { u_int band = SubBand_LL; Channel *channel; #ifdef BOUNDS_CHECK assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK if (r >= GetRlow()) { r -= GetRlow(); band += SubBand_HL; } if (c >= GetClow()) { c -= GetClow(); band += SubBand_LH; } channel = SubBands[band]; #ifdef BOUNDS_CHECK assert(channel != NULL); #endif // BOUNDS_CHECK return((*channel)(c, r)); } inline PixType LChannelCR::operator()(u_int c, u_int r) const { u_int band = SubBand_LL; Channel *channel; #ifdef BOUNDS_CHECK assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK if (r >= GetRlow()) { r -= GetRlow(); band += SubBand_HL; } if (c >= GetClow()) { c -= GetClow(); band += SubBand_LH; } channel = SubBands[band]; #ifdef BOUNDS_CHECK assert(channel != NULL); #endif // BOUNDS_CHECK return((*channel)(c, r)); } inline LChannelCR *LChannelCR::Clone(void) const { return(new LChannelCR(*this)); } #endif // WAILI_LCHANNELCR_H waili-gpl-19990723/include/waili/LChannelR.h100640 24520 25417 10435 6745120260 17050 0ustar geertnatw// // LChannelR Class // // $Id: LChannelR.h,v 4.3.2.1.2.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_LCHANNELR_H #define WAILI_LCHANNELR_H #include #include "Blit.h" // Lifted Channel Class (lifted Rows) class LChannelR : public LChannel { friend class NTChannel; public: // Construction/Destruction LChannelR(const Wavelet &filter); LChannelR(const Wavelet &filter, u_int cols, u_int rows, int offx, int offy); LChannelR(const LChannelR &channel); // Properties virtual void GetMask(u_int &maskx, u_int &masky) const; virtual TransformType GetTransformType(void) const; u_int GetClow(void) const; u_int GetChigh(void) const; // Manipulation virtual PixType &operator()(u_int c, u_int r); virtual PixType operator()(u_int c, u_int r) const; virtual void Resize(u_int cols, u_int rows); virtual LChannelR *Clone(void) const; virtual void SetOffsetX(int offx); virtual void SetOffsetY(int offy); virtual void Add(const Channel &channel); virtual void Subtract(const Channel &channel); virtual LChannelR *Diff(const Channel &channel) const; // Wavelet Transforms virtual NTChannel *IFwt(int x1, int y1, int x2, int y2) const; protected: // Internal Wavelet Transform Steps virtual void Lazy(const NTChannel &source); virtual void ILazy(NTChannel &dest) const; virtual void CakeWalk(void); virtual void ICakeWalk(void); void Zip(const LChannelR &channel); // Wavelet Based Operations virtual LChannelR *Crop_rec(int x1, int y1, int x2, int y2, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right) const; virtual void Merge_rec(const Channel *channel, NTChannel *top, NTChannel *bottom, NTChannel *left, NTChannel *right); virtual Channel *DownScale(u_int s, const Wavelet &wavelet); private: NTChannel *CropMergeH(LChannelR *channel, int x1_l, int x1_h, int y1, int x2_l, int x2_h, int y2); static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// inline LChannelR::LChannelR(const Wavelet &filter) : LChannel(filter, 2) { Shifts[SubBand_L] = filter.GetShiftL(); Shifts[SubBand_H] = filter.GetShiftH(); } inline TransformType LChannelR::GetTransformType(void) const { return(TT_Rows); } inline u_int LChannelR::GetClow(void) const { assert(SubBands[SubBand_L] != NULL); return(SubBands[SubBand_L]->GetCols()); } inline u_int LChannelR::GetChigh(void) const { assert(SubBands[SubBand_H] != NULL); return(SubBands[SubBand_H]->GetCols()); } inline PixType &LChannelR::operator()(u_int c, u_int r) { Channel *channel; #ifdef BOUNDS_CHECK assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK if (c < GetClow()) channel = SubBands[0]; else { c -= GetClow(); channel = SubBands[1]; } #ifdef BOUNDS_CHECK assert(channel != NULL); #endif // BOUNDS_CHECK return((*channel)(c, r)); } inline PixType LChannelR::operator()(u_int c, u_int r) const { Channel *channel; #ifdef BOUNDS_CHECK assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK if (c < GetClow()) channel = SubBands[0]; else { c -= GetClow(); channel = SubBands[1]; } #ifdef BOUNDS_CHECK assert(channel != NULL); #endif // BOUNDS_CHECK return((*channel)(c, r)); } inline LChannelR *LChannelR::Clone(void) const { return(new LChannelR(*this)); } #endif // WAILI_LCHANNELR_H waili-gpl-19990723/include/waili/Lifting.h100640 24520 25417 21135 6745120260 16635 0ustar geertnatw// // Integer Lifting Operations // // $Id: Lifting.h,v 4.3.4.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_LIFTING_H #define WAILI_LIFTING_H #include "Types.h" class NTChannel; // Integer Lifting Abstract Base Class class Lifting { public: virtual ~Lifting(); // Lifting Steps (Full Rounding) virtual void Lift_L1R1_FR(int primal, const s16 b[2], const u16 a) const = 0; virtual void ILift_L1R1_FR(int primal, const s16 b[2], const u16 a) const = 0; virtual void Lift_L2R2_FR(int primal, const s16 b[4], const u16 a) const = 0; virtual void ILift_L2R2_FR(int primal, const s16 b[4], const u16 a) const = 0; virtual void Lift_L3R3_FR(int primal, const s16 b[6], const u16 a) const = 0; virtual void ILift_L3R3_FR(int primal, const s16 b[6], const u16 a) const = 0; // Lifting Steps (No Rounding) virtual void Lift_L1R1_NR(int primal, const s16 b[2], const u16 a) const = 0; virtual void ILift_L1R1_NR(int primal, const s16 b[2], const u16 a) const = 0; virtual void Lift_L2R2_NR(int primal, const s16 b[4], const u16 a) const = 0; virtual void ILift_L2R2_NR(int primal, const s16 b[4], const u16 a) const = 0; virtual void Lift_L3R3_NR(int primal, const s16 b[6], const u16 a) const = 0; virtual void ILift_L3R3_NR(int primal, const s16 b[6], const u16 a) const = 0; // Lifting Steps (Mixed) virtual void Lift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const = 0; virtual void ILift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const = 0; virtual void Lift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const = 0; virtual void ILift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const = 0; virtual void Lift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const = 0; virtual void ILift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const = 0; // Optimized functions for specific wavelet transforms virtual void Lift_L1R1_NR_0_m1_m1_2(void) const = 0; virtual void ILift_L1R1_NR_0_m1_m1_2(void) const = 0; virtual void Lift_L1R1_FR_1_1_1_8(void) const = 0; virtual void ILift_L1R1_FR_1_1_1_8(void) const = 0; virtual void Lift_L1R1_FR_0_m1_m1_2(void) const = 0; virtual void ILift_L1R1_FR_0_m1_m1_2(void) const = 0; virtual void Lift_L1R1_FR_1_1_1_4(void) const = 0; virtual void ILift_L1R1_FR_1_1_1_4(void) const = 0; virtual void Lift_L1R1_FR_0_m1_0_1(void) const = 0; virtual void ILift_L1R1_FR_0_m1_0_1(void) const = 0; virtual void Lift_L1R1_FR_1_0_1_2(void) const = 0; virtual void ILift_L1R1_FR_1_0_1_2(void) const = 0; private: static const char *rcsid; }; // ---------------------------------------------------------------------------- // Derived Classes // Integer Lifting Operations on the Rows of NTChannels class LiftChannelR : public Lifting { public: LiftChannelR(NTChannel *lowpass, NTChannel *highpass); virtual ~LiftChannelR(); // Lifting Steps (Full Rounding) virtual void Lift_L1R1_FR(int primal, const s16 b[2], const u16 a) const; virtual void ILift_L1R1_FR(int primal, const s16 b[2], const u16 a) const; virtual void Lift_L2R2_FR(int primal, const s16 b[4], const u16 a) const; virtual void ILift_L2R2_FR(int primal, const s16 b[4], const u16 a) const; virtual void Lift_L3R3_FR(int primal, const s16 b[6], const u16 a) const; virtual void ILift_L3R3_FR(int primal, const s16 b[6], const u16 a) const; // Lifting Steps (No Rounding) virtual void Lift_L1R1_NR(int primal, const s16 b[2], const u16 a) const; virtual void ILift_L1R1_NR(int primal, const s16 b[2], const u16 a) const; virtual void Lift_L2R2_NR(int primal, const s16 b[4], const u16 a) const; virtual void ILift_L2R2_NR(int primal, const s16 b[4], const u16 a) const; virtual void Lift_L3R3_NR(int primal, const s16 b[6], const u16 a) const; virtual void ILift_L3R3_NR(int primal, const s16 b[6], const u16 a) const; // Lifting Steps (Mixed) virtual void Lift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const; virtual void ILift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const; virtual void Lift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const; virtual void ILift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const; virtual void Lift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const; virtual void ILift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const; // Optimized functions for specific wavelet transforms virtual void Lift_L1R1_NR_0_m1_m1_2(void) const; virtual void ILift_L1R1_NR_0_m1_m1_2(void) const; virtual void Lift_L1R1_FR_1_1_1_8(void) const; virtual void ILift_L1R1_FR_1_1_1_8(void) const; virtual void Lift_L1R1_FR_0_m1_m1_2(void) const; virtual void ILift_L1R1_FR_0_m1_m1_2(void) const; virtual void Lift_L1R1_FR_1_1_1_4(void) const; virtual void ILift_L1R1_FR_1_1_1_4(void) const; virtual void Lift_L1R1_FR_0_m1_0_1(void) const; virtual void ILift_L1R1_FR_0_m1_0_1(void) const; virtual void Lift_L1R1_FR_1_0_1_2(void) const; virtual void ILift_L1R1_FR_1_0_1_2(void) const; protected: PixType *Even, *Odd; u_int Ceven, Codd, Rows; int Parity; }; // Integer Lifting Operations on the Columns of NTChannels class LiftChannelC : public Lifting { public: LiftChannelC(NTChannel *lowpass, NTChannel *highpass); virtual ~LiftChannelC(); // Lifting Steps (Full Rounding) virtual void Lift_L1R1_FR(int primal, const s16 b[2], const u16 a) const; virtual void ILift_L1R1_FR(int primal, const s16 b[2], const u16 a) const; virtual void Lift_L2R2_FR(int primal, const s16 b[4], const u16 a) const; virtual void ILift_L2R2_FR(int primal, const s16 b[4], const u16 a) const; virtual void Lift_L3R3_FR(int primal, const s16 b[6], const u16 a) const; virtual void ILift_L3R3_FR(int primal, const s16 b[6], const u16 a) const; // Lifting Steps (No Rounding) virtual void Lift_L1R1_NR(int primal, const s16 b[2], const u16 a) const; virtual void ILift_L1R1_NR(int primal, const s16 b[2], const u16 a) const; virtual void Lift_L2R2_NR(int primal, const s16 b[4], const u16 a) const; virtual void ILift_L2R2_NR(int primal, const s16 b[4], const u16 a) const; virtual void Lift_L3R3_NR(int primal, const s16 b[6], const u16 a) const; virtual void ILift_L3R3_NR(int primal, const s16 b[6], const u16 a) const; // Lifting Steps (Mixed) virtual void Lift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const; virtual void ILift_L1R1_MX(int primal, const s16 b[2], const u16 a1, const u16 a2) const; virtual void Lift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const; virtual void ILift_L2R2_MX(int primal, const s16 b[4], const u16 a1, const u16 a2) const; virtual void Lift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const; virtual void ILift_L3R3_MX(int primal, const s16 b[6], const u16 a1, const u16 a2) const; // Optimized functions for specific wavelet transforms virtual void Lift_L1R1_NR_0_m1_m1_2(void) const; virtual void ILift_L1R1_NR_0_m1_m1_2(void) const; virtual void Lift_L1R1_FR_1_1_1_8(void) const; virtual void ILift_L1R1_FR_1_1_1_8(void) const; virtual void Lift_L1R1_FR_0_m1_m1_2(void) const; virtual void ILift_L1R1_FR_0_m1_m1_2(void) const; virtual void Lift_L1R1_FR_1_1_1_4(void) const; virtual void ILift_L1R1_FR_1_1_1_4(void) const; virtual void Lift_L1R1_FR_0_m1_0_1(void) const; virtual void ILift_L1R1_FR_0_m1_0_1(void) const; virtual void Lift_L1R1_FR_1_0_1_2(void) const; virtual void ILift_L1R1_FR_1_0_1_2(void) const; protected: PixType *Even, *Odd; u_int Cols, Reven, Rodd; int Parity; }; #endif // WAILI_LIFTING_H waili-gpl-19990723/include/waili/Lifting.inline.h100640 24520 25417 5154 6745120260 20075 0ustar geertnatw// // Lifting Operations // // $Id: Lifting.inline.h,v 4.0.2.1.2.1 1999/07/20 16:15:44 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_LIFTING_INLINE_H #define WAILI_LIFTING_INLINE_H // Inline Class Member Functions // Integer Lifting Abstract Base Class inline Lifting::~Lifting() {} // Integer Lifting Operations on the Rows of NTChannels inline LiftChannelR::LiftChannelR(NTChannel *lowpass, NTChannel *highpass) { assert(lowpass != NULL); assert(highpass != NULL); if (lowpass->GetOffsetX() != highpass->GetOffsetX()) { Parity = 1; Even = highpass->Data; /* Even in memory */ Ceven = highpass->GetCols(); Odd = lowpass->Data; /* Odd in memory */ Codd = lowpass->GetCols(); } else { Parity = 0; Even = lowpass->Data; /* Even in memory */ Ceven = lowpass->GetCols(); Odd = highpass->Data; /* Odd in memory */ Codd = highpass->GetCols(); } assert(Ceven >= Codd); assert(Ceven <= Codd+1); Rows = lowpass->GetRows(); assert(highpass->GetRows() == Rows); } inline LiftChannelR::~LiftChannelR() {} // Integer Lifting Operations on the Columns of NTChannels inline LiftChannelC::LiftChannelC(NTChannel *lowpass, NTChannel *highpass) { assert(lowpass != NULL); assert(highpass != NULL); Cols = lowpass->GetCols(); assert(highpass->GetCols() == Cols); if (lowpass->GetOffsetY() != highpass->GetOffsetY()) { Parity = 1; Even = highpass->Data; /* Even in memory */ Reven = highpass->GetRows(); Odd = lowpass->Data; /* Odd in memory */ Rodd = lowpass->GetRows(); } else { Parity = 0; Even = lowpass->Data; /* Even in memory */ Reven = lowpass->GetRows(); Odd = highpass->Data; /* Odd in memory */ Rodd = highpass->GetRows(); } assert(Reven >= Rodd); assert(Reven <= Rodd+1); } inline LiftChannelC::~LiftChannelC() {} #endif // WAILI_LIFTING_INLINE_H waili-gpl-19990723/include/waili/Makefile100640 24520 25417 2350 6745120261 16507 0ustar geertnatw# # Makefile for include/waili # # $Id: Makefile,v 3.2.4.1 1999/07/20 16:15:45 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # include ../../Rules.config RCSOBJS = Blit.h \ Channel.h \ Color.h \ Compiler.h \ Image.h \ LChannel.h \ LChannelC.h \ LChannelCR.h \ LChannelR.h \ Lifting.h \ Lifting.inline.h \ NTChannel.h \ Storage.h \ Timer.h \ Types.h \ Util.h \ Wavelet.h All: $(RCSOBJS) depend: $(RCSOBJS) clean: include ../../Rules.make waili-gpl-19990723/include/waili/NTChannel.h100640 24520 25417 12676 6745120261 17066 0ustar geertnatw// // NTChannel Class // // $Id: NTChannel.h,v 4.8.2.1.2.1 1999/07/20 16:15:45 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_NTCHANNEL_H #define WAILI_NTCHANNEL_H #include #include "Blit.h" // Non-Transformed Channel Class class NTChannel : public Channel { friend class Channel; friend class LChannel; friend class LChannelCR; friend class LChannelC; friend class LChannelR; friend class LiftChannelR; friend class LiftChannelC; public: // Construction/Destruction NTChannel(); NTChannel(u_int cols, u_int rows, int offx = 0, int offy = 0); NTChannel(const NTChannel &channel); virtual ~NTChannel(); // Properties virtual void GetMask(u_int &maskx, u_int &masky) const; virtual u_int GetDepth(void) const; void GetMinMax(PixType &min, PixType &max, u_int smoothing = 0) const; u64 *Histogram(PixType min, PixType max) const; virtual u64 *FullHistogram(PixType &min, PixType &max, u64 &numpixels) const; // Manipulation virtual PixType &operator()(u_int c, u_int r); virtual PixType operator()(u_int c, u_int r) const; virtual void Clear(void); virtual void Resize(u_int cols, u_int rows); virtual NTChannel *Clone(void) const; virtual void SetOffsetX(int offx); virtual void SetOffsetY(int offy); virtual NTChannel *Crop(int x1, int y1, int x2, int y2) const; virtual void Merge(const Channel &channel); virtual void Add(const Channel &channel); virtual void Subtract(const Channel &channel); virtual NTChannel *Diff(const Channel &channel) const; s32 *Correlate(const NTChannel &channel, u_int diff) const; virtual void Enhance(f32 m); virtual void Enhance(int m, u_int shift); // Wavelet Transforms virtual LChannel *Fwt(const TransformDescriptor transform[], u_int depth); virtual LChannelCR *PushFwtStepCR(const Wavelet &wavelet); virtual LChannelC *PushFwtStepC(const Wavelet &wavelet); virtual LChannelR *PushFwtStepR(const Wavelet &wavelet); virtual Channel *PopFwtStep(void); virtual LChannelCR *RedundantFwtCR(const Wavelet &wavelet); virtual LChannelC *RedundantFwtC(const Wavelet &wavelet); virtual LChannelR *RedundantFwtR(const Wavelet &wavelet); // Thresholding virtual u64 Threshold(double threshold, int soft = 0); u64 ThresholdHard(u_int threshold); u64 ThresholdSoft(u_int threshold); u_int OptimalGCVThreshold(void) const; // This should be removed later!! The user doesn't need to know // what's the internal representation of the channel virtual int IsLifted(void) const; // Scaling using a duplication scheme NTChannel *DupliScale(u_int s) const; protected: virtual void Destroy(void); // Wavelet Based Operations virtual NTChannel *DownScale(u_int s, const Wavelet &wavelet); // Scaling using a linear interpolation scheme void Interpolate(f32 s); // Generalized Cross Validation double GCV(u_int threshold) const; static PixType Interpolate(PixType y1, PixType y2, f32 x); protected: PixType *Data; private: static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// inline NTChannel::NTChannel() : Channel(), Data(NULL) {} inline void NTChannel::GetMask(u_int &maskx, u_int &masky) const { maskx = masky = 0; } inline u_int NTChannel::GetDepth(void) const { return(0); } inline PixType &NTChannel::operator()(u_int c, u_int r) { #ifdef BOUNDS_CHECK assert(Data != NULL); assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK return(Data[r*Cols+c]); } inline PixType NTChannel::operator()(u_int c, u_int r) const { #ifdef BOUNDS_CHECK assert(Data != NULL); assert(c < Cols); assert(r < Rows); #endif // BOUNDS_CHECK return(Data[r*Cols+c]); } inline NTChannel *NTChannel::Clone(void) const { return(new NTChannel(*this)); } inline void NTChannel::SetOffsetX(int offx) { OffsetX = offx; } inline void NTChannel::SetOffsetY(int offy) { OffsetY = offy; } inline Channel *NTChannel::PopFwtStep(void) { return(NULL); } inline u64 NTChannel::Threshold(double threshold, int soft) { u_int ithresh = u_int(fabs(threshold)+0.5); return(soft ? ThresholdSoft(ithresh) : ThresholdHard(ithresh)); } inline int NTChannel::IsLifted(void) const { return(0); } inline PixType NTChannel::Interpolate(PixType y1, PixType y2, f32 x) { return((PixType)rint((y2-y1)*x)+y1); } ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions for Class Lifting !!!!!! // ///////////////////////////////////////////////////////////////////////////// #include "Lifting.inline.h" #endif // WAILI_NTCHANNEL_H waili-gpl-19990723/include/waili/Storage.h100640 24520 25417 12431 6745120261 16645 0ustar geertnatw// // Data Storage Class // // $Id: Storage.h,v 4.0.2.2.2.1 1999/07/20 16:15:45 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_STORAGE_H #define WAILI_STORAGE_H #include "Types.h" #include #include // Normal or Compressed Stream Class class Stream { public: Stream(); Stream(const char *name, const char *mode = "r"); virtual ~Stream(); virtual void Open(const char *name, const char *mode = "r"); virtual void Close(void); virtual void RawRead(void *data, int size); virtual void RawWrite(const void *data, int size); void Read(u8 *x, u_int cnt = 1); void Read(u16 *x, u_int cnt = 1); void Read(u32 *x, u_int cnt = 1); void Read(u64 *x, u_int cnt = 1); void Read(s8 *x, u_int cnt = 1); void Read(s16 *x, u_int cnt = 1); void Read(s32 *x, u_int cnt = 1); void Read(s64 *x, u_int cnt = 1); void Read(f32 *x, u_int cnt = 1); void Read(f64 *x, u_int cnt = 1); void Write(const u8 *x, u_int cnt = 1); void Write(const u16 *x, u_int cnt = 1); void Write(const u32 *x, u_int cnt = 1); void Write(const u64 *x, u_int cnt = 1); void Write(const s8 *x, u_int cnt = 1); void Write(const s16 *x, u_int cnt = 1); void Write(const s32 *x, u_int cnt = 1); void Write(const s64 *x, u_int cnt = 1); void Write(const f32 *x, u_int cnt = 1); void Write(const f64 *x, u_int cnt = 1); void Read(u8 &x); void Read(u16 &x); void Read(u32 &x); void Read(u64 &x); void Read(s8 &x); void Read(s16 &x); void Read(s32 &x); void Read(s64 &x); void Read(f32 &x); void Read(f64 &x); void Write(const u8 &x); void Write(const u16 &x); void Write(const u32 &x); void Write(const u64 &x); void Write(const s8 &x); void Write(const s16 &x); void Write(const s32 &x); void Write(const s64 &x); void Write(const f32 &x); void Write(const f64 &x); void Puts(const char *s); void Printf(const char *fmt, ...) #ifdef __GNUG__ __attribute__ ((format (printf, 2, 3))) #endif // __GNUG__ ; protected: FILE *File; char *Name; char *Mode; u_int Compressed; private: static const char *rcsid; }; // ---------------------------------------------------------------------------- // Inline Class Member Functions inline Stream::Stream() : File(NULL) {} inline void Stream::Read(u8 *x, u_int cnt) { RawRead(x, cnt*sizeof(*x)); } inline void Stream::Read(s8 *x, u_int cnt) { Read((u8 *)x, cnt); } inline void Stream::Read(s16 *x, u_int cnt) { Read((u16 *)x, cnt); } inline void Stream::Read(s32 *x, u_int cnt) { Read((u32 *)x, cnt); } inline void Stream::Read(s64 *x, u_int cnt) { Read((u64 *)x, cnt); } inline void Stream::Read(f32 *x, u_int cnt) { Read((u32 *)x, cnt); } inline void Stream::Read(f64 *x, u_int cnt) { Read((u64 *)x, cnt); } inline void Stream::Write(const u8 *x, u_int cnt) { RawWrite(x, cnt*sizeof(*x)); } inline void Stream::Write(const s8 *x, u_int cnt) { Write((const u8 *)x, cnt); } inline void Stream::Write(const s16 *x, u_int cnt) { Write((u16 *)x, cnt); } inline void Stream::Write(const s32 *x, u_int cnt) { Write((u32 *)x, cnt); } inline void Stream::Write(const s64 *x, u_int cnt) { Write((u64 *)x, cnt); } inline void Stream::Write(const f32 *x, u_int cnt) { Write((u32 *)x, cnt); } inline void Stream::Write(const f64 *x, u_int cnt) { Write((u64 *)x, cnt); } inline void Stream::Read(u8 &x) { Read(&x, 1); } inline void Stream::Read(u16 &x) { Read(&x, 1); } inline void Stream::Read(u32 &x) { Read(&x, 1); } inline void Stream::Read(u64 &x) { Read(&x, 1); } inline void Stream::Read(s8 &x) { Read(&x, 1); } inline void Stream::Read(s16 &x) { Read(&x, 1); } inline void Stream::Read(s32 &x) { Read(&x, 1); } inline void Stream::Read(s64 &x) { Read(&x, 1); } inline void Stream::Read(f32 &x) { Read(&x, 1); } inline void Stream::Read(f64 &x) { Read(&x, 1); } inline void Stream::Write(const u8 &x) { Write(&x, 1); } inline void Stream::Write(const u16 &x) { Write(&x, 1); } inline void Stream::Write(const u32 &x) { Write(&x, 1); } inline void Stream::Write(const u64 &x) { Write(&x, 1); } inline void Stream::Write(const s8 &x) { Write(&x, 1); } inline void Stream::Write(const s16 &x) { Write(&x, 1); } inline void Stream::Write(const s32 &x) { Write(&x, 1); } inline void Stream::Write(const s64 &x) { Write(&x, 1); } inline void Stream::Write(const f32 &x) { Write(&x, 1); } inline void Stream::Write(const f64 &x) { Write(&x, 1); } inline void Stream::Puts(const char *s) { RawWrite(s, strlen(s)); } #endif // WAILI_STORAGE_H waili-gpl-19990723/include/waili/Timer.h100640 24520 25417 3755 6745120261 16312 0ustar geertnatw// // Timer Class // // $Id: Timer.h,v 4.0.4.1 1999/07/20 16:15:45 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_TIMER_H #define WAILI_TIMER_H #include "Types.h" #ifdef __ultrix #define _POSIX_SOURCE #endif // __ultrix #include #ifdef __ultrix #undef _POSIX_SOURCE #endif // __ultrix class Timer { public: Timer(); Timer(const Timer &t); void Start(void); void Stop(void); void Reset(void); f32 GetReal(void) const; f32 GetUser(void) const; f32 GetSystem(void) const; Timer GetStamp(void) const; int IsRunning(void) const; void Tic(void); void Toc(void); Timer operator+(const Timer &t); Timer operator-(const Timer &t); void operator+=(const Timer &t); void operator-=(const Timer &t); private: int Running; time_t Real; time_t User; time_t System; private: static const char *rcsid; }; // ---------------------------------------------------------------------------- // Inline Class Member Functions inline Timer::Timer() : Running(0), Real(0), User(0), System(0) {} inline Timer::Timer(const Timer &t) : Running(t.Running), Real(t.Real), User(t.User), System(t.System) {} inline int Timer::IsRunning(void) const { return(Running); } #endif // WAILI_TIMER_H waili-gpl-19990723/include/waili/Types.h100640 24520 25417 3531 6745120261 16326 0ustar geertnatw// // Data Types // // $Id: Types.h,v 4.0.4.1 1999/07/20 16:15:45 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_TYPES_H #define WAILI_TYPES_H #include "Compiler.h" #include // // These type definitions should work fine for at least the following // architectures: // // DEC Alpha (OSF/1) // HP PA-RISC (HP-UX) // IBM RS/6000 (AIX) // Intel 386 (Linux) // MIPS R2000, R3000 (ULTRIX) // Motorola 68k (SunOS, Linux) // Sun SPARC (SunOS, Solaris) // typedef unsigned char u8; /* 8 bit unsigned integer */ typedef unsigned short u16; /* 16 bit unsigned integer */ typedef unsigned int u32; /* 32 bit unsigned integer */ typedef unsigned long long u64; /* 64 bit unsigned integer */ typedef signed char s8; /* 8 bit signed integer */ typedef signed short s16; /* 16 bit signed integer */ typedef signed int s32; /* 32 bit signed integer */ typedef signed long long s64; /* 64 bit signed integer */ typedef float f32; /* 32 bit floating point */ typedef double f64; /* 64 bit floating point */ // Pixel type typedef s16 PixType; #endif // WAILI_TYPES_H waili-gpl-19990723/include/waili/Util.h100640 24520 25417 4211 6745120261 16133 0ustar geertnatw// // Utility Routines // // $Id: Util.h,v 4.0.4.1 1999/07/20 16:15:45 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_UTIL_H #define WAILI_UTIL_H #include "Types.h" #include #include #define EPS (1E-14) // Program Failure void Die(const char *fmt, ...) #ifdef __GNUG__ __attribute__ ((noreturn, format (printf, 1, 2))) #endif // __GNUG__ ; // Unimplemented Functions #define NotYetImplemented \ Die("%s: Not yet implemented (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__) // Memory Tracking #ifdef TRACK_MEMORY void *operator new(size_t); void *operator new[](size_t); void operator delete(void *); void operator delete[](void *); void DumpMemoryStatus(void); #endif /* TRACK_MEMORY */ // Min/Max Functions template inline Type Min(Type x, Type y) { #ifdef __GNUG__ return(x inline Type Max(Type x, Type y) { #ifdef __GNUG__ return(x >? y); #else /* !__GNUG__ */ return(x > y ? x : y); #endif /* !__GNUG__ */ } inline int Odd(int x) { return(x%2); } inline int Even(int x) { return(!Odd(x)); } template inline Type Abs(Type x) { return(x < 0 ? -x : x); } inline f32 Abs(f32 x) { return(fabs(x)); } inline f64 Abs(f64 x) { return(fabs(x)); } #endif // WAILI_UTIL_H waili-gpl-19990723/include/waili/Wavelet.h100640 24520 25417 27350 6745120261 16656 0ustar geertnatw// // Integer Wavelet Classes // // $Id: Wavelet.h,v 4.1.2.4.2.1 1999/07/20 16:15:45 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef WAILI_WAVELET_H #define WAILI_WAVELET_H #include #include #include "Lifting.h" // Optimization #define LIFTING_OPTIMIZE_STEPS 1 // Use optimized lifting steps // ---------------------------------------------------------------------------- // // Integer Wavelet Abstract Base Class // // ---------------------------------------------------------------------------- class Wavelet { public: virtual Wavelet *Clone(void) const = 0; // Biorthogonal Cohen-Daubechies-Feauveau static Wavelet *CreateCDF(u_int np, u_int d); virtual void CakeWalk(Lifting &lifting) const = 0; virtual void ICakeWalk(Lifting &lifting) const = 0; // Filter Length int GetGStart() const; int GetGEnd() const; int GetHStart() const; int GetHEnd() const; // Normalization int GetShiftL(void) const; int GetShiftH(void) const; // Unique private IDs for different Wavelets u8 GetID(void) const; static Wavelet *CreateFromID(u8 id); protected: int GStart, GEnd, HStart, HEnd; // Normalization int ShiftL, ShiftH; // Unique private IDs enum Wavelet_IDs { ID_Lazy = 0, ID_CDF_1_1 = 1, ID_CDF_1_3 = 2, ID_CDF_1_5 = 3, ID_CDF_2_2 = 4, ID_CDF_2_4 = 5, ID_CDF_2_6 = 6, ID_CDF_4_2 = 7, ID_CDF_4_4 = 8, ID_CDF_4_6 = 9, ID_CRF_13_7 = 100, ID_SWE_13_7 = 101 }; u8 ID; private: static const char *rcsid; }; // ---------------------------------------------------------------------------- // Lazy Wavelet // Equivalent to Biorthogonal Cohen-Daubechies-Feauveau (0, 0) class Wavelet_Lazy : public Wavelet { public: Wavelet_Lazy(); Wavelet_Lazy *Clone(void) const; // Lifting steps on Channels void CakeWalk(Lifting &) const {}; void ICakeWalk(Lifting &) const {}; private: static const char *rcsid; }; // ---------------------------------------------------------------------------- // Biorthogonal Cohen-Daubechies-Feauveau (1, x) class LiftCoef_CDF_1_x { protected: static const s16 D1b[2]; static const u16 D1a; }; class LiftCoef_CDF_1_1 : public LiftCoef_CDF_1_x { protected: static const s16 P2b[2]; static const u16 P2a; }; class LiftCoef_CDF_1_3 : public LiftCoef_CDF_1_x { protected: static const s16 P2b[4]; static const u16 P2a; }; class LiftCoef_CDF_1_5 : public LiftCoef_CDF_1_x { protected: static const s16 P2b[6]; static const u16 P2a; }; class Wavelet_CDF_1_x : public Wavelet { protected: Wavelet_CDF_1_x(); private: static const char *rcsid; }; class Wavelet_CDF_1_1 : public Wavelet_CDF_1_x, public LiftCoef_CDF_1_1 { public: Wavelet_CDF_1_1(); virtual Wavelet_CDF_1_1 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; class Wavelet_CDF_1_3 : public Wavelet_CDF_1_x, public LiftCoef_CDF_1_3 { public: Wavelet_CDF_1_3(); virtual Wavelet_CDF_1_3 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; class Wavelet_CDF_1_5 : public Wavelet_CDF_1_x, public LiftCoef_CDF_1_5 { public: Wavelet_CDF_1_5(); virtual Wavelet_CDF_1_5 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; // ---------------------------------------------------------------------------- // Biorthogonal Cohen-Daubechies-Feauveau (2, x) class LiftCoef_CDF_2_x { protected: static const s16 D1b[2]; static const u16 D1a; }; class LiftCoef_CDF_2_2 : public LiftCoef_CDF_2_x { protected: static const s16 P2b[2]; static const u16 P2a; }; class LiftCoef_CDF_2_4 : public LiftCoef_CDF_2_x { protected: static const s16 P2b[4]; static const u16 P2a; }; class LiftCoef_CDF_2_6 : public LiftCoef_CDF_2_x { protected: static const s16 P2b[6]; static const u16 P2a; }; class Wavelet_CDF_2_x : public Wavelet { protected: Wavelet_CDF_2_x(); private: static const char *rcsid; }; class Wavelet_CDF_2_2 : public Wavelet_CDF_2_x, public LiftCoef_CDF_2_2 { public: Wavelet_CDF_2_2(); virtual Wavelet_CDF_2_2 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; class Wavelet_CDF_2_4 : public Wavelet_CDF_2_x, public LiftCoef_CDF_2_4 { public: Wavelet_CDF_2_4(); virtual Wavelet_CDF_2_4 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; class Wavelet_CDF_2_6 : public Wavelet_CDF_2_x, public LiftCoef_CDF_2_6 { public: Wavelet_CDF_2_6(); virtual Wavelet_CDF_2_6 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; // ---------------------------------------------------------------------------- // Biorthogonal Cohen-Daubechies-Feauveau (4, x) class LiftCoef_CDF_4_x { protected: static const s16 P1b[2]; static const u16 P1a1; static const u16 P1a2; static const s16 D2b[2]; static const u16 D2a; }; class LiftCoef_CDF_4_2 : public LiftCoef_CDF_4_x { protected: static const s16 P3b[2]; static const u16 P3a; }; class LiftCoef_CDF_4_4 : public LiftCoef_CDF_4_x { protected: static const s16 P3b[4]; static const u16 P3a; }; class LiftCoef_CDF_4_6 : public LiftCoef_CDF_4_x { protected: static const s16 P3b[6]; static const u16 P3a; }; class Wavelet_CDF_4_x : public Wavelet { protected: Wavelet_CDF_4_x(); private: static const char *rcsid; }; class Wavelet_CDF_4_2 : public Wavelet_CDF_4_x, public LiftCoef_CDF_4_2 { public: Wavelet_CDF_4_2(); virtual Wavelet_CDF_4_2 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; class Wavelet_CDF_4_4 : public Wavelet_CDF_4_x, public LiftCoef_CDF_4_4 { public: Wavelet_CDF_4_4(); virtual Wavelet_CDF_4_4 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; class Wavelet_CDF_4_6 : public Wavelet_CDF_4_x, public LiftCoef_CDF_4_6 { public: Wavelet_CDF_4_6(); virtual Wavelet_CDF_4_6 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; }; // ---------------------------------------------------------------------------- // JPEG 2000 class Wavelet_CRF_13_7 : public Wavelet { public: Wavelet_CRF_13_7(); virtual Wavelet_CRF_13_7 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; protected: static const s16 D1b[4]; static const u16 D1a; static const s16 P2b[4]; static const u16 P2a; private: static const char *rcsid; }; class Wavelet_SWE_13_7 : public Wavelet { public: Wavelet_SWE_13_7(); virtual Wavelet_SWE_13_7 *Clone(void) const; // Lifting steps on Channels virtual void CakeWalk(Lifting &lifting) const; virtual void ICakeWalk(Lifting &lifting) const; protected: static const s16 D1b[4]; static const u16 D1a; static const s16 P2b[4]; static const u16 P2a; private: static const char *rcsid; }; ///////////////////////////////////////////////////////////////////////////// // // Inline Member Functions // ///////////////////////////////////////////////////////////////////////////// inline int Wavelet::GetGStart(void) const { return(GStart); } inline int Wavelet::GetGEnd(void) const { return(GEnd); } inline int Wavelet::GetHStart(void) const { return(HStart); } inline int Wavelet::GetHEnd(void) const { return(HEnd); } inline int Wavelet::GetShiftL(void) const { return(ShiftL); } inline int Wavelet::GetShiftH(void) const { return(ShiftH); } inline u8 Wavelet::GetID(void) const { return ID; } inline Wavelet_Lazy::Wavelet_Lazy() { HStart = 0; HEnd = 0; GStart = 1; GEnd = 1; ShiftH = 0; ShiftL = 0; } inline Wavelet_Lazy *Wavelet_Lazy::Clone(void) const { return(new Wavelet_Lazy(*this)); } inline Wavelet_CDF_1_x::Wavelet_CDF_1_x() { GStart = 0; GEnd = 1; ShiftL = 1; ShiftH = -1; } inline Wavelet_CDF_2_x::Wavelet_CDF_2_x() { GStart = 0; GEnd = 2; ShiftL = 1; ShiftH = -1; } inline Wavelet_CDF_4_x::Wavelet_CDF_4_x() { GStart = -1; GEnd = 3; ShiftL = 1; ShiftH = -1; } inline Wavelet_CDF_1_1::Wavelet_CDF_1_1() { HStart = 0; HEnd = 1; ID = ID_CDF_1_1; } inline Wavelet_CDF_1_1 *Wavelet_CDF_1_1::Clone(void) const { return(new Wavelet_CDF_1_1(*this)); } inline Wavelet_CDF_1_3::Wavelet_CDF_1_3() { HStart = -2; HEnd = 3; ID = ID_CDF_1_3; } inline Wavelet_CDF_1_3 *Wavelet_CDF_1_3::Clone(void) const { return(new Wavelet_CDF_1_3(*this)); } inline Wavelet_CDF_1_5::Wavelet_CDF_1_5() { HStart = -4; HEnd = 5; ID = ID_CDF_1_5; } inline Wavelet_CDF_1_5 *Wavelet_CDF_1_5::Clone(void) const { return(new Wavelet_CDF_1_5(*this)); } inline Wavelet_CDF_2_2::Wavelet_CDF_2_2() { HStart = -2; HEnd = 2; ID = ID_CDF_2_2; } inline Wavelet_CDF_2_2 *Wavelet_CDF_2_2::Clone(void) const { return(new Wavelet_CDF_2_2(*this)); } inline Wavelet_CDF_2_4::Wavelet_CDF_2_4() { HStart = -4; HEnd = 4; ID = ID_CDF_2_4; } inline Wavelet_CDF_2_4 *Wavelet_CDF_2_4::Clone(void) const { return(new Wavelet_CDF_2_4(*this)); } inline Wavelet_CDF_2_6::Wavelet_CDF_2_6() { HStart = -6; HEnd = 6; ID = ID_CDF_2_6; } inline Wavelet_CDF_2_6 *Wavelet_CDF_2_6::Clone(void) const { return(new Wavelet_CDF_2_6(*this)); } inline Wavelet_CDF_4_2::Wavelet_CDF_4_2() { HStart = -3; HEnd = 3; ID = ID_CDF_4_2; } inline Wavelet_CDF_4_2 *Wavelet_CDF_4_2::Clone(void) const { return(new Wavelet_CDF_4_2(*this)); } inline Wavelet_CDF_4_4::Wavelet_CDF_4_4() { HStart = -5; HEnd = 5; ID = ID_CDF_4_4; } inline Wavelet_CDF_4_4 *Wavelet_CDF_4_4::Clone(void) const { return(new Wavelet_CDF_4_4(*this)); } inline Wavelet_CDF_4_6::Wavelet_CDF_4_6() { HStart = -7; HEnd = 7; ID = ID_CDF_4_6; } inline Wavelet_CDF_4_6 *Wavelet_CDF_4_6::Clone(void) const { return(new Wavelet_CDF_4_6(*this)); } inline Wavelet_CRF_13_7::Wavelet_CRF_13_7() { GStart = -4; GEnd = 2; HStart = -6; HEnd = 6; ID = ID_CRF_13_7; ShiftL = 1; ShiftH = 1; } inline Wavelet_CRF_13_7 *Wavelet_CRF_13_7::Clone(void) const { return new Wavelet_CRF_13_7(*this); } inline Wavelet_SWE_13_7::Wavelet_SWE_13_7() { GStart = -4; GEnd = 2; HStart = -6; HEnd = 6; ID = ID_SWE_13_7; ShiftL = 1; ShiftH = 1; } inline Wavelet_SWE_13_7 *Wavelet_SWE_13_7::Clone(void) const { return new Wavelet_SWE_13_7(*this); } #endif // WAILI_WAVELET_H waili-gpl-19990723/man/ 40755 24520 25417 0 6746056436 13016 5ustar geertnatwwaili-gpl-19990723/man/Blit.tex100640 24520 25417 10167 6745120316 14534 0ustar geertnatw% % Low-Level Block Operations % % $Id: Blit.tex,v 4.1.2.1.2.1 1999/07/20 16:16:14 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Blit}{$ $Revision: 4.1.2.1.2.1 $ $} \subtitle{Name} Blit --- Low-level block operations % ----------------------------------------------------------------------------- \subtitle{Description} This package provides some frequently used low-level block operations. All functions are template functions, allowing for different operand types. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Blit.h} % ----------------------------------------------------------------------------- \subtitle{Operations} \function{void Copy(const~Type$\ast$ src, Type$\ast$ dst, u\_int len)} Copy \name{len} objects from \name{src} to \name{dst}. \function{void Copy(const~Type$\ast$ src, Type$\ast$ dst)} Copy the object pointed to by \name{src} to \name{dst}. \function{void Fill(Type$\ast$ dst, u\_int len, Type value)} Fill \name{len} objects pointed to by \name{dst} with \name{value}. \function{void Clear(Type$\ast$ dst, u\_int len)} Clear \name{len} objects pointed to by \name{dst}. \function{void Clear(Type$\ast$ dst)} Clear the object pointed to by \name{dst}. \function{void CopyRect(const~Type$\ast$ src, u\_int sw, Type$\ast$ dst, u\_int dw, u\_int cols, u\_int rows)} Copy a rectangular block of objects with \name{cols} columns and \name{rows} rows from \name{src} to \name{dst}. The source area has \name{sw} columns, while the destination area has \name{dw} columns. \function{void CopyRect(const~Type$\ast$ src, u\_int sw, u\_int sx, u\_int sy, Type$\ast$ dst, u\_int dw, u\_int dx, u\_int dy, u\_int cols, u\_int rows)} Copy a rectangular block of objects with \name{cols} columns and \name{rows} rows from \name{src} at position (\name{sx}, \name{sy}) to \name{dst} at position (\name{dx}, \name{dy}). The source area has \name{sw} columns, while the destination area has \name{dw} columns. \function{void FillRect(Type$\ast$ dst, u\_int dw, u\_int cols, u\_int rows, Type value)} Fill a rectangular block of objects with \name{cols} columns and \name{rows} rows, pointed to by \name{dst} with \name{value}. The destination area has \name{dw} columns. \function{void FillRect(Type$\ast$ dst, u\_int dw, u\_int dx, u\_int dy, u\_int cols, u\_int rows, Type value)} Fill a rectangular block of objects with \name{cols} columns and \name{rows} rows, pointed to by \name{dst} at position (\name{dx}, \name{dy}) with \name{value}. The destination area has \name{dw} columns. \function{void ClearRect(Type$\ast$ dst, u\_int dw, u\_int cols, u\_int rows)} Clear a rectangular block of objects with \name{cols} columns and \name{rows} rows, pointed to by \name{dst}. The destination area has \name{dw} columns. \function{void ClearRect(Type$\ast$ dst, u\_int dw, u\_int dx, u\_int dy, u\_int cols, u\_int rows)} Clear a rectangular block of objects with \name{cols} columns and \name{rows} rows, pointed to by \name{dst} at position (\name{dx}, \name{dy}). The destination area has \name{dw} columns. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Blit.h,v 4.0 1997/05/05 09:46:21 geert Exp} \end{manpage} waili-gpl-19990723/man/Channel.tex100640 24520 25417 65644 6745120316 15224 0ustar geertnatw% % Channel Class % % $Id: Channel.tex,v 4.14.2.3.2.1 1999/07/20 16:16:14 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Channel}{$ $Revision: 4.14.2.3.2.1 $ $} \subtitle{Name} Channel --- Generic channel class % ----------------------------------------------------------------------------- \subtitle{Description} This class provides a low-level channel abstraction. A channel is a (rectangular) matrix containing one-valued pixels (of type \texttt{PixType}). % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Channel.h} \name{Channel} is an abstract base class. No instances can be declared. Different channel types are implemented through inheritance. \function{Channel()} Create an empty channel. \function{Channel(u\_int cols, u\_int rows, int offx = 0, int offy = 0)} Create a channel with given dimensions. \name{cols} and \name{rows} are the number of columns respectively rows, \name{offx} and \name{offy} are the offsets of the upper left pixel in the universal coordinate system. \function{Channel(const~Channel\& channel)} Create a new channel by copying channel \name{channel}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{u\_int GetCols(void)\ const} \function{u\_int GetRows(void)\ const} Get the number of columns respectively rows of the channel. \function{int GetOffsetX(void)\ const} \function{int GetOffsetY(void)\ const} Get the offset of upper left pixel of the channel in the universal coordinate system. % ----------------------------------------------------------------------------- \subtitle{Static \\ Operations} \function{Channel$\ast$ CreateFromDescriptor(u\_int cols, u\_int rows, const~TransformDescriptor transform[], u\_int depth, int offsetx = 0, int offsety = 0)} Create a channel with given dimensions. \name{cols} and \name{rows} are the number of columns respectively rows, \name{offsetx} and \name{offsety} are the offsets of the upper left pixel in the universal coordinate system. The channel will be pretransformed using the transform descriptor \name{transform} with transform depth \name{depth}. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{void GetMask(u\_int\& maskx, u\_int\& masky)\ const} Get the coordinate masks for the offsets. A set bit in a mask corresponds to a bit in the offset that can't be choosen freely without retransforming the channel. \function{u\_int GetDepth(void)\ const} Get the transform depth of the channel. \function{double Psnr(const~Channel\& channel, PixType maxval = 255)\ const} Calculate the Peak Signal to Noise Ratio (in dB) between the current channel en channel \name{channel}. \name{maxval} is the Peak Signal value. \function{u64$\ast$ FullHistogram(PixType\& min, PixType\& max, u64\& numpixels) const} Create a histogram for the current channel. The lower histogram limit will be put in \name{min}, the upper limit in \name{max}. The number of analyzed pixels will be put in \name{numpixels}. The result is an array of length $\name{max}-\name{min}+1$ containing the occurrency counts. \function{double Entropy(void) const} Calculate the first order entropy (Shannon-Weaver) for this channel, in bits per pixel. \function{PixType\& \mbox{operator()}(u\_int c, u\_int r)} \function{PixType \mbox{operator()}(u\_int c, u\_int r)\ const} Access the `pixel' at column \name{c} and row \name{r}. This may refer to a wavelet coefficient instead of a real pixel value if the channel is wavelet transformed. \function{void Clear(void)} Clear all pixel values to zero. \function{void Resize(u\_int cols, u\_int rows)} Change the number of columns and rows of the channel to \name{cols} respectively \name{rows}. \function{Channel$\ast$ Clone(void)\ const} Make a copy of the current channel. \function{int SetOffsetX(void)\ const} \function{int SetOffsetY(void)\ const} Change the offset of the channel in the universal coordinate system. If you change the bits that are covered by the corresponding coordinate mask, the channel will be retransformed. \function{Channel$\ast$ Crop(int x1, int y1, int x2, int y2)\ const} Get a rectangular part of the current channel, of which the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). \function{void Merge(const~Channel\& channel)} Paste \name{channel} into the current channel. The paste position is determined by the offsets of \name{channel}. \function{void Add(const~Channel\& channel)} \function{void Subtract(const~Channel\& channel)} Add respectively subtract \name{channel} to (from) the current channel. Both channels must have the same number of columns, number of rows, offsets and structure. \function{Channel$\ast$ Diff(const~Channel\& channel)\ const} This function returns the difference channel between the current channel and \name{channel}. Both channels must have the same number of columns, number of rows, offsets and structure. \function{void Enhance(f32 m)} Enhance the channel by multiplying all pixel values with \name{m}. If the channel is lifted, then only its high-pass coefficients will be changed. \function{void Enhance(int m, u\_int shift)} Enhance the channel by multiplying all pixel values with \name{m} and shifting the result \name{shift} binary positions to the right. If the channel is lifted, then only its high-pass coefficients will be changed. \function{LChannel$\ast$ PushFwtStepCR(const~Wavelet\& wavelet)} \function{LChannel$\ast$ PushFwtStepC(const~Wavelet\& wavelet)} \function{LChannel$\ast$ PushFwtStepR(const~Wavelet\& wavelet)} Add one transform level, using the wavelet transform specified by \name{wavelet}. The transform can operate on both columns and rows (\name{PushFwtStepCR}), on the colums only (\name{PushFwtStepC}) or on the rows only (\name{PushFwtStepR}). Note that the current channel will be destroyed!!! This function can return the following values: \begin{itemize} \item[\texttt{NULL}] The operation wasn't sucessful because the maximum number of transform levels was already reached. \item[\texttt{this}] If the result is equal to the current channel, the operation was successful. \item[Else] The operation was successful, and the current channel should be deleted and replaced by the returned channel. \end{itemize} \function{Channel$\ast$ PopFwtStep(void)} Remove one transform level. This is the inverse operation of the last \name{PushFwtStep$\ast$} operation. \function{u64 Threshold(double threshold, int soft = 0)} Perform hard (\name{soft = 0}) or soft (\name{soft = 1}) thresholding with the thresholding value \name{threshold}. The number of pixels that had a value smaller than \name{threshold} is returned. \function{int IsLifted(void)\ const} This function returns non-zero if the current channel is already lifted. \emph{This should be removed later!! The user doesn't need to know what's the internal representation of the channel!} \function{Channel$\ast$ Scale(f32 s, const~Wavelet\& wavelet)} Scale the channel with scaling factor \name{scale}. Note that the current channel will be destroyed!!! % ----------------------------------------------------------------------------- \subtitle{Protected \\ Operations} \function{Channel$\ast$ UpScale(u\_int s, const~Wavelet\& wavelet)} Scale the current channel up. The applied scaling factor is the next power of 2 of \name{s} if \name{s} is not a power of 2 by itself. Note that the current channel will be destroyed!!! % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Protected \\ Operations} \function{void Destroy(void)} Delete the contents of the channel and zero the number of columns and rows. \function{Channel$\ast$ DownScale(u\_int s, const~Wavelet\& wavelet)} Scale the current channel down. The applied scaling factor is the previous power of 2 of \name{s} if \name{s} is not a power of 2 by itself. Note that the current channel will be destroyed!!! % ----------------------------------------------------------------------------- \subtitle{Static \\ Protected \\ Operations} \function{int GetEven(int len)} \function{int GetOdd(int len)} Calculate the number of even respectively odd coefficients for a signal with length \name{len}. % ----------------------------------------------------------------------------- \separator \subtitle{Derived \\ Classes} These are derived classes of the generic \name{Channel} class that add support for non-transformed and wavelet transformed channels. % ----------------------------------------------------------------------------- \separator \subtitle{Name} NTChannel --- Class for a non-transformed channel. % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{NTChannel()} Create an empty non-transformed channel. \function{NTChannel(u\_int cols, u\_int rows, int offx = 0, int offy = 0)} Create a non-transformed channel with given dimensions. \name{cols} and \name{rows} are the number of columns respectively rows, \name{offx} and \name{offy} are the offsets of the upper left pixel in the universal coordinate system. \function{NTChannel(const~NTChannel\& channel)} Create a new non-transformed channel by copying the non-transformed channel \name{channel}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{void GetMinMax(PixType\& min, PixType\& max, u\_int smoothing = 0) const} Return the minimum and maximum pixel values in \name{min} respectively \name{max}. \name{smoothing} defines the degree of neglection of extraordinary pixel values. \emph{Smoothing is not yet implemented} \function{s32$\ast$ Correlate(const~NTChannel\& channel, u\_int diff)\ const} Calculate the correlation matrix between the current channel and \name{channel}. \name{diff} indicates the difference of resolution level between the current channel and the more coarse \name{channel}. Note that the returned correlation matrix has the same dimensions as the current channel. \function{u64$\ast$ Histogram(PixType min, PixType max)} Create a histogram for the current channel. The lower histogram limit will be \name{min}, the upper limit will be \name{max}. The result is an array of length $\name{max}-\name{min}+1$ containing the occurrency counts. \function{u64 ThresholdHard(u\_int threshold)} \function{u64 ThresholdSoft(u\_int threshold)} Perform hard or soft thresholding with the thresholding value \name{threshold}. The number of pixels that had a value smaller than \name{threshold} is returned. \function{u\_int OptimalGCVThreshold(void)\ const} Calculate the optimal soft thresholding value using a technique called Generalized Cross Validation. Note that the channel should contain at least 1000 pixels to give a meaningful result. \function{NTChannel$\ast$ DupliScale(u\_int s)\ const} Create a scaled version of the current channel by duplicating the original pixel values. \name{s} is the scaling factor. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{NTChannel$\ast$ Clone(void)\ const} Make a copy of the current channel. \function{NTChannel$\ast$ Crop(int x1, int y1, int x2, int y2)\ const} Get a rectangular part of the current channel, of which the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). \function{NTChannel$\ast$ Diff(const~Channel\& channel)\ const} This function returns the difference channel between the current channel and \name{channel}. Both channels must have the same number of columns, number of rows, offsets and structure. \function{LChannel$\ast$ Fwt(const~TransformDescriptor transform[], u\_int depth)} Transform the channel using the Fast Wavelet Transform. The two-dimensional wavelet transform will be applied to all channels independently. The type of wavelet transform is determined by the \name{transform} array and its length \name{depth}. Note that the current channel will be destroyed!!! % ----------------------------------------------------------------------------- \subtitle{Protected \\ Operations} \function{void Interpolate(f32 s)} Scale the channel using a linear interpolation scheme. \function{double GCV(u\_int threshold)\ const} Calculate the GCV value of the channel for Generalized Cross Validation. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Protected \\ Operations} \function{NTChannel$\ast$ DownScale(u\_int s, const~Wavelet\& wavelet)} Scale the current channel down. The applied scaling factor is the previous power of 2 of \name{s} if \name{s} is not a power of 2 by itself. % ----------------------------------------------------------------------------- \separator \subtitle{Name} LChannel --- Class for a wavelet transformed channel. % ----------------------------------------------------------------------------- \subtitle{Declaration} \name{LChannel} is an abstract base class. No instances can be declared. Different wavelet transformed channel types are implemented through inheritance. \function{LChannel(const~LChannel\& channel)} Create a new channel by copying channel \name{channel}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{Channel$\ast$\& operator[](SubBand band)} \function{const~Channel$\ast$\& operator[](SubBand band)\ const} Get the subband of type \name{band}. \emph{Make sure the subband does exist!} \function{TransformDescriptor$\ast$ GetTransform(void)} Get a transform descriptor array for all transform levels. \function{int GetShift(SubBand band)} Get the number of steps (in base-$\sqrt{2}$!) the coefficients of subband \name{band} have to be shifted to the left to obtain their real values. \function{NTChannel$\ast$ IFwt(void)} Transform the channel using the inverse fast wavelet transform. Note that the current channel will be destroyed!!! % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{TransformType GetTransformType(void)\ const} Get the transform type for this transform level. \function{LChannel$\ast$ Clone(void)\ const} Make a copy of the current channel. \function{NTChannel$\ast$ IFwt(int x1, int y1, int x2, int y2)\ const} Perform recursively the inverse fast wavelet transform on the rows and columns of the channel determined by the upper left and lower right corner respectively (\name{x1}, \name{y1}) and (\name{x2}, \name{y2}). \function{LChannel$\ast$ Crop(int x1, int y1, int x2, int y2)\ const} Get a rectangular part of the current channel, of which the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). % ----------------------------------------------------------------------------- \subtitle{Protected \\ Operations} \function{LChannel(const~Wavelet\& filter, u\_int numsubbands, u\_int cols = 0, u\_int rows = 0)} Create a channel with given dimensions. \name{numsubbands} is the number of subbands, \name{cols} and \name{rows} are the number of columns respectively rows. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Protected \\ Operations} \function{NTChannel$\ast$ IFwtStep(void)} Perform one step of the inverse fast wavelet transform. Note that the current channel will be destroyed!!! \function{void Lazy(const~NTChannel\& source)} Calculate the Lazy Wavelet Transform of \name{source} and store the result in the current channel. \function{void ILazy(NTChannel\& dest)\ const} Calculate the inverse Lazy Wavelet Transform of the current channel and put the result in \name{dest}. \function{void CakeWalk(void)} \function{void ICakeWalk(void)} Perform the (inverse) `Cake Walk' operation on the current channel. \function{LChannel$\ast$ Crop\_rec(int x1, int y1, int x2, int y2, NTChannel$\ast$ top, NTChannel$\ast$ bottom, NTChannel$\ast$ left, NTChannel$\ast$ right) const} Get a rectangular part of the current channel, of which the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). \name{top}, \name{bottom}, \name{left} and \name{right} are the resulting borders in the LP-band of the higher resolution level which affect lower resolutions. \function{void Merge\_rec(const Channel$\ast$ channel, NTChannel$\ast$ top, NTChannel$\ast$ bottom, NTChannel$\ast$ left, NTChannel$\ast$ right)} Paste \name{channel} into the current channel. The paste position is determined by the offsets of \name{channel}. \name{top}, \name{bottom}, \name{left} and \name{right} are the resulting borders in the LP-band of the higher resolution level which affect lower resolutions. % ----------------------------------------------------------------------------- \subtitle{Subband \\ Types} Valid subband types are \begin{center}\begin{tabular}{|l|l|} \hline LL & lowpass in both the vertical and the horizontal direction \\ LH & lowpass in the vertical, highpass in the horizontal direction \\ HL & highpass in the vertical, lowpass in the horizontal direction \\ HH & highpass in both the vertical and the horizontal direction \\ \hline \end{tabular}\end{center} % ----------------------------------------------------------------------------- \separator \subtitle{Name} LChannelCR --- Class for a wavelet transformed channel (both columns and rows). % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{LChannelCR(const~Wavelet\& filter)} Create an empty channel. \function{LChannelCR(const~Wavelet\& filter, u\_int cols, u\_int rows, int offx, int offy)} Create a channel with given dimensions. \name{cols} and \name{rows} are the number of columns respectively rows, \name{offx} and \name{offy} are the coordinates in the universal coordinate system. \function{LChannelCR(const~LChannelCR\& channel)} Create a new channel by copying channel \name{channel}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{u\_int GetClow(void)\ const} \function{u\_int GetChigh(void)\ const} \function{u\_int GetRlow(void)\ const} \function{u\_int GetRhigh(void)\ const} Get the number of columns and rows in the low and high frequency subbands. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{LChannelCR$\ast$ Clone(void)\ const} Make a copy of the current channel. \function{LChannelCR$\ast$ Diff(const~Channel\& channel)\ const} This function returns the difference channel between the current channel and \name{channel}. Both channels must have the same number of columns, number of rows, offsets and structure. \function{LChannelCR$\ast$ Crop\_rec(int x1, int y1, int x2, int y2, NTChannel$\ast$ top, NTChannel$\ast$ bottom, NTChannel$\ast$ left, NTChannel$\ast$ right) const} Get a rectangular part of the current channel, of which the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). \name{top}, \name{bottom}, \name{left} and \name{right} are the resulting borders in the LP-band of the higher resolution level which affect lower resolutions. % ----------------------------------------------------------------------------- \separator \subtitle{Name} LChannelC --- Class for a wavelet transformed channel (columns only). % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{LChannelC(const~Wavelet\& filter)} Create an empty channel. \function{LChannelC(const~Wavelet\& filter, u\_int cols, u\_int rows, int offx, int offy)} Create a channel with given dimensions. \name{cols} and \name{rows} are the number of columns respectively rows, \name{offx} and \name{offy} are the coordinates in the universal coordinate system. \function{LChannelC(const~LChannelC\& channel)} Create a new channel by copying channel \name{channel}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{u\_int GetRlow(void)\ const} \function{u\_int GetRhigh(void)\ const} Get the number of rows in the low and high frequency subbands. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{LChannelC$\ast$ Clone(void)\ const} Make a copy of the current channel. \function{LChannelC$\ast$ Diff(const~Channel\& channel)\ const} This function returns the difference channel between the current channel and \name{channel}. Both channels must have the same number of columns, number of rows, offsets and structure. \function{LChannelC$\ast$ Crop\_rec(int x1, int y1, int x2, int y2, NTChannel$\ast$ top, NTChannel$\ast$ bottom, NTChannel$\ast$ left, NTChannel$\ast$ right) const} Get a rectangular part of the current channel, of which the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). \name{top}, \name{bottom}, \name{left} and \name{right} are the resulting borders in the LP-band of the higher resolution level which affect lower resolutions. % ----------------------------------------------------------------------------- \separator \subtitle{Name} LChannelR --- Class for a wavelet transformed channel (rows only). % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{LChannelR(const~Wavelet\& filter)} Create an empty channel. \function{LChannelR(const~Wavelet\& filter, u\_int cols, u\_int rows, int offx, int offy)} Create a channel with given dimensions. \name{cols} and \name{rows} are the number of columns respectively rows, \name{offx} and \name{offy} are the coordinates in the universal coordinate system. \function{LChannelR(const~LChannelR\& channel)} Create a new channel by copying channel \name{channel}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{u\_int GetClow(void)\ const} \function{u\_int GetChigh(void)\ const} Get the number of columns in the low and high frequency subbands. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{LChannelR$\ast$ Clone(void)\ const} Make a copy of the current channel. \function{LChannelR$\ast$ Diff(const~Channel\& channel)\ const} This function returns the difference channel between the current channel and \name{channel}. Both channels must have the same number of columns, number of rows, offsets and structure. \function{LChannelR$\ast$ Crop\_rec(int x1, int y1, int x2, int y2, NTChannel$\ast$ top, NTChannel$\ast$ bottom, NTChannel$\ast$ left, NTChannel$\ast$ right) const} Get a rectangular part of the current channel, of which the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). \name{top}, \name{bottom}, \name{left} and \name{right} are the resulting borders in the LP-band of the higher resolution level which affect lower resolutions. % ----------------------------------------------------------------------------- \separator \subtitle{TransformDescriptor} The TransformDescriptor determines the kind of wavelet transform for one transform level. It contains 2 parts: \variable{TransformType type} \name{type} is the transform type and can be one of: \begin{center}\begin{tabular}{|l|l|} \hline \texttt{TT\_ColsRows} & Transform both columns and rows \\ \texttt{TT\_Cols} & Transform columns only \\ \texttt{TT\_Rows} & Transform rows only \\ \hline \end{tabular}\end{center} \variable{const~Wavelet$\ast$ filter} \name{filter} is a pointer to a wavelet filter. % ----------------------------------------------------------------------------- \subtitle{Dependency \\ Graphs} \begin{description} \item[Fig.~\ref{fig:Channel}] Inheritance dependency graph for the channel class hierarchy (\emph{Channel}). \end{description} \begin{figure}[ht]\begin{center} \resizebox{100mm}{!}{\includegraphics{Channel_dep.eps}} \caption{Inheritance dependency graph for the channel class hierarchy (\emph{Channel}).} \label{fig:Channel} \end{center}\end{figure} \subtitle{See Also} The \name{Wavelet} and \name{Lifting} classes. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Channel.C,v 4.4.2.2 1999/04/15 09:35:09 geert Exp} \rev{Channel.h,v 4.5.2.3 1999/07/20 13:18:57 geert Exp} \rev{LChannel.C,v 4.5.2.2 1999/07/20 13:19:02 geert Exp} \rev{LChannel.h,v 4.3.2.2 1999/07/20 13:18:57 geert Exp} \rev{LChannelC.C,v 4.6.2.1 1999/07/20 13:19:02 geert Exp} \rev{LChannelC.h,v 4.3.2.1 1999/07/20 13:18:57 geert Exp} \rev{LChannelCR.C,v 4.6.2.1 1999/07/20 13:19:03 geert Exp} \rev{LChannelCR.h,v 4.3.2.1 1999/07/20 13:18:58 geert Exp} \rev{LChannelR.C,v 4.6.2.1 1999/07/20 13:19:04 geert Exp} \rev{LChannelR.h,v 4.3.2.1 1999/07/20 13:18:58 geert Exp} \rev{NTChannel.C,v 4.12.2.3 1999/07/20 13:19:04 geert Exp} \rev{NTChannel.h,v 4.8.2.1 1999/07/20 13:18:58 geert Exp} \end{manpage} waili-gpl-19990723/man/Channel_dep.fig100640 24520 25417 4252 6745120316 15765 0ustar geertnatw#FIG 3.1 # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Portrait Center Inches 1200 2 6 2625 1650 3675 2100 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2625 1650 3675 1650 3675 2100 2625 2100 2625 1650 4 0 -1 0 0 0 12 0.0000 4 135 720 2775 1950 LChannel\001 -6 6 525 1650 1575 2100 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 525 1650 1575 1650 1575 2100 525 2100 525 1650 4 0 -1 0 0 0 12 0.0000 4 135 855 600 1950 NTChannel\001 -6 6 1575 450 2625 900 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 1575 450 2625 450 2625 900 1575 900 1575 450 4 0 -1 0 0 0 12 0.0000 4 135 615 1800 750 Channel\001 -6 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 3150 2100 1875 2850 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 3150 2100 4425 2850 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 2100 900 1050 1650 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 2100 900 3150 1650 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2625 2850 3675 2850 3675 3300 2625 3300 2625 2850 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 1350 2850 2400 2850 2400 3300 1350 3300 1350 2850 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 3900 2850 4950 2850 4950 3300 3900 3300 3900 2850 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 3150 2100 3150 2850 4 0 -1 0 0 0 12 0.0000 4 135 840 2700 3150 LChannelC\001 4 0 -1 0 0 0 12 0.0000 4 135 840 3975 3150 LChannelR\001 4 0 -1 0 0 0 12 0.0000 4 135 960 1388 3150 LChannelCR\001 waili-gpl-19990723/man/Color.tex100640 24520 25417 4032 6745120316 14672 0ustar geertnatw% % Color Spaces % % $Id: Color.tex,v 4.1.2.2.2.1 1999/07/20 16:16:14 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Color}{$ $Revision: 4.1.2.2.2.1 $ $} \subtitle{Name} Color --- Various color representations % ----------------------------------------------------------------------------- \subtitle{Description} Various color representations. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Color.h} \function{Color\_RGB()} \function{Color\_XYZ()} \function{Color\_LAB()} \function{Color\_RGB8()} \function{Color\_XYZ8()} \function{Color\_LAB8()} \function{Color\_CIEY()} \function{Color\_CIEL()} \function{Color\_RGB16()} \function{Color\_YUVr16()} % ----------------------------------------------------------------------------- \subtitle{Plans} Use \texttt{PixType} to represent the color components. % ----------------------------------------------------------------------------- \subtitle{See Also} The \name{ColorSpace} class. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Color.C,v 4.0.2.1 1999/04/15 10:06:45 geert Exp} \rev{Color.h,v 4.0.2.1 1999/04/15 10:06:42 geert Exp} \end{manpage} waili-gpl-19990723/man/ColorSpace.tex100640 24520 25417 3252 6745120317 15652 0ustar geertnatw% % Color Spaces % % $Id: ColorSpace.tex,v 4.1.2.2.2.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{ColorSpace}{$ $Revision: 4.1.2.2.2.1 $ $} \subtitle{Name} ColorSpace --- Color spaces and color space conversions % ----------------------------------------------------------------------------- \subtitle{Description} Color space specification and conversion. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Color.h} % ----------------------------------------------------------------------------- \subtitle{See Also} The various \name{Color} classes. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Color.C,v 4.0.2.1 1999/04/15 10:06:45 geert Exp} \rev{Color.h,v 4.0.2.1 1999/04/15 10:06:42 geert Exp} \end{manpage} waili-gpl-19990723/man/Compiler.tex100640 24520 25417 3060 6745120317 15367 0ustar geertnatw% % Compiler Dependent Definitions % % $Id: Compiler.tex,v 4.3.2.1.2.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Compiler}{$ $Revision: 4.3.2.1.2.1 $ $} \subtitle{Name} Compiler --- Compiler dependent definitions % ----------------------------------------------------------------------------- \subtitle{Description} This file contains the compiler dependent definitions. Currently these are definitions for \emph{GNU \CC} only. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Compiler.h} % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Compiler.h,v 4.1 1997/05/05 09:46:35 geert Exp} \end{manpage} waili-gpl-19990723/man/Credits.tex100640 24520 25417 3643 6745120317 15221 0ustar geertnatw% % Credits % % $Id: Credits.tex,v 4.5.2.1.2.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \section{Credits} \libname\ was developed by \begin{tabular}{l} \textbf{Geert Uytterhoeven} \\ Department of Computer Science \\ Katholieke Universiteit Leuven \\ Celestijnenlaan 200A \\ B-3001 Heverlee \\ Belgium \\ \geertemail \\ \geertwww \end{tabular} \begin{tabular}{l} \textbf{Filip Van Wulpen} \\ Department of Computer Science \\ Katholieke Universiteit Leuven \\ Celestijnenlaan 200A \\ B-3001 Heverlee \\ Belgium \\ \filipemail \\ \filipwww \end{tabular} The denoising algorithm \cite{jansen97:GCV,ArtJB97a} was developed by \begin{tabular}{l} \textbf{Maarten Jansen} \\ Department of Computer Science \\ Katholieke Universiteit Leuven \\ Celestijnenlaan 200A \\ B-3001 Heverlee \\ Belgium \\ \maartenemail \\ \maartenwww \end{tabular} \medskip This library has been developed within the project `Wavelet Based Interactive Video Communication and Image Database Consulting', funded by IWT --- Vlaams Actieprogramma Informatietechnologie (project ITA/950244). \vfill \begin{center} \resizebox{60mm}{!}{\includegraphics{WAILI.eps}} \end{center} waili-gpl-19990723/man/Decomposition.fig100640 24520 25417 6203 6745120317 16400 0ustar geertnatw#FIG 3.2 # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Landscape Center Inches Letter 100.00 Single 0 1200 2 6 5700 900 8625 3000 6 6225 900 8625 3000 6 6375 2250 8475 2850 6 6675 2250 8475 2850 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 6675 2250 8475 2250 8475 2850 6675 2850 6675 2250 4 0 0 0 0 3 18 0.0000 4 195 1380 6885 2647 NTChannel\001 -6 6 6375 2250 6675 2850 6 6375 2250 6675 2850 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 6375 2250 6675 2250 6675 2850 6375 2850 6375 2250 4 0 0 0 0 0 18 0.0000 4 195 195 6427 2647 H\001 -6 -6 -6 6 6375 1500 8475 2100 6 6375 1500 6675 2100 6 6375 1500 6675 2100 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 6375 1500 6675 1500 6675 2100 6375 2100 6375 1500 4 0 0 0 0 0 18 0.0000 4 195 165 6442 1897 L\001 -6 -6 6 6675 1500 8475 2100 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 6675 1500 8475 1500 8475 2100 6675 2100 6675 1500 4 0 0 0 0 3 18 0.0000 4 195 1380 6885 1897 NTChannel\001 -6 -6 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 6225 900 8625 900 8625 3000 6225 3000 6225 900 4 0 0 0 0 3 18 0.0000 4 195 1380 6735 1297 LChannelC\001 -6 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 5700 900 6225 900 6225 3000 5700 3000 5700 900 4 0 0 0 0 0 18 0.0000 4 195 330 5775 2100 LL\001 -6 6 5700 3150 8625 5250 6 6225 3150 8625 5250 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 6225 3150 8625 3150 8625 5250 6225 5250 6225 3150 4 0 0 0 0 3 18 0.0000 4 195 1380 6735 4297 NTChannel\001 -6 6 5700 3150 6225 5250 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 5700 3150 6225 3150 6225 5250 5700 5250 5700 3150 4 0 0 0 0 0 18 0.0000 4 195 360 5782 4297 HL\001 -6 -6 6 8775 900 11700 3000 6 9300 900 11700 3000 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 9300 900 11700 900 11700 3000 9300 3000 9300 900 4 0 0 0 0 3 18 0.0000 4 195 1380 9810 2047 NTChannel\001 -6 6 8775 900 9300 3000 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 8775 900 9300 900 9300 3000 8775 3000 8775 900 4 0 0 0 0 0 18 0.0000 4 195 360 8857 2047 LH\001 -6 -6 6 8775 3150 11700 5250 6 9300 3150 11700 5250 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 9300 3150 11700 3150 11700 5250 9300 5250 9300 3150 4 0 0 0 0 3 18 0.0000 4 195 1380 9810 4297 NTChannel\001 -6 6 8775 3150 9300 5250 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 8775 3150 9300 3150 9300 5250 8775 5250 8775 3150 4 0 0 0 0 0 18 0.0000 4 195 390 8842 4297 HH\001 -6 -6 2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5 5550 300 11850 300 11850 5400 5550 5400 5550 300 4 0 0 0 0 3 18 0.0000 4 195 1560 7920 697 LChannelCR\001 waili-gpl-19990723/man/Demo.tex100640 24520 25417 7073 6745120317 14511 0ustar geertnatw% % A Simple Demo Program % % $Id: Demo.tex,v 4.6.2.1.2.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \section{A simple demo program} \texttt{Lifting/test/Demo} is a simple interactive demo program that allows you to play with wavelet transforms. It understands the following commands: \begin{description} \item[\texttt{Help}] \item[\texttt{?}]\mbox{}\\ Display some help information. \item[\texttt{Quit}] \item[\texttt{Exit}]\mbox{}\\ Terminate the program. \item[\texttt{Load} \emph{image}]\mbox{}\\ Load an image from file \emph{image}. Make sure this file does exist! \item[\texttt{Save} \emph{image}]\mbox{}\\ Save the current image to file \emph{image}. \item[\texttt{View}]\mbox{}\\ View the current image using \emph{xv}. Make sure the \texttt{xv} executable is in your path! \item[\texttt{Wavelet} $n$ $\widetilde{n}$]\mbox{}\\ Use the biorthogonal Cohen-Daubechies-Feauveau wavelet with $(n, \widetilde{n})$ vanishing moments. Make sure you select a supported wavelet! \item[\texttt{Wavelet} $n$]\mbox{}\\ Use a biorthogonal wavelet from the JPEG2000 draft. Values of $n$: \begin{description} \item[1] CRF (13, 7) \item[2] SWE (13, 7) \end{description} \item[\texttt{Fstep cr}] \item[\texttt{Fstep c}] \item[\texttt{Fstep r}]\mbox{}\\ Add one transform level. The transform can operate on both colums and rows (default), or on the columns or rows only. \item[\texttt{Bstep}]\mbox{}\\ Remove one transform level. \item[\texttt{Ifwt}]\mbox{}\\ Perform the full inverse transform. \item[\texttt{Noise} \emph{var}]\mbox{}\\ Add white Gaussian noise with variance \emph{var}. \item[\texttt{Denoise}]\mbox{}\\ Denoise the wavelet transformed image by using soft thresholding with a GCV (Generalized Cross Validation) estimated threshold. Only subbands that count at least 1000 pixels will be thresholded. \item[\texttt{Backup}]\mbox{}\\ Create a backup of the current image for later comparison. \item[\texttt{Psnr}]\mbox{}\\ Calculate the PSNR (Peak Signal to Noise Ratio) of the current image, compared to the backup image. \item[\texttt{Threshold} \emph{value}]\mbox{}\\ Perform hard thresholding with threshold value \emph{value}. \item[\texttt{Scale} \emph{value}]\mbox{}\\ Scale the image with factor \emph{value}. \item[\texttt{Histogram} \emph{level subband channel}]\mbox{}\\ View the histogram of subband \emph{subband} at level \emph{level} of the decomposition of channel \emph{channel}. \item[\texttt{Entropy}]\mbox{}\\ Calculate the first order entropy (Shannon-Weaver) for this channel, in bits per pixel. \item[\texttt{Yuv}]\mbox{}\\ Convert from RGB to YUVr (or vice versa). \end{description} All commands can be abbreviated. \subsection*{Revision} \rev{Demo.C,v 4.6.2.2 1999/04/15 10:10:14} waili-gpl-19990723/man/Depend.tex100640 24520 25417 2336 6745120317 15021 0ustar geertnatw% % Include Dependencies % % $Id: Depend.tex,v 4.0.4.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \section{Include dependencies} \begin{description} \item[Fig.~\ref{fig:Includes}] Dependency graph for the various include files. \end{description} \begin{figure}[h]\begin{center} \resizebox{\textwidth}{!}{\includegraphics{Includes.eps}} \caption{Dependency graph for the various include files.} \label{fig:Includes} \end{center}\end{figure} waili-gpl-19990723/man/Design.tex100640 24520 25417 22541 6745120317 15053 0ustar geertnatw% % Design and Implementation of the wavelet transform library % % $Id: Design.tex,v 4.5.2.3.2.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \section{Design and Implementation of \libname} \libname\ is meant to operate on two-dimensional images of various kinds. Applications are situated in image processing. \subsection{Design decisions} This section discusses some of the design decisions we made for this library. For more information about the theoretical foundations behind the library, please refer to `Wavelet Transforms Using the Lifting Scheme' (Report ITA-Wavelets-WP1.1) \cite{ITA-Wavelets-WP1.1,UytVWuJanRooBul98}. We chose to implement two-dimensional wavelet transforms using the integer version of the Lifting Scheme. The wavelets we use are a subclass of the Cohen-Daubechies-Feauveau family of biorthogonal wavelets. \subsubsection{The Lifting Scheme} The Lifting Scheme \cite{swe:lift1,swe:lift2,swe:spie95} provides a fast and simple algorithm for arbitrary wavelet transforms \cite{ds:factor}. Furthermore the inverse transform is trivial to find. Although the Lifting Scheme allows to transform signals with a finite length without extending the signal, we did not choose to take this approach. Instead we use the classical symmetric extension \cite{bris:acha96} because it's easier to implement and suffices for the applications we have in mind. \subsubsection{The integer wavelet transform} In many applications (e.g.\ image compression and processing) the input data consists of integer samples only. In addition the storage and encoding of integer numbers is easier, compared to floating point numbers. To take advantage of this we use the integer version of the Lifting Scheme, which maps integers to integers and is reversible, retaining the perfect reconstruction property \cite{cdsy:integer}. All arithmetic operations are done in 16 bit. This should suffice for applications where the input data is 8 bit wide. Of course this can easily be changed if necessary. \subsubsection{Cohen-Daubechies-Feauveau biorthogonal wavelets} The key benefits of the Cohen-Daubechies-Feauveau biorthogonal wavelets \cite{coh-dau-fea:biorthogonal} are: \begin{itemize} \item They have finite support. This preserves the locality of image features. \item The scaling function $\phi(x)$ is always symmetric, and the wavelet function $\psi(x)$ is always symmetric or antisymmetric. This is important for image processing operations. \item Its filter coefficients are of the form $z\over2^n$, with $z \in \mathbf{Z}$ and $n \in \mathbf{N}$. This simplifies the implementation. But unfortunately this feature isn't always preserved by the decomposition in lifting steps. \end{itemize} We choose not to use wavelets with more than 6 vanishing moments to restrict the filter lengths. Longer filters have less locality and thus perform worse in image processing applications, in spite of their increase in smoothness. We implemented the following wavelet transforms of this family($(n, \tilde{n})$ means that the primal wavelet has $n$ vanishing moments, while the dual wavelet has $\tilde{n}$ vanishing moments): \begin{description} \item[\boldmath{(1, x)}:] $(1, 1)$, $(1, 3)$, $(1, 5)$ \item[\boldmath{(2, x)}:] $(2, 2)$, $(2, 4)$, $(2, 6)$ \item[\boldmath{(4, x)}:] $(4, 2)$, $(4, 4)$, $(4, 6)$ \end{description} We deliberately didn't implement any of the $(3, x)$ or $(5, x)$ wavelet transforms because their lifting steps require divisions by 3 or 5, which are not reversible in integer math. $(6, x)$ aren't implemented either because they require more than 16 bits (for 8 bit input data). \subsubsection{Wavelets and translation-invariance} A disadvantage of the wavelet transform is that it's not translation-invariant: if the image is translated before performing the wavelet transform, the result is not a translated version of the wavelet transform of the original image. The redundant wavelet transform is translation-invariant, but it needs much more memory and processing time, so this isn't an option in many applications. Since we wanted to allow crop and merge operations on wavelet transformed images we came up with the following scheme. If each transform level is considered independently, one step of a wavelet transform is translation-invariant if the translation is limited to an even number of pixels. Thus we associate with every matrix \emph{coordinates} (a horizontal and vertical offset for the upper left pixel) which depend on the transform level. At every transform level we have two versions of the wavelet transform: an \emph{even} and an \emph{odd} version. Which transform is used depends on the parity of the offset. If the parities of the coordinates match at each level, we can merge two images without retransforming one of them. If they don't match, we have to retransform one image. The main idea behind this scheme is that in many cases the coordinates of the subimage that will be pasted into another image are known in advance, so it can be transformed correctly. An example of this is the creation of one large image by concatenating several separately created subimages. \subsection{Implementation} The software library is written in \CC. We extensively use features of the ISO \CC\ Standard, which was finalized in November 1997 (from now on called \emph{\CC\ 97}), since they provide a great enrichment of the \CC\ language and allow for a cleaner design. Unfortunately there aren't many compilers that adhere to \CC\ 97 yet. The development was done using \emph{GNU \CC\ 2.7.2} and \emph{egcs 1.0}. Fortunately these compilers are available for about any platform, and they're free\footnote{Available from \texttt{ftp://prep.ai.mit.edu/pub/gnu/} and \texttt{http://egcs.cygnus.com/}.}! \subsubsection{\emph{Image} objects} An \emph{Image} consists of one or more independent channels, thus allowing for different sizes and wavelet transform types per channel. No interpretation or format is imposed on the channels and its data. The actual meaning of the image data can be freely choosen by the user. Examples are grayscale, RGB, YUV or Lab color, etc.\ \ldots \subsubsection{\emph{Channel} objects} The basic building block of the library is the \emph{Channel}. A channel is a rectangular matrix containing one-valued pixels. A channel can be non-transformed (a \emph{NTChannel}), or wavelet-transformed (a \emph{LChannel}\footnote{Rumors say that \emph{NT} and \emph{L} refer to two popular operating systems --- with the goal of this project to convert as many NTChannels to LChannels as possible --- but this hasn't been confirmed officially.}). Since a wavelet transform is some kind of \emph{recursive} transform, a LChannel contains some subchannels (subbands), which can be either non-transformed or wavelet-transformed. The number of subchannels in a LChannel depends on the type of wavelet transform. You can have the following combinations: \begin{description} \item[\emph{LChannelCR}] Obtained by transforming both the columns and rows of a NTChannel. As a result, you have 4 subbands: \begin{description} \item[LL] Low pass band in both the horizontal and the vertical direction, \item[LH] Low pass band in the vertical direction, high pass in the horizontal direction, \item[HL] High pass band in the vertical direction, low pass in the horizontal direction, \item[HH] High pass band in both the horizontal and the vertical direction. \end{description} \item[\emph{LChannelC}] Obtained by transforming only the columns of a NTChannel. As a result, you have 2 subbands: \begin{description} \item[L] Low pass band in the vertical direction, \item[H] High pass band in the vertical direction. \end{description} \item[\emph{LChannelR}] Obtained by transforming only the rows of a NTChannel. As a result, you have 2 subbands: \begin{description} \item[L] Low pass band in the horizontal direction, \item[H] High pass band in the horizontal direction. \end{description} \end{description} Fig.~\ref{fig:eg_transform} shows an example of a channel after two transform levels. \begin{figure}\begin{center} \resizebox{100mm}{!}{\includegraphics{Decomposition.eps}} \caption{Example of a channel after two transform levels. In the first step both the columns and the rows are transformed, in the second step only the columns are transformed.} \label{fig:eg_transform} \end{center}\end{figure} \subsubsection{\emph{Wavelet} objects} A \emph{Wavelet} represents the filters and lifting steps associated with a specific wavelet transform. Some wavelet transforms of the Cohen-Daubechies-Feauveau family are implemented. You can add your own favorite wavelet transform if you have a decomposition in integer lifting steps for it. waili-gpl-19990723/man/Features.tex100640 24520 25417 3040 6745120317 15371 0ustar geertnatw% % Features % % $Id: Features.tex,v 4.3.4.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \section{Features of \libname} \libname\ is a wavelet transform library: \begin{itemize} \item Uses integer wavelet transforms based on the lifting Scheme \item Provides various wavelet transforms of the Cohen-Daubechies-Feauveau family of biorthogonal wavelets \item Provides crop and merge operations on wavelet-transformed images \item Provides noise reduction based on wavelet thresholding using Generalized Cross Validation \item Provides scaling of images \item Provides edge enhancement of images \item Provides also some simple image operations (addition and subtraction of images) \item Allows different image representations (RGB, YUV, Lab, \ldots ) \end{itemize} waili-gpl-19990723/man/Image.tex100640 24520 25417 23662 6745120317 14671 0ustar geertnatw% % Image Class % % $Id: Image.tex,v 4.7.2.3.2.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Image}{$ $Revision: 4.7.2.3.2.1 $ $} \subtitle{Name} Image --- Generic image class % ----------------------------------------------------------------------------- \subtitle{Description} This class provides a low-level image abstraction. An image consists of a number of channels containing pixels (of type \texttt{PixType}). Each channel can have a different size. No interpretation or format is imposed on the channels and it's data. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Image.h} \function{Image()} Create an empty image. \function{Image(u\_int channels)} Create an empty image containing\name{channels} channels. \function{Image(u\_int cols, u\_int rows, u\_int channels = 1)} Create an image with given dimensions. \name{cols} and \name{rows} are the number of columns respectively rows, \name{channels} is the number of channels. All channels will have the same size. \function{Image(const~u\_int cols[], const~u\_int rows[], u\_int channels)} Create an image with given dimensions. \name{cols} and \name{rows} are arrays containing the number of columns respectively rows for every channel, \name{channels} is the number of channels. \function{Image(const~Channel\& channel, u\_int channels = 1)} Create an image containing\name{channels} channels. Every channel will be a copy of \name{channel}. \function{Image(const~Channel$\ast$ channel[], u\_int channels)} Create an image containing\name{channels} channels. The channels will be initialized using the array of channels \name{channel}. \function{Image(const~Image\& im)} Create a new image by copying image \name{im}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{ImageType Import(const~char$\ast$ filename, ImageFormat format = IF\_AUTO)} Import an image from a file named \name{filename}, stored in a specific format \name{format}. If \name{format} is IF\_AUTO, the routine will try to guess the file format by examining the file name. The type of the image is returned. Images are assumed to contain 8-bit data, which is converted to the range $-128 \ldots 127$ for internal use. \function{void Export(const~char$\ast$ filename, ImageFormat format = IF\_AUTO)\ const} Export the to a file named \name{filename} using the specific file format \name{format}. If \name{format} is IF\_AUTO, the routine will try to guess the file format by examining the file name. The pixel values are considered to lay within the range $-128 \ldots 127$. If a pixel value doesn't fit, it will be clipped. Note: export in \name{IF\_TIFF} is not yet supported. \function{void Convert(ImageType from, ImageType to)} Convert the image from type \name{from} to type \name{to}. \emph{Not all conversions are implemented yet.} \function{u\_int GetChannels(void)\ const} \function{u\_int GetCols(void)\ const} \function{u\_int GetRows(void)\ const} Get the number of channels, columns or rows of the image. \function{int GetOffsetX(void)\ const} \function{int GetOffsetY(void)\ const} Get the offset of the first channel of the image in the universal coordinate system. \function{Channel$\ast$\& operator[](u\_int channel)} \function{const$\ast$~Channel\& operator[](u\_int channel)\ const} Access channel \name{channel}. \function{PixType\& \mbox{operator()}(u\_int c, u\_int r, u\_int ch = 0)} \function{const~PixType \mbox{operator()}(u\_int c, u\_int r, u\_int ch = 0)\ const} Access the `pixel' at column \name{c} and row \name{r} in channel \name{ch}. This may refer to a wavelet coefficient instead of a real pixel value if the channel is wavelet transformed. \function{void Clear(void)} Clear all pixel values to zero. \function{void Resize(u\_int cols, u\_int rows)} Change the number of columns and rows of the image to \name{cols} respectively \name{rows}. The number of channels is unchanged. \function{void Resize(u\_int cols, u\_int rows, u\_int channels)} Change the number of columns, rows and channels of the image to \name{cols}, \name{rows} and \name{channels}. All channels will have the same size. \function{Image\& operator$=$(const~Image\& im)} Make a copy of image \name{im}. \function{Image$\ast$ Clone(void)\ const} Make a copy of the current image. \function{void SetOffsetX(int offx)\ const} \function{void SetOffsetY(int offy)\ const} Set the offset of the first channel of the image in the universal coordinate system. \function{Image$\ast$ Crop(u\_int x1, u\_int y1, u\_int x2, u\_int y2)\ const} Cut the image so the upper left corner is positioned at (\name{x1}, \name{y1}), and the lower right corner at (\name{x2}, \name{y2}). \function{void Merge(const~Image\& im)} Paste image \name{im} into the current image. The paste position is determined by the offsets of \name{im}. \function{void Add(const~Image\& im)} \function{void Subtract(const~Image\& im)} Add respectively subtract image \name{im} to (from) the current image. Both images must have the same number of columns, rows and channels and their corresponding channels must have the same structure. \function{Image$\ast$ Diff(const~Image\& im)\ const} This function returns the difference image between the current image and \name{im}. Both images must have the same number of columns, rows and channels and their corresponding channels must have the same structure. \function{void InsertChannel(Channel\& data, u\_int ch)} Replace channel number \name{ch} of the image by the contents of channel \name{channel}. \function{void DeleteChannel(u\_int channel)} Delete channel number \name{ch} from the image. \function{void Fwt(const~TransformDescriptor transform[], u\_int depth)} Transform the image using the Fast Wavelet Transform. The two-dimensional wavelet transform will be applied to all channels independently. The type of wavelet transform is determined by the \name{transform} array and its length \name{depth}. \function{void IFwt(void)} Transform the image using the inverse Fast Wavelet Transform. The two-dimensional inverse wavelet transform will be applied to all channels independently. This is the inverse operation of \name{Fwt}. \function{void Scale(f32 scale)} Scale the image with scaling factor \name{scale}. % ----------------------------------------------------------------------------- \subtitle{Image Types \\ and Formats} The following image types are defined: \begin{center}\begin{tabular}{|l|l|} \hline \texttt{IT\_Unknown} & Unknown \\ \texttt{IT\_Mono} & Monochrome (black/white) \\ \texttt{IT\_CIEY} & Greyscale \\ \texttt{IT\_CIEL} & CIE luminance \\ \texttt{IT\_RGB} & RGB color \\ \texttt{IT\_CIEXYZ} & CIE XYZ color \\ \texttt{IT\_CIELab} & CIE L$^*$a$^*$b$^*$ color \\ \texttt{IT\_YUV} & YUV \\ \texttt{IT\_YUVr} & Reversible YUV \\ \hline \end{tabular}\end{center} The following image formats are defined: \begin{center}\begin{tabular}{|l|l|} \hline \texttt{IF\_AUTO} & Automatic \\ \texttt{IF\_PNMASCII} & Portable AnyMap ASCII \\ \texttt{IF\_PNMRAW} & Portable AnyMap Binary \\ \texttt{IF\_TIFF} & Tag(ged) Image File Format \\ \hline \end{tabular}\end{center} % ----------------------------------------------------------------------------- \subtitle{See Also} The \name{Channel}, \name{Wavelet}, \name{Color} and \name{ColorSpace} classes. % ----------------------------------------------------------------------------- \subtitle{Example} \begin{verbatim} // // Simple image compression example // #ifndef NULL #define NULL 0 #endif #include int main(void) { const char infile[] = "image.pgm"; const char outfile[] = "result.pgm"; double threshold = 20.0; Image image; // Read the image image.Import(infile); // Transform the image using the Cohen-Daubechies-Feauveau // (2, 2) biorthogonal wavelets Wavelet *wavelet = Wavelet::CreateCDF(2, 2); TransformDescriptor transform[] = { { TT_ColsRows, wavelet }, { TT_ColsRows, wavelet }, { TT_ColsRows, wavelet }, { TT_ColsRows, wavelet }, { TT_ColsRows, wavelet }, { TT_ColsRows, wavelet }, { TT_ColsRows, wavelet }, { TT_ColsRows, wavelet } }; image.Fwt(transform, sizeof(transform)/sizeof(*transform)); // Zero all entries smaller than the threshold for (u_int ch = 0; ch < image.GetChannels(); ch++) image[ch]->Threshold(threshold); // Inverse wavelet transform image.IFwt(); // Write the reconstructed image to a file image.Export(outfile); return(0); } \end{verbatim} % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Image.C,v 4.4.2.4 1999/07/20 13:19:02 geert Exp} \rev{Image.h,v 4.6.2.3 1999/07/20 13:18:57 geert Exp} \rev{Example.C,v 4.0.2.1 1998/06/22 13:49:10 geert Exp} \end{manpage} waili-gpl-19990723/man/Includes.fig100640 24520 25417 23336 6745120317 15360 0ustar geertnatw#FIG 3.1 # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Portrait Center Inches 1200 2 6 9300 6150 10500 6600 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 9375 6150 10425 6150 10425 6600 9375 6600 9375 6150 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 9300 6150 10500 6150 10500 6600 9300 6600 9300 6150 4 0 -1 0 0 0 12 0.0000 4 135 840 9480 6442 LChannelR\001 -6 6 7500 6150 8700 6600 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 7575 6150 8625 6150 8625 6600 7575 6600 7575 6150 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 7500 6150 8700 6150 8700 6600 7500 6600 7500 6150 4 0 -1 0 0 0 12 0.0000 4 135 840 7680 6442 LChannelC\001 -6 6 7500 4950 8700 5400 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 7575 4950 8625 4950 8625 5400 7575 5400 7575 4950 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 7500 4950 8700 4950 8700 5400 7500 5400 7500 4950 4 0 -1 0 0 0 12 0.0000 4 135 720 7740 5242 LChannel\001 -6 6 5700 6150 6900 6600 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 5775 6150 6825 6150 6825 6600 5775 6600 5775 6150 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 5700 6150 6900 6150 6900 6600 5700 6600 5700 6150 4 0 -1 0 0 0 12 0.0000 4 135 960 5820 6442 LChannelCR\001 -6 6 7500 7350 8700 7800 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 7500 7350 8700 7350 8700 7800 7500 7800 7500 7350 4 0 -1 0 0 0 12 0.0000 4 135 270 7965 7642 Blit\001 -6 6 3900 4950 5100 5400 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 3975 4950 5025 4950 5025 5400 3975 5400 3975 4950 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 3900 4950 5100 4950 5100 5400 3900 5400 3900 4950 4 0 -1 0 0 0 12 0.0000 4 135 855 4072 5242 NTChannel\001 -6 6 3900 6150 5100 6600 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 3900 6150 5100 6150 5100 6600 3900 6600 3900 6150 4 0 -1 0 0 0 12 0.0000 4 180 945 4027 6420 Lifting inline\001 -6 6 3900 7350 5100 7800 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 3975 7350 5025 7350 5025 7800 3975 7800 3975 7350 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 3900 7350 5100 7350 5100 7800 3900 7800 3900 7350 4 0 -1 0 0 0 12 0.0000 4 135 435 4282 7642 Timer\001 -6 6 5700 7350 6900 7800 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 5775 7350 6825 7350 6825 7800 5775 7800 5775 7350 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 5700 7350 6900 7350 6900 7800 5700 7800 5700 7350 4 0 -1 0 0 0 12 0.0000 4 180 585 6007 7620 Storage\001 -6 6 9300 7350 10500 7800 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 9375 7350 10425 7350 10425 7800 9375 7800 9375 7350 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 9300 7350 10500 7350 10500 7800 9300 7800 9300 7350 4 0 -1 0 0 0 12 0.0000 4 135 405 9697 7642 Color\001 -6 6 2100 7350 3300 7800 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2175 7350 3225 7350 3225 7800 2175 7800 2175 7350 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2100 7350 3300 7350 3300 7800 2100 7800 2100 7350 4 0 -1 0 0 0 12 0.0000 4 180 495 2452 7620 Lifting\001 -6 6 2100 4950 3300 5400 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2100 4950 3300 4950 3300 5400 2100 5400 2100 4950 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2175 4950 3225 4950 3225 5400 2175 5400 2175 4950 4 0 -1 0 0 0 12 0.0000 4 135 645 2377 5242 Wavelet\001 -6 6 4800 3750 6000 4200 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 4875 3750 5925 3750 5925 4200 4875 4200 4875 3750 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 4800 3750 6000 3750 6000 4200 4800 4200 4800 3750 4 0 -1 0 0 0 12 0.0000 4 135 615 5092 4042 Channel\001 -6 6 300 7350 1500 7800 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 300 7350 1500 7350 1500 7800 300 7800 300 7350 4 0 -1 0 0 0 12 0.0000 4 135 285 757 7642 Util\001 -6 6 4800 8550 6000 9000 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 4800 8550 6000 8550 6000 9000 4800 9000 4800 8550 4 0 -1 0 0 0 12 0.0000 4 180 465 5167 8820 Types\001 -6 6 4800 9750 6000 10200 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 4800 9750 6000 9750 6000 10200 4800 10200 4800 9750 4 0 -1 0 0 0 12 0.0000 4 180 675 5062 10020 Compiler\001 -6 6 2550 2550 3750 3000 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2625 2550 3675 2550 3675 3000 2625 3000 2625 2550 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2550 2550 3750 2550 3750 3000 2550 3000 2550 2550 4 0 -1 0 0 0 12 0.0000 4 180 465 2917 2820 Image\001 -6 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 2700 5400 2700 7350 2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 4500 5400 4500 6150 2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8100 5400 8100 6150 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 0 0 1.00 60.00 120.00 8100 6600 8100 7350 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 5400 9000 5400 9750 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 6 0 0 1.00 60.00 120.00 8250 5400 8325 5550 8850 6000 8850 6675 8325 7050 8250 7350 2100.00 0.00 8287.77 5488.84 8306.52 5526.34 8426.57 5680.09 8769.64 5825.28 8928.45 6170.56 8939.19 6501.68 8764.75 6840.66 8420.01 6910.44 8290.84 7100.17 8272.09 7175.17 2100.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 0 0 1.00 60.00 120.00 6300 6600 6375 6675 7875 7050 7950 7350 2100.00 0.00 6339.10 6646.54 6357.85 6665.29 6708.37 6863.75 7540.24 6715.25 7925.21 7100.21 7943.96 7175.21 2100.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 0 0 1.00 60.00 120.00 9900 6600 9825 6675 8475 7125 8400 7350 2100.00 0.00 9860.16 6646.11 9841.41 6664.86 9531.43 6856.44 8762.65 6837.34 8439.04 7160.96 8420.29 7217.21 2100.00 0.00 3 2 1 1 -1 7 0 0 -1 4.000 0 1 0 4 0 0 1.00 60.00 120.00 8400 5400 8475 5475 9825 6000 9900 6150 2100.00 0.00 8440.29 5445.84 8459.04 5464.59 8765.63 5664.64 9541.65 5741.79 9849.60 6022.42 9868.35 6059.92 2100.00 0.00 3 2 1 1 -1 7 0 0 -1 4.000 0 1 0 4 0 0 1.00 60.00 120.00 5625 4200 5700 4275 8025 4800 8100 4950 0.00 0.00 5663.87 4246.67 5682.62 4265.42 6220.79 4562.04 7498.17 4387.23 8052.80 4821.78 8071.55 4859.28 0.00 0.00 3 2 1 1 -1 7 0 0 -1 4.000 0 1 0 4 0 0 1.00 60.00 120.00 5325 4200 5250 4350 4575 4800 4500 4950 0.00 0.00 5289.25 4289.28 5270.50 4326.78 5117.80 4499.75 4707.20 4650.24 4554.50 4823.22 4535.75 4860.72 0.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 7 0 0 1.00 60.00 120.00 4650 5400 4725 5550 5175 5850 5475 6900 6600 7050 7575 7200 7650 7350 0.00 0.00 4685.75 5489.28 4704.50 5526.78 4813.13 5649.84 5091.59 5735.73 5343.42 6080.72 5212.43 6673.16 5747.90 7135.76 6344.04 7013.25 6822.47 7081.94 7344.41 7031.91 7604.40 7221.43 7623.15 7258.93 0.00 0.00 3 2 1 1 -1 7 0 0 -1 4.000 0 1 0 4 0 0 1.00 60.00 120.00 7950 5400 7875 5475 6375 6000 6300 6150 2100.00 0.00 7910.02 5446.02 7891.27 5464.77 7549.91 5679.29 6694.80 5718.42 6349.69 6022.29 6330.94 6059.79 2100.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 0 0 1.00 60.00 120.00 5175 4200 5100 4275 2775 4800 2700 4950 0.00 0.00 5136.13 4246.67 5117.38 4265.42 4579.22 4562.04 3301.82 4387.21 2747.20 4821.78 2728.45 4859.28 0.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 7 0 0 1.00 60.00 120.00 5475 4200 5475 4275 5475 6000 5625 6750 6600 6900 7725 7125 7800 7350 0.00 0.00 5475.00 4243.44 5475.00 4262.19 5475.00 4667.97 5435.82 5604.35 5492.37 6175.43 5444.17 6577.09 5858.23 6973.02 6378.57 6860.85 6857.52 6945.53 7465.16 6895.62 7765.29 7160.56 7784.04 7216.81 0.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 0 0 1.00 60.00 120.00 4500 7800 4575 7875 5250 8250 5325 8550 -1500.00 0.00 4541.44 7845.08 4560.19 7863.83 4718.71 7983.40 5121.58 8082.58 5288.57 8300.28 5307.32 8375.28 -1500.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 0 0 1.00 60.00 120.00 6300 7800 6225 7875 5550 8250 5475 8550 -1500.00 0.00 6258.55 7845.08 6239.80 7863.83 6081.29 7983.40 5678.42 8082.58 5511.43 8300.29 5492.68 8375.29 -1500.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 5 0 0 1.00 60.00 120.00 2709 7780 2775 7875 3900 8100 5100 8325 5175 8550 -1500.00 0.00 2739.08 7838.51 2755.58 7862.26 3031.80 8043.43 3643.40 8050.29 4173.07 8152.90 4820.47 8081.23 5140.72 8360.52 5159.47 8416.77 -1500.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 5 0 0 1.00 60.00 120.00 8100 7800 8025 7875 6900 8100 5700 8325 5625 8550 -1500.00 0.00 8061.38 7846.81 8042.63 7865.56 7770.69 8011.10 7156.60 8050.28 6626.93 8152.91 5979.52 8081.22 5659.28 8360.52 5640.53 8416.77 -1500.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 6 0 0 1.00 60.00 120.00 9900 7800 9825 7875 8700 8100 6900 8250 5850 8400 5775 8550 -1500.00 0.00 9861.38 7846.81 9842.63 7865.56 9570.69 8011.10 8959.81 8063.31 8290.96 8157.76 7309.30 8203.74 6659.65 8277.16 6100.07 8219.75 5820.34 8421.38 5801.59 8458.88 -1500.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 6 0 0 1.00 60.00 120.00 900 7800 975 7875 2100 8100 3900 8250 4950 8400 5025 8550 -1500.00 0.00 938.62 7846.81 957.37 7865.56 1229.31 8011.10 1840.19 8063.32 2509.04 8157.75 3490.70 8203.76 4140.35 8277.16 4699.92 8219.76 4979.66 8421.37 4998.41 8458.87 -1500.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 0 0 1.00 60.00 120.00 3225 3000 3300 3075 5325 3600 5400 3750 0.00 0.00 3264.18 3046.49 3282.93 3065.24 3748.78 3331.67 4874.35 3235.28 5352.10 3621.93 5370.85 3659.43 0.00 0.00 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 5 0 0 1.00 60.00 120.00 3075 3000 3000 3075 1800 4500 975 7125 900 7350 0.00 0.00 3031.03 3042.87 3012.28 3061.62 2712.37 3388.34 2013.89 4110.51 1484.09 5075.28 1168.10 6528.58 962.52 7163.56 943.77 7219.81 0.00 0.00 waili-gpl-19990723/man/Install.tex100640 24520 25417 5710 6745120317 15227 0ustar geertnatw% % Installation % % $Id: Install.tex,v 4.1.2.2.2.1 1999/07/20 16:16:15 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \section{Installation} \subsection{Requirements} Before you start building the library, make sure you have the following items at hand: \begin{itemize} \item a decent UNIX system, \item \emph{GNU Make}, \item a \CC\ compiler that adheres to the \emph{ISO \CC\ Standard}, e.g.\ e.g.\ \emph{GNU \CC\ 2.7.2}, \end{itemize} \subsection{Building the package} \begin{itemize} \item Extract the archive. \item Change the current directory to \texttt{Lifting}. \item Enter \begin{quote} \texttt{make} \end{quote} to build the package. \item For the experts, the following make targets are available: \begin{itemize} \item Configure the package: \begin{quote} \texttt{make config} \end{quote} \item Create the dependencies among the various source files: \begin{quote} \texttt{make depend} \end{quote} \item Clean up all object files and executables: \begin{quote} \texttt{make clean} \end{quote} \item Clean up all object files, executables and configuration files: \begin{quote} \texttt{make distclean} \end{quote} \end{itemize} \end{itemize} \subsection{Additional notes} \begin{itemize} \item By default it is assumed that the \emph{TIFF} library is available on the Linux platform, and that it's not available on the other platforms. If you want to change this, you'll have to edit the \emph{TIFF$\ast$} definitions in the file \texttt{Rules.config} (created by \texttt{make config}). \item Currently the \texttt{Makefile} assumes you're using \emph{GNU Make} and \emph{GNU \CC\ 2.7.2}. \item The development was mainly done under \emph{Linux/ia32 2.0.x} and \emph{2.2.x}, with some testing under \emph{Solaris/SPARC 2.5.x} and \emph{2.6.x}, and \emph{Linux 2.0.x} through \emph{2.3.x} on non-Intel platforms (\emph{m68k, PPC, AXP}). Your mileage may vary on other systems. \item The linker might complain about undefined symbols on systems where the native linker doesn't support constructors and \name{collect2} is used. \item If you want support for \emph{TIFF}, then you need the \emph{TIFF} library. \end{itemize} waili-gpl-19990723/man/Lifting.tex100640 24520 25417 16707 6745120320 15237 0ustar geertnatw% % Lifting Operations % % $Id: Lifting.tex,v 4.6.2.2.2.1 1999/07/20 16:16:16 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Lifting}{$ $Revision: 4.6.2.2.2.1 $ $} \subtitle{Name} Lifting --- Generic class for integer \name{Lifting Scheme} steps % ----------------------------------------------------------------------------- \subtitle{Description} This class provides a generic lifting step interface, to be used for wavelet transforms using the \name{Lifting Scheme}. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Lifting.h} \name{Lifting} is an abstract base class. No instances can be declared. Lifting steps on different types of data are implemented through inheritance. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{void Lift\_L1R1\_FR(int primal, const~s16 b[2], const~u16 a)\ const} \function{void ILift\_L1R1\_FR(int primal, const~s16 b[2], const~u16 a)\ const} \function{void Lift\_L2R2\_FR(int primal, const~s16 b[4], const~u16 a)\ const} \function{void ILift\_L2R2\_FR(int primal, const~s16 b[4], const~u16 a)\ const} \function{void Lift\_L3R3\_FR(int primal, const~s16 b[6], const~u16 a)\ const} \function{void ILift\_L3R3\_FR(int primal, const~s16 b[6], const~u16 a)\ const} Primal (\name{primal} $= 1$) and dual (\name{primal} $= 0$) integer lifting steps with full rounding. \name{Lift\_LmRn\_FR} implements a lifting operation of the form \[ x_i \leftarrow x_i + \left\{ {\sum_{j=-m}^{n-1} b_{j+m} y_j \over a} \right\}, \] with $x_i$ and $y_i$ the low pass and high pass samples (or vice versa, depending on the value of \name{primal}), and $\left\{\right\}$ a rounding operation. \name{ILift\_LmRn\_FR} is the corresponding inverse operation. \function{void Lift\_L1R1\_NR(int primal, const~s16 b[2], const~u16 a)\ const} \function{void ILift\_L1R1\_NR(int primal, const~s16 b[2], const~u16 a)\ const} \function{void Lift\_L2R2\_NR(int primal, const~s16 b[4], const~u16 a)\ const} \function{void ILift\_L2R2\_NR(int primal, const~s16 b[4], const~u16 a)\ const} \function{void Lift\_L3R3\_NR(int primal, const~s16 b[6], const~u16 a)\ const} \function{void ILift\_L3R3\_NR(int primal, const~s16 b[6], const~u16 a)\ const} Primal (\name{primal} $= 1$) and dual (\name{primal} $= 0$) integer lifting steps without rounding. \name{Lift\_LmRn\_FR} implements a lifting operation of the form \[ x_i \leftarrow a x_i + \sum_{j=-m}^{n-1} b_{j+m} y_j, \] with $x_i$ and $y_i$ the low pass and high pass samples (or vice versa, depending on the value of \name{primal}). \name{ILift\_LmRn\_NR} is the corresponding inverse operation. \function{void Lift\_L1R1\_MX(int primal, const~s16 b[2], const~u16 a1, const~u16 a2)\ const} \function{void ILift\_L1R1\_MX(int primal, const~s16 b[2], const~u16 a1, const~u16 a2)\ const} \function{void Lift\_L2R2\_MX(int primal, const~s16 b[4], const~u16 a1, const~u16 a2)\ const} \function{void ILift\_L2R2\_MX(int primal, const~s16 b[4], const~u16 a1, const~u16 a2)\ const} \function{void Lift\_L3R3\_MX(int primal, const~s16 b[6], const~u16 a1, const~u16 a2)\ const} \function{void ILift\_L3R3\_MX(int primal, const~s16 b[6], const~u16 a1, const~u16 a2)\ const} Primal ($\name{primal} = 1$) and dual (\name{primal} $= 0$) integer lifting steps with mixed rounding. \name{Lift\_LmRn\_FR} implements a lifting operation of the form \[ x_i \leftarrow a_1 x_i + \left\{ {\sum_{j=-m}^{n-1} b_{j+m} y_j \over a_2} \right\}, \] with $x_i$ and $y_i$ the low pass and high pass samples (or vice versa, depending on the value of \name{primal}), and $\left\{\right\}$ a rounding operation. \name{ILift\_LmRn\_MX} is the corresponding inverse operation. % ----------------------------------------------------------------------------- \separator \subtitle{Derived \\ Classes} Lifting operations on various objects are available through classes derived from the \name{Lifting} class: % ----------------------------------------------------------------------------- \separator \subtitle{Name} LiftChannelR --- Lifting operations on the rows of 2 \name{NTChannel}s % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{LiftChannelR(NTChannel$\ast$ lowpass, NTChannel$\ast$ highpass)} Create a Lifting object for lifting operations on the rows of 2 \name{NTChannels}. \name{lowpass} contains the low pass samples, while \name{highpass} contains the high pass samples. Both \name{lowpass} and \name{highpass} must have the same number of rows, and the number of columns of \name{lowpass} and \name{highpass} must differ maximum 1. % ----------------------------------------------------------------------------- \separator \subtitle{Name} LiftChannelC --- Lifting operations on the columns of 2 \name{NTChannel}s % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{LiftChannelC(NTChannel$\ast$ lowpass, NTChannel$\ast$ highpass)} Create a Lifting object for lifting operations on the columns of 2 \name{NTChannel}s. \name{lowpass} contains the low pass samples, while \name{highpass} contains the high pass samples. Both \name{lowpass} and \name{highpass} must have the same number of columns, and the number of rows of \name{lowpass} and \name{highpass} must differ maximum 1. % ----------------------------------------------------------------------------- \subtitle{Plans} Add support for transforms of a rectangular subarea of a channel. emph{???} % ----------------------------------------------------------------------------- \subtitle{Dependency \\ Graphs} \begin{description} \item[Fig.~\ref{fig:Lifting}] Inheritance dependency graph for the lifting class hierarchy (\emph{Lifting}). \end{description} \begin{figure}[h]\begin{center} \resizebox{65mm}{!}{\includegraphics{Lifting_dep.eps}} \caption{Inheritance dependency graph for the lifting class hierarchy (\emph{Lifting}).} \label{fig:Lifting} \end{center}\end{figure} % ----------------------------------------------------------------------------- \subtitle{See Also} The \name{Wavelet} and \name{Channel} classes. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Lifting.C,v 4.5.2.1 1999/07/15 10:18:15 geert Exp} \rev{Lifting.h,v 4.3 1997/05/05 09:46:35 geert Exp} \rev{Lifting.inline.h,v 4.0.2.1 1999/07/20 13:18:58 geert Exp} \end{manpage} waili-gpl-19990723/man/Lifting_dep.fig100640 24520 25417 3021 6745120320 15775 0ustar geertnatw#FIG 3.1 # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Portrait Center Inches 1200 2 6 450 450 3450 2100 6 450 1650 1725 2100 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 450 1650 1725 1650 1725 2100 450 2100 450 1650 4 0 -1 0 0 0 12 0.0000 4 135 1005 600 1950 LiftChannelR\001 -6 6 2175 1650 3450 2100 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 2175 1650 3450 1650 3450 2100 2175 2100 2175 1650 4 0 -1 0 0 0 12 0.0000 4 135 1005 2325 1950 LiftChannelC\001 -6 6 1425 450 2475 900 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 1425 450 2475 450 2475 900 1425 900 1425 450 4 0 -1 0 0 0 12 0.0000 4 180 495 1725 750 Lifting\001 -6 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 1950 900 1125 1650 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 1950 900 2775 1650 -6 waili-gpl-19990723/man/Macros.tex100640 24520 25417 5545 6745120320 15045 0ustar geertnatw% % LaTeX Macros % % $Id: Macros.tex,v 4.2.4.1 1999/07/20 16:16:16 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \newcommand{\mynote}[1]{\subsubsection*{*** #1 ***}} \renewcommand{\phi}{\varphi} \newcommand{\dotp}[2]{\langle #1,#2 \rangle} \newcommand{\norm}[1]{\| #1 \|} \newcommand{\name}[1]{\emph{#1}} \newcommand{\CC}{{C\nolinebreak[4]\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}} \newcommand{\libname}{WAILI} \newcommand{\liblogo}{\includegraphics{WAILI.eps}} \newcommand{\libtitle}{\libname\ --- Wavelets with Integer Lifting} \newcommand{\needsinclude}[1]{\#include $\langle$waili/#1$\rangle$} \newcommand{\geertemail}{\texttt{Geert.Uytterhoeven@cs.kuleuven.ac.be}} \newcommand{\filipemail}{\texttt{Filip.VanWulpen@cs.kuleuven.ac.be}} \newcommand{\maartenemail}{\texttt{Maarten.Jansen@cs.kuleuven.ac.be}} \newcommand{\waveletsemail}{\texttt{wavelets@cs.kuleuven.ac.be}} \newcommand{\geertwww}{\texttt{http://www.cs.kuleuven.ac.be/\~{}geert/}} \newcommand{\filipwww}{\texttt{http://www.cs.kuleuven.ac.be/\~{}filip/}} \newcommand{\maartenwww}{\texttt{http://www.cs.kuleuven.ac.be/\~{}maarten/}} \newcommand{\waveletswww}{\texttt{http://www.cs.kuleuven.ac.be/\~{}wavelets/}} \newcommand{\libemail}{\waveletsemail} \newcommand{\libwww}{\waveletswww} \newcommand{\geertauthor}{Geert Uytterhoeven, Department of Computer Science, Katholieke Universiteit Leuven, Belgium (\geertemail)} \newcommand{\filipauthor}{Filip Van Wulpen, Department of Computer Science, Katholieke Universiteit Leuven, Belgium (\filipemail)} \newcommand{\rev}[1]{\texttt{#1}\\} \newenvironment{license}{% \small \begin{center}% {\bfseries \licensename\vspace{-.5em}}% \end{center}% \quotation }{} \newcommand\licensename{License Conditions} \newenvironment{acknowledgements}{% \small \begin{center}% {\bfseries \acknowledgementsname\vspace{-.5em}}% \end{center}% \quotation }{} \newcommand\acknowledgementsname{Acknowledgements} \newcommand\itaacknowledgement{This research is supported by the Flemish Information Technology Action Program (`Vlaams Actieprogramma Informatietechnologie'), project number ITA/950244.} waili-gpl-19990723/man/Makefile100640 24520 25417 3671 6745120320 14535 0ustar geertnatw# # Makefile for LaTeX2e documents # # $Id: Makefile,v 4.6.2.1.2.1 1999/07/20 16:16:16 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ifeq (Rules.LaTeX.config,$(wildcard Rules.LaTeX.config)) include Rules.LaTeX.config endif # ----------------------------------------------------------------------------- # Document and figure definitions and dependencies # ----------------------------------------------------------------------------- DOC = Manual MANPAGES = Blit.tex \ Channel.tex \ Color.tex \ ColorSpace.tex \ Compiler.tex \ Image.tex \ Lifting.tex \ Stream.tex \ Timer.tex \ Types.tex \ Util.tex \ Wavelet.tex TEXSRCS = Manual.tex \ Macros.tex \ Title.tex \ Features.tex \ Design.tex \ Overview.tex \ Man.tex $(MANPAGES) \ Depend.tex \ Install.tex \ Demo.tex \ Credits.tex TEXSTYLES = mymanpage.sty GENFIGS = WAILI.eps Channel_dep.eps Lifting_dep.eps Wavelet_dep.eps \ Includes.eps Decomposition.eps FIGS = $(GENFIGS) # ----------------------------------------------------------------------------- # Elementary build rules # ----------------------------------------------------------------------------- include Rules.LaTeX.build depend: waili-gpl-19990723/man/Man.tex100640 24520 25417 2141 6745120320 14321 0ustar geertnatw% % Manual Pages % % $Id: Man.tex,v 3.0.4.1 1999/07/20 16:16:16 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \input{Blit.tex} \input{Channel.tex} \input{Color.tex} \input{ColorSpace.tex} \input{Compiler.tex} \input{Image.tex} \input{Lifting.tex} \input{Stream.tex} \input{Timer.tex} \input{Types.tex} \input{Util.tex} \input{Wavelet.tex} waili-gpl-19990723/man/Manual.tex100640 24520 25417 2442 6746056236 15046 0ustar geertnatw% % Manual for the Wavelet Transform Library % % $Id: Manual.tex,v 4.3.4.2 1999/07/23 12:14:22 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \documentclass[a4paper,11pt]{article} \usepackage{graphics} \usepackage{mymanpage} \usepackage{times} \input{Macros} \begin{document} \input{Title} \newpage \input{Features} \input{Design} \newpage \input{Overview} \input{Man} \input{Depend} \newpage \input{Install} \appendix \input{Demo} \newpage \input{Credits} \newpage \bibliographystyle{plain} \bibliography{libman} \end{document} waili-gpl-19990723/man/Overview.tex100640 24520 25417 3524 6745120320 15422 0ustar geertnatw% % Overview % % $Id: Overview.tex,v 4.1.4.1 1999/07/20 16:16:16 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \section{Overview of \libname} The wavelet transform library consists of the following parts: \begin{description} \item[Blit] Low-level block operations \item[Channel] Generic channel class \item[Color] Various color representations \item[ColorSpace] Color spaces and color space conversions \item[Compiler] Compiler dependent definitions \item[Image] Generic image class \item[Lifting] Lifting steps for the Lifting Scheme \item[Stream] Input/output with support for compression \item[Timer] Measurement of execution times \item[Types] Platform independent type definitions \item[Util] Utility routines \item[Wavelet] Wavelet transforms using the Lifting Scheme \end{description} \textbf{Note: Currently only \name{Image}, \name{Channel} and some parts of \name{Wavelet} (\name{CreateCDF()}) are of general interest to application programmers. The other parts are only used internally or aren't completely finished yet (\name{Color}, \name{ColorSpace}).} \section{Manual pages} waili-gpl-19990723/man/Rules.LaTeX.build100640 24520 25417 4011 6745615616 16172 0ustar geertnatw# # Makefile for LaTeX2e documents (build) # # $Id: Rules.LaTeX.build,v 4.1.4.2 1999/07/22 13:24:30 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ----------------------------------------------------------------------------- # Makefile for LaTeX2e documents (build) # ----------------------------------------------------------------------------- fake: $(DOC).dvi $(EXTRA) $(DOC).dvi: $(LINKS) $(TEXSRCS) $(TEXSTYLES) $(FIGS) show: $(DOC).dvi $(XDVI) $(DOC).dvi & draft: $(DOC).ps $(MULTI) $(DOC).ps bib: $(DOC).bbl $(RM) $(DOC).dvi make $(DOC).dvi print: $(DOC).ps $(LPR) $(DOC).ps pdf: $(DOC).pdf clean: $(RM) *.aux *.dvi *.log *.toc *.bbl *.blg $(DOC).ps \ $(DOC).pdf $(GENFIGS) $(LINKS) $(EXTRACLEAN) # ----------------------------------------------------------------------------- # Elementary build rules # ----------------------------------------------------------------------------- %.dvi: %.tex $(LATEX) $< %.bbl: %.aux $(BIBTEX) $* %.ps: %.dvi $(DVIPS) $< -o %.pdf: %.ps $(PS2PDF) $< %.eps: %.fig $(FIG2PS) $< > $@ %.eps: %.pgm $(PNMTOPS) $< > $@ %.eps: %.pgm.gz $(ZCAT) $< | $(PNMTOPS) > $@ %.eps: %.gif $(GIFTOPNM) $< | $(PNMTOPS) > $@ %.eps: %.eps.gz $(ZCAT) $< > $@ %: $(LINKEDDIR)/% ln -sf $< waili-gpl-19990723/man/Rules.LaTeX.config100640 24520 25417 2551 6745615616 16347 0ustar geertnatw# # Makefile for LaTeX2e documents (configuration) # # $Id: Rules.LaTeX.config,v 4.0.2.1.2.2 1999/07/22 13:24:30 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ----------------------------------------------------------------------------- # Makefile for LaTeX2e documents (configuration) # ----------------------------------------------------------------------------- LATEX = ./rlatex BIBTEX = bibtex RM = rm -f FIG2PS = fig2dev -L ps DVIPS = dvips -D 600 XDVI = xdvi LPR = lpr -Pwit MULTI = multi -2 -Pgrijs ZCAT = zcat PNMTOPS = pnmtops -noturn GIFTOPNM = giftopnm PS2PDF = ps2pdf All: fake waili-gpl-19990723/man/Stream.tex100640 24520 25417 11660 6745120320 15067 0ustar geertnatw% % Stream Class % % $Id: Stream.tex,v 4.1.2.3.2.1 1999/07/20 16:16:16 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Stream}{$ $Revision: 4.1.2.3.2.1 $ $} \subtitle{Name} Stream --- Input/output with support for compression % ----------------------------------------------------------------------------- \subtitle{Description} Flexible file storage with support for simple data compression. If a filename ends with \texttt{.gz} it will be compressed/decompressed automatically using \name{gzip}. \function{Stream()} Create a file handler for a stream. \function{Stream(const~char$\ast$ name, const~char$\ast$ type = "r")} Create a file handler for a stream and open it. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Storage.h} % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{void Read(u8$\ast$ x, u\_int cnt = 1)} \function{void Read(u16$\ast$ x, u\_int cnt = 1)} \function{void Read(u32$\ast$ x, u\_int cnt = 1)} \function{void Read(u64$\ast$ x, u\_int cnt = 1)} \function{void Read(s8$\ast$ x, u\_int cnt = 1)} \function{void Read(s16$\ast$ x, u\_int cnt = 1)} \function{void Read(s32$\ast$ x, u\_int cnt = 1)} \function{void Read(s64$\ast$ x, u\_int cnt = 1)} \function{void Read(f32$\ast$ x, u\_int cnt = 1)} \function{void Read(f64$\ast$ x, u\_int cnt = 1)} Read \name{cnt} elements from the stream. \function{void Write(const~u8$\ast$ x, u\_int cnt = 1)} \function{void Write(const~u16$\ast$ x, u\_int cnt = 1)} \function{void Write(const~u32$\ast$ x, u\_int cnt = 1)} \function{void Write(const~u64$\ast$ x, u\_int cnt = 1)} \function{void Write(const~s8$\ast$ x, u\_int cnt = 1)} \function{void Write(const~s16$\ast$ x, u\_int cnt = 1)} \function{void Write(const~s32$\ast$ x, u\_int cnt = 1)} \function{void Write(const~s64$\ast$ x, u\_int cnt = 1)} \function{void Write(const~f32$\ast$ x, u\_int cnt = 1)} \function{void Write(const~f64$\ast$ x, u\_int cnt = 1)} Write \name{cnt} elements to the stream. \function{void Read(u8\& x)} \function{void Read(u16\& x)} \function{void Read(u32\& x)} \function{void Read(u64\& x)} \function{void Read(s8\& x)} \function{void Read(s16\& x)} \function{void Read(s32\& x)} \function{void Read(s64\& x)} \function{void Read(f32\& x)} \function{void Read(f64\& x)} Read the element \name{x} from the stream. \function{void Write(const~u8\& x)} \function{void Write(const~u16\& x)} \function{void Write(const~u32\& x)} \function{void Write(const~u64\& x)} \function{void Write(const~s8\& x)} \function{void Write(const~s16\& x)} \function{void Write(const~s32\& x)} \function{void Write(const~s64\& x)} \function{void Write(const~f32\& x)} \function{void Write(const~f64\& x)} Write the element \name{x} to the stream. \function{void Puts(const~char$\ast$ s)} Write the string \name{s} to the stream. \function{void Printf(const~char$\ast$ fmt, ...)} Format and write a string to the stream. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{virtual~void Open(const~char$\ast$ name, const~char$\ast$ mode = "r")} Open the stream using filename \name{name} and mode \name{mode}. \function{virtual~void Close(void)} Close the stream. \function{virtual~void RawRead(void$\ast$ data, int size)} \function{virtual~void RawWrite(const~void$\ast$ data, int size)} Read or write a raw block of memory from or to the stream. Note that no endianness conversion will be done! % ----------------------------------------------------------------------------- \subtitle{Endiannes} All I/O operations are done using network byte order, i.e.\ most significant byte first or big endian. % ----------------------------------------------------------------------------- \separator \subtitle{See Also} The \name{gzip} command. % ----------------------------------------------------------------------------- \separator \subtitle{Revision} \rev{Storage.C,v 4.0.2.2 1999/07/20 13:14:18 geert Exp} \rev{Storage.h,v 4.0.2.2 1999/07/20 13:14:16 geert Exp} \end{manpage} waili-gpl-19990723/man/Timer.tex100640 24520 25417 5646 6745120320 14703 0ustar geertnatw% % Timer Class % % $Id: Timer.tex,v 4.1.2.1.2.1 1999/07/20 16:16:16 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Timer}{$ $Revision: 4.1.2.1.2.1 $ $} \subtitle{Name} Timer --- Measurement of execution times % ----------------------------------------------------------------------------- \subtitle{Description} This is a simple class for the measurement of execution times. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Timer.h} \function{Timer()} Create a timer. \function{Timer(const~Timer\& t)} Create a timer by copying timer \name{t}. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{void Start(void)} Start the timer. \function{void Stop(void)} Stop the timer. \function{void Reset(void)} Reset the timer to zero. \function{f32 GetReal(void)\ const} Get the \name{Real} part of the run time. \function{f32 GetUser(void)\ const} Get the \name{User} part of the run time. \function{f32 GetSystem(void)\ const} Get the \name{System} part of the run time. \function{Timer GetStamp(void)\ const} Get a time stamp copy of the timer. \function{int IsRunning(void)\ const} Check whether the timer is running. \function{void Tic(void)} Reset and start the timer. \function{void Toc(void)} Dump the current \name{Real}, \name{User} and \name{System} run time to \name{stderr}. \function{Timer operator$+$(const~Timer\& t)} \function{Timer operator$-$(const~Timer\& t)} Add or subtract two timers and return a sum or difference timer. \function{void operator$+=$(const~Timer\& t)} \function{void operator$-=$(const~Timer\& t)} Add or subtract a timer to or from the current timer. % ----------------------------------------------------------------------------- \subtitle{See Also} The \name{times} function. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Timer.C,v 4.0 1997/05/05 09:42:23 geert Exp} \rev{Timer.h,v 4.0 1997/05/05 09:47:07 geert Exp} \end{manpage} waili-gpl-19990723/man/Title.tex100640 24520 25417 5024 6745120321 14673 0ustar geertnatw% % Title % % $Id: Title.tex,v 4.2.4.1 1999/07/20 16:16:17 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \title{\resizebox{30mm}{!}{\liblogo} \raisebox{16mm}{\textsf{\libtitle}}} \author{Geert Uytterhoeven\thanks{Department of Computer Science, Katholieke Universiteit Leuven, Celestijnenlaan 200A, B-3001 Heverlee, Belgium} \and Filip Van Wulpen\addtocounter{footnote}{-1}\footnotemark} \maketitle \begin{center} \libemail \\ \libwww \end{center} \vfill \begin{abstract} \begin{quotation} This manual describes \emph{\libname}, a wavelet transform library. For more information about the theoretical foundations behind the library, please refer to `Wavelet Transforms Using the Lifting Scheme' (Report ITA-Wavelets-WP1.1). \end{quotation} \end{abstract} \vfill \begin{acknowledgements} \begin{quotation} \sloppy \itaacknowledgement \end{quotation} \end{acknowledgements} \vfill \newpage \vspace*{80mm} \begin{license} \begin{quotation} \noindent Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium \noindent This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. \noindent This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. \noindent You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \end{quotation} \end{license} \newpage \tableofcontents waili-gpl-19990723/man/Types.tex100640 24520 25417 5126 6745120321 14721 0ustar geertnatw% % Data Types % % $Id: Types.tex,v 4.1.2.1.2.1 1999/07/20 16:16:17 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Types}{$ $Revision: 4.1.2.1.2.1 $ $} \subtitle{Name} Types --- Platform independent type definitions % ----------------------------------------------------------------------------- \subtitle{Description} This package provides some platform independent type definitions for very common types of specific sizes. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Types.h} % ----------------------------------------------------------------------------- \subtitle{Generic Types} Available types are: \begin{itemize} \item Unsigned integer \begin{tabular}{|l|l|} \hline \texttt{u8} & 8 bit unsigned integer \\ \texttt{u16} & 16 bit unsigned integer \\ \texttt{u32} & 32 bit unsigned integer \\ \texttt{u64} & 64 bit unsigned integer \\ \hline \end{tabular} \item Signed integer \begin{tabular}{|l|l|} \hline \texttt{s8} & 8 bit signed integer \\ \texttt{s16} & 16 bit signed integer \\ \texttt{s32} & 32 bit signed integer \\ \texttt{s64} & 64 bit signed integer \\ \hline \end{tabular} \item \name{IEEE} Floating point \begin{tabular}{|l|l|} \hline \texttt{f32} & 32 bit floating point \\ \texttt{f64} & 64 bit floating point \\ \hline \end{tabular} \end{itemize} \subtitle{Pixel type} All pixels are of type \texttt{PixType}: \begin{tabular}{|l|l|} \hline \texttt{PixType} & 16 bit signed integer \\ \hline \end{tabular} % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Types.h,v 4.0 1997/05/05 09:47:15 geert Exp} \end{manpage} waili-gpl-19990723/man/Util.tex100640 24520 25417 4474 6745120321 14537 0ustar geertnatw% % Utility Routines % % $Id: Util.tex,v 4.1.2.1.2.1 1999/07/20 16:16:17 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Util}{$ $Revision: 4.1.2.1.2.1 $ $} \subtitle{Name} Utility --- Utility routines % ----------------------------------------------------------------------------- \subtitle{Description} This file contains some miscellaneous utility routines and definitions. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Util.h} % ----------------------------------------------------------------------------- \subtitle{Operations} \function{void Die(const~char$\ast$ fmt, \ldots)} Exit the program with a formatted error message. \variable{NotYetImplemented} Exit the program with a verbose `Not yet implemented' message. \function{Type Min(Type x, Type y)} Calculate the minimum of two objects. \function{Type Max(Type x, Type y)} Calculate the maximum of two objects. \function{int Odd(int x)} Check whether a number is odd. \function{int Even(int x)} Check whether a number is even. \function{Type Abs(Type x)} Calculate the absolute value of a number. % ----------------------------------------------------------------------------- \subtitle{Definitions} \variable{EPS} $\varepsilon$-value. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Util.C,v 4.0.2.2 1999/07/20 12:34:51 geert Exp} \rev{Util.h,v 4.0 1997/05/05 09:47:22 geert Exp} \end{manpage} waili-gpl-19990723/man/WAILI.fig100640 24520 25417 3752 6745120321 14432 0ustar geertnatw#FIG 3.2 # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Landscape Center Inches A4 100.00 Single 0 1200 2 0 32 #aeaeae 6 2700 1500 3300 2100 2 2 0 1 7 0 5 0 -1 0.000 0 0 -1 0 0 5 2700 1500 3300 1500 3300 2100 2700 2100 2700 1500 4 0 0 0 0 16 24 0.0000 4 285 120 2940 1942 I\001 -6 6 3300 2100 3900 2700 2 2 0 1 7 0 5 0 -1 0.000 0 0 -1 0 0 5 3300 2100 3900 2100 3900 2700 3300 2700 3300 2100 4 0 0 0 0 16 24 0.0000 4 285 210 3495 2542 L\001 -6 6 3900 2700 4500 3300 2 2 0 1 7 0 5 0 -1 0.000 0 0 -1 0 0 5 3900 2700 4500 2700 4500 3300 3900 3300 3900 2700 4 0 0 0 0 16 24 0.0000 4 285 120 4140 3142 I\001 -6 2 1 0 5 32 7 0 0 -1 0.000 1 0 7 0 0 2 2700 2700 5100 2700 2 1 0 5 32 7 0 0 -1 0.000 1 0 7 0 0 2 3900 2100 2700 2100 2 1 0 5 32 7 0 0 -1 0.000 1 0 7 0 0 2 3300 1500 3300 2700 2 1 0 5 32 7 0 0 -1 0.000 1 0 7 0 0 2 3900 3900 3900 1500 2 2 0 5 32 7 0 0 -1 0.000 1 0 7 0 0 5 2700 1500 7500 1500 7500 6300 2700 6300 2700 1500 2 1 0 5 32 7 0 0 -1 0.000 1 0 7 0 0 2 5100 1500 5100 6300 2 1 0 5 32 7 0 0 -1 0.000 1 0 7 0 0 2 2700 3900 7500 3900 2 1 0 5 0 7 0 0 -1 0.000 1 0 -1 0 0 7 2700 3900 3000 3900 3900 5100 5100 1500 6300 5100 7200 3900 7500 3900 2 1 0 1 18 18 0 0 20 0.000 0 0 -1 0 0 4 5100 2025 4500 3900 5700 3900 5100 2025 waili-gpl-19990723/man/Wavelet.tex100640 24520 25417 16516 6745120321 15251 0ustar geertnatw% % Wavelet Classes % % $Id: Wavelet.tex,v 4.6.2.4.2.1 1999/07/20 16:16:17 geert Exp $ % % Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA % \begin{manpage}{\libtitle}{Wavelet}{$ $Revision: 4.6.2.4.2.1 $ $} \subtitle{Name} Wavelet --- Integer wavelet transforms using the \name{Lifting Scheme} % ----------------------------------------------------------------------------- \subtitle{Description} The basic operational step of a wavelet transform is a filter bank with 2 kinds of filters: a low pass and a high pass filter. These 2 filters depend on the type of wavelet. In a wavelet transform the filter operations are performed iteratively on the low pass part of a signal. The two-dimensional wavelet transform uses the same algorithm, applied to both the rows and the columns of a matrix. One can consider the wavelet transform as a `black box' operation: a matrix is transformed into another matrix, its wavelet representation. Here the filter operations are performed in integer math using techniques based on the \name{Lifting Scheme}. The sequence of Lifting steps is called a `Cake Walk' and strongly depends on the wavelet type. % ----------------------------------------------------------------------------- \subtitle{Declaration} \needsinclude{Wavelet.h} \name{Wavelet} is an abstract base class. No instances can be declared. Different wavelet filters are implemented through inheritance. % ----------------------------------------------------------------------------- \subtitle{Public \\ Operations} \function{int GetGStart()\ const} \function{int GetGEnd()\ const} \function{int GetHStart()\ const} \function{int GetHEnd()\ const} Get the start respectively end position of the high pass (`G') respectively low pass(`H') filter. \function{int GetShiftL(void)\ const} \function{int GetShiftH(void)\ const} Get the number of steps (in base-$\sqrt{2}$!) the coefficients of the low pass respectively high pass subband have to be shifted to the left to obtain their real values. \function{u8 GetID(void)\ const} Get the unique private ID for this type of wavelet. % ----------------------------------------------------------------------------- \subtitle{Virtual \\ Operations} \function{Wavelet$\ast$ Clone(void)\ const} Make a copy of the current wavelet filter. \function{void CakeWalk(Lifting\& lifting)\ const} Perform a `Cake Walk' operation on the lifting object \name{lifting}. \function{void ICakeWalk(Lifting\& lifting)\ const} Perform an inverse `Cake Walk' operation on the lifting object \name{lifting}. % ----------------------------------------------------------------------------- \subtitle{Static \\ Operations} \function{Wavelet$\ast$ CreateCDF(u\_int np, u\_int nd)} Create a \name{Wavelet} object for some wavelet filters of the biorthogonal Cohen-Daubechies-Feauveau family. \name{np} and \name{nd} are the numbers of vanishing moments for the primal respectively dual wavelet function. The following wavelet bases are available. Table entries are in the form (\name{np}, \name{nd}): \begin{center}\begin{tabular}{llllll} $(1, 1)$ & $(1, 3)$ & $(1, 5)$ & $(2, 2)$ & $(2, 4)$ & $(2, 6)$ \\ $(4, 2)$ & $(4, 4)$ & $(4, 6)$ \\ \end{tabular}\end{center} Note that $(1, 1)$ is the Haar basis, and $(1, 3)$ is the wavelet basis used by Ricoh's CREW. $(0, 0)$ is used for the lazy wavelet filter. \function{Wavelet$\ast$ CreateFromID(u8 id)} Create a \name{Wavelet} object that corresponds to the unique private ID \name{id}. % ----------------------------------------------------------------------------- \separator \subtitle{Name} Wavelet\_Lazy --- \name{Lazy} integer wavelet transform using the \name{Lifting Scheme} % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{Wavelet\_Lazy()} Create a \name{Wavelet} object for the lazy integer wavelet transform. % ----------------------------------------------------------------------------- \separator \subtitle{Name} Wavelet\_CDF\_x\_y --- \name{Cohen-Daubechies-Feauveau} (x, y) integer wavelet transforms using the \name{Lifting Scheme} % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{Wavelet\_CDF\_1\_1()} \function{Wavelet\_CDF\_1\_3()} \function{Wavelet\_CDF\_1\_5()} \function{Wavelet\_CDF\_2\_2()} \function{Wavelet\_CDF\_2\_4()} \function{Wavelet\_CDF\_2\_6()} \function{Wavelet\_CDF\_4\_2()} \function{Wavelet\_CDF\_4\_4()} \function{Wavelet\_CDF\_4\_6()} Create a \name{Wavelet} object for the Cohen-Daubechies-Feauveau (x, y) integer wavelet transform. % ----------------------------------------------------------------------------- \subtitle{Note} Internally there also exist the classes \name{LiftCoefI\_CDF\_?\_?}. % ----------------------------------------------------------------------------- \separator \subtitle{Name} Wavelet\_CRF\_13\_7, Wavelet\_SWE\_13\_7 --- Integer wavelet transforms using the \name{Lifting Scheme} for some more wavelets used by JPEG2000. % ----------------------------------------------------------------------------- \subtitle{Declaration} \function{Wavelet\_CRF\_13\_7()} \function{Wavelet\_SWE\_13\_7()} Create a \name{Wavelet} object for the CRF (13, 7) and SWE (13, 7) integer wavelet transforms. % ----------------------------------------------------------------------------- \separator \subtitle{Dependency \\ Graphs} \begin{description} \item[Fig.~\ref{fig:Wavelet}] Inheritance dependency graph for the Wavelet class hierarchy (\emph{Wavelet}). \end{description} \begin{figure}[ht]\begin{center} \resizebox{\textwidth}{!}{\includegraphics{Wavelet_dep.eps}} \caption{Inheritance dependency graph for the Wavelet class hierarchy (\emph{Wavelet}).} \label{fig:Wavelet} \end{center}\end{figure} % ----------------------------------------------------------------------------- \subtitle{See Also} The \name{Lifting} and \name{Channel} classes. % ----------------------------------------------------------------------------- \subtitle{Revision} \rev{Wavelet.C,v 4.1.2.3 1999/04/15 12:26:44 geert Exp} \rev{Wavelet.h,v 4.1.2.4 1999/04/15 12:26:48 geert Exp} \rev{Wavelet\_CDF\_1\_x.C,v 4.1 1997/05/05 09:42:33 geert Exp} \rev{Wavelet\_CDF\_2\_x.C,v 4.2.2.1 1999/03/16 15:05:38 geert Exp} \rev{Wavelet\_CDF\_4\_x.C,v 4.2.2.1 1999/03/16 15:05:39 geert Exp} \rev{Wavelet\_JPEG2000.C,v 5.1.2.1 1999/04/15 10:06:05 geert Exp} \end{manpage} waili-gpl-19990723/man/Wavelet_dep.fig100640 24520 25417 21431 6745120321 16036 0ustar geertnatw#FIG 3.2 # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Portrait Center Metric A4 100.00 Single -2 1200 2 6 3150 2655 4905 3105 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3170 2666 4885 2666 4885 3094 3170 3094 3170 2666 4 0 -1 0 0 0 12 0.0000 4 180 1110 3472 2925 Wavelet_Lazy\001 -6 6 3105 4230 4905 4680 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3147 4240 4862 4240 4862 4669 3147 4669 3147 4240 4 0 -1 0 0 0 12 0.0000 4 180 1455 3277 4500 Wavelet_CDF_1_x\001 -6 6 3105 6300 4905 6750 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3147 6311 4862 6311 4862 6739 3147 6739 3147 6311 4 0 -1 0 0 0 12 0.0000 4 180 1455 3277 6570 Wavelet_CDF_2_x\001 -6 6 3105 8415 4905 8865 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3147 8426 4862 8426 4862 8854 3147 8854 3147 8426 4 0 -1 0 0 0 12 0.0000 4 180 1455 3277 8685 Wavelet_CDF_4_x\001 -6 6 3150 9855 4905 10305 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3170 9866 4885 9866 4885 10294 3170 10294 3170 9866 4 0 -1 0 0 0 12 0.0000 4 180 1530 3262 10125 Wavelet_CRF_13_7\001 -6 6 3150 10530 4905 10980 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 3170 10541 4885 10541 4885 10969 3170 10969 3170 10541 4 0 -1 0 0 0 12 0.0000 4 180 1590 3232 10800 Wavelet_SWE_13_7\001 -6 6 5895 9045 7650 9495 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 9055 7630 9055 7630 9484 5915 9484 5915 9055 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 9315 Wavelet_CDF_4_6\001 -6 6 5895 8415 7650 8865 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 8426 7630 8426 7630 8854 5915 8854 5915 8426 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 8685 Wavelet_CDF_4_4\001 -6 6 5895 7740 7650 8235 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 7773 7630 7773 7630 8201 5915 8201 5915 7773 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 8032 Wavelet_CDF_4_2\001 -6 6 5895 6930 7650 7425 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 6963 7630 6963 7630 7391 5915 7391 5915 6963 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 7222 Wavelet_CDF_2_6\001 -6 6 5895 6300 7650 6750 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 6311 7630 6311 7630 6739 5915 6739 5915 6311 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 6570 Wavelet_CDF_2_4\001 -6 6 5895 5670 7650 6120 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 5681 7630 5681 7630 6109 5915 6109 5915 5681 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 5940 Wavelet_CDF_2_2\001 -6 6 5895 4860 7650 5355 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 4893 7630 4893 7630 5322 5915 5322 5915 4893 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 5152 Wavelet_CDF_1_5\001 -6 6 5895 4230 7650 4680 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 4240 7630 4240 7630 4669 5915 4669 5915 4240 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 4500 Wavelet_CDF_1_3\001 -6 6 5895 3600 7650 4050 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 5915 3610 7630 3610 7630 4039 5915 4039 5915 3610 4 0 -1 0 0 0 12 0.0000 4 180 1455 6045 3870 Wavelet_CDF_1_1\001 -6 6 8685 3600 10440 4050 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 4039 10420 4039 10420 3610 8705 3610 8705 4039 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 3870 LiftCoef_CDF_1_1\001 -6 6 8685 4230 10440 4680 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 4669 10420 4669 10420 4240 8705 4240 8705 4669 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 4500 LiftCoef_CDF_1_3\001 -6 6 8685 4860 10440 5355 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 5322 10420 5322 10420 4893 8705 4893 8705 5322 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 5152 LiftCoef_CDF_1_5\001 -6 6 8685 5670 10440 6120 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 6109 10420 6109 10420 5681 8705 5681 8705 6109 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 5940 LiftCoef_CDF_2_2\001 -6 6 8685 6300 10440 6750 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 6739 10420 6739 10420 6311 8705 6311 8705 6739 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 6570 LiftCoef_CDF_2_4\001 -6 6 8685 6930 10440 7425 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 7391 10420 7391 10420 6963 8705 6963 8705 7391 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 7222 LiftCoef_CDF_2_6\001 -6 6 8685 7740 10440 8235 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 8201 10420 8201 10420 7773 8705 7773 8705 8201 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 8032 LiftCoef_CDF_4_2\001 -6 6 8685 8415 10440 8865 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 8854 10420 8854 10420 8426 8705 8426 8705 8854 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 8685 LiftCoef_CDF_4_4\001 -6 6 8685 9045 10440 9495 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 8705 9484 10420 9484 10420 9055 8705 9055 8705 9484 4 0 -1 0 0 0 12 0.0000 4 180 1440 8842 9315 LiftCoef_CDF_4_6\001 -6 6 11475 8415 13230 8865 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 11495 8854 13210 8854 13210 8426 11495 8426 11495 8854 4 0 -1 0 0 0 12 0.0000 4 180 1440 11632 8685 LiftCoef_CDF_4_x\001 -6 6 11475 6300 13230 6750 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 11495 6739 13210 6739 13210 6311 11495 6311 11495 6739 4 0 -1 0 0 0 12 0.0000 4 180 1440 11632 6570 LiftCoef_CDF_2_x\001 -6 6 11475 4230 13230 4680 2 2 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 5 11495 4669 13210 4669 13210 4240 11495 4240 11495 4669 4 0 -1 0 0 0 12 0.0000 4 180 1440 11632 4500 LiftCoef_CDF_1_x\001 -6 6 360 6300 2115 6750 2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5 380 6310 2094 6310 2094 6739 380 6739 380 6310 4 0 -1 0 0 0 12 0.0000 4 135 645 915 6592 Wavelet\001 -6 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 4457 7647 4457 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 6529 7647 6529 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 7172 7647 7172 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 5886 7647 5886 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 5100 7647 5100 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 3814 7647 3814 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 4457 5932 5100 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 4457 5932 3814 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 4457 5932 4457 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 6529 5932 7172 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 6529 5932 5886 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 6529 5932 6529 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 6529 10433 7172 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 6529 10433 5886 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 6529 10433 6529 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 4457 10433 5100 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 4457 10433 3814 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 4457 10433 4457 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 8629 7647 8629 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 9272 7647 9272 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 8718 7986 7647 7986 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 8629 5932 9272 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 8629 5932 7986 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 4861 8629 5932 8629 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 8629 10433 9272 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 8629 10433 7986 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2 1 1 1.00 57.15 114.30 11504 8629 10433 8629 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 3 1 1 1.00 57.15 114.30 2074 6522 2745 6525 3150 6525 0.000 -1.000 0.000 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 1 1 1.00 57.15 114.30 2074 6522 2475 5400 2925 4545 3150 4455 0.000 -1.000 -1.000 0.000 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 1 1 1.00 57.15 114.30 2074 6528 2475 7650 2925 8505 3150 8595 0.000 -1.000 -1.000 0.000 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 1 1 1.00 57.15 114.30 2070 6525 2475 4275 2925 3105 3150 2970 0.000 -1.000 -1.000 0.000 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 1 1 1.00 57.15 114.30 2070 6525 2475 8775 2925 9945 3150 10080 0.000 -1.000 -1.000 0.000 3 2 0 1 -1 7 0 0 -1 0.000 0 1 0 4 1 1 1.00 57.15 114.30 2070 6525 2483 9449 2933 10619 3158 10754 0.000 -1.000 -1.000 0.000 waili-gpl-19990723/man/libman.bib100640 24520 25417 10501 6745100140 15021 0ustar geertnatw @string {ACHA = "Appl.\ Comput.\ Harmon.\ Anal."} @string {CPAM = "Comm.\ Pure Appl.\ Math."} @article{swe:lift1, author = {W. Sweldens}, title = {The lifting scheme: {A} custom-design construction of biorthogonal wavelets}, journal = ACHA, volume = 3, number = 2, pages = {186--200}, year = 1996, url = {http://cm.bell-labs.com/who/wim/papers/lift1.ps.gz} } @article {swe:lift2, author = {W. Sweldens}, title = {The lifting scheme: {A} construction of second generation wavelets}, journal = {SIAM J. Math. Anal.}, number = 2, year = 1997, volume = 29, pages = {511--546}, url = {http://cm.bell-labs.com/who/wim/papers/lift2.ps.gz} } @inproceedings {swe:spie95, author = {W. Sweldens}, title = {The Lifting Scheme: A New Philosophy in Biorthogonal Wavelet Constructions}, booktitle = {Wavelet Applications in Signal and Image Processing III}, editor = {A. F. Laine and M. Unser}, publisher = {Proc.\ SPIE~2569}, year = {1995}, pages = {68--79}, url = {http://cm.bell-labs.com/who/wim/papers/lift2.ps.gz} } @techreport{cdsy:integer, author = {R. Calderbank and I. Daubechies and W. Sweldens and B.-L. Yeo}, title = {Wavelet transforms that map integers to integers}, journal = ACHA, volume = 5, number = 3, pages = {332--369}, year = {1998}, url = {http://cm.bell-labs.com/who/wim/papers/integer.ps.gz} } @techreport{ds:factor, author = {I. Daubechies and W. Sweldens}, title = {Factoring Wavelet Transforms into Lifting Steps}, journal = {J. Fourier Anal. Appl.}, volume = 4, number = 3, pages = {245--267}, year = {1998}, url = {http://cm.bell-labs.com/who/wim/papers/factor.ps.gz} } @article{coh-dau-fea:biorthogonal, author = {A. Cohen and I. Daubechies and J. Feauveau}, title = {Bi-orthogonal bases of compactly supported wavelets}, journal = CPAM, volume = 45, pages = {485--560}, year = 1992, libis = {370180 K.U.Leuven WWIS} } @techreport{bris:symwvlt, author = {C. M. Brislawn}, title = {Classification of Symmetric Wavelet transforms}, institution = {Computer Research Group}, address = {Los Alamos National Laboratory, Los Alamos, NM}, type = {Los Alamos Technical Report}, number = {LA-UR-92-2823}, year = 1993, url = {ftp://ftp.c3.lanl.gov/pub/WSQ/documents/classify.ps.Z} } @article{bris:acha96, author = {C. M. Brislawn}, title = {Classification of nonexpansive symmetric extension transforms for multirate filter banks}, journal = ACHA, volume = 3, year = 1996, pages = {337--357}, url = {ftp://ftp.c3.lanl.gov/pub/WSQ/documents/acha96.ps.Z} } @techreport{ITA-Wavelets-WP1.1, author = {G. Uytterhoeven and D. Roose and A. Bultheel}, title = {Wavelet Transforms Using the {L}ifting {S}cheme}, institution = {Department of Computer Science}, address = {Katholieke Universiteit Leuven, Belgium}, type = {{ITA-Wavelets} {R}eport}, number = {WP 1.1}, year = 1996, month = Nov } @article { jansen97:GCV, author = "Jansen, M. and Malfait, M. and Bultheel, A.", journal = "Signal Processing", volume = "56", number = "1", title = "Generalized Cross Validation for wavelet thresholding", year = "1997", month = "January", pages = "33--44", } @article{ArtJB97a, author = "Jansen, M. and Bultheel, A.", journal = "IEEE Transactions on Image Processing", note = "Accepted", title = "Multiple wavelet threshold estimation by generalised cross validation for images with correlated noise", year = "1998", url = "http://www.cs.kuleuven.ac.be/\~{}maarten/corgcv.ps.gz", } @inproceedings { UytVWuJanRooBul98, author = "Uytterhoeven, G. and Van Wulpen, F. and Jansen, M. and Roose, D. and Bultheel, A.", editor = "Hanson, K.M.", booktitle = "{M}edical {I}maging 1998: Image Processing", month = "February", pages = "1490--1501", publisher = "The {I}nternational {S}ociety for {O}ptical {E}ngineering", series = "{SPIE} {P}roceedings", title = "{WAILI}: {A} Software Library for Image Processing using Integer Wavelet transforms", volume = "3338", year = "1998", } waili-gpl-19990723/man/mymanpage.sty100640 24520 25417 30502 6271171045 15631 0ustar geertnatw% % ++Geert: commented out all character definitions/redefinitions (except `"') % because they conflict with the other things I use. % % $Id: mymanpage.sty,v 3.0 1997/01/21 16:43:17 geert Exp $ % %%% ==================================================================== %%% @LaTeX-style-file{ %%% author = "Rong Chen", %%% version = "1.03", %%% date = "11 June 1992", %%% time = "15:16:26 CDT", %%% filename = "manpage.sty", %%% address = "Department of Computer Science %%% University of Illinois at Urbana-Champaign %%% 1304 W. Springfield Ave. %%% Urbana, IL 61801 %%% USA", %%% telephone = "(217) 244-7118", %%% FAX = "(217) 333-3501", %%% checksum = "03245 575 2732 22501", %%% email = "rchen@cs.uiuc.edu (Internet)", %%% codetable = "ISO/ASCII", %%% keywords = "LaTeX, manpage", %%% supported = "yes", %%% docstring = "This LaTeX style file is similar to the UNIX troff %%% man macros in format and is specially tuned for %%% documenting the C++ library that the author wrote. %%% %%% This style option is designed to work with both %%% report and article document styles of LaTeX v2.09, %%% e.g., \documentstyle[11pt,twoside,manpage]{report} %%% %%% The checksum field above contains a CRC-16 %%% checksum as the first value, followed by %%% the equivalent of the standard UNIX wc %%% (word count) utility output of lines, %%% words, and characters. This is produced by %%% Robert Solovay's checksum utility.", %%% } %%% ==================================================================== % manpage.sty % % Copyright (c) 1990 by Rong Chen (rchen@cs.uiuc.edu) % Permission to copy all or part of this work is granted, provided % that the copies are not made or distributed for resale, and that % the copyright notice and this notice are retained. % % THIS WORK IS PROVIDED ON AN "AS IS" BASIS. THE AUTHOR PROVIDES NO % WARRANTY WHATSOEVER, EITHER EXPRESS OR IMPLIED, REGARDING THE WORK, % INCLUDING WARRANTIES WITH RESPECT TO ITS MERCHANTABILITY OR FITNESS % FOR ANY PARTICULAR PURPOSE. % % The commands defined in the style file are listed bellow: % % \begin{manpage}{Title}{Module}{Version} % see an example, all will be clear % % latex supplies the current date if no \date{} is specified % \end{manpage} % end of manpage environment % \variable{#1} (e.g., \variable{int foo}) % with \medskip added % \variable*{#1} (e.g., \variable*{int bar})% no extra spacing % \function{#1} (e.g., \function{void demo(int dummy)}) % with \medskip added % \function*{#1} (e.g., \function*{void demo(int dummy)})% no extra spacing % \subtitle{#1} (e.g., \subtitle{AUTHOR}) % fit in the same line if possible % \subtitle*{#1} (e.g., \subtitle*{AUTHOR})% always break a newline % ++Geert: commented out % "#1" (e.g., "dummy_variable") % argument is in italic&unbreakable % \separator % draw a thin line to separate subtitle from the text % \header{#1}{#2}{#3} % in case you want to have a header and % \footer{#1}{#2}{#3} % a footer outside of the manpage environment % % In the \function macro, data types and their dummy arguments are separated % by a space. So if you have a function like "int f(const int n)", you should % document it as \function{int f(const~int n)}. The argument n is optional. % In the \subtitle macro, two lines of text may be divided by "\\". % % ++Geert: commented out % The following characters (control-sequents) are defined (or redefined) as: % % \" --- print the double quote character ("), use $\ddot{\rm#1}$ for accent % \~ --- defined as $\sim$ being raised 0.6ex, use $\tilde{\rm#1}$ for accent % \* --- the same as $\ast$ % \< --- the same as $\langle$ % \> --- the same as $\rangle$ % < --- the same as $<$ % > --- the same as $>$ % _ --- the same as \_, use $\sb{#1}$ for subscript (see TeXbook pp. 135) % + --- the same as $+$ % | --- the same as $\mid$ % ^ --- {\small $\wedge$} being raised 0.6ex, superscript is now $\sp{#1}$ % " --- the same as {\tt "} when outside of the manpage environment, % otherwise use \" instead \headheight 24pt % see Lamport's LaTeX book for definitions \headsep 12pt \textwidth 6.25in \textheight 8.0in \topmargin 0in \marginparwidth 0pt \oddsidemargin 0pt \evensidemargin 0pt \marginparsep 0pt \parindent 0pt \parskip 10pt plus 1pt \newdimen\funindent \funindent 0pt % indentation for function/variable entries \newdimen\argindent \argindent -1pt % indentation for function arguments % when \argindent >= 0pt, subsequent lines of arguments have fixed indentation % i.e., \argindent (e.g., 3em). See the following example: % int foo ( int x, int y, int w, % int h, char a, char b, % char c, char d ) % % when \argindent < 0pt (value doesn't matter), arguments are auto-indented: % int foo ( int x, int y, int w, % int h, char a, char b, % char c, char d ) % \tableofcontents and \chapter macros are also modified in manpage.sty. % The standard LaTeX \tableofcontents couldn't handle \chapter* correctly. % In the table of contents each manpage has the same indentation as a section. % Chapter titles have smaller font and they are pushed to the right margin. % > From: Vick Khera % > one more thing you may like... we have this cprog.sty style % > (formatting of C programs, by \'Eamonn McManus ) % > that lets you place C, C++, Pascal, and Modula-2 source code in your % > LaTeX source directly. no more verbatim mode, which i think is ugly % > for C code. just be sure to include it *before* you include manpage.sty % > or things break. i don't know why, but i can live with it: % > \documentstyle[cprog,manpage]{report} will do the trick. then just replace % > those pesky \begin{verbatim}\end{verbatim} with \begin{cprog}\end{cprog} % > and it looks much better. i also like to put after the \documentstyle % > the command \let\ctextfont=\sf so the code is typeset in the \sf font % > to differentiate it from normal text. % (you may do the same with \let\ccommentfont=\sl and \let\cstringfont=\sf) % If you make any improvements, I'd like to hear about them. % % STOP STOP STOP -- comments end here :-( % but there is a sample.tex file in the back. \newcommand{\header}[3]{\gdef\@header{{#1}{#2}{#3}}} \newcommand{\footer}[3]{\gdef\@footer{{#1}{#2}{#3}}} \def\separator{\rule{\linewidth}{0.5pt}} \catcode`\"=\active %\def\arg@quote#1"{\hbox{\it #1\/}} \def\tt@quote{\hbox{\tt \char34}} \let"=\tt@quote %\let\"=\tt@quote \def\variable{\pagebreak[3]\@ifstar{\var@star}{\var@norm}} \def\var@star#1{\expandafter\print@var#1\@@\\ } \def\var@norm#1{\expandafter\print@var#1\@@\medskip\\ } \def\print@var#1\@@{\expandafter\parse@var#1 =\@@} \def\parse@var#1=#2\@@{ \print@name#1\@@ \ifx #2\@nil\else{\unskip\rm\ \(=\)\ }\strip@eq#2\fi } \def\function{\pagebreak[3]\@ifstar{\@func@star}{\@func@norm}} \def\@func@star#1{\expandafter\@function#1 \\ } \def\@func@norm#1{\expandafter\@function#1 \medskip\\ } \newdimen\arg@dim % temp variables that you don't want to know \newdimen\arg@indent \newdimen\line@siz \newbox\arg@box \def\@function#1(#2)#3 { \expandafter\print@name#1 \@@ \setbox\arg@box=\hbox{\rm\ \((\)\ }% \global\advance\arg@dim\wd\arg@box \unskip\box\arg@box \edef\@fortmp{#2}% \ifx\@fortmp\@empty {\rm \()\)#3}\else \setbox\arg@box=\hbox{\rm\ \()\);}% \global\line@siz\linewidth \global\advance\line@siz-\wd\arg@box \ifdim\argindent<0pt \global\arg@indent\arg@dim \else\global\arg@indent\argindent\fi \def\@comma{}% \@for\@tempa:=#2\do{% \setbox\arg@box=\hbox{\@comma}% \global\advance\arg@dim\wd\arg@box \unskip\@comma\def\@comma{\nobreak,\penalty-\@m\ }% \expandafter\print@arg\@tempa\@@ }% \unskip\nobreak\hbox{\rm\ \()\)#3}% \fi } \def\print@name#1#2 #3\@@{% \edef\tmp@name{#3}% \ifx\tmp@name\@empty \setbox\arg@box=\hbox{\bf #1#2}% \else\setbox\arg@box=\hbox{\rm #1#2 \bf #3\unskip}\fi \global\arg@dim\funindent \global\advance\arg@dim\wd\arg@box \unskip\hspace{\funindent}\box\arg@box } \def\print@arg#1\@@{\expandafter\print@type#1 \@@} \def\print@type#1#2 #3\@@{% \setbox\arg@box=\hbox{{\rm #1#2}% \ifx #3\@nil\else\expandafter\print@dummy#3=\@@\fi \unskip\/}% \global\advance\arg@dim\wd\arg@box \ifdim\arg@dim>\line@siz \global\arg@dim\arg@indent \global\advance\arg@dim\wd\arg@box \hfill\penalty-\@m\hbox{}\kern\arg@indent\fi \box\arg@box } \def\print@dummy#1=#2\@@{% \edef\tmp@name{#1}\def\a@space{ }% \ifx\tmp@name\a@space\else {\unskip\it\ #1\/}% \ifx #2\@nil\else{\unskip\rm\ \(=\)\ }\strip@eq#2\fi \fi } \def\strip@eq#1={\rm \expandafter\ignorespaces#1\unskip} \def\subtitle{\pagebreak[3]\@ifstar{\@subtit@star}{\@subtit@norm}} \def\@subtit@star#1{ \item[\hbox{\large\bf\begin{tabular}[t]{l}#1\end{tabular}}\hfill] \hfil\par \expandafter{\let\par=\space\ignorespaces\let\par=\endgraf} } \def\@subtit@norm#1{ \setbox\arg@box=\hbox{\large\bf\begin{tabular}[t]{l}#1\end{tabular}} \ifdim \wd\arg@box > \labelwidth \item[\copy\arg@box\hfill]\hfil\par \else \dp\arg@box=0pt \item[\copy\arg@box\hfill] \fi \expandafter{\let\par=\space\ignorespaces\let\par=\endgraf} } \newenvironment{manpage}[3]{\@beginManpage#1\@@#2\@@#3\@@}{\@endManpage} \def\@beginManpage#1\@@#2\@@#3\@@{ \newpage \pagestyle{headings} \addcontentsline{toc}{subsection}{#2} \clearpage \gdef\@header{{#2}{#1}{#2}} \gdef\@footer{{#3}{\thepage}{\@date}} \begin{list}{}{ \setlength\labelwidth{1.2in} \setlength\leftmargin{\labelwidth} \addtolength\leftmargin{\labelsep} \topsep 5pt plus 2pt minus 2pt \itemsep 5pt plus 2pt minus 2pt \parsep 10pt plus 2pt minus 2pt } \raggedbottom % \let"=\arg@quote } \def\@endManpage{ \end{list} \clearpage \flushbottom % \let"=\tt@quote } \def\@first#1#2#3{#1} \def\@second#1#2#3{#2} \def\@third#1#2#3{#3} \def\ps@headings{ \def\@oddhead{\parbox{\textwidth}{ {\rm\ \ \expandafter\@first\@header\hfill \expandafter\@second\@header\hfill \expandafter\@third\@header\ \ } \\[.1cm] \hbox{}\rule[12pt]{\textwidth}{1pt} }} \def\@evenhead{\parbox{\textwidth}{ {\rm\ \ \expandafter\@third\@header\hfill \expandafter\@second\@header\hfill \expandafter\@first\@header\ \ } \\[.1cm] \hbox{}\rule[12pt]{\textwidth}{1pt} }} \def\@oddfoot{\parbox{\textwidth}{ \hbox{}\rule{\textwidth}{1pt} \\[.1cm] {\sl\ \ \expandafter\@first\@footer\hfill \rm\expandafter\@second\@footer\hfill \sl\expandafter\@third\@footer\ } }} \def\@evenfoot{\parbox{\textwidth}{ \hbox{}\rule{\textwidth}{1pt} \\[.1cm] {\sl\ \ \expandafter\@third\@footer\hfill \rm\expandafter\@second\@footer\hfill \sl\expandafter\@first\@footer\ } }} } \gdef\@header{{}{}{}} \gdef\@footer{{}{}{}} \def\tableofcontents{\@restonecolfalse \newskip\@savskip \@savskip=\parskip \parskip 0pt plus 1pt \clearpage \thispagestyle{plain} \global\@topnum\z@ \@afterindentfalse \@makeschapterhead{{Contents\@mkboth{CONTENTS}{CONTENTS}}} \@afterheading \@starttoc{toc} \parskip=\@savskip } \def\@makechapterhead#1{ \vspace*{50pt} { \raggedleft \Large\bf \@chapapp{} \thechapter \par \vskip 15pt \huge\bf #1\par \nobreak \vskip 30pt } } \def\@makeschapterhead#1{ \vspace*{50pt} { \raggedleft \huge\bf #1\par \nobreak \vskip 30pt } } \def\@schapter#1{ \addcontentsline{toc}{chapter}{#1} \@makeschapterhead{#1} \@afterheading } %\catcode`\<=\active \def\mit@less{\hbox{\(\char60\)}} \let<=\mit@less %\catcode`\>=\active \def\mit@more{\hbox{\(\char62\)}} \let>=\mit@more %\def\<{\(\langle\)} %\def\>{\(\rangle\)} %\def\*{\(\ast\)} %\def\~{\(\raise.6ex\hbox{\(\sim\)}\)} %% \catcode`\_=\active \def_={\hbox{\kern.1em\vbox{\hrule width.3em}}} %\catcode`\_=\active \global\let_=\_ %\def\mit@wedge{\hbox{\raise.6ex\hbox{\small \(\wedge\)}}} %\catcode`\^=\active \let^=\mit@wedge %\catcode`\+=\active \def\mit@add{\hbox{\(\char43\)}} \let+=\mit@add %\catcode`\|=\active \def\mit@mid{\hbox{\(\mid\)}} \let|=\mit@mid \endinput waili-gpl-19990723/man/rlatex100755 24520 25417 2436 6745073513 14337 0ustar geertnatw#!/bin/sh # This script was taken from the LILO distribution (Version 19): # # : LILO program code, documentation and auxiliary programs are # : Copyright 1992-1996 Werner Almesberger. # : All rights reserved. # : # : Redistribution and use in source and binary forms of parts of or the # : whole original or derived work are permitted provided that the # : original work is properly attributed to the author. The name of the # : author may not be used to endorse or promote products derived from # : this software without specific prior written permission. This work # : is provided "as is" and without any express or implied warranties. # # Modified by Geert Uytterhoeven to run BibTeX when # necessary. bibtexcnt=0 while [ $bibtexcnt != 4 ]; do pid=$$ export pid rm -f /tmp/rlok$pid ( if latex $1; then touch /tmp/rlok$pid fi ) | tee /tmp/rlso$pid if [ ! -f /tmp/rlok$pid ]; then rm -f /tmp/rlso$pid exit 1 fi if grep '^LaTeX Warning: Citation' /tmp/rlso$pid >/dev/null; then echo "Running BibTeX" bibtex `echo $1 | sed -e 's/.tex$//'` bibtexcnt=`expr $bibtexcnt + 1` else if grep '^LaTeX Warning: Label(s) may' /tmp/rlso$pid >/dev/null; then : else rm -f /tmp/rlso$pid exit 0 fi fi echo "Re-running LaTeX" done waili-gpl-19990723/test/ 40755 24520 25417 0 6746056437 13223 5ustar geertnatwwaili-gpl-19990723/test/Demo.C100640 24520 25417 37143 6745120323 14315 0ustar geertnatw// // Simple Interactive Demo // // $Id: Demo.C,v 4.6.2.3.2.1 1999/07/20 16:16:19 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef NULL #define NULL 0 #endif #include #include #include #include #include #include #define MAX_CMD_LINE 256 int ExitFlag = 0; char CommandLine[MAX_CMD_LINE]; char *File = NULL; Wavelet *MyWavelet = NULL; Image MyImage; Image *Backup = NULL; int ImageLoaded = 0; const char **DeleteList = NULL; u_int DeleteListLen = 0; struct Command { const char *Name; void (*Function)(int argc, const char **); }; #define arraysize(x) (sizeof(x)/sizeof(*(x))) static const char *TmpFileName(void) { static int cnt = 0; char *filename = new char[sizeof("/var/tmp/Demo.xxxxx.xxxxx")]; sprintf(filename, "/var/tmp/Demo.%05d.%05d", getpid(), cnt++); DeleteListLen++; const char **list = new const char *[DeleteListLen]; for (u_int i = 0; i < DeleteListLen-1; i++) list[i] = DeleteList[i]; list[DeleteListLen-1] = filename; if (DeleteList) delete [] DeleteList; DeleteList = list; return filename; } static void CleanUp(void) { if (DeleteList) { for (u_int i = 0; i < DeleteListLen; i++) { unlink(DeleteList[i]); delete [] DeleteList[i]; } delete [] DeleteList; } } static char *ReadCommandLine(void) { fgets(CommandLine, MAX_CMD_LINE, stdin); u_int last = strlen(CommandLine)-1; if (CommandLine[last] == '\n') CommandLine[last] = '\0'; return CommandLine; } /* * Split a line into arguments */ static void CreateArgs(char *cmdline, int *argcp, const char **argvp[]) { int argc = 0, i; char *p, *q; const char **argv = NULL; *argcp = 0; p = cmdline; for (argc = 0;; argc++) { while (*p == ' ' || *p == '\t') p++; if (!*p) break; if (*p == '"') { for (p++; *p && *p != '"'; p++) if (*p == '\\') { p++; if (!*p) break; } if (*p) p++; } else while (*p && *p != ' ' && *p != '\t') p++; } if (argc) { if (!(argv = new const char*[argc+1])) return; p = cmdline; for (i = 0; i < argc; i++) { while (*p == ' ' || *p == '\t') p++; if (!*p) break; if (*p == '"') { q = p++; argv[i] = q; while (*p && *p != '"') { if (*p == '\\') { p++; if (!*p) break; } *q++ = *p++; } } else { q = p; argv[i] = q; while (*p && *p != ' ' && *p != '\t') { if (*p == '\\') { p++; if (!*p) break; } *q++ = *p++; } } *q = '\0'; p++; } } *argcp = argc; *argvp = argv; } static void DeleteArgs(int argc, const char *argv[]) { if (argc) delete [] argv; } /* * Partial strcasecmp() (s1 may be an abbreviation for s2) */ static int PartStrCaseCmp(const char *s1, const char *s2) { char c1, c2; while (*s1) { c1 = *s1++; if (c1 >= 'A' && c1 <= 'Z') c1 += ('a'-'A'); c2 = *s2++; if (c2 >= 'A' && c2 <= 'Z') c2 += ('a'-'A'); if (!c2 || c1 != c2) return 0; } return 1; } static int ExecCommand(const struct Command commands[], u_int numcommands, int argc, const char *argv[]) { if (argc) for (u_int i = 0; i < numcommands; i++) if (PartStrCaseCmp(argv[0], commands[i].Name)) { commands[i].Function(argc-1, argv+1); return 1; } return 0; } static void Do_NotYetImplemented(int, const char **) { fputs("Not yet implemented\n", stderr); } static int NoImage(void) { int res = 0; if (!ImageLoaded) { fputs("No image loaded\n", stderr); res = 1; } return res; } static int NoBackup(void) { int res = 0; if (!Backup) { fputs("No backup image present\n", stderr); res = 1; } return res; } static int NoWavelet(void) { int res = 0; if (!MyWavelet) { fputs("No wavelet specified\n", stderr); res = 1; } return res; }; void Do_Help(int, const char **) { fputs("\nDemo\n\n" " Help, ? Display this help\n" " Quit, eXit Terminate program\n" " Load Load an image\n" " Save Save an image\n" " View View the current image\n" " Wavelet Specify the CDF wavelet\n" " Wavelet Specify another wavelet type:\n" " 1: CRF (13, 7)\n" " 2: SWE (13, 7)\n" " Fstep cr One forward transform step (rows and columns)\n" " Fstep c One forward transform step (columns only)\n" " Fstep r One forward transform step (rows only)\n" " Bstep One backward transform step\n" " Ifwt Full inverse transform\n" " Noise Add Gaussian noise with a specific variance\n" " Denoise GCV Denoising\n" " BAckup Create a backup of the current image\n" " Psnr PSNR, compared to the backup image\n" " Threshold Hard thresholding with a specific threshold\n" " SCale Scale the image\n" " Histogram \n" " View the histogram of a subband\n" " Entropy Calculate the first-order entropy in bits per pixel\n" " Yuv Convert from RGB to YUVr (or vice versa)\n" "\n", stderr); } void Do_Quit(int, const char **) { ExitFlag = 1; } void Do_Load(int argc, const char *argv[]) { if (argc > 0) { delete File; File = new char[strlen(argv[0])+1]; strcpy(File, argv[0]); } if (!File) { fputs("No file specified\n", stderr); return; } MyImage.Import(File); ImageLoaded = 1; } void Do_Save(int argc, const char *argv[]) { if (argc > 0) { delete File; File = new char[strlen(argv[0])+1]; strcpy(File, argv[0]); } if (!File) { fputs("No file specified\n", stderr); return; } MyImage.Export(File); } void Do_View(int, const char **) { char command[32]; if (NoImage()) return; const char *filename = TmpFileName(); MyImage.Export(filename); sprintf(command, "xv %s &", filename); system(command); } void Do_Wavelet(int argc, const char *argv[]) { if (argc < 1) { fputs("Invalid arguments\n", stderr); return; } if (argc >= 2) { u_int np = atoi(argv[0]); u_int nd = atoi(argv[1]); delete MyWavelet; MyWavelet = Wavelet::CreateCDF(np, nd); } else { u_int n = atoi(argv[0]); switch (n) { case 1: delete MyWavelet; MyWavelet = new Wavelet_CRF_13_7; break; case 2: delete MyWavelet; MyWavelet = new Wavelet_SWE_13_7; break; default: fprintf(stderr, "Unknown wavelet type %d\n", n); return; } } } void Do_FStep_CR(int, const char **) { for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) { Channel *ch2 = MyImage[ch]->PushFwtStepCR(*MyWavelet); if (ch2 && ch2 != MyImage[ch]) { delete MyImage[ch]; MyImage[ch] = ch2; } } } void Do_FStep_C(int, const char **) { for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) { Channel *ch2 = MyImage[ch]->PushFwtStepC(*MyWavelet); if (ch2 && ch2 != MyImage[ch]) { delete MyImage[ch]; MyImage[ch] = ch2; } } } void Do_FStep_R(int, const char **) { for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) { Channel *ch2 = MyImage[ch]->PushFwtStepR(*MyWavelet); if (ch2 && ch2 != MyImage[ch]) { delete MyImage[ch]; MyImage[ch] = ch2; } } } const struct Command Commands_FStep[] = { { "c", Do_FStep_C }, { "r", Do_FStep_R }, { "cr", Do_FStep_CR }, { "rc", Do_FStep_CR }, }; void Do_FStep(int argc, const char *argv[]) { if (NoImage() || NoWavelet()) return; if (argc) { if (!ExecCommand(Commands_FStep, arraysize(Commands_FStep), argc, argv)) fputs("Invalid arguments\n", stderr); } else Do_FStep_CR(argc-1, argv+1); } void Do_BStep(int, const char **) { if (NoImage()) return; for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) { Channel *ch2 = MyImage[ch]->PopFwtStep(); if (ch2 && ch2 != MyImage[ch]) { delete MyImage[ch]; MyImage[ch] = ch2; } } } void Do_IFwt(int, const char **) { if (NoImage()) return; MyImage.IFwt(); } // Uniform random generator between 0 and 1 static double ranu(void) { double x; x = (double)random()/INT_MAX; return x; } static int igauss = 0 ; // Gaussian random generator static double rang(double sdv) { static double x1, x2; double s, num1, num2, v1, v2, tvar; struct timeval tv1; int seed; if (igauss != 2) { if (igauss == 0) { gettimeofday(&tv1, (struct timezone *)NULL); // `real' rand value seed = (int) tv1.tv_sec & ((1L << 17) - 1); // starts with a `real' rand value srandom(seed); } do { num1 = ranu(); num2 = ranu(); v1 = 2.0*num1-1.0; v2 = 2.0*num2-1.0; s = v1*v1+v2*v2; } while (s >= 1.0 || s == 0.0); tvar = sqrt(-2.0*log(s)/s); x1 = v1*tvar; x2 = v2*tvar; igauss = 2; return x1*sdv; } else { igauss = 1; return (x2*sdv); } } void Do_Noise(int argc, const char *argv[]) { if (NoImage()) return; if (!argc) { fputs("No variance specified\n", stderr); return; } double variance = atof(argv[0]); double stdev = sqrt(variance); for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) for (u_int r = 0; r < MyImage[ch]->GetRows(); r++) for (u_int c = 0; c < MyImage[ch]->GetCols(); c++) (*MyImage[ch])(c, r) += (s16)(rang(stdev)+0.5); } void Do_Denoise(int, const char **) { if (NoImage()) return; for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) { Channel *channel = MyImage[ch]; while (channel && channel->IsLifted()) { LChannel *lch = (LChannel *)channel; for (u_int i = SubBand_LH; i <= SubBand_HH; i++) { NTChannel *ntch = (NTChannel *)(*lch)[(SubBand)i]; if (ntch && ntch->GetCols()*ntch->GetRows() >= 1000) { u_int threshold = ntch->OptimalGCVThreshold(); ntch->ThresholdSoft(threshold); } channel = (*lch)[SubBand_LL]; } } } } void Do_Backup(int, const char **) { if (NoImage()) return; if (Backup) { delete Backup; Backup = NULL; } Backup = MyImage.Clone(); } void Do_Psnr(int, const char **) { if (NoImage() || NoBackup()) return; if (MyImage.GetChannels() != Backup->GetChannels()) { fputs("The current image must have the same number of channels as the " "backup image\n", stderr); return; } for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) printf("Channel %d: %f dB\n", ch, MyImage[ch]->Psnr(*(*Backup)[ch])); } void Do_Threshold(int argc, const char *argv[]) { if (NoImage()) return; if (!argc) { fputs("No threshold specified\n", stderr); return; } double threshold = atof(argv[0]); u64 count = 0; u64 total = 0; for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) { count += MyImage[ch]->Threshold(threshold); total += MyImage.GetCols(ch)*MyImage.GetRows(ch); } printf("Zeroed %llu coefficients (out of %llu)\n", count, total); } void Do_Scale(int argc, const char *argv[]) { if (NoImage() || NoWavelet()) return; if (!argc) { fputs("No scale factor specified\n", stderr); return; } double scale = fabs(atof(argv[0])); MyImage.Scale(scale, *MyWavelet); } void Do_Histogram(int argc, const char *argv[]) { if (NoImage()) return; if (!argc) { fputs("No level specified\n", stderr); return; } u_int level = atoi(argv[0]); argc--; argv++; if (!argc) { fputs("No subband specified\n", stderr); return; } u_int subband = atoi(argv[0]); if (subband > SubBand_HH) { fputs("Illegal subband\n", stderr); return; } argc--; argv++; u_int ch = 0; if (argc) { ch = atoi(argv[0]); if (ch > MyImage.GetChannels()) { fputs("Illegal channel\n", stderr); return; } } Channel *channel = MyImage[ch]; if (level == 0) { if (subband != SubBand_LL) { fputs("Subband must be 0 for this level\n", stderr); return; } } else { u_int l2 = level; while (l2 > 1) { if (!channel || !channel->IsLifted()) { fputs("Illegal level\n", stderr); return; } LChannel *lch = (LChannel *)channel; channel = (*lch)[SubBand_LL]; l2--; } if (!channel || !channel->IsLifted()) { fputs("Illegal level\n", stderr); return; } LChannel *lch = (LChannel *)channel; channel = (*lch)[(SubBand)subband]; } if (!channel || channel->IsLifted()) { fputs("Illegal level\n", stderr); return; } NTChannel *ntchan = (NTChannel *)channel; PixType min, max; ntchan->GetMinMax(min, max); u64 *histogram = ntchan->Histogram(min, max); const char *plotdata = TmpFileName(); Stream stream; stream.Open(plotdata, "w"); for (int i = min; i <= max; i++) #ifdef __linux__ stream.Printf("%d\t%Ld\n", i, histogram[i-min]); #else // no %Ld stream.Printf("%d\t%ld\n", i, (long)histogram[i-min]); #endif // no %Ld stream.Close(); delete [] histogram; const char *plotscript = TmpFileName(); stream.Open(plotscript, "w"); stream.Printf("plot [%d:%d]\"%s\" title \"Level %d Subband %d [%d:%d]\" " "with impulses\n", min, max, plotdata, level, subband, min, max); stream.Puts("pause -1\n"); stream.Close(); char command[160]; sprintf(command, "xterm -iconic -ut -T gnuplot -e gnuplot -name \"Level " "%d Subband %d [%d:%d]\" %s &", level, subband, min, max, plotscript); system(command); } void Do_Entropy(int, const char **) { if (NoImage()) return; for (u_int ch = 0; ch < MyImage.GetChannels(); ch++) printf("Channel %d: %f bits/pixel\n", ch, MyImage[ch]->Entropy()); } static bool is_yuv = false; void Do_YUV(int, const char **) { if (NoImage()) return; if (is_yuv) MyImage.Convert(IT_RGB, IT_YUVr); else MyImage.Convert(IT_YUVr, IT_RGB); is_yuv = !is_yuv; } const struct Command Commands[] = { { "help", Do_Help }, { "?", Do_Help }, { "quit", Do_Quit }, { "exit", Do_Quit }, { "x", Do_Quit }, { "load", Do_Load }, { "save", Do_Save }, { "view", Do_View }, { "wavelet", Do_Wavelet }, { "fstep", Do_FStep }, { "bstep", Do_BStep }, { "ifwt", Do_IFwt }, { "noise", Do_Noise }, { "denoise", Do_Denoise }, { "backup", Do_Backup }, { "psnr", Do_Psnr }, { "threshold", Do_Threshold }, { "scale", Do_Scale }, { "histogram", Do_Histogram }, { "entropy", Do_Entropy }, { "yuv", Do_YUV }, }; /* * Parse the Command Line */ static void ParseCommandLine(char *line) { int argc; const char **argv; CreateArgs(line, &argc, &argv); if (argc && !ExecCommand(Commands, arraysize(Commands), argc, argv)) fputs("Unknown command\n", stderr); DeleteArgs(argc, argv); } int main(void) { char *line; fputs("Please enter your commands (`help' for help)\n\n", stderr); do { fprintf(stderr, "demo> "); line = ReadCommandLine(); ParseCommandLine(line); } while (!ExitFlag); CleanUp(); exit(0); } waili-gpl-19990723/test/Example.C100640 24520 25417 3631 6745120323 14777 0ustar geertnatw// // Simple image compression example // // $Id: Example.C,v 4.0.2.1.2.1 1999/07/20 16:16:19 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef NULL #define NULL 0 #endif #include int main(void) { const char infile[] = "image.pgm"; const char outfile[] = "result.pgm"; double threshold = 20.0; Image image; // Read the image image.Import(infile); // Transform the image using the Cohen-Daubechies-Feauveau // (2, 2) biorthogonal wavelets Wavelet *wavelet = Wavelet::CreateCDF(2, 2); u8 id = wavelet->GetID(); delete wavelet; TransformDescriptor transform[] = { { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id } }; image.Fwt(transform, sizeof(transform)/sizeof(*transform)); // Zero all entries smaller than the threshold for (u_int ch = 0; ch < image.GetChannels(); ch++) image[ch]->Threshold(threshold); // Inverse wavelet transform image.IFwt(); // Write the reconstructed image to a file image.Export(outfile); return(0); } waili-gpl-19990723/test/Histogram.C100640 24520 25417 11047 6745120323 15361 0ustar geertnatw// // Create histograms of the various subbands // // $Id: Histogram.C,v 4.3.4.1 1999/07/20 16:16:19 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef NULL #define NULL 0 #endif #include #include #include #include #include const char *ProgramName; const char *Prefix = NULL; static void #ifdef __GNUG__ __attribute__ ((noreturn)) #endif // __GNUG__ Usage(void) { Die("\nUsage: %s [options] filename [prefix]\n\n" "Valid options are:\n" " -h, --help display this usage information\n" " -p, --primal number number of primal vanishing moments (default: 2)\n" " -d, --dual number number of dual vanishing moments (default: 2)\n" " -l, --levels number of transform levels (default: 1)\n" "\n", ProgramName); } void CreateHistogram(const NTChannel *ntch, u_int channel, u_int level, u_int subband) { char *epsfile = new char[strlen(Prefix)+sizeof("_xx_xx_x.eps")]; sprintf(epsfile, "%s_%02d_%02d_%1d.eps", Prefix, channel, level, subband); Stream stream; PixType min, max; u64 numpixels; u64 *histogram = ntch->FullHistogram(min, max, numpixels); char *plotdata = new char[sizeof("/tmp/tmp.xxxxx.data")]; sprintf(plotdata, "/tmp/tmp.%05d.data", getpid()); stream.Open(plotdata, "w"); for (int i = min; i <= max; i++) #ifdef __linux__ stream.Printf("%d\t%Ld\n", i, histogram[i-min]); #else // no %Ld stream.Printf("%d\t%ld\n", i, (long)histogram[i-min]); #endif // no %Ld stream.Close(); char *plotscript = new char[sizeof("/tmp/tmp.xxxxx.script")]; sprintf(plotscript, "/tmp/tmp.%05d.script", getpid()); stream.Open(plotscript, "w"); stream.Puts("set term postscript eps\n"); stream.Printf("set output '%s'\n", epsfile); stream.Printf("plot [%d:%d]\"%s\" title \"Channel %d Level %d Subband %d " "[%d:%d]\" with impulses\n", min, max, plotdata, channel, level, subband, min, max); stream.Puts("quit\n"); stream.Close(); char *command = new char[strlen(plotscript)+sizeof("gnuplot ")]; sprintf(command, "gnuplot %s", plotscript); system(command); delete [] command; unlink(plotscript); delete [] plotscript; unlink(plotdata); delete [] plotdata; delete [] epsfile; } int main(int argc, char *argv[]) { const char *infile = NULL; Image image; u_int maxlevels = 1; int np = 2, nd = 2; Wavelet *wavelet = NULL; ProgramName = argv[0]; while (--argc > 0) { argv++; if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) Usage(); else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--primal")) if (argc > 1) { np = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--dual")) if (argc > 1) { nd = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--levels")) if (argc > 1) { maxlevels = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!infile) infile = argv[0]; else if (!Prefix) Prefix = argv[0]; else Usage(); } if (!infile) Usage(); if (!Prefix) Prefix = infile; image.Import(infile); wavelet = Wavelet::CreateCDF(np, nd); for (u_int ch = 0; ch < image.GetChannels(); ch++) { fprintf(stderr, "channel %d: 0", ch); NTChannel *ntch = (NTChannel *)image[ch]; CreateHistogram(ntch, ch, 0, 0); for (u_int l = 1; l <= maxlevels; l++) { LChannel *lch = ntch->PushFwtStepCR(*wavelet); if (!lch) break; fprintf(stderr, " %d", l); for (u_int sb = SubBand_LL; sb <= SubBand_HH; sb++) CreateHistogram((const NTChannel *)(*lch)[(SubBand)sb], ch, l, sb); ntch = (NTChannel *)(*lch)[SubBand_LL]; } fputs("\n", stderr); } return(0); } waili-gpl-19990723/test/Makefile100640 24520 25417 3057 6745120323 14742 0ustar geertnatw# # Makefile for test # # $Id: Makefile,v 4.2.2.1.2.1 1999/07/20 16:16:19 geert Exp $ # # Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # include ../Rules.config ALL = Example Demo Proof Rangecheck Test Histogram All: $(ALL) Example: Example.o $(DEPLIBS) $(CXX) -o Example Example.o $(LFLAGS) Demo: Demo.o $(DEPLIBS) $(CXX) -o Demo Demo.o $(LFLAGS) Proof: Proof.o $(DEPLIBS) $(CXX) -o Proof Proof.o $(LFLAGS) Test: Test.o $(DEPLIBS) $(CXX) -o Test Test.o $(LFLAGS) Rangecheck: Rangecheck.o $(DEPLIBS) $(CXX) -o Rangecheck Rangecheck.o $(LFLAGS) Histogram: Histogram.o $(DEPLIBS) $(CXX) -o Histogram Histogram.o $(LFLAGS) depend: rm -f .depend $(CXX) $(CFLAGS) -M -E *.C > .depend clean: rm -f .depend *.o $(ALL) result.pgm out.pgm out.ppm reco.pgm \ reco.ppm include ../Rules.make waili-gpl-19990723/test/Proof.C100640 24520 25417 11625 6745120323 14513 0ustar geertnatw// // Counter Example for the `Beer Theorem' // // $Id: Proof.C,v 4.0.2.1.2.1 1999/07/20 16:16:19 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef NULL #define NULL 0 #endif #include #include #include const char *ProgramName; static void #ifdef __GNUG__ __attribute__ ((noreturn)) #endif // __GNUG__ Usage(void) { Die("\nUsage: %s [options] filename\n\n" "Valid options are:\n" " -h, --help display this usage information\n" " -p, --primal number number of primal vanishing moments (default: 2)\n" " -d, --dual number number of dual vanishing moments (default: 2)\n" " -l, --levels number of transform levels (default: 3)\n" " -s, --scale scaling factor (default: 1.5)\n" "\n", ProgramName); } static void DoScale(Channel &ch1, Channel &ch2) { u_int c1 = ch1.GetCols(); u_int r1 = ch1.GetRows(); u_int c2 = ch2.GetCols(); u_int r2 = ch2.GetRows(); for (u_int r = 0; r < r2; r++) { f32 rold = (f32)r*(f32)(r1-1)/(f32)(r2-1); u_int rx1 = (u_int)rold; u_int rx2 = rx1+1 < r1 ? rx1+1 : rx1; f32 r2c = rold-rx1; f32 r1c = 1-r2c; for (u_int c = 0; c < c2; c++) { f32 cold = (f32)c*(f32)(c1-1)/(f32)(c2-1); u_int cx1 = (u_int)cold; u_int cx2 = cx1+1 < c1 ? cx1+1 : cx1; f32 c2c = cold-cx1; f32 c1c = 1-c2c; ch2(c, r) = PixType(c1c*(r1c*ch1(cx1, rx1)+ r2c*ch1(cx1, rx2))+ c2c*(r1c*ch1(cx2, rx1)+ r2c*ch1(cx2, rx2))); } } } int main(int argc, char *argv[]) { const char *infile = NULL; const char *outfile = NULL; Image im1, im2; u_int channels, cols, rows; u_int levels = 3; int np = 2, nd = 2; f32 scale = 1.5; ProgramName = argv[0]; while (--argc > 0) { argv++; if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) Usage(); else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--primal")) if (argc > 1) { np = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--dual")) if (argc > 1) { nd = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--levels")) if (argc > 1) { levels = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-s") || !strcmp(argv[0], "--scale")) if (argc > 1) { scale = atof(argv[1]); argc--; argv++; } else Usage(); else if (!infile) infile = argv[0]; else Usage(); } if (!infile) Usage(); im1.Import(infile); Wavelet *wavelet = Wavelet::CreateCDF(np, nd); u8 id = wavelet->GetID(); delete wavelet; channels = im1.GetChannels(); if (channels != 1) Die("The image must have exactly 1 channel\n"); cols = im1[0]->GetCols(); rows = im1[0]->GetRows(); printf("%dx%dx%d picture\n", cols, rows, channels); im2.Resize(u_int(scale*cols), u_int(scale*rows), 1); if (levels) { TransformDescriptor *transform = new TransformDescriptor[levels]; for (u_int i = 0; i < levels; i++) { transform[i].type = TT_ColsRows; transform[i].filter = id; }; puts("Forward FWT transform"); im1.Fwt(transform, levels); u_int depth = im1[0]->GetDepth(); if (depth != levels) Die("depth1 = %d != levels\n", depth); printf("Transform depth 1 = %d\n", depth); im2.Fwt(transform, levels); depth = im2[0]->GetDepth(); if (depth != levels) Die("depth2 = %d != levels\n", depth); } Channel *ch1 = im1[0]; Channel *ch2 = im2[0]; for (u_int i = 0; i < levels; i++) { LChannel *lch1 = (LChannel *)ch1; LChannel *lch2 = (LChannel *)ch2; DoScale(*(*lch1)[(SubBand)1], *(*lch2)[(SubBand)1]); DoScale(*(*lch1)[(SubBand)2], *(*lch2)[(SubBand)2]); DoScale(*(*lch1)[(SubBand)3], *(*lch2)[(SubBand)3]); ch1 = (*lch1)[(SubBand)0]; ch2 = (*lch2)[(SubBand)0]; } DoScale(*ch1, *ch2); outfile = "out1.pgm"; im1.Export(outfile); outfile = "out2.pgm"; im2.Export(outfile); if (levels) { puts("Inverse FWT transform"); im1.IFwt(); im2.IFwt(); } outfile = "reco1.pgm"; im1.Export(outfile); outfile = "reco2.pgm"; im2.Export(outfile); return(0); } waili-gpl-19990723/test/Rangecheck.C100640 24520 25417 20177 6745120323 15462 0ustar geertnatw// // Range checking for wavelet coefficients // // $Id: Rangecheck.C,v 4.2.4.1 1999/07/20 16:16:19 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef NULL #define NULL 0 #endif #include #include #include #include #define PIXTYPE_MINBITS (64) #define PIXTYPE_PROBE_MINVAL (-36028797018963968LL) #define PIXTYPE_PROBE_MAXVAL (36028797018963967LL) const char *ProgramName; int Verbose = 0; static void #ifdef __GNUG__ __attribute__ ((noreturn)) #endif // __GNUG__ Usage(void) { Die("\nUsage: %s [options] filename\n\n" "Valid options are:\n" " -h, --help display this usage information\n" " -v, --verbose verbose mode\n" " -p, --primal number number of primal vanishing moments (default: 2)\n" " -d, --dual number number of dual vanishing moments (default: 2)\n" " -l, --levels number of transform levels (default: 1)\n" " --min number minimum pixel value\n" " --max number maximum pixel value\n" "\n", ProgramName); } Channel *DoFwt(Channel *test, const Wavelet *wavelet, u_int numlevels) { for (u_int j = 0; j < numlevels; j++) { Channel *ch = test->PushFwtStepR(*wavelet); if (!ch) Die("PushFwtStepR() returned NULL (j = %d)\n", j); if (ch != test) { delete test; test = ch; } } return(test); } void DumpScale(const NTChannel &ch) { for (u_int i = 0; i < ch.GetCols(); i++) putc(i%10 == 0 ? '0'+((i/10)%10) : ' ', stdout); puts(""); for (u_int i = 0; i < ch.GetCols(); i++) putc('0'+(i%10), stdout); puts(""); } void DumpMarks(const NTChannel &ch) { for (u_int i = 0; i < ch.GetCols(); i++) { PixType val = ch(i, 0); char mark; if (val < 0) mark = '-'; else if (val > 0) mark = '+'; else mark = '0'; putc(mark, stdout); } puts(""); } void TestData(const NTChannel &ch) { int state = 0; for (u_int i = 0; i < ch.GetCols(); i++) switch (state) { case 0: /* initial */ if (ch(i, 0)) goto bad; state = 1; break; case 1: /* leading zeroes */ if (ch(i, 0)) state = 2; break; case 2: /* real data */ if (!ch(i, 0)) state = 3; break; case 3: /* trailing zeroes */ if (ch(i, 0)) goto bad; break; } if (state == 3) return; bad: DumpMarks(ch); Die("bad result sequence\n"); } PixType DoEval(const NTChannel &ch, const Wavelet *wavelet, u_int len, u_int numlevels, u_int probe) { Channel *test = new NTChannel(len, 1); test->Clear(); TestData(ch); if (Verbose) DumpMarks(ch); for (u_int i = 0; i < ch.GetCols(); i++) (*test)(i, 0) = ch(i, 0); test = DoFwt(test, wavelet, numlevels); PixType val = (*test)(probe, 0); delete test; return(val); } int main(int argc, char *argv[]) { if (sizeof(PixType) < PIXTYPE_MINBITS/8) Die("PixType must contain %d bits (now: %d bits)\n", PIXTYPE_MINBITS, 8*sizeof(PixType)); Wavelet *wavelet = NULL; u_int np = 2, nd = 2; u_int numlevels = 1; PixType minval = -128; PixType maxval = 127; ProgramName = argv[0]; while (--argc > 0) { argv++; if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) Usage(); else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--verbose")) Verbose = 1; else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--primal")) if (argc > 1) { np = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--dual")) if (argc > 1) { nd = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--levels")) if (argc > 1) { numlevels = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "--min")) if (argc > 1) { minval = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "--max")) if (argc > 1) { maxval = atoi(argv[1]); argc--; argv++; } else Usage(); else Usage(); } if (minval > maxval) Die("The minimum value must not be larger than the maximum value\n"); if (numlevels < 1) Die("The number of levels must be equal to or greather than 1\n"); wavelet = Wavelet::CreateCDF(np, nd); u_int fstart = wavelet->GetGStart() GetHStart(); u_int fend = wavelet->GetGEnd() >? wavelet->GetHEnd(); u_int limit = (-fstart >? fend)+1; #if 0 u_int start = fstart, end = fend; for (u_int i = 1; i < numlevels; i++) { start = 2*start+fstart; end = 2*end+fend; } if (Verbose) printf("start = %d, end = %d (real)\n", start, end); start -= 2; end += 2; u_int len = end-start+1; u_int len2 = 1; while (len2 < len) len2 <<= 1; u_int lprobe = (-start)>>numlevels; u_int hprobe = lprobe+(len2>>numlevels); if (Verbose) printf("start = %d, end = %d, len = %d, len2 = %d, lprobe = %d, " "hprobe = %d\n", start, end, len, len2, lprobe, hprobe); #else u_int len = 2*limit; for (u_int i = 1; i < numlevels; i++) len = 2*(len+limit); len += 5; u_int len2 = 1; while (len2 < len) len2 <<= 1; u_int lprobe = (len>>(numlevels+1)); u_int hprobe = lprobe+(len2>>numlevels); if (Verbose) printf("fstart = %d, fend = %d, limit = %d, len = %d, len2 = %d, " "lprobe = %d, hprobe = %d\n", fstart, fend, limit, len, len2, lprobe, hprobe); #endif printf("Wavelet CDF (%d, %d), vector of %d elements, %d levels\n", np, nd, len2, numlevels); Channel *test; NTChannel minlchan(len, 1); NTChannel maxlchan(len, 1); NTChannel minhchan(len, 1); NTChannel maxhchan(len, 1); Timer timer; timer.Tic(); for (u_int i = 0; i < len; i++) { test = new NTChannel(len2, 1); test->Clear(); (*test)(i, 0) = PIXTYPE_PROBE_MINVAL; test = DoFwt(test, wavelet, numlevels); PixType minltest = (*test)(lprobe, 0); PixType minhtest = (*test)(hprobe, 0); delete test; test = new NTChannel(len2, 1); test->Clear(); (*test)(i, 0) = PIXTYPE_PROBE_MAXVAL; test = DoFwt(test, wavelet, numlevels); PixType maxltest = (*test)(lprobe, 0); PixType maxhtest = (*test)(hprobe, 0); delete test; if (minltest == 0 && maxltest == 0) { minlchan(i, 0) = 0; maxlchan(i, 0) = 0; } else if (minltest < maxltest) { minlchan(i, 0) = minval; maxlchan(i, 0) = maxval; } else { minlchan(i, 0) = maxval; maxlchan(i, 0) = minval; } if (minhtest == 0 && maxhtest == 0) { minhchan(i, 0) = 0; maxhchan(i, 0) = 0; } else if (minhtest < maxhtest) { minhchan(i, 0) = minval; maxhchan(i, 0) = maxval; } else { minhchan(i, 0) = maxval; maxhchan(i, 0) = minval; } } PixType minlpval = DoEval(minlchan, wavelet, len2, numlevels, lprobe); PixType maxlpval = DoEval(maxlchan, wavelet, len2, numlevels, lprobe); if (Verbose) DumpScale(minlchan); PixType minhpval = DoEval(minhchan, wavelet, len2, numlevels, hprobe); PixType maxhpval = DoEval(maxhchan, wavelet, len2, numlevels, hprobe); timer.Toc(); #ifdef __linux printf("Low-Pass: minimum = %Ld, maximum = %Ld\n", minlpval, maxlpval); printf("High-Pass: minimum = %Ld, maximum = %Ld\n", minhpval, maxhpval); #else /* no %Ld */ printf("Low-Pass: minimum = %ld, maximum = %ld\n", (long)minlpval, (long)maxlpval); printf("High-Pass: minimum = %ld, maximum = %ld\n", (long)minhpval, (long)maxhpval); #endif /* no %Ld */ exit(0); } waili-gpl-19990723/test/Test.C100640 24520 25417 11061 6745120323 14337 0ustar geertnatw// // Miscellaneous tests // // $Id: Test.C,v 4.1.2.1.2.1 1999/07/20 16:16:19 geert Exp $ // // Copyright (C) 1996-1999 Department of Computer Science, K.U.Leuven, Belgium // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #ifndef NULL #define NULL 0 #endif #include #include #include #include const char *ProgramName; static void #ifdef __GNUG__ __attribute__ ((noreturn)) #endif // __GNUG__ Usage(void) { Die("\nUsage: %s [options] filename\n\n" "Valid options are:\n" " -h, --help display this usage information\n" " -p, --primal number number of primal vanishing moments (default: 2)\n" " -d, --dual number number of dual vanishing moments (default: 2)\n" " -l, --levels number of transform levels (default: -1 is max)\n" "\n", ProgramName); } static void GetRange(const Channel &ch, PixType &min, PixType &max) { u_int cols = ch.GetCols(); u_int rows = ch.GetRows(); if (!cols || !rows) { min = 0; max = 0; } else { min = max = ch(0, 0); for (u_int r = 0; r < rows; r++) for (u_int c = 0; c < cols; c++) if (ch(c, r) < min) min = ch(c, r); else if (ch(c, r) > max) max = ch(c, r); } } int main(int argc, char *argv[]) { const char *infile = NULL; const char *outfile = NULL; Image im1, *im2 = NULL; u_int channels; int maxlevels = -1; int np = 2, nd = 2; Timer timer; ProgramName = argv[0]; while (--argc > 0) { argv++; if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) Usage(); else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--primal")) if (argc > 1) { np = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--dual")) if (argc > 1) { nd = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--levels")) if (argc > 1) { maxlevels = atoi(argv[1]); argc--; argv++; } else Usage(); else if (!infile) infile = argv[0]; else Usage(); } if (!infile) Usage(); im1.Import(infile); im2 = im1.Clone(); Wavelet *wavelet = Wavelet::CreateCDF(np, nd); u8 id = wavelet->GetID(); delete wavelet; channels = im1.GetChannels(); printf("%dx%dx%d picture\n", im1.GetCols(0), im1.GetRows(0), channels); TransformDescriptor transform[] = { { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, { TT_ColsRows, id }, }; int transformdepth = sizeof(transform)/sizeof(*transform); if (maxlevels < transformdepth) transformdepth = maxlevels; u_int depth; puts("Forward FWT transform"); timer.Tic(); im1.Fwt(transform, transformdepth); depth = im1[0]->GetDepth(); timer.Toc(); printf("Transform depth = %d\n", depth); #if 1 if (transformdepth == 1) { LChannel &channel = *(LChannel *)im1[0]; PixType min, max; for (u_int i = SubBand_LL; i < SubBand_HH+1; i++) { GetRange(*channel[(SubBand)i], min, max); printf("%d range: (%d, %d)\n", i, min, max); } } #endif outfile = channels > 1 ? "out.ppm" : "out.pgm"; im1.Export(outfile); puts("Inverse FWT transform"); timer.Tic(); im1.IFwt(); timer.Toc(); double maxerr = 0; for (u_int ch = 0; ch < channels; ch++) for (u_int r = 0; r < im1.GetRows(ch); r++) for (u_int c = 0; c < im1.GetCols(ch); c++) { double d = fabs(im1(c, r, ch)-(*im2)(c, r, ch)); if (d > maxerr) maxerr = d; } printf("Maxerr = %f\n", maxerr); outfile = channels > 1 ? "reco.ppm" : "reco.pgm"; im1.Export(outfile); delete im2; return(0); } waili-gpl-19990723/test/image.pgm100640 24520 25417 200020 6255513354 15124 0ustar geertnatwP5 256 256 255 ƿľǷƾп{ļϻ~~~Ļѽqyƽ̸yü˴q{{vÿʳv~y~ǿ˳yy~ļ̬~{ļˮv{~l~v˯vqjvv~ĻȪjv{{v½ɭvo~{v~ļ̴{q{̮oqo{úǪ~qqty~οȭ{v~tyt~~¹˯q{tq{~{yyʲtqoy{ytǴ{tytv{{»Ʃvt{tv{~{½ǯ~qqqvt~~ov~ͿŬloqyvyyyqv{yt¸̳qeqvt~y~~t{ο˵qvo{q~{~yξܷqlqjvy~{q{˿tqjtv~~tοjeglvy~{yvvyοelqtvt{vy~vy{~~ɾͿlggeq{qtyvyv~~¶ξޓjeqvqv~t{vv{~{Tɷ̽ߙolvvqv{~{y{v~T'μͻٕq~tvt~y~~{q@ǸͻΓy{{vqovy{{TEν̼ӾΝ{ytlyloyqqY@Ķɼ⽼ڴytyo{ooyy{~eT̹̾۹ܼyt{oqytvt~cĸ˼³ſɏy{~qoqv{~yɺʻ䷷·ӟvqjgtv{v{ty{Ͽʿڷ´۵{ogeo~yoy~ķ˿βÿĭăleqjj{ot~v~ʼ˽ƲȳКylttv~ytvv~ѿ̿㸳ɹoخvt{yyyȹȿ¿ۮ˷l{߾{q{vvv~v~ͼȾŵƶ^qҙl^otvygqv÷³³ɵq۵lcjq{y{jtؼ˿îȸvtŊqjejtq~{tԸ˿Ӯɸqlvћcjlgyvtt{պǹ~{jq۵yeoqt~yӹʿ棗˺{togqȈvl{y{ytvԹʾΛ˺~yqttӠoyqtt~~~~~{ּ˺vv{le{ܸyqttvy{lֽ̿㨠ʺ{{vllvNjvv{v{{lYֿ͕̿˺{vyyvjgtПvov{yt{վ唨ʺyy{vl^Tjtq{o{~ovӺ˿񳢷ʼyytejglYlvv~{otս˼ڞǹqqg^e{lqv~~lӹ˺Ǻ~gejYooyt{yӻɺ⳾ƴjOYgloot~{վɻϹį~TOoqqtvtoֽ˼Ӿ˿ͿoOtlo{{{tvԾʽÿȺ{jjt~tt{ytvֿʾ±eet~~yvqjOt˾ſll~~yJJ˿ǿvoq~~{jJo¿lv~yvtggοȿql{{yt{ɿt~lq¿̿{~qq¼¼cv{{{¼eoq~~oyÿο^ot{~{v~~οTqy{tyytп{cqttvlϿoqyv~~{¿ͽĿ¹o{qvtv¿̿ÿþȿļqov~vy~Ϳſgeoyl{~ÿ¾geqoyo~~ֿ¾evyy~t{~Ŀgl~yԿĵþȾ^gt~Ͼмǿc^o~~ο¼ҿԼ{JTlvt{{пǹɒȵY^gt~{{¿ǷǿĝgҼcl{{to~³±v{~ljeelytyv{ѿȼ˹Τ~{o{tgqĽݒol{{oqҿƭԾ̵voTcYƼqttttlϾ¿µɺjTEJӿ껋goj~oj¿ȵĽżҥȃcg^cüqoyvy~{~vҿĴʹξtoJ@vǾo{{~yyvпɼ̺~vvc;YҼvl~t{t¾¾ĵͿ{vϣĢe^oҲqtq~tqڹ~y~¿ԷcogΤgeq{~yq¼̿ӹteȢ~ƺYEڴylgt{v~Ŀͼβeg ǴϻojEtƧjyl~{vy¿ÿӺo^j¸ͼ1⾙±~ljq{v¼Ʊq̈eo{q{lޓ{ltll{vӿºſvtolcttȒ^Τַ½ُo{tovv~~y¿ǿtjjelytēܻȻċ{lt{t~{¿ƺoyǶeªϿֿͽۨtv{~tvqvĿDZ{~ĵ˺þoo~qyo½Ĵ¿Ѻʹ~~{~yeĻgttoyyj{½³оƼt{ʷqt~qtl̻¼{Զtolt{{lv~ijþĴtvvoNjv~vtvge{ʺt֪vtt{qvvõƾċ~{{~ogֽyqoOYlǺ̻~y̒~~~yyvĵǓj{yyTκgeTOeԼӾ~qqĈ~yv{yv{¿ƴyql{{vʀj^EJùgy{yy~vyy{{yǷǮoq{~{qcjO@Eɼjjvƃ{~~t¿Ƹĺtqy~؊lTYTнol~ϒyv~yvƹǽljtvtėϬO;@վYTyѝto{¿ƹĹqgov~{g'{gYj̭~~{qƸɾgjo~oqYcɹqeqyο{{{ķã~qeoy{~ycE՘;vlvԸ{{t{¿ĵ~^jtoogEEOtoj۳ty½ķɻ~qYt~t¨ell{e'E¹ljl༃{t¼ŸζeOȣ~oţvqgoyyYyԼĹjlq㿏tŷټY^̥Y~jqtvleejogqy¥vķ଀Ǡ^vqYvvly~eqlOܵ״vggt̝~ĹͲYgtξƟeqJlvvt{cEֿľĤlgjvإ~töԝlq¤äooYel~{ttyJtŲĶllo~ܬ~ĵ⯋jj{vtctlj^gqYƼovܻýŵᨠy­Ǯl˲eq{qTooov;~oqÐy¿ƸՠlYytlevvjgy{ovv@YϺ۽ͻľytģ~Ƕ޼̋TJtq^v©ot{{yvt^@˶~Ǫvol˩tǹѕyO^Խojvjcj~̭qq{yyYl@l­tqγ{jeɴ~qoǸ̨YOɼŽTqqgc^y̼{coec;ƣ{{ov~ẚqoĵ{tvǴ¿ÿ¿žeJԸ۵^oqqljoqTOƮ{~ܹ~lo⤎˧t{tq⼷~~Ŀǵܻ~^ƸoÃ^ƼΔt~~t΅yvy~vYJεtq^Ē뼋vÒvot⿾{~{ƶڋjjv~lǺАvye~qy˟lgvvttqۿ~ĔҼԳtѪy{t¾tȸ̸ڹgljɨ~~μ؋v{qgttyv{ojoeYoϼ۵Ž׮yq{~yqyǹ~¾ɻƢ~oqtctٔlotqt~ogctvڹǧϺڸѮ{v~tlʮ~y~¿ʼƻ{ogeͷ۪~qyvo{yyyclOlĴɿ̱Ш{ɽدv̗~tďlTطħjeq~qcJjȾּմyy{{ɼl测oɿĭe^tžyqlvy~~^TEֿ{۷~yĿ˽ީڲڶϒlqνзevvqy{qe^Je޹ɥl߿{¿˽¥o{jϻ¹lvy~~y~^EE෾Ķ¿g~Ƞy~qt˽վoqqʳqy̺Ͼt~~y{yqcTq䴾ſl̘{tq¾̺̲{g¸o^ƴȩyvv{t{~{Ye鲺ñlНq{q˾ʵü~~˚µjc{ٺtqvvyoIJyҔto{tݾ̭̽ȼɒTg~įઙyyv~~jǴtq֔g~{yݽȼƼı̼ʣgjc~¿ĺڬȹg{{v~ttg֍˷ovۚcqyvݺ˺Ε²ĺ̲~lovvŠt̿{y{y{qt{ɶyvਝv~~vݸɺѼӶ{{~yTe϶v{y{ytoljʲvv㷍ooy{qݷ˾DZַ~{~{vyeTǧvooyyYqjǬyq~Yt{{ݵ˼ζŵȹԾyq~y^Jݢqeo^vcEtv~ģ~loyl{{yݴ̺ŠջǾˮ۽ĕv{~evπYgTYO^qѿqojۊeeܱ˹Էƨ̬vvqve{oɶLjcTYgceλv~eeޝ{c̸ܱ˲صӚƊvytqoܿe^ggeYgδ^^ܳoqݳ˸ǾΎӼǛ{طԓjljgy֗OO;lTYgȮleo޿qg{ݳʷąѳț¶ΣԻҵcgOTų㞚J1TTYjy{e^Y^{tݴɹƙ˲ƽ˾Ńojje~̧q;1Yee^cc̾o~YTcqy~ݵɷɚ³λƿӔ^jt~yvg¤ˤct^TcjecjȵoylJӀqto޵v̺ӺķǼڕƋjvtvqv׿Ǡye^OYEj^jlȠqq~oTڟ{e^޶yv͹ɧħ؞Ȭݟlyq^YױƸ^elJ῀Tell¶Ͽtt~vTݧOj޸{{̸Ƭεɘ{Πޥ{t~^Ϥƺ~eTYlEjܝOY{jlq¿̪oqj^ܻJ^߹{¿ѿ˺~չt̩㹍ܝ{{Jojtɾecj^߳tOYy{oy½ӿottg{tj^ݷĵѹռ{vг̻֎ӹv~OlocYlvj@;qTTgtqqۿΥtv{vyoy޵ѾȭҵYۺɻ^voTTet{Y;TjjettlȲƵ¾Ĉ~{yve˃ݵϻ̴̵¢;Oj׶ygOOѷvqg^oyvy{ȳб~tvyjlЙg޵ϼɺvlβκك@Ӭ@Oeo^gtqʺǍy{yogѮl޳ϼѹtqtͨ˼˿ڲ^~E@llqlyǺԲ~{{~eɵ޴ѽyy׶v̽̍yάt{~{ȾΕ{t~~^ȹ޴ϾܿԽ~ɩӷĢve߻{~Ŀصo˽ݮϾ̼ηõÝqqvly~yqļϏ~~v~vYݱϿѷ؟y÷ϕϤY¾ct~vvoǼٹ{~{tgѼݪϼԱ̓Һ~{{濼oo{oɹԗ~y~oҿݪѼѧɻݠJ~jcytqĺڿvyv{gvٽݥѾˤɬ™j^þ~vj{vqמvy{~lggܠϻֿТo̷Ʒř׷cٿejovq{{ogtڗϺ͗~¾ģȼjj{yot~ty̺нڞv{~{coڔϼȹǘoſ´ңqtyov{yjqɿ¿vt~lyْϺιtÿ֣޽yy{q~t~ژv~{yyjyֵُѿ~~ܼƞq{jv~~ܼ{y~{vyؓش¥vvl۹ĵqt{~эvq{oqo{ؒӲķe{oÍȾࠃ~tyv۲vovyyov~ٔռǞ۱{yҲк寊{͎{{yֈ̷ŚݢqyŔѴӿҶvy{~~ڐιʹޒtYyɢʢо̏{ڭyvloy~يιђyyqףβ¸ۊvǎyvvv~vŪ؊кȾgyq̯̿˷Ѩ藈ښto{tĮ؊~лĽvoϵ۩﷈t~~ty{ttv~Ǫԃ~Ͽojvºά𼋅v~yܝovv{ǭ~μéyc{ܾǺљ~{{{~tvv~ɭр~~Ϻǿąoyؽ˷ۛԗ~{{{{޼ly~̴{t{ѺÀ~ܿôǥ{{{ۧt{ʲ~~{Ϲ̮~’qjˍٻɪ~~{vҝlɱ݀~~yvqηĚyqtԧͧ¨ΣvǶ̷tq~tvͷܽvooڲƻĈtyyy~Ɣ~ɷھ~v{y{t{toDz߿ݳoyt~{qιҬோvy{~•ɵչjjvyqqqjķ੨ޣogqvvo޼џۿӬۼloygyy{ݿ~ɶ{qlgvyojt~ิ۟qtϴȪyly{j~غtɵĞ{qo~y~vgyܣyqgΧyоͤƀ{߿vȲήvlytyΝڵlo^~Şʙߵǹq~t~ħɶԳo{ֳ^gclɷؾļԴovv~~ƞyoljoŴǩo{÷ʶ߽vlogtcJѿѮ¸{~{t~~ygeYe࿐~ǻ͹Ҋegjeqqɍ@vƲOqǵ׶ſӷϿjy~v{ܧl^^ɓt̼{oovovtъJYѬʍ~eϿڣ̷˃ᚋvcyyYþŵǝƽyqolljeʛcgƢvѩ׽ݺt͎vt͍Ǵںt¹yŀttyeeOc§~˝©ܝ{ᤔ{~ՐyǸߺtʾ{ĿoljqjtŹѩqØۈj݊юvqٕyǼԟl¾Ƿ¥{g~Tܷ~Ź^̳ⓅvvtԎčv¼ҿYov~{v€ļճĢ޺~ɍܷǬ޲ߍco{~vvgqqvĵ¶п׀܃~vv{ãyty{ϯƿĶϵӹjet{j~t{tlñgte̼׾Ÿ벲cqct~yɳ~y驃ogۿ¼ĿĬԿ~{jlyj{{vqǝylotqٱtݩYge~y˹y܏tl̴½Ĥjqۺecqtlq{~{͚eYl·ǽؚYٷTTY~q{;lcy^ܼ¼ƣcǎol^voq{~ѝ~jYyĴ϶gljg^~y̺~jlcҶģ@jɊYƣlt{o{{~{tvӊ~e^tcǧݱgjYyql{yvojƷƿç^jlgѹjyqy~{{tvqqgqƿ^OOJt{Úyytojecپ¾¼ģ^tܿvcݠtv~~v̓^~lo{Ź~~Tloq~Ǖ~YccYlɽžĿà@evJψ~g{vg{yyyygvjyƺtloEgv{ɝgjTYyü˿ƙ@Eo{Tˆ{yqytyYjyyy{DZ޴ɵOOɛ{TOJҿǿĿ•@EgyYܒg~ylqtgYlտ~gjy{~~ѯٛYj˞1'¿˜E@eɍYےytlyt{{qeyӴˠvqottctռբtyƙE;@ƿú;El˔Yқq{ttvtˠ̪tt{go~^gclo1Jľ¾@;cΝe̴qt~~t{qqƵ~vtjtlcֳԽ';ľſ@;^ѩlؽ{{{yv{~y~yq~t{v²ڵ{ӸJÿƿĿ1;Tԥ^۵vqytv{~~y{tOeοOoȺ ҸOTE1YԪl̯v~q~y~~vev~ԿԼoo~vJ׼ɲ~ѱoýEJT~ԲjΥtttv~~yj^o^سojecǵy̨yĺ^ccyֱyαtvq{{yyt~jqylא~~jtvžڈƿ¹TTOyظڹqcl~{{yetvyζẕ́qco{ԺĿľqlYlپ޳ejj~{tqO·ɼյeqyϱ¿jYJjś൴ooq~{tvtvvvjֹ{v~~{ŞeT^jƚ㳶oy{vyYtoƢlب~gq{q~ѹϾſº{eYJgĢ೷yqv{vv{v~oetàqoܲۘqqjqtqy̤¼þ¿þ^JceƟعct{tv{{ogv֨qqvv~vylcvӿºý~^OJgϥϾgt~q~y{{totlļяƮl{~gttve~ʟ洲¾tEJYg{Աĭot{{vv~~yvv{tɼΠӼgvqy~yqvѶ{ﷶ¹eO1Evع̵~^q{qt{~~vgY^Ѳӵ{tltovo{t‹lŲķɻĿ~jg^evڽȵ{too{gvtvetoɾħjvyvtqeoojqv˛c۱ʹĽ޼߼ɢt{qtt~v~~l~~olöjtt{vy^qqtͲvq굺yvovս½ܿӤ{vyvv{{gtco{vؾɓ^olvlqqjjgq~ѻov^eg®½ƿȧұl{yyyqql{eŵѲtvvtjlqctyqo~ַ{tcTȥǻļϱɹ{l~~~yyt{vo~ǶԪ~tytvttjYgy~j䴹tooΩǾ¾ӴĶv{y~y{yvvjvƾ~~vy{o~gOc~ϾYv¿Ҫշ¯q{{{{~evĨӋv{~ovleov͵ycϵ¿ѹֹt~~{~vtvqڴy{yt{qj^gy̺el೺¾ɵĿĿԿظǙl~tvo~~qyqִ~lqvqjjc^lþlg鶷־ÿ»Ծ۳ˆgv~~vȎoyyŠݷlg{goq~tj{ջĿ{ݹv~qtoĈv {~{j֠ݬ~cjt{q~yjv״ѺyȽ෮tqvvovŷ~eͤΩycttg~yygoy⯷ϼú¾ο⹢q~v{lvv~eΞĘƒt~jljj춵»ú൤{vy{jIJ̋g^jgșϾ{jteYooǮſĿϪvy{vo…glķֹljӟJJq˸oljq{֧ľºܸyv~tvϘq~ƼН{̬Jдjto{㥵¾͸{yly̔yǿںvcťjl̐ƷqYetĿƼěvt{q̿y˸̃tvÃyt̷̷gJYqï½ſ̼yqԭDz۳gʧĬշggtڬƿ¸~ܺooqܐͲњίqgoͷ乹¾ĸĐ޷ol~~{ӏʴtčϞqttt­ƾƼq