This patch is from netbsd pkgsrc ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/editors/ted/patches/ --- bitmap/bmpng.c +++ bitmap/bmpng.c @@ -20,23 +20,32 @@ /* */ /************************************************************************/ -static int bpPngiToBitmap( const png_info * pngi, +static int bpPngiToBitmap( const png_structp pngp, + png_info * pngi, BitmapDescription * bd ) { unsigned int col; + png_uint_32 res_x, res_y; + int unit_type= 0; - bd->bdPixelsWide= pngi->width; - bd->bdPixelsHigh= pngi->height; + bd->bdPixelsWide= png_get_image_width( pngp, pngi ); + bd->bdPixelsHigh= png_get_image_height( pngp, pngi ); bd->bdHasAlpha= 0; - switch( pngi->color_type ) + switch( png_get_color_type( pngp, pngi ) ) { case PNG_COLOR_TYPE_PALETTE: + { + int num_palette; + png_colorp palette; + + png_get_PLTE( pngp, pngi, &palette, &num_palette ); + bd->bdColorEncoding= BMcoRGB8PALETTE; - bd->bdColorCount= pngi->num_palette; + bd->bdColorCount= num_palette; bd->bdBitsPerSample= 8; bd->bdSamplesPerPixel= 3; - bd->bdBitsPerPixel= pngi->bit_depth; + bd->bdBitsPerPixel= png_get_bit_depth( pngp, pngi ); bd->bdRGB8Palette= (RGB8Color *) malloc( bd->bdColorCount* sizeof(RGB8Color) ); @@ -46,47 +55,51 @@ static int bpPngiToBitmap( const png_inf for ( col= 0; col < bd->bdColorCount; col++ ) { - bd->bdRGB8Palette[col].rgb8Red= pngi->palette[col].red; - bd->bdRGB8Palette[col].rgb8Green= pngi->palette[col].green; - bd->bdRGB8Palette[col].rgb8Blue= pngi->palette[col].blue; + bd->bdRGB8Palette[col].rgb8Red= palette[col].red; + bd->bdRGB8Palette[col].rgb8Green= palette[col].green; + bd->bdRGB8Palette[col].rgb8Blue= palette[col].blue; bd->bdRGB8Palette[col].rgb8Alpha= 0; } + } break; case PNG_COLOR_TYPE_RGB: bd->bdColorEncoding= BMcoRGB; - bd->bdBitsPerSample= pngi->bit_depth; - bd->bdSamplesPerPixel= pngi->channels; - bd->bdBitsPerPixel= pngi->pixel_depth; + bd->bdBitsPerSample= png_get_bit_depth( pngp, pngi ); + bd->bdSamplesPerPixel= png_get_channels( pngp, pngi ); + bd->bdBitsPerPixel= bd->bdSamplesPerPixel* bd->bdBitsPerSample; break; case PNG_COLOR_TYPE_GRAY: bd->bdColorEncoding= BMcoWHITEBLACK; - bd->bdBitsPerSample= pngi->bit_depth; - bd->bdSamplesPerPixel= pngi->channels; - bd->bdBitsPerPixel= pngi->pixel_depth; + bd->bdBitsPerSample= png_get_bit_depth( pngp, pngi ); + bd->bdSamplesPerPixel= png_get_channels( pngp, pngi ); + bd->bdBitsPerPixel= bd->bdSamplesPerPixel* bd->bdBitsPerSample; break; case PNG_COLOR_TYPE_RGB_ALPHA: bd->bdHasAlpha= 1; bd->bdColorEncoding= BMcoRGB; - bd->bdBitsPerSample= pngi->bit_depth; - bd->bdSamplesPerPixel= pngi->channels; - bd->bdBitsPerPixel= pngi->pixel_depth; + bd->bdBitsPerSample= png_get_bit_depth( pngp, pngi ); + bd->bdSamplesPerPixel= png_get_channels( pngp, pngi ); + bd->bdBitsPerPixel= bd->bdSamplesPerPixel* bd->bdBitsPerSample; break; case PNG_COLOR_TYPE_GRAY_ALPHA: bd->bdHasAlpha= 1; - LDEB(pngi->color_type); return -1; + LDEB(png_get_color_type( pngp, pngi )); return -1; default: - LDEB(pngi->color_type); return -1; + LDEB(png_get_color_type( pngp, pngi )); return -1; } - bd->bdBytesPerRow= pngi->rowbytes; + bd->bdBytesPerRow= png_get_rowbytes( pngp, pngi ); bd->bdBufferLength= bd->bdBytesPerRow* bd->bdPixelsHigh; - switch( pngi->phys_unit_type ) + if ( ! png_get_pHYs( pngp, pngi, &res_x, &res_y, &unit_type ) ) + { unit_type= PNG_RESOLUTION_UNKNOWN; } + + switch( unit_type ) { case PNG_RESOLUTION_UNKNOWN: bd->bdUnit= BMunPIXEL; @@ -96,12 +109,12 @@ static int bpPngiToBitmap( const png_inf case PNG_RESOLUTION_METER: bd->bdUnit= BMunM; - bd->bdXResolution= pngi->x_pixels_per_unit; - bd->bdYResolution= pngi->y_pixels_per_unit; + bd->bdXResolution= res_x; + bd->bdYResolution= res_y; break; default: - LDEB(pngi->phys_unit_type); + LDEB(unit_type); return -1; } @@ -119,11 +132,11 @@ static int bmPngReadContents( png_info * unsigned char * buffer; numberOfPasses= 1; - if ( pngi->interlace_type ) + if ( png_get_interlace_type( png, pngi ) ) { numberOfPasses= png_set_interlace_handling( png ); } - if ( pngi->color_type == PNG_COLOR_TYPE_RGB && - pngi->bit_depth == 16 ) + if ( png_get_color_type( png, pngi ) == PNG_COLOR_TYPE_RGB && + png_get_bit_depth( png, pngi ) == 16 ) { const unsigned short one= 1; const unsigned char * testEndian= (const unsigned char *)&one; @@ -133,9 +146,6 @@ static int bmPngReadContents( png_info * } png_start_read_image( png ); - /* - png_read_update_info( png, pngi ); - */ buffer= (unsigned char *)malloc( bd->bdBufferLength ); if ( ! buffer ) @@ -236,9 +246,9 @@ int bmPngReadPng( BitmapDescription * bd png_read_info( pngp, pngip ); - if ( bpPngiToBitmap( pngip, bd ) ) + if ( bpPngiToBitmap( pngp, pngip, bd ) ) { - LLLDEB(pngip->color_type,bd->bdColorCount,bd->bdRGB8Palette); + LLDEB(bd->bdColorCount,bd->bdRGB8Palette); png_destroy_read_struct( &pngp, &pngip, (png_infop *)0 ); return -1; } @@ -282,44 +292,43 @@ int bmCanWritePngFile( const BitmapDescr static int bpPngiFromBitmap( png_structp png, png_info * pngi, + png_colorp * pPalette, const BitmapDescription * bd ) { - png_info_init( pngi ); - pngi->width= bd->bdPixelsWide; - pngi->height= bd->bdPixelsHigh; + int bit_depth; + int color_type; + png_color_8 sig_bit; switch( bd->bdUnit ) { case BMunM: - pngi->phys_unit_type= PNG_RESOLUTION_METER; - pngi->x_pixels_per_unit= bd->bdXResolution; - pngi->y_pixels_per_unit= bd->bdYResolution; - pngi->valid |= PNG_INFO_pHYs; + png_set_pHYs( png, pngi, + bd->bdXResolution, + bd->bdYResolution, + PNG_RESOLUTION_METER); break; case BMunINCH: - pngi->phys_unit_type= PNG_RESOLUTION_METER; - pngi->x_pixels_per_unit= (int)( 39.37* bd->bdXResolution ); - pngi->y_pixels_per_unit= (int)( 39.37* bd->bdYResolution ); - pngi->valid |= PNG_INFO_pHYs; + png_set_pHYs( png, pngi, + (int)( 39.37* bd->bdXResolution ), + (int)( 39.37* bd->bdYResolution ), + PNG_RESOLUTION_METER); break; case BMunPOINT: - pngi->phys_unit_type= PNG_RESOLUTION_METER; - pngi->x_pixels_per_unit= POINTS_PER_M* bd->bdXResolution; - pngi->y_pixels_per_unit= POINTS_PER_M* bd->bdYResolution; - pngi->valid |= PNG_INFO_pHYs; + png_set_pHYs( png, pngi, + POINTS_PER_M* bd->bdXResolution, + POINTS_PER_M* bd->bdYResolution, + PNG_RESOLUTION_METER); break; case BMunPIXEL: - pngi->phys_unit_type= PNG_RESOLUTION_UNKNOWN; - pngi->x_pixels_per_unit= 1; - pngi->y_pixels_per_unit= 1; + png_set_pHYs(png, pngi, 1, 1, PNG_RESOLUTION_UNKNOWN); break; default: LDEB(bd->bdUnit); - pngi->phys_unit_type= PNG_RESOLUTION_UNKNOWN; + png_set_pHYs(png, pngi, 1, 1, PNG_RESOLUTION_UNKNOWN); break; } @@ -329,41 +338,48 @@ static int bpPngiFromBitmap( png_structp case BMcoBLACKWHITE: case BMcoWHITEBLACK: - pngi->bit_depth= bd->bdBitsPerPixel; + bit_depth= bd->bdBitsPerPixel; if ( bd->bdHasAlpha ) - { pngi->color_type= PNG_COLOR_TYPE_GRAY_ALPHA; } - else{ pngi->color_type= PNG_COLOR_TYPE_GRAY; } - pngi->sig_bit.gray= bd->bdBitsPerSample; + { color_type= PNG_COLOR_TYPE_GRAY_ALPHA; } + else{ color_type= PNG_COLOR_TYPE_GRAY; } + sig_bit.gray= bd->bdBitsPerSample; break; case BMcoRGB: - pngi->bit_depth= bd->bdBitsPerSample; + bit_depth= bd->bdBitsPerSample; if ( bd->bdHasAlpha ) - { pngi->color_type= PNG_COLOR_TYPE_RGB_ALPHA; } - else{ pngi->color_type= PNG_COLOR_TYPE_RGB; } - pngi->sig_bit.red= bd->bdBitsPerSample; - pngi->sig_bit.green= bd->bdBitsPerSample; - pngi->sig_bit.blue= bd->bdBitsPerSample; + { color_type= PNG_COLOR_TYPE_RGB_ALPHA; } + else{ color_type= PNG_COLOR_TYPE_RGB; } + sig_bit.red= bd->bdBitsPerSample; + sig_bit.green= bd->bdBitsPerSample; + sig_bit.blue= bd->bdBitsPerSample; break; case BMcoRGB8PALETTE: - pngi->bit_depth= bd->bdBitsPerPixel; - pngi->color_type= PNG_COLOR_TYPE_PALETTE; + bit_depth= bd->bdBitsPerPixel; + color_type= PNG_COLOR_TYPE_PALETTE; - pngi->valid |= PNG_INFO_PLTE; - pngi->palette= (png_color *)malloc( 256* sizeof( png_color ) ); - if ( ! pngi->palette ) - { XDEB(pngi->palette); return -1; } - pngi->num_palette= bd->bdColorCount; - pngi->sig_bit.red= bd->bdBitsPerSample; - pngi->sig_bit.green= bd->bdBitsPerSample; - pngi->sig_bit.blue= bd->bdBitsPerSample; - for ( i= 0; i < pngi->num_palette; i++ ) + if ( bd->bdColorCount > PNG_MAX_PALETTE_LENGTH ) { - pngi->palette[i].red= bd->bdRGB8Palette[i].rgb8Red; - pngi->palette[i].green= bd->bdRGB8Palette[i].rgb8Green; - pngi->palette[i].blue= bd->bdRGB8Palette[i].rgb8Blue; + LLDEB(bd->bdColorCount,PNG_MAX_PALETTE_LENGTH); + return -1; } + + *pPalette= (png_color *)malloc( PNG_MAX_PALETTE_LENGTH* + sizeof( png_color ) ); + if ( ! *pPalette ) + { XDEB(*pPalette); return -1; } + sig_bit.red= bd->bdBitsPerSample; + sig_bit.green= bd->bdBitsPerSample; + sig_bit.blue= bd->bdBitsPerSample; + for ( i= 0; i < bd->bdColorCount; i++ ) + { + (*pPalette)[i].red= bd->bdRGB8Palette[i].rgb8Red; + (*pPalette)[i].green= bd->bdRGB8Palette[i].rgb8Green; + (*pPalette)[i].blue= bd->bdRGB8Palette[i].rgb8Blue; + } + + png_set_PLTE( png, pngi, (*pPalette), bd->bdColorCount ); break; default: @@ -371,7 +387,13 @@ static int bpPngiFromBitmap( png_structp return -1; } - pngi->interlace_type= 0; + png_set_sBIT( png, pngi, &sig_bit ); + png_set_IHDR( png, pngi, + bd->bdPixelsWide, bd->bdPixelsHigh, + bit_depth, color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE ); return 0; } @@ -395,8 +417,8 @@ static void bmPngWriteContents( png_stru } } - if ( pngi->color_type == PNG_COLOR_TYPE_RGB && - bd->bdBitsPerSample == 16 ) + if ( png_get_color_type( png, pngi ) == PNG_COLOR_TYPE_RGB && + bd->bdBitsPerSample == 16 ) { const unsigned short one= 1; const unsigned char * testEndian= (const unsigned char *)&one; @@ -431,9 +453,9 @@ static void bmPngWriteContents( png_stru from= scratch; } - if ( pngi->color_type == PNG_COLOR_TYPE_RGB && - bd->bdBitsPerSample == 16 && - scratch ) + if ( png_get_color_type( png, pngi ) == PNG_COLOR_TYPE_RGB && + bd->bdBitsPerSample == 16 && + scratch ) { int col; const BmUint16 * fr= (const BmUint16 *)from; @@ -453,10 +475,6 @@ static void bmPngWriteContents( png_stru png_write_end( png, pngi ); - if ( bd->bdColorEncoding == BMcoRGB8PALETTE && - pngi->palette ) - { free( pngi->palette ); } - if ( scratch ) { free( scratch ); } @@ -510,50 +528,43 @@ int bmPngWritePng( const BitmapDescript const unsigned char * buffer, SimpleOutputStream * sos ) { + int rval= 0; png_structp pngp= (png_structp)0; png_infop pngip= (png_infop)0; + png_colorp palette= (png_colorp)0; pngp = png_create_write_struct( PNG_LIBPNG_VER_STRING, (void *)0, (png_error_ptr)0, (png_error_ptr)0 ); if ( ! pngp ) - { LDEB(1); return -1; } + { XDEB(pngp); rval= -1; goto ready; } pngip = png_create_info_struct( pngp ); if ( ! pngip ) - { - LDEB(1); - png_destroy_write_struct( &pngp, (png_infop *)0 ); - return -1; - } + { XDEB(pngip); rval= -1; goto ready; } + + /* + As the info struct is built by libpng this is not needed: + (The call will disappear from libpng in version 1.4) + png_info_init( pngi ); + */ if ( setjmp( png_jmpbuf( pngp ) ) ) - { - LDEB(1); - png_destroy_write_struct( &pngp, &pngip ); - /* Crashes: - if ( bd->bdColorEncoding == BMcoRGB8PALETTE && - pngip->palette ) - { free( pngip->palette ); } - */ - return -1; - } + { LDEB(1); rval= -1; goto ready; } png_init_io( pngp, (FILE *)0 ); png_set_write_fn( pngp, (void *)sos, bmPngWriteBytes, bmPngFlushBytes ); - if ( bpPngiFromBitmap( pngp, pngip, bd ) ) - { - LDEB(bd->bdColorEncoding); - png_destroy_write_struct( &pngp, &pngip ); - return -1; - } - - /* - png_write_info( pngp, pngip ); - */ + if ( bpPngiFromBitmap( pngp, pngip, &palette, bd ) ) + { LDEB(bd->bdColorEncoding); rval= -1; goto ready; } bmPngWriteContents( pngp, pngip, buffer, bd ); + ready: + + if ( palette ) + { free( palette ); } + png_destroy_write_struct( &pngp, &pngip ); - return 0; + + return rval; }