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

📄 image.cpp

📁 wavelet codec there are 34 files with code about the wavelet theory
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "global.h"
#include "image.h"
/*---------------------------------------------------------------------------*/
// Create a blank image with width=hsize, height=vsize
//    If hsize is unspecified, creates an image with width=0, height=0
//    If vsize is unspecified, creates a square image with width =
//       height = hsize

Image::Image  (int new_hsize, int new_vsize) : hsize(new_hsize),
	 vsize(new_vsize)
{
  if (hsize == -1)
	 hsize = vsize = 0;
  if (vsize == -1)
	 vsize = hsize;

  num_of_pixels=((unsigned long)hsize)*vsize;
  value = new Real [num_of_pixels];
  if (value == NULL)
	 error ("Can't allocate memory for image of size %d by %d\n",
		hsize, vsize);
}

/*---------------------------------------------------------------------------*/
// Copy constructor

Image::Image (const Image& image)
{
	int i;

	hsize = image.hsize;
	vsize = image.vsize;
	num_of_pixels=image.num_of_pixels;
	value = new Real [num_of_pixels];
	if (value == NULL)
	  error ("Can't allocate memory for image of size %d by %d\n",
		 hsize, vsize);

	for (i = 0; i < num_of_pixels; i++)
	  value[i] = image.value[i];
}

/*---------------------------------------------------------------------------*/
// Loads a raw image of size hsize by vsize from the specified file
//    The file is assumed to contain an image in raw byte format

Image::Image (const char *filename, int new_hsize, int new_vsize) :
  hsize(new_hsize), vsize(new_vsize)
{
  if (hsize == -1)
	 hsize = vsize = 0;
  if (vsize == -1)
	 vsize = hsize;

  num_of_pixels=((unsigned long)hsize)*vsize;
  value = new Real [num_of_pixels];
  if (value == NULL)
	 error ("Can't allocate memory for image of size %d by %d\n",
		hsize, vsize);

	loadRaw (filename);
}

/*---------------------------------------------------------------------------*/
// Loads a PGM image from a file. Sets hsize, vsize.

Image::Image (const char *filename)
{
  vsize = hsize = 0;
  value = NULL;
  loadPGM (filename);
}

/*---------------------------------------------------------------------------*/
// Destructor

Image::~Image ()
{
	hsize = vsize = -1;
	delete [] value;
}

/*---------------------------------------------------------------------------*/
// Assignment operator

Image &Image::operator= (const Image& image)
{
  delete [] value;
  hsize = image.hsize;
  vsize = image.vsize;
  num_of_pixels=image.num_of_pixels;

  value = new Real [num_of_pixels];

  for (int i = 0; i < num_of_pixels; i++)
	 value[i] = image.value[i];

  return *this;
}

/*---------------------------------------------------------------------------*/
// Loads an image from the specified file.  The file is assumed to
//   contain an image in raw byte format of size hsize by vsize

void Image::loadRaw (const char *filename)
{
	FILE *infile;
	unsigned char *buffer;
	int i;

	infile = fopen (filename, "rb");
	if (infile == NULL)
		error ("Unable to open file %s\n", filename);

	buffer = new unsigned char [num_of_pixels];

	if (fread (buffer,  sizeof(unsigned char),num_of_pixels, infile) != num_of_pixels)
	  error ("Read < %d chars when loading file %s\n", num_of_pixels, filename);

	for (i = 0; i < num_of_pixels; i++)
	  value[i] = (Real)buffer[i];

	delete [] buffer;
	fclose (infile);
}

/*---------------------------------------------------------------------------*/
// Saves an image to the specified file.  The image is written in
//   raw byte format.

void Image::saveRaw (const char *filename)
{
  FILE *outfile;
  unsigned char *buffer;
  int i;

  outfile = fopen (filename, "wb+");
  if (outfile == NULL)
	 error ("Unable to open file %s\n", filename);

  buffer = new unsigned char [num_of_pixels];

  for (i = 0; i < num_of_pixels; i++)
	 buffer[i] = realToChar(value[i]);

  fwrite (buffer,1 , num_of_pixels,  outfile);

  delete [] buffer;
  fclose (outfile);
}

/*---------------------------------------------------------------------------*/
// Private stuff to load pgms/ppms

void Image::PGMSkipComments (FILE* infile, unsigned char* ch)
{
  while ((*ch == '#')) {
	 while (*ch != '\n') { *ch = fgetc(infile); }
	 while (*ch <  ' ' ) { *ch = fgetc(infile); }
  }
} // Comment(s)

/*---------------------------------------------------------------------------*/
// Get a number from a pgm file header, skipping comments etc.

unsigned int Image::PGMGetVal (FILE* infile)
{
  unsigned int tmp;
  unsigned char ch;
  do { ch = fgetc(infile); } while ((ch <= ' ') && (ch != '#'));
  PGMSkipComments(infile, &ch);
  ungetc(ch, infile);
  if (fscanf(infile,"%u",&tmp) != 1) {
	 printf("%s\n","Error parsing file!");
	 exit(1);
  }
  return(tmp);
}

/*---------------------------------------------------------------------------*/
// Loads a binary (P5) PGM image from the specified file. Sets hsize and
// vsize to the correct values for the file.

void Image::loadPGM (const char *filename)
{
  FILE* infile;
  unsigned char ch = ' ';

  infile = fopen (filename, "rb");
  if (infile == NULL)
	 error ("Unable to open file %s\n", filename);

  // Look for type indicator
  while ((ch != 'P') && (ch != '#')) { ch = fgetc(infile); }
  PGMSkipComments(infile, &ch);
  char ftype = fgetc(infile); // get type, 5 or 6

  // Look for x size, y size, max grey level
  int xsize = (int)PGMGetVal(infile);
  int ysize = (int)PGMGetVal(infile);
  int maxg = (int)PGMGetVal(infile);

  // Do some consistency checks

  if ( (hsize <= 0) && (vsize <= 0) ) {
	 resize (xsize, ysize);
	 if (value == NULL)
		error ("Can't allocate memory for image of size %d by %d\n",
		  hsize, vsize);
  } else {
	 if ((xsize != hsize) || (ysize != vsize)) {
		error ("File dimensions conflict with image settings\n");
	 }
  }

  if (ftype == '5') {
	 printf("File %s is of type PGM, is %d x %d with max gray level %d\n",
			  filename, hsize, vsize, maxg);
	 PGMLoadData(infile, filename);
  }
  if (ftype == '6') {
	 printf("File %s is of type PPM, is %d x %d with max gray level %d\n",
			  filename, hsize, vsize, maxg);
	 error("Attempt to load a PPM as a PGM\n");
  }

  fclose(infile);
}

/*---------------------------------------------------------------------------*/
// Loads the data segment of a PGM image from the specified file.

void Image::PGMLoadData (FILE *infile, const char *filename)
{
	unsigned char *buffer;
	int i;

	buffer = new unsigned char [num_of_pixels];

	long fp = -1*num_of_pixels;
	fseek(infile, fp, SEEK_END);

	if (fread (buffer,  sizeof(unsigned char),num_of_pixels, infile) != num_of_pixels)
	  error ("Read < %d chars when loading file %s\n", num_of_pixels, filename);

	for (i = 0; i <num_of_pixels; i++)
	  value[i] = (Real)buffer[i];

	delete [] buffer;
}

/*---------------------------------------------------------------------------*/
// Saves an image to the specified file.  The image is written in
// (P5) PGM byte format

void Image::savePGM (const char *filename)
{
  FILE *outfile;

  outfile = fopen (filename, "wb+");
  if (outfile == NULL)
	 error ("Unable to open file %s\n", filename);

  fprintf(outfile, "P5\n#%s\n%d %d\n255\n", filename, hsize, vsize);
  PGMSaveData(outfile);
  fclose(outfile);
}

/*---------------------------------------------------------------------------*/
// Saves image data to the specified file.  The image is written in
// (P5) PGM raw byte format

void Image::PGMSaveData (FILE* outfile)
{
  unsigned char *buffer;
  int i;
  buffer = new unsigned char [num_of_pixels];

  for (i = 0; i < num_of_pixels; i++)
	 buffer[i] = realToChar(value[i]);

  fwrite (buffer, num_of_pixels, 1, outfile);

  delete [] buffer;
}

/*---------------------------------------------------------------------------*/
// Compares one image to another and returns the PSNR

Real Image::compare_psnr (const Image *im2)
{
  if (im2->hsize != hsize || im2->vsize != vsize)
	 error ("Cannot compare images of different sizes (%dx%d and %dx%d)\n",
		hsize, vsize, im2->hsize, im2->vsize);

  Real total_error = 0.0;

  for (int i = 0; i < num_of_pixels; i++)
	 total_error += square (value[i] - im2->value[i]);

  Real RMS = sqrt(total_error/(Real)(num_of_pixels));
  Real PSNR = 20.0 * log(255.0/RMS)/log(10.0);

  return PSNR;
}

/*---------------------------------------------------------------------------*/
// Compares one image to another and returns the mean squared error

Real Image::compare_mse (const Image *im2)
{
  if (im2->hsize != hsize || im2->vsize != vsize)
	 error ("Cannot compare images of different sizes (%dx%d and %dx%d)\n",
		hsize, vsize, im2->hsize, im2->vsize);

  Real total_error = 0.0;

  for (int i = 0; i <num_of_pixels; i++)
	 total_error += square (value[i] - im2->value[i]);

  Real MSE = total_error/(Real)(num_of_pixels);

  return MSE;
}

/*---------------------------------------------------------------------------*/
// Resize an image -- crop original image or pad with 0's to make fit
//   new boundaries

void Image::resize (int new_hsize, int new_vsize)
{
	int new_num_of_pixels=((long)new_hsize)*new_vsize;
  Real *new_value = new Real [new_num_of_pixels];

  for (int i = 0; i < new_num_of_pixels; i++)
	 new_value[i] = 0;

  for (int j = 0; j < min(vsize, new_vsize); j++)
	 for (int i = 0; i < min(hsize, new_hsize); i++)
		new_value[j*new_hsize+i] = value[j*hsize+i];

  hsize = new_hsize;
  vsize = new_vsize;
  num_of_pixels=new_num_of_pixels;

  if (value != NULL)
	 delete [] value;
  value = new_value;
}

/*---------------------------------------------------------------------------*/

⌨️ 快捷键说明

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