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

📄 gpng.cpp

📁 一个非常有用的开源代码
💻 CPP
字号:
/*	Copyright (C) 2006, Mike Gashler	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Lesser General Public	License as published by the Free Software Foundation; either	version 2.1 of the License, or (at your option) any later version.	see http://www.gnu.org/copyleft/lesser.html*/#include "GPNG.h"#ifdef WIN32#include "png.h"#else#ifdef DARWIN#include <libpng/png.h>#else#include <png.h>#endif#endif // !WIN32#include "GMacros.h"#include "GImage.h"class GPNGReader{public:	png_structp m_pReadStruct;	png_infop m_pInfoStruct;	png_infop m_pEndInfoStruct;	const unsigned char* m_pData;	int m_nPos;	GPNGReader(const unsigned char* pData)	{		m_pData = pData;		m_nPos = 0;		m_pReadStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);		if(!m_pReadStruct)		{			m_pReadStruct = NULL;			GAssert(false, "Failed to create the read struct");			return;			}		m_pInfoStruct = png_create_info_struct(m_pReadStruct);		m_pEndInfoStruct = png_create_info_struct(m_pReadStruct);	}	~GPNGReader()	{		if(m_pReadStruct)			png_destroy_read_struct(&m_pReadStruct, &m_pInfoStruct, &m_pEndInfoStruct);	}	void ReadBytes(unsigned char* pBuf, int nBytes)	{		memcpy(pBuf, m_pData + m_nPos, nBytes);		m_nPos += nBytes;	}};void readFunc(png_struct* pReadStruct, png_bytep pBuf, png_size_t nSize){	GPNGReader* pReader = (GPNGReader*)png_get_io_ptr(pReadStruct);	pReader->ReadBytes((unsigned char*)pBuf, (int)nSize);}bool LoadPng(GImage* pImage, const unsigned char* pData, int nDataSize){	// Check for the PNG signature	if(nDataSize < 8 || png_sig_cmp((png_bytep)pData, 0, 8) != 0)	{		GAssert(false, "Not a PNG file");		return false;	}	// Read all PNG data up until the image data chunk.	GPNGReader reader(pData);	png_set_read_fn(reader.m_pReadStruct, (png_voidp)&reader, (png_rw_ptr)readFunc);	png_read_info(reader.m_pReadStruct, reader.m_pInfoStruct);	// Get the image data	int depth, color;	unsigned long width, height;	png_get_IHDR(reader.m_pReadStruct, reader.m_pInfoStruct, &width, &height, &depth, &color, NULL, NULL, NULL);GAssert(depth == 8, "todo: remove this line");	pImage->SetSize(width, height);	// Set gamma correction	double dGamma;	if (png_get_gAMA(reader.m_pReadStruct, reader.m_pInfoStruct, &dGamma))		png_set_gamma(reader.m_pReadStruct, 2.2, dGamma);	else		png_set_gamma(reader.m_pReadStruct, 2.2, 1.0 / 2.2); // 1.0 = viewing gamma, 2.2 = screen gamma	// Update the 'info' struct with the gamma information	png_read_update_info(reader.m_pReadStruct, reader.m_pInfoStruct);	// Tell it to expand palettes to full channels	png_set_expand(reader.m_pReadStruct);	png_set_gray_to_rgb(reader.m_pReadStruct);	// Allocate the row pointers	unsigned long rowbytes = png_get_rowbytes(reader.m_pReadStruct, reader.m_pInfoStruct);	unsigned long channels = rowbytes / width;	ArrayHolder<unsigned char*> hData(new unsigned char[rowbytes * height]);	png_bytep pRawData = (png_bytep)hData.Get();	unsigned int i;	{		ArrayHolder<unsigned char*> hRows(new unsigned char[sizeof(png_bytep) * height]);		png_bytep* pRows = (png_bytep*)hRows.Get();		for(i = 0; i < height; i++)			pRows[i] = pRawData + i * rowbytes;		png_read_image(reader.m_pReadStruct, pRows);	}	// Copy to the GImage	unsigned long nPixels = width * height;	GColor* pRGBQuads = pImage->GetRGBQuads();	unsigned char *pBytes = pRawData;	if(channels > 3)	{		GAssert(channels == 4, "unexpected number of channels");		for(i = 0; i < nPixels; i++)		{			*pRGBQuads = gARGB(pBytes[3], pBytes[0], pBytes[1], pBytes[2]);			pBytes += channels;			pRGBQuads++;		}	}	else	{		GAssert(channels == 3, "unexpected number of channels");		int alpha;		for(i = 0; i < nPixels; i++)		{			if(pBytes[0] == 0 && pBytes[1] == 0xff && pBytes[2] == 0) // If the color is pure green (0x00ff00)				alpha = 0;			else				alpha = 0xff;			*pRGBQuads = gARGB(alpha, pBytes[0], pBytes[1], pBytes[2]);			pBytes += channels;			pRGBQuads++;		}	}	// Check for additional tags	png_read_end(reader.m_pReadStruct, reader.m_pEndInfoStruct);	return true;}// -----------------------------------------------------------------------class GPNGWriter{public:	png_structp m_pWriteStruct;	png_infop m_pInfoStruct;	GPNGWriter()	{		m_pWriteStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);		if(m_pWriteStruct == NULL)		{			GAssert(false, "Failed to create write struct. Out of mem?");			return;		}		m_pInfoStruct = png_create_info_struct(m_pWriteStruct);		if(m_pInfoStruct == NULL)		{			GAssert(false, "Failed to create info struct. Out of mem?");			return;		}	}	~GPNGWriter()	{		png_destroy_write_struct(&m_pWriteStruct, &m_pInfoStruct);	}};bool SavePng(GImage* pImage, FILE* pFile, bool bIncludeAlphaChannel){	GPNGWriter writer;	// Allocate the row pointers	unsigned long width = pImage->GetWidth();	unsigned long height = pImage->GetHeight();	unsigned long channels = bIncludeAlphaChannel ? 4 : 3;	unsigned long rowbytes = width * channels;	ArrayHolder<unsigned char*> hData(new unsigned char[rowbytes * height]);	png_bytep pRawData = (png_bytep)hData.Get();	unsigned int i;	ArrayHolder<unsigned char*> hRows(new unsigned char[sizeof(png_bytep) * height]);	png_bytep* pRows = (png_bytep*)hRows.Get();	for(i = 0; i < height; i++)		pRows[i] = pRawData + i * rowbytes;	// Copy to the GImage	unsigned long nPixels = width * height;	GColor* pRGBQuads = pImage->GetRGBQuads();	GColor col;	unsigned char *pBytes = pRawData;	if(channels > 3)	{		GAssert(channels == 4, "unexpected number of channels");		for(i = 0; i < nPixels; i++)		{			col = *(pRGBQuads++);			*(pBytes++) = gRed(col);			*(pBytes++) = gGreen(col);			*(pBytes++) = gBlue(col);			*(pBytes++) = gAlpha(col);		}	}	else	{		GAssert(channels == 3, "unexpected number of channels");		for(i = 0; i < nPixels; i++)		{			col = *(pRGBQuads++);			*(pBytes++) = gRed(col);			*(pBytes++) = gGreen(col);			*(pBytes++) = gBlue(col);		}	}	// Set the jump value	if(setjmp(png_jmpbuf(writer.m_pWriteStruct)))	{		GAssert(false, "Failed to set the jump value for writing");		return false;	}	// Init the IO	png_init_io(writer.m_pWriteStruct, pFile);	// Write image stats and settings	png_set_IHDR(writer.m_pWriteStruct, writer.m_pInfoStruct,			width, height, 8,			bIncludeAlphaChannel ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,			PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);	png_write_info(writer.m_pWriteStruct, writer.m_pInfoStruct);	// Write the image data	png_write_image(writer.m_pWriteStruct, pRows);	png_write_end(writer.m_pWriteStruct, writer.m_pInfoStruct);	return true;}

⌨️ 快捷键说明

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