⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image_bw.c

📁 SPIHT 源代码
💻 C
字号:
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =//                     I M A G E   C L A S S// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =//           > > > >    C++ version 11.05 -  06/26/95   < < < <// Amir Said - amir@densis.fee.unicamp.br// University of Campinas (UNICAMP)// Campinas, SP 13081, Brazil// William A. Pearlman - pearlman@ecse.rpi.edu// Rensselaer Polytechnic Institute// Troy, NY 12180, USA// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Copyright (c) 1995 Amir Said & William A. Pearlman// This program is Copyright (c) by Amir Said & William A. Pearlman.// It may be freely redistributed in its entirety provided that this// copyright notice is not removed. It may not be sold for profit or// incorporated in commercial programs without the written permission// of the copyright holders. This program is provided as is, without any// express or implied warranty, without even the warranty of fitness// for a particular purpose.// - - Inclusion - - - - - - - - - - - - - - - - - - - - - - - - - - - -#include "general.h"#include "image_bw.h"#include <string.h>// - - Constants - - - - - - - - - - - - - - - - - - - - - - - - - - - -static char * M_MSG = "< Image_SP >";static char * R_MSG = "< Image_BW > cannot read from file";static char * W_MSG = "< Image_BW > cannot write to file";static char * L_MSG = "< Image_BW > larger than specified dimension";// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =//  Auxiliary functions// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =#ifdef LOSSLESSstatic void SP_Transform(int m, int in[], int l[], int h[]){  int i, k, d1, d2, mm = m - 1;  for (i = k = 0; i < m; i++, k += 2) {    l[i] = (in[k] + in[k+1]) >> 1;    h[i] =  in[k] - in[k+1]; }  h[0] -= (d2 = l[0] - l[1]) >> 2;  for (i = 1; i < mm; i++) {    d1 = d2;  d2 = l[i] - l[i+1];    h[i] -= (((d1 + d2 - h[i+1]) << 1) + d2 + 3) >> 3; }  h[i] -= d2 >> 2;}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -static void SP_Recover(int m, int l[], int h[], int out[]){  int i, k, d1, d2, t;  t = (h[m-1] += (d1 = l[m-2] - l[m-1]) >> 2);  for (i = m - 2; i > 0; i--) {    d2 = d1;  d1 = l[i-1] - l[i];    t = (h[i] += (((d1 + d2 - t) << 1) + d2 + 3) >> 3); }  h[0] += d1 >> 2;  for (i = k = 0; i < m; i++, k += 2) {    out[k] = l[i] + ((h[i] + 1) >> 1);    out[k+1] = out[k] - h[i]; }}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#elsestatic const float SmoothingFactor = 0.8;static const int NumbTap = 4;static const float T_LowPass[5] =  { 0.852699,  0.377403, -0.110624, -0.023849, 0.037829 };static const float T_HighPass[5] =  { 0.788485, -0.418092, -0.040690,  0.064539, 0.0 };static const float R_LowPass[5] =  { 0.852699,  0.418092, -0.110624, -0.064539, 0.037829 };static const float R_HighPass[5] =  { 0.788485, -0.377403, -0.040690,  0.023849, 0.0 };// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline float Filter_L(const float * f, float * v){  return f[0] * v[0] +    f[1] * (v[1] + v[-1]) + f[2] * (v[2] + v[-2]) +    f[3] * (v[3] + v[-3]) + f[4] * (v[4] + v[-4]);}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline float Filter_H(const float * f, float * v){  return f[0] * v[0] +    f[1] * (v[1] + v[-1]) + f[2] * (v[2] + v[-2]) +    f[3] * (v[3] + v[-3]);}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -static void Reflection(float * h, float * t){    for (int i = 1; i <= NumbTap; i++) {    h[-i] = h[i];  t[i] = t[-i]; }}#endif// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =//  Member functions of the class  < Image_BW >// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =// - - Private functions - - - - - - - - - - - - - - - - - - - - - - - -int Image_BW::max_levels(int n){  int l1, l2;  for (l1 = 0; !(n & 1); l1++) n >>= 1;#ifdef LOSSLESS  for (l2 = l1 - 3; n; l2++) n >>= 1;#else  for (l2 = l1 - 4; n; l2++) n >>= 1;#endif  return (l1 < l2 ? l1 : l2);}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::assign_mem(Image_Coord d, int b){  if ((b < 1) || (b > 2)) Error("Invalid number of < Image_BW > bytes");  if ((levels >= 0) && (dim.x == d.x) && (dim.y == d.y)) return;  free_mem();  if ((d.x < 64) || (d.y < 64))    Error("< Image_BW > dimension is too small or negative");  dim = d;    pdim.x = (d.x < 256 ? (d.x + 7) & 0x3FF8 : (d.x + 15) & 0x3FF0);   pdim.y = (d.y < 256 ? (d.y + 7) & 0x3FF8 : (d.y + 15) & 0x3FF0);   NEW_VECTOR(coeff, pdim.x, Pel_Type *, M_MSG);  for (int i = 0; i < pdim.x; i++) {    NEW_VECTOR(coeff[i], pdim.y, Pel_Type, M_MSG); }}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::free_mem(void){  if (levels >= 0) {    for (int i = pdim.x - 1; i >= 0; i--) delete [] coeff[i];    delete [] coeff; }  bytes = dim.x = dim.y = 0;  levels = -1;}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::extend(void){  int i, j;  for (j = dim.y - 1; j < pdim.y - 1; j++) {    coeff[0][j+1] = (coeff[0][j] + coeff[1][j]) / 2;    coeff[dim.x-1][j+1] = (coeff[dim.x-1][j] + coeff[dim.x-2][j]) / 2;    for (i = dim.x - 2; i > 0; i--)      coeff[i][j+1] = (coeff[i-1][j] + coeff[i][j] + coeff[i+1][j]) / 3; }  for (i = dim.x - 1; i < pdim.x - 1; i++) {    coeff[i+1][0] = (coeff[i][0] + coeff[i][1]) / 2;    coeff[i+1][pdim.y-1] = (coeff[i][pdim.y-1] + coeff[i][pdim.y-2]) / 2;    for (j = pdim.y - 2; j > 0; j--)      coeff[i+1][j] = (coeff[i][j-1] + coeff[i][j] + coeff[i][j+1]) / 3; }}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// - - Public functions  - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::read_pic(Image_Coord d, char * file_name, int b){  assign_mem(d, b);  mean = levels = 0;  bytes = b;  FILE * in_file = fopen(file_name, "rb");  if (in_file == NULL) Error(R_MSG);  int i, j, k, p, c;  for (i = 0; i < dim.x; i++)    for (j = 0; j < dim.y; j++) {      for (p = k = 0; k < bytes; k++) {        if ((c = getc(in_file)) == EOF) Error(R_MSG);        p = (p << 8) | c; }      coeff[i][j] = p; }  if (getc(in_file) != EOF) Error(L_MSG);  fclose(in_file);  extend();}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -float Image_BW::compare(char * file_name){  if (levels) Error("cannot compare < Image_BW >");  FILE * in_file = fopen(file_name, "rb");  if (in_file == NULL) Error(R_MSG);  double mse = 0.0;  int i, j, k, p, c, t;  for (i = 0; i < dim.x; i++)    for (j = 0; j < dim.y; j++) {#ifdef LOSSLESS      t = coeff[i][j];#else      t = int(floor(0.499 + coeff[i][j]));#endif      if (t < 0) t = 0;      if ((bytes == 1) && (t > 255)) t = 255;      for (p = k = 0; k < bytes; k++) {        if ((c = getc(in_file)) == EOF) Error(R_MSG);        p = (p << 8) | c; }      mse += Sqr(p - t); }  if (getc(in_file) != EOF) Error(L_MSG);  fclose(in_file);  return (mse / dim.x) / dim.y;}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::write_pic(char * file_name){  if (levels) Error("cannot write < Image_BW >");  FILE * out_file = fopen(file_name, "wb");  if (out_file == NULL) Error(W_MSG);  int i, j, k;  for (i = 0; i < dim.x; i++)    for (j = 0; j < dim.y; j++) {#ifdef LOSSLESS      k = coeff[i][j];#else      k = int(floor(0.499 + coeff[i][j]));#endif      if (k < 0) k = 0;      if (bytes == 2) {        if (putc(k >> 8, out_file) == EOF) Error(W_MSG); }      else {        if (k > 255) k = 255; }      if (putc(k & 0xFF, out_file) == EOF) Error(W_MSG); }  fclose(out_file);}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::reset(Image_Coord d){  assign_mem(d, 1);  bytes = 1;  mean = shift = smoothing = 0;  levels = Min(max_levels(pdim.x), max_levels(pdim.y));  int i, j;  for (i = 0; i < pdim.x; i++)    for (j = 0; j < pdim.y; j++) coeff[i][j] = 0;}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::reset(Image_Coord d, int b, int m, int shf, int smt){  reset(d);  bytes = b;  mean = m;  shift = shf;  smoothing = smt;}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::transform(int sm_numb){  if (levels) Error("cannot transform < Image_BW >");  if ((dim.x < 32) || (dim.y < 32))    Error("< Image_BW > is too small to transform");  Chronometer cpu_time;  cpu_time.start("\n  Starting image transformation...");  levels = Min(max_levels(pdim.x), max_levels(pdim.y));  if (levels < 3) Error("invalid < Image_BW > dimension");  smoothing = sm_numb;  if ((sm_numb < 0) || (sm_numb > 7))    Error("invalid < Image_BW > smoothing factor");#ifdef LOSSLESS  int i = 0, j = Max(pdim.x, pdim.y), k = j << 1;#else  int i = NumbTap, j = 0, k = Max(pdim.x, pdim.y) + (i << 1);  float sm_mt;#endif  CREATE_VECTOR(temp_line, k, Pel_Type, M_MSG);  Pel_Type * t, * in_line = temp_line + i, * out_line = in_line + j;// hierarchical wavelet or S+P transformation  int nx, ny, mx = pdim.x, my = pdim.y;  for (int lv = 0; lv < levels; lv++) {  // shifts are halved, multiplier is updated    nx = mx;  mx >>= 1;  ny = my;  my >>= 1;#ifndef LOSSLESS  float sm_mt = 1 + smoothing * SmoothingFactor / (2 + lv * lv);#endif  // transformation of columns    for (j = 0; j < ny; j++) {      for (i = 0; i < nx; i++) in_line[i] = coeff[i][j];#ifdef LOSSLESS      SP_Transform(mx, in_line, out_line, out_line + mx);      for (i = 0; i < nx; i++) coeff[i][j] = out_line[i]; }#else      Reflection(in_line, in_line + nx - 1);      for (i = 0, t = in_line; i < mx; i++) {        coeff[i][j] = sm_mt * Filter_L(T_LowPass, t++);        coeff[i+mx][j] = Filter_H(T_HighPass, t++); } }#endif  // transformation of rows    for (i = 0; i < nx; i++) {      memcpy(in_line, coeff[i], ny * sizeof(Pel_Type));#ifdef LOSSLESS      SP_Transform(my, in_line, coeff[i], coeff[i] + my); } }#else      Reflection(in_line, in_line + ny - 1);      for (j = 0, t = in_line; j < my; j++) {        coeff[i][j] = sm_mt * Filter_L(T_LowPass, t++);        coeff[i][j+my] = Filter_H(T_HighPass, t++); } } }#endif// calculate and subtract mean  float s = 0;  for (i = 0; i < mx; i++)    for (j = 0; j < my; j++) s += coeff[i][j];  s /= float(mx) * float(my);  for (shift = 0; s > 1e3; shift++) s *= 0.25;  mean = int(0.5 + s);#ifdef LOSSLESS  int tm = mean << (shift + shift);#else  float tm = mean * pow(4, shift);#endif  for (i = 0; i < mx; i++)    for (j = 0; j < my; j++) coeff[i][j] -= tm;  delete [] temp_line;  cpu_time.display(" Image transformed in");}// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Image_BW::recover(void){  if (levels <= 0) Error("cannot recover < Image_BW >");  Chronometer cpu_time;  cpu_time.start("\n  Starting inverse transformation...");#ifdef LOSSLESS  int i = 0, j = Max(pdim.x, pdim.y), k = j << 1;#else  int i = NumbTap, j = 0, k = Max(pdim.x, pdim.y) + (i << 1);  float sm_mt;#endif  CREATE_VECTOR(temp_line, k, Pel_Type, M_MSG);  Pel_Type * t, * in_line = temp_line + i, * out_line = in_line + j;  int mx, my, nx = pdim.x >> levels, ny = pdim.y >> levels;// add mean#ifdef LOSSLESS  int tm = mean << (shift + shift);#else  float tm = mean * pow(4, shift);#endif  for (i = 0; i < nx; i++)    for (j = 0; j < ny; j++) coeff[i][j] += tm;// inverse hierarchical wavelet or S+P transformation  for (int lv = levels - 1; lv >= 0; lv--) {  // shifts are doubled, multiplier is updated    mx = nx;  nx <<= 1;  my = ny;  ny <<= 1;#ifndef LOSSLESS  float sm_mt = 1 / (1 + smoothing * SmoothingFactor / (2 + lv * lv));#endif  // inverse transformation of rows    for (i = 0; i < nx; i++) {#ifdef LOSSLESS      memcpy(in_line, coeff[i], ny * sizeof(Pel_Type));      SP_Recover(my, in_line, in_line + my, coeff[i]); }#else      for (j = 0, t = in_line; j < my; j++) {        *(t++) = sm_mt * coeff[i][j];  *(t++) = coeff[i][j+my]; }      Reflection(in_line, in_line + ny - 1);      for (j = 0, t = in_line; j < ny;) {        coeff[i][j++] = Filter_H(R_HighPass, t++);        coeff[i][j++] = Filter_L(R_LowPass, t++); } }#endif  // inverse transformation of columns    for (j = 0; j < ny; j++) {#ifdef LOSSLESS      for (i = 0; i < nx; i++) in_line[i] = coeff[i][j];      SP_Recover(mx, in_line, in_line + mx, out_line);      for (i = 0; i < nx; i++) coeff[i][j] = out_line[i]; } }#else      for (i = 0, t = in_line; i < mx; i++) {        *(t++) = sm_mt * coeff[i][j];  *(t++) = coeff[i+mx][j]; }      Reflection(in_line, in_line + nx - 1);      for (i = 0, t = in_line; i < nx;) {        coeff[i++][j] = Filter_H(R_HighPass, t++);        coeff[i++][j] = Filter_L(R_LowPass, t++); } } }#endif  levels = 0;  delete [] temp_line;  cpu_time.display(" Image transformed in");}// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =// end of file  < Image_BW.C >

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -