?? pngfunc.c
字號:
/***
* pngfunc.c
***
* soucast knihovny libopen
* 2007-04-29
* xbarin02@stud.fit.vutbr.cz
***
* fce pro praci s PNG
*/
#include "pngfunc.h"
#include "error.h"
#include <stdlib.h>
PFrameBuff loadpng(char *fname)
{
FILE* png_file;
png_bytep png_sig_buff;
if( NULL == (png_file = fopen(fname, "rb")) )
{
eprintf("fopen() fails!");
return(NULL);
}
const png_size_t _png_sig_num_bytes = 4;
png_sig_buff = malloc( sizeof(png_byte)*_png_sig_num_bytes );
if( NULL == png_sig_buff)
{
fclose( png_file );
eprintf("malloc() fails!");
return(NULL);
}
if( fread(png_sig_buff, 1, _png_sig_num_bytes, png_file) != _png_sig_num_bytes
|| ferror(png_file) )
{
fclose( png_file );
free( png_sig_buff );
eprintf("fread() fails!");
return(NULL);
}
if( png_sig_cmp( png_sig_buff, 0, _png_sig_num_bytes) )
{
fclose( png_file );
free( png_sig_buff );
eprintf("png_sig_cmp() fails!");
return(NULL);
}
free( png_sig_buff );
png_structp _png_read;
_png_read = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if(!_png_read)
{
fclose( png_file );
eprintf("png_create_read_struct() fails!");
return(NULL);
}
png_infop _info;
_info = png_create_info_struct( _png_read );
if(!_info)
{
fclose( png_file );
eprintf("png_create_info_struct() fails!");
return(NULL);
}
int ret = setjmp(_png_read->jmpbuf);
if( ret )
{
png_destroy_read_struct( &_png_read, &_info, (png_infopp)NULL );
fclose( png_file );
eprintf("setjmp() fails! (%i)", ret);
return(NULL);
}
png_init_io( _png_read, png_file );
png_set_sig_bytes( _png_read, _png_sig_num_bytes );
png_read_info( _png_read, _info );
if(_info->bit_depth == 16)
png_set_strip_16(_png_read);
if(_info->color_type == PNG_COLOR_TYPE_GRAY && _info->bit_depth < 8)
png_set_expand(_png_read);
if(_info->color_type == PNG_COLOR_TYPE_PALETTE && _info->bit_depth < 8)
png_set_packing(_png_read);
if(_info->color_type == PNG_COLOR_TYPE_PALETTE )
png_set_expand(_png_read);
if(_info->color_type != PNG_COLOR_TYPE_PALETTE && (_info->valid & PNG_INFO_tRNS))
png_set_expand(_png_read);
if(_info->bit_depth < 8)
png_set_packing(_png_read);
if(_info->color_type == PNG_COLOR_TYPE_GRAY || _info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(_png_read);
int _n_of_passes;
_n_of_passes = png_set_interlace_handling(_png_read);
// _n_of_passes = 1;
png_read_update_info(_png_read, _info);
uint32 w, h;
w = _info->width;
h = _info->height;
png_bytepp row_pointers = malloc( sizeof(png_bytep)*_info->height );
if( NULL == row_pointers )
{
png_destroy_read_struct( &_png_read, &_info, (png_infopp)NULL );
fclose( png_file );
eprintf("malloc() fails!");
return(NULL);
}
png_uint_32 row_bytes = png_get_rowbytes( _png_read, _info );
for( unsigned int row = 0; row < _info->height; row++ )
if( NULL == (row_pointers[row] = malloc( sizeof(png_byte)*row_bytes )) )
{
for(unsigned tmp = 0; tmp < row; tmp++)
free(row_pointers[tmp]);
free(row_pointers);
png_destroy_read_struct( &_png_read, &_info, (png_infopp)NULL );
fclose( png_file );
eprintf("malloc() fails (%u)!",row);
return(NULL);
}
for( int pass = 1; pass <= _n_of_passes; pass++ )
png_read_rows(_png_read, row_pointers, NULL, _info->height);
PFrameBuff fbuff = malloc(sizeof(TFrameBuff));
if( NULL == fbuff )
{
png_read_end( _png_read, _info );
for( unsigned int row = 0; row < _info->height; row++ )
free( row_pointers[row] );
free( row_pointers );
png_destroy_read_struct( &_png_read, &_info, (png_infopp)NULL );
fclose( png_file );
eprintf("malloc() fails!");
return(NULL);
}
fbuff->w = w;
fbuff->h = h;
fbuff->buff = malloc(sizeof(TPixel)*w*h);
if( NULL == fbuff->buff )
{
png_read_end( _png_read, _info );
free(fbuff);
for( unsigned int row = 0; row < _info->height; row++ )
free( row_pointers[row] );
free( row_pointers );
png_destroy_read_struct( &_png_read, &_info, (png_infopp)NULL );
fclose( png_file );
eprintf("malloc() fails!");
return(NULL);
}
for( unsigned int row = 0, pixel = 0; row < _info->height; row++ )
{
for( unsigned int byte_in_row = 0; byte_in_row + (_info->channels-1) < row_bytes;
byte_in_row += _info->channels )
{
fbuff->buff[pixel].r = row_pointers[row][byte_in_row];
fbuff->buff[pixel].g = row_pointers[row][byte_in_row + 1];
fbuff->buff[pixel].b = row_pointers[row][byte_in_row + 2];
pixel += 1; // next pixel in framebuffer
}
}
png_read_end( _png_read, _info );
for( unsigned int row = 0; row < _info->height; row++ )
free( row_pointers[row] );
free( row_pointers );
fclose(png_file);
png_destroy_read_struct( &_png_read, &_info, (png_infopp)NULL );
return(fbuff);
}
int savepng(char *fname, PFrameBuff fbuff)
{
png_structp _png_read;
png_infop _info;
_png_read = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!_png_read)
{
eprintf("png_create_read_struct() fails!");
return(-1);
}
_info = png_create_info_struct( _png_read );
if(!_info)
{
eprintf("png_create_info_struct() fails!");
return(-1);
}
_info->height = fbuff->h;
_info->width = fbuff->w;
_info->channels = 3;
_info->rowbytes = _info->channels*fbuff->w;
_info->color_type = PNG_COLOR_TYPE_RGB;
_info->bit_depth = 8;
_info->interlace_type = PNG_INTERLACE_NONE;
_info->filter_type = PNG_FILTER_TYPE_BASE;
_info->compression_type = PNG_COMPRESSION_TYPE_BASE;
_info->pixel_depth = 8;
_info->srgb_intent = 0;
int _n_of_passes = 1;
FILE* png_file;
if( NULL == (png_file = fopen(fname, "wb")) )
{
eprintf("fopen() fails!");
return(-1);
}
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if( NULL == png_ptr )
{
fclose(png_file);
eprintf("png_create_write_struct() fails!");
return(-1);
}
if ( setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, NULL);
fclose( png_file );
eprintf("setjmp(png_jmpbuf()) fails!");
return(-1);
}
png_init_io(png_ptr, png_file);
png_write_info( png_ptr, _info );
png_bytepp row_pointers = malloc( sizeof(png_bytep)*_info->height );
if( NULL == row_pointers )
{
png_destroy_write_struct(&png_ptr, NULL);
fclose( png_file );
eprintf("malloc() fails!");
return(-1);
}
png_uint_32 row_bytes = _info->channels*_info->width;
for( unsigned int row = 0; row < _info->height; row++ )
if( NULL == (row_pointers[row] = malloc( sizeof(png_byte)*row_bytes )) )
{
for(unsigned tmp=0; tmp<row; tmp++)
free(row_pointers[tmp]);
free(row_pointers);
png_destroy_write_struct(&png_ptr, NULL);
fclose( png_file );
eprintf("malloc() fails!");
return(-1);
}
for( unsigned int row = 0, pixel = 0; row < _info->height; row++)
{
for( unsigned int byte_in_row = 0; byte_in_row + (_info->channels-1) < row_bytes;
byte_in_row += _info->channels)
{
row_pointers[row][byte_in_row] = fbuff->buff[pixel].r;
row_pointers[row][byte_in_row + 1] = fbuff->buff[pixel].g;
row_pointers[row][byte_in_row + 2] = fbuff->buff[pixel].b;
pixel += 1; // next pixel in framebuffer
}
}
for( int pass = 1; pass <= _n_of_passes; pass++ )
png_write_rows(png_ptr, row_pointers, _info->height);
png_write_end(png_ptr, _info );
png_destroy_write_struct( &png_ptr, NULL );
for( unsigned int row = 0; row < _info->height; row++ )
free(row_pointers[row]);
free(row_pointers);
fclose(png_file);
png_destroy_read_struct(&_png_read, &_info, (png_infopp)NULL );
return(0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -