$OpenBSD: patch-bitmap_bmpng_c,v 1.3 2011/07/08 20:36:09 naddy Exp $

Fix build with png-1.5.

--- bitmap/bmpng.c.orig	Wed Jan 26 23:16:11 2005
+++ bitmap/bmpng.c	Tue Jul  5 23:09:18 2011
@@ -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_info *		pngi,
 
 	    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_info *		pngi,
 
 	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 *		pngi,
     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 *		pngi,
 	}
 
     png_start_read_image( png );
-    /*
-    png_read_update_info( png, pngi );
-    */
 
     buffer= (unsigned char *)malloc( bd->bdBufferLength );
     if  ( ! buffer )
@@ -238,9 +248,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;
 	}
@@ -283,45 +293,45 @@ int bmCanWritePngFile( const BitmapDescription *	bd,
 /*									*/
 /************************************************************************/
 
-static int bpPngiFromBitmap(	png_info *			pngi,
+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;
 	}
 
@@ -331,41 +341,48 @@ static int bpPngiFromBitmap(	png_info *			pngi,
 
 	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:
@@ -373,7 +390,13 @@ static int bpPngiFromBitmap(	png_info *			pngi,
 	    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;
     }
@@ -397,8 +420,8 @@ static void bmPngWriteContents(	png_structp			png,
 	    }
 	}
 
-    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;
@@ -433,9 +456,9 @@ static void bmPngWriteContents(	png_structp			png,
 	    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;
@@ -455,10 +478,6 @@ static void bmPngWriteContents(	png_structp			png,
 
     png_write_end( png, pngi );
 
-    if  ( bd->bdColorEncoding == BMcoRGB8PALETTE	&&
-	  pngi->palette					)
-	{ free( pngi->palette );	}
-
     if  ( scratch )
 	{ free( scratch );	}
 
@@ -513,46 +532,49 @@ int bmPngWritePng(		const BitmapDescription *	bd,
 				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( pngip, bd ) )
+    if  ( bpPngiFromBitmap( pngp, pngip, &palette, bd ) )
 	{
 	LDEB(bd->bdColorEncoding);
 	png_destroy_write_struct( &pngp, &pngip );
 	return -1;
 	}
+    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;
     }
