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

📄 pngr.cpp

📁 一种效率高
💻 CPP
字号:
/** PNGR.CPP -- QImageIO read/write handlers for*       the PNG graphic format using libpng.**       Copyright (c) October 1998, Sirtaj Singh Kang.  Distributed under*       the LGPL.**       $Id: pngr.cpp,v 1.1 2003/09/08 19:42:14 jasonk Exp $*/#ifdef HAVE_CONFIG_H#include"config.h"#endif#ifdef HAVE_LIBPNG#include<stdio.h>#include<stdlib.h>#include<qimage.h>#include<qfile.h>extern "C" {#include<png.h>}void kimgio_png_read( QImageIO *io ){	// open png file	QImage image;	FILE *fp = fopen ( io->fileName(), "r" );	int passes = 0;	if( fp == 0 ) {		debug( "Couldn't open %s for reading.", io->fileName() );		return;	}			// init png structures	png_structp png_ptr = png_create_read_struct(  // image ptr		PNG_LIBPNG_VER_STRING, 0, 0, 0 );	if( png_ptr == 0 ) {		fclose( fp );		return;	}	png_infop png_info = png_create_info_struct( png_ptr ); // info ptr	if( png_info == 0 ) {		png_destroy_read_struct( &png_ptr, 0, 0 );		fclose( fp );		return;	}	png_infop png_end = png_create_info_struct( png_ptr );	if( !png_end ) {		png_destroy_read_struct( &png_ptr, &png_info, 0 );		fclose( fp );		return;	}	// error jump point	if( setjmp( png_ptr->jmpbuf ) ) {		png_destroy_read_struct( &png_ptr, &png_info, &png_end );		fclose( fp );		return;	}	// read header	png_init_io( png_ptr, fp );	png_read_info( png_ptr, png_info );	// transformations	png_set_packing( png_ptr );	png_set_strip_16( png_ptr );	if( !(png_ptr->color_type & PNG_COLOR_MASK_COLOR) ) {		png_set_gray_to_rgb( png_ptr );	}	else {		png_set_expand( png_ptr );	}	if( ! (png_info->color_type & PNG_COLOR_MASK_ALPHA) ) {		debug( "using filler" );		png_set_filler( png_ptr, 0, PNG_FILLER_BEFORE );	}	passes = png_set_interlace_handling ( png_ptr );	png_read_update_info( png_ptr, png_info );	if ( png_info->color_type != PNG_COLOR_TYPE_RGB_ALPHA ) {		debug( "Colortype %d is not rgb/alpha",			png_info->color_type );	}	if( png_info->bit_depth != 8 ) {		debug( "Depth %d is not 8", png_info->bit_depth );	}	// create image	if ( !image.create( png_info->width, png_info->height, 32 ) ) {		// out of memory		warning( "Out of memory creating QImage." );		png_destroy_read_struct( &png_ptr, &png_info, &png_end );		fclose( fp );		return;	}	// read image	for( ; passes; passes-- ) {		for( unsigned row = 0; row < png_info->height; row++ ) {			png_read_row( png_ptr, image.scanLine( row ), NULL );		}	}	if ( png_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ) {		debug( "Colortype %d is rgb/alpha",			png_info->color_type );		image.setAlphaBuffer(true);	}	else {		unsigned *pixels = (unsigned *) image.bits();		for( unsigned row = 0; row < png_info->height; row++ ) {			for( int i = 0; i < image.width(); i++ ) {				*pixels = *pixels >> 8;				pixels++;			}		}	}	png_read_end( png_ptr, png_info );	io->setImage( image );	io->setStatus( 0 );		// clean up 	png_destroy_read_struct( &png_ptr, &png_info, &png_end );	fclose( fp );	return;}#if (defined PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 100)void kimgio_png_write( QImageIO *iio ){	QIODevice *f = ( iio->ioDevice() );	FILE *fp = 0;	png_structp png_ptr;	png_infop info_ptr;        int colortype = 0;	const QImage& image = iio->image();	int w = image.width(), h = image.height();	int numcolors = image.numColors();	int depth = image.depth() == 1 ? 1 : 8;	//debug("Size:\t%d X %d\n\tColors:\t%d\n\tDepth:\t%d",	//	w, h, numcolors, image.depth());	if(numcolors > 0) {		//debug("PALETTE");		colortype = PNG_COLOR_TYPE_PALETTE;	}	else if(image.hasAlphaBuffer()) {		//debug("RGB_ALPHA");		colortype = PNG_COLOR_TYPE_RGB_ALPHA;	}	else {		//debug("RGB");		colortype = PNG_COLOR_TYPE_RGB;	}	// open the file	fp = fdopen(((QFile*)f)->handle(), "wb");	if (fp == 0) {		iio->setStatus( -1 );		return;	}	/* Create and initialize the png_struct with the desired error handler	 * functions.  If you want to use the default stderr and longjump method,	 * you can supply NULL for the last three parameters.  We also check that	 * the library version is compatible with the one used at compile time,	 * in case we are using dynamically linked libraries.  REQUIRED.	 */	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);	if (png_ptr == 0) {		fclose(fp);		iio->setStatus( -2 );		return;	}	/* Allocate/initialize the image information data.  REQUIRED */	info_ptr = png_create_info_struct(png_ptr);	if (info_ptr == 0) {		fclose(fp);		png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);		iio->setStatus( -3 );		return;	}	/* set up the output control if you are using standard C streams */	png_init_io(png_ptr, fp);	/* Set the image information here.  Width and height are up to 2^31,	* bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on	* the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,	* PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,	* or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or	* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST	* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED	*/	png_set_IHDR(png_ptr, info_ptr, w, h, depth, colortype,		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);	/* set the palette if there is one.  REQUIRED for indexed-color images */	if(numcolors > 0) {		info_ptr->palette = (png_colorp)png_malloc(png_ptr, numcolors * sizeof (png_color));		for(int i = 0; i < numcolors; i++) {			info_ptr->palette[i].red = qRed(image.color(i));			info_ptr->palette[i].blue = qBlue(image.color(i));			info_ptr->palette[i].green = qGreen(image.color(i));		}		png_set_PLTE(png_ptr, info_ptr, info_ptr->palette, numcolors);	}	//optional significant bit chunk	if(image.isGrayscale()) {		info_ptr->sig_bit.gray = 8;	}	else {		info_ptr->sig_bit.red = 8;		info_ptr->sig_bit.green = 8;		info_ptr->sig_bit.blue = 8;	}	if(image.hasAlphaBuffer())		info_ptr->sig_bit.alpha = 8;  	// Optional gamma chunk is strongly suggested if you have any guess	// as to the correct gamma of the image.	//png_set_gAMA(png_ptr, info_ptr, gamma);	// Optionally write comments into the image	//text_ptr[0].key = "Title";	//text_ptr[0].text = "Mona Lisa";	//text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;	//text_ptr[1].key = "Author";	//text_ptr[1].text = "Leonardo DaVinci";	//text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;	//text_ptr[2].key = "Description";	//text_ptr[2].text = "<long text>";	//text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;	//png_set_text(png_ptr, info_ptr, text_ptr, 2);	// Write the file header information.  REQUIRED	png_write_info(png_ptr, info_ptr);	// Once we write out the header, the compression type on the text	// chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or	// PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again	// at the end.	// pack pixels into bytes	png_set_packing( png_ptr );	png_set_strip_16( png_ptr );	// swap location of alpha bytes from ARGB to RGBA 	//png_set_swap_alpha(png_ptr);	// Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into	// RGB (4 channels -> 3 channels). The second parameter is not used.	if ( depth == 8 && !image.hasAlphaBuffer() )		png_set_filler(png_ptr, 0,	    QImage::systemByteOrder() == QImage::BigEndian ?		PNG_FILLER_BEFORE : PNG_FILLER_AFTER);	// flip BGR pixels to RGB	//png_set_bgr(png_ptr);	// swap bytes of 16-bit files to most significant byte first	//png_set_swap(png_ptr);	// swap bits of 1, 2, 4 bit packed pixel formats	//png_set_packswap(png_ptr);	// The easiest way to write the image (you may have a different memory	// layout, however, so choose what fits your needs best).  You need to	// use the first method if you aren't handling interlacing yourself.#define entire	// One of the following output methods is REQUIRED #ifdef entire // write out the entire image data in one call	png_byte **row_pointers = image.jumpTable();	png_write_image(png_ptr, row_pointers);#else // (no_entire) write out the image data by one or more scanlines	// If you are only writing one row at a time, this works	for (int y = 0; y < h; y++) {		png_bytep row_pointer = image.scanLine(y);		png_write_rows(png_ptr, row_pointer, 1);	}#endif // (no_entire) use only one output method	// You can write optional chunks like tEXt, zTXt, and tIME at the end as well.	// It is REQUIRED to call this to finish writing the rest of the file	png_write_end(png_ptr, info_ptr);	// if you malloced the palette, free it here	if(numcolors > 0)		free(info_ptr->palette);	// if you allocated any text comments, free them here	// clean up after the write, and free any memory allocated	png_destroy_write_struct(&png_ptr, (png_infopp)NULL);	// close the file	fclose(fp);	iio->setStatus( 0 );	return;}#else	// png library is too oldvoid kimgio_png_write( QImageIO *iio ){        // TODO: implement this        warning("kimgio_png_write: not yet implemented for old PNG libraries");}#endif#endif /* HAVE_LIBPNG */

⌨️ 快捷键说明

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