#include "stdafx.h" #include "basefwt.h" #include "vec1d.h" ///////////////////////////////////constructors/destructors/////////////////////////////////////////////////////////////////// //constructor status 0-not initilized, 1,2-ok after init(), -1,-2,... errors BaseFWT2D::BaseFWT2D(const wchar_t* fname) : m_status(0), tH(0), tG(0), H(0), G(0), H2m(0), G2m(0), H2m1(0), G2m1(0), J(0), TH(0), m_width(0), m_height(0), spec(0), tspec(0), spec2d(0), tspec2d(0) { wcscpy(filter, fname); FILE* flt = _wfopen(fname, L"rt"); if (flt) { if ((tH = loadfilter(flt)) == 0) { m_status = -2; return; } if ((tG = loadfilter(flt)) == 0) { m_status = -3; return; } if ((H = loadfilter(flt)) == 0) { m_status = -4; return; } if ((G = loadfilter(flt)) == 0) { m_status = -5; return; } fclose(flt); makeHGsynth(); } else { m_status = -1; //filter file failed to open } } BaseFWT2D::BaseFWT2D(const wchar_t* fname, const float* tH, unsigned int thL, int thZ, const float* tG, unsigned int tgL, int tgZ, const float* H, unsigned int hL, int hZ, const float* G, unsigned int gL, int gZ) : m_status(0), tH(0), tG(0), H(0), G(0), H2m(0), G2m(0), H2m1(0), G2m1(0), J(0), TH(0), m_width(0), m_height(0), spec(0), tspec(0), spec2d(0), tspec2d(0) { wcscpy(filter, fname); this->tH = new vec1D(thL, -thZ, tH); this->tG = new vec1D(tgL, -tgZ, tG); this->H = new vec1D(hL, -hZ, H); this->G = new vec1D(gL, -gZ, G); makeHGsynth(); } BaseFWT2D::~BaseFWT2D() { if (tH) delete tH; if (tG) delete tG; if (H) delete H; if (G) delete G; if (H2m) delete H2m; if (G2m) delete G2m; if (H2m1) delete H2m1; if (G2m1) delete G2m1; close(); //close spec,tspec,spec2d,tspec2d buffers } ///////////////////////////////////constructors/destructors/////////////////////////////////////////////////////////////////// //////////////////////////////////init/status functions////////////////////////////////////////////////////////////////////// const wchar_t* BaseFWT2D::status(int& status) const { status = m_status; switch (m_status) { default: case 0: return 0; case 1: case 2: return L"ready for transforms"; case -1: return L"failed to open filter file"; case -2: return L"failed to load tH filter"; case -3: return L"failed to load tG filter"; case -4: return L"failed to load H filter"; case -5: return L"failed to load G filter"; } } vec1D* BaseFWT2D::loadfilter(FILE* flt) const { int L, Z; if (fwscanf(flt, L"%d %d", &L, &Z) != 2) return 0; vec1D* wf = new vec1D(L, -Z); for (int i = wf->first(); i <= wf->last(); i++) { float tmp; if (fwscanf(flt, L"%*d %f", &tmp) != 1) return 0; else (*wf)(i) = tmp; } return wf; } void BaseFWT2D::makeHGsynth() { int size2m, offset2m; int size2m1, offset2m1; size2m = 0; size2m1 = 0; //arrange H2m,H2m1 for (int m = H->first(); m <= H->last(); m++) //count how many odd even coeffs { if (m % 2) size2m1++; else size2m++; } offset2m = (H->first() - (H->first() % 2)) / 2; offset2m1 = (H->first() + (H->first() % 2)) / 2; H2m = new vec1D(size2m, offset2m); H2m1 = new vec1D(size2m1, offset2m1); for (int m = H2m->first(); m <= H2m->last(); m++) (*H2m)(m) = (*H)(2 * m); for (int m = H2m1->first(); m <= H2m1->last(); m++) (*H2m1)(m) = (*H)(2 * m + 1); size2m = 0; size2m1 = 0; //arrange G2m,G2m1 for (int m = G->first(); m <= G->last(); m++) { if (m % 2) size2m1++; else size2m++; } offset2m = (G->first() - (G->first() % 2)) / 2; offset2m1 = (G->first() + (G->first() % 2)) / 2; G2m = new vec1D(size2m, offset2m); G2m1 = new vec1D(size2m1, offset2m1); for (int m = G2m->first(); m <= G2m->last(); m++) (*G2m)(m) = (*G)(2 * m); for (int m = G2m1->first(); m <= G2m1->last(); m++) (*G2m1)(m) = (*G)(2 * m + 1); } void BaseFWT2D::tracefilters(const wchar_t* fname) const { FILE* fp = _wfopen(fname, L"wt"); if (fp) { fwprintf(fp, L"tH\n"); for (int i = tH->first(); i <= tH->last(); i++) fwprintf(fp, L" %2d %g\n", i, (*tH)(i)); fwprintf(fp, L"\ntG\n"); for (int i = tG->first(); i <= tG->last(); i++) fwprintf(fp, L" %2d %g\n", i, (*tG)(i)); fwprintf(fp, L"\nH\n"); for (int i = H->first(); i <= H->last(); i++) fwprintf(fp, L" %2d %g\n", i, (*H)(i)); fwprintf(fp, L"\nG\n"); for (int i = G->first(); i <= G->last(); i++) fwprintf(fp, L" %2d %g\n", i, (*G)(i)); fwprintf(fp, L"\n\nH2m\n"); for (int i = H2m->first(); i <= H2m->last(); i++) fwprintf(fp, L" %2d %g\n", 2*i, (*H2m)(i)); fwprintf(fp, L"\nH2m1\n"); for (int i = H2m1->first(); i <= H2m1->last(); i++) fwprintf(fp, L" %2d %g\n", 2*i + 1, (*H2m1)(i)); fwprintf(fp, L"\nG2m\n"); for (int i = G2m->first(); i <= G2m->last(); i++) fwprintf(fp, L" %2d %g\n", 2*i, (*G2m)(i)); fwprintf(fp, L"\nG2m1\n"); for (int i = G2m1->first(); i <= G2m1->last(); i++) fwprintf(fp, L" %2d %g\n", 2*i + 1, (*G2m1)(i)); fclose(fp); } } void BaseFWT2D::init(unsigned int width, unsigned int height) { if (width != m_width || height != m_height) { close(); m_width = width; m_height = height; spec = (char*)malloc(2 * width * height * sizeof(char)); tspec = spec + width * height; spec2d = (char**)malloc(2 * height * sizeof(char*)); //setup rows for (unsigned int j = 0; j < 2*height; j++) spec2d[j] = &spec[j*width]; //setup cols tspec2d = &spec2d[height]; m_status = 1; } } void BaseFWT2D::init(char* data, char* tdata, unsigned int width, unsigned int height) { close(); m_width = width; m_height = height; spec = data; //data - tdata might be not continuous in memory tspec = tdata; spec2d = (char**)malloc(2 * height * sizeof(char *)); //setup rows for (unsigned int j = 0; j < height; j++) spec2d[j] = &spec[j*width]; //setup cols for (unsigned int j = 0; j < height; j++) spec2d[j+height] = &tspec[j*width]; //setup cols tspec2d = &spec2d[height]; m_status = 2; } void BaseFWT2D::close(void) { m_width = 0; m_height = 0; if (m_status == 1) { if (spec != 0) { free(spec); spec = 0; } } if (spec2d != 0) { free(spec2d); spec2d = 0; } m_status = 0; } //////////////////////////////////init/status functions////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////transforms///////////////////////////////////////////////////////////////////// int BaseFWT2D::trans(unsigned int scales, unsigned int th) { if (m_status <= 0) return -1; J = scales; TH = th; unsigned int w = m_width; unsigned int h = m_height; for (unsigned int j = 0; j < J; j++) { transrows(tspec2d, spec2d, w, h); transcols(spec2d, tspec2d, w, h); w /= 2; h /= 2; TH /= 4; } return 0; } int BaseFWT2D::trans(const char* data, unsigned int scales, unsigned int th) { if (m_status <= 0) return -1; mmxmemcpy(spec, data, m_width*m_height); //copy data to spec return trans(scales, th); //fwt transform } int BaseFWT2D::trans(const unsigned char* data, unsigned int scales, unsigned int th) { if (m_status <= 0) return -1; sub128(spec, data, m_width*m_height); //copy data to spec and correct DC return trans(scales, th); //fwt transform } ///////////////////////////////////////////////transforms///////////////////////////////////////////////////////////////////// //////////////////////////////////////////////synths////////////////////////////////////////////////////////////////////////// int BaseFWT2D::synth() { if (m_status <= 0) return -1; unsigned int w = m_width / (unsigned int)pow(2.0f, (float)J); unsigned int h = m_height / (unsigned int)pow(2.0f, (float)J); while (J) { synthcols(tspec2d, spec2d, w, h); synthrows(spec2d, tspec2d, w, h); w *= 2; h *= 2; J--; } return 0; } int BaseFWT2D::synth(char* data) { int res; res = synth(); if (res != 0) return res; mmxmemcpy(data, spec, m_width*m_height); //copy restored spec to data return res; } int BaseFWT2D::synth(unsigned char* data) { int res; res = synth(); if (res != 0) return res; add128(data, spec, m_width*m_height); //copy restored spec to data and correct DC return res; } //////////////////////////////////////////////synths////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////denoising/////////////////////////////////////////////////////////////////////// void BaseFWT2D::remove_LLband() { if (m_status <= 0) return; unsigned int width = m_width / (unsigned int)(pow(2.0f, (float)getJ())); unsigned int height = m_height / (unsigned int)(pow(2.0f, (float)getJ())); for (unsigned int y = 0; y < height; y++) for (unsigned int x = 0; x < width; x++) spec2d[y][x] = 0; } //////////////////////////////////////////////denoising/////////////////////////////////////////////////////////////////////// //////////////////////////mmx routines//////////////////////////////////////////////////////////////////////////////////////// void BaseFWT2D::mmxmemcpy(char* dest, const char* sour, unsigned int size) { //for(int i=0; i