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

📄 imapng.cpp

📁 一套图像处理程序,支持三种图像文件格式,我调试过了,很好用
💻 CPP
字号:
/*
 * File:	imapng.cc
 * Purpose:	Platform Independent JPEG Image Class
 * Author:	Alejandro Aguilar Sierra
 * Created:	1995
 * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
 *
 *      logjmp
 */

// #include "stdafx.h"

#include "imapng.h"
#if CIMAGE_SUPPORT_PNG
   
extern "C" {
#include "png.h"
}

#include "imaiter.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

void
ima_png_error(png_struct *png_ptr, char *message)
{
//        AfxMessageBox(message);

	longjmp(png_ptr->jmpbuf, 1);
}

BOOL
CImagePNG::ReadFile(const CString& imageFileName)
{
  int number_passes;

  if (imageFileName != "")
    filename = imageFileName;

	FILE *fp;
	png_struct *png_ptr;
   png_info *info_ptr;
	CImageIterator iter(this);

	/* open the file */
	fp = fopen((const char *)filename, "rb");
	if (!fp)
		return FALSE;

	/* allocate the necessary structures */
	png_ptr = new (png_struct);
	if (!png_ptr)
	{
		fclose(fp);
		return FALSE;
	}

	info_ptr = new (png_info);
	if (!info_ptr)
	{
		fclose(fp);
		delete(png_ptr);
		return FALSE;
	}
	/* set error handling */
	if (setjmp(png_ptr->jmpbuf))
	{
		png_read_destroy(png_ptr, info_ptr, (png_info *)0);
		fclose(fp);
		delete(png_ptr);
		delete(info_ptr);

		/* If we get here, we had a problem reading the file */
		return FALSE;
	}
        //png_set_error(ima_png_error, NULL);

	/* initialize the structures, info first for error handling */
	png_info_init(info_ptr);
	png_read_init(png_ptr);

	/* set up the input control */
	png_init_io(png_ptr, fp);

	/* read the file information */
	png_read_info(png_ptr, info_ptr);

	/* allocate the memory to hold the image using the fields
		of png_info. */
	png_color_16 my_background={ 0, 31, 127, 255, 0 };
 /*
	if (info_ptr->valid & PNG_INFO_bKGD)
		png_set_background(png_ptr, &(info_ptr->background),
			PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
	else   */ {//puts(" back ");
		png_set_background(png_ptr, &my_background,
			PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
	 }

	/* tell libpng to strip 16 bit depth files down to 8 bits */
	if (info_ptr->bit_depth == 16)
		png_set_strip_16(png_ptr);

	int pixel_depth=(info_ptr->pixel_depth<24) ? info_ptr->pixel_depth: 24;
	Create(info_ptr->width, info_ptr->height, pixel_depth,
		info_ptr->color_type);

	if (info_ptr->num_palette>0)
	  SetPalette((int)info_ptr->num_palette, (rgb_color_struct*)info_ptr->palette);

	int row_stride = info_ptr->width * ((pixel_depth+7)>>3);
 //	printf("P = %d D = %d RS= %d ", info_ptr->num_palette, info_ptr->pixel_depth,row_stride);
//	printf("CT = %d TRS = %d BD= %d ", info_ptr->color_type, info_ptr->valid & PNG_INFO_tRNS,info_ptr->bit_depth);

	byte *row_pointers = new byte[row_stride];

	/* turn on interlace handling */
	if (info_ptr->interlace_type)
		number_passes = png_set_interlace_handling(png_ptr);
	else
		number_passes = 1;
//	printf("NP = %d ", number_passes);

	for (int pass=0; pass< number_passes; pass++) {
	iter.Upset();
	int y=0;
	do	{
//	  (unsigned char *)iter.GetRow();
	  if (info_ptr->interlace_type)  {
		 if (pass>0)
			iter.GetRow(row_pointers, row_stride);
		 png_read_row(png_ptr, row_pointers, NULL);
	  }
	  else
		 png_read_row(png_ptr, row_pointers, NULL);

	  iter.SetRow(row_pointers, row_stride);
	  y++;
	} while(iter.PrevRow());
//	printf("Y=%d ",y);
	}
	delete[] row_pointers;

	/* read the rest of the file, getting any additional chunks
		in info_ptr */
	png_read_end(png_ptr, info_ptr);

	/* clean up after the read, and free any memory allocated */
	png_read_destroy(png_ptr, info_ptr, (png_info *)0);

	/* free the structures */
	delete(png_ptr);
	delete(info_ptr);

	/* close the file */
	fclose(fp);

	/* that's it */
	return TRUE;
}


/* write a png file */

BOOL CImagePNG::SaveFile(const CString& imageFileName)
{
	if (imageFileName != "")
		filename = imageFileName;

  CImageIterator iter(this);
  FILE *fp;
   png_struct *png_ptr;
	png_info *info_ptr;

   /* open the file */
	fp = fopen((const char *)filename, "wb");
	if (!fp)
		return FALSE;

	/* allocate the necessary structures */
	png_ptr = new (png_struct);
	if (!png_ptr)
	{
		fclose(fp);
		return FALSE;
	}

	info_ptr = new (png_info);
	if (!info_ptr)
	{
		fclose(fp);
		delete(png_ptr);
		return FALSE;
	}

	/* set error handling */
	if (setjmp(png_ptr->jmpbuf))
	{
		png_write_destroy(png_ptr);
		fclose(fp);
		delete(png_ptr);
		delete(info_ptr);

		/* If we get here, we had a problem reading the file */
		return FALSE;
	}
        //png_set_error(ima_png_error, NULL);

//	printf("writig pg %s ", filename);
   /* initialize the structures */
	png_info_init(info_ptr);
	png_write_init(png_ptr);
            
	int row_stride = GetWidth() * ((GetDepth()+7)>>3);
	/* set up the output control */
   png_init_io(png_ptr, fp);

	/* set the file information here */
	info_ptr->width = GetWidth();
	info_ptr->height = GetHeight();
	info_ptr->pixel_depth = GetDepth();
	info_ptr->channels = (GetDepth()>8) ? 3: 1;
	info_ptr->bit_depth = GetDepth()/info_ptr->channels;
	info_ptr->color_type = GetColorType();
	info_ptr->compression_type = info_ptr->filter_type = info_ptr->interlace_type=0;
	info_ptr->valid = 0;
	info_ptr->rowbytes = row_stride;


// printf("P = %d D = %d RS= %d GD= %d CH= %d ", info_ptr->pixel_depth, info_ptr->bit_depth, row_stride, GetDepth(), info_ptr->channels);
	/* set the palette if there is one */
	if ((GetColorType() & COLORTYPE_PALETTE) && GetPalette())
	{
	  printf("writig paleta[%d %d %x]",GetColorType() ,COLORTYPE_PALETTE, GetPalette());
	  info_ptr->valid |= PNG_INFO_PLTE;
	  info_ptr->palette = new png_color[256];
	  info_ptr->num_palette = 256;
	  for (int i=0; i<256; i++)
		 GetPalette()->GetRGB(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue);
	}  
//	  printf("Paleta [%d %d %x]",GetColorType() ,COLORTYPE_PALETTE, GetPalette());


   /* optional significant bit chunk */
//   info_ptr->valid |= PNG_INFO_sBIT;
//   info_ptr->sig_bit = true_bit_depth;

	/* optional gamma chunk */
//   info_ptr->valid |= PNG_INFO_gAMA;
//   info_ptr->gamma = gamma;

	/* other optional chunks */

   /* write the file information */
   png_write_info(png_ptr, info_ptr);

   /* set up the transformations you want.  Note that these are
      all optional.  Only call them if you want them */

	/* shift the pixels up to a legal bit depth and fill in
      as appropriate to correctly scale the image */
//   png_set_shift(png_ptr, &(info_ptr->sig_bit));

	/* pack pixels into bytes */
//   png_set_packing(png_ptr);

	/* flip bgr pixels to rgb */
//   png_set_bgr(png_ptr);

   /* swap bytes of 16 bit files to most significant bit first */
//   png_set_swap(png_ptr);

   /* get rid of filler bytes, pack rgb into 3 bytes */
//   png_set_rgbx(png_ptr);

/* If you are only writing one row at a time, this works */

	byte *row_pointers = new byte[row_stride];
  	iter.Upset();
	do	{
//	  (unsigned char *)iter.GetRow();
	  iter.GetRow(row_pointers, row_stride);
	  png_write_row(png_ptr, row_pointers);
	} while(iter.PrevRow());
        
        delete[] row_pointers;

/* write the rest of the file */
   png_write_end(png_ptr, info_ptr);

	/* clean up after the write, and free any memory allocated */
   png_write_destroy(png_ptr);

   /* if you malloced the palette, free it here */
   if (info_ptr->palette)
		delete[] (info_ptr->palette);

	/* free the structures */
	delete(png_ptr);
	delete(info_ptr);

	/* close the file */
	fclose(fp);

	/* that's it */
	return TRUE;
}


#endif // CIMAGE_SUPPORT_PNG

⌨️ 快捷键说明

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