Problem writing PNG-Files

Hello list,

I’ve experienced problems writing PNG-Files with SDL and first thought
this was a libpng-Bug. The responses on the mailing list directed me to
SDL, however, and without knowing much about how the files are being
accessed (I just took the code snipped from someone else) I think this
might be the right place now. I’ll copy my message (the one I originally
posted on the libpng-list) here now, hoping to find some help.

Thank you,
Johannes

=== My other message following ===

Hello list,

I’ve been reading here for a while and trying to solve the problem I
have on my own - no luck. So I’m trying here, maybe someone can help me.

I’m trying to save files to PNG format (using libpng) from within SDL
(and the appropriate SDL_Surface structure). Yet there seems to be some
error when writing the files: they do not get closed! Therefore, many
problems are associated with this (they are not ‘complete’ until the
program ends, cannot immediately be read from the program and so on).

The closing of the file should be done by the png_write_end() function
if I’m not completely mistaken… this function is being called, yet:
files are not complete.

Please have a look at the code. It can be found at

http://www.johannes-bauer.com/PngSave.c

Thank you very much,
Greetings,
Johannes

Johannes Bauer wrote:

Hello list,

I’ve experienced problems writing PNG-Files with SDL and first thought
this was a libpng-Bug. The responses on the mailing list directed me
to SDL, however, and without knowing much about how the files are
being accessed (I just took the code snipped from someone else) I
think this might be the right place now. I’ll copy my message (the one
I originally posted on the libpng-list) here now, hoping to find some
help.

Thank you,
Johannes

Don’t you have a main() function in your program ? How am I supposed to
use it to cause trouble ?

Stephane

Hi,

I’ve looked your file and I have looked an old PNG_Save of mine and in
your code, you affect value to infop with png_set_IHDR and with my
working example, I affect direct values

Murlock

int Img_Save_Png( char name, unsigned char buffer,
int tx, int ty, int type_img,
int nb_col, Mik_Img_RVB *palette )
{
FILE *file=fopen(name,“wb”);
png_structp write_png;
png_infop info_ptr;
unsigned char **row_pointers=NULL; // a modifier pour etre en
// conformite avec libpng
int i=0;

if (!file)
	return 0;

write_png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
    NULL, NULL, NULL);

 info_ptr = png_create_info_struct(write_png);

 png_init_io(write_png, file);

 info_ptr->width=tx;
 info_ptr->height=ty;
 info_ptr->rowbytes=tx;
 info_ptr->bit_depth=8;
 info_ptr->interlace_type=0;
info_ptr->num_palette=0;
info_ptr->palette=NULL;
info_ptr->valid=0;


 switch( type_img )
 {
 	case MIK_RGB:
 		info_ptr->rowbytes *= 3;
	    info_ptr->sig_bit.red=8;
	    info_ptr->sig_bit.green=8;
	    info_ptr->sig_bit.blue=8;
 		info_ptr->color_type=PNG_COLOR_TYPE_RGB;
 		break;
 	case MIK_GRAY:
		info_ptr->sig_bit.gray=8;
 		info_ptr->color_type=PNG_COLOR_TYPE_GRAY;
 		break;
 	case MIK_PALETTE:
		info_ptr->valid=PNG_INFO_PLTE;    	
		info_ptr->num_palette=nb_col;
 		info_ptr->color_type=PNG_COLOR_TYPE_PALETTE;
 		info_ptr->palette=(png_color*) malloc(nb_col*sizeof(png_color));
 		for(i=0; i<nb_col; i++ )
 		{
 			info_ptr->palette[i].red=palette[i].r;
 			info_ptr->palette[i].green=palette[i].v;
 			info_ptr->palette[i].blue=palette[i].b;
 		}
 		break;
 }

 png_write_info(write_png, info_ptr);

/*
	calcul de row_pointers
*/
row_pointers=(unsigned char**) malloc( info_ptr->height*sizeof(unsigned 

char*) );
row_pointers[0]=buffer;

for(i=1; i<info_ptr->height; i++ )
	row_pointers[i] = row_pointers[i-1] + info_ptr->rowbytes;

 png_write_image(write_png, row_pointers);

 png_write_end(write_png, info_ptr);

if ( info_ptr ) free( info_ptr->palette );
free( row_pointers );
 png_destroy_write_struct(&write_png, &info_ptr);

return MIK_IMG_OK;

}

Stephane Marchesin wrote:

Don’t you have a main() function in your program ? How am I supposed to
use it to cause trouble ?

I’ve updated the file, it now is compilable.

Try to run it first with the sleep() statement commented out, it will
work just fine, because the program exits.

Then try to run it with sleep() in there and open the image while the
program is still running. This will fail, because the PNG-file is
incomplete.

Thank you for your help,
Greetings
Joe

Murlock wrote:

I’ve looked your file and I have looked an old PNG_Save of mine and in
your code, you affect value to infop with png_set_IHDR and with my
working example, I affect direct values

Thanks for your code, I’ll try it out and post the results!

Greetings
Joe

I think the problem is caused by the following line:

#define SDL_SavePNG(surface, file) IMG_SavePNG_RW(surface,
SDL_RWFromFile(file, “wb”))

The SDL_RWops structure created by SDL_RWFromFile here is never closed
or freed, causing the file not to be closed.

-Willem JanOn Tue, 2004-07-06 at 12:41, Johannes Bauer wrote:

Hello list,

I’ve experienced problems writing PNG-Files with SDL and first thought
this was a libpng-Bug. The responses on the mailing list directed me to
SDL, however, and without knowing much about how the files are being
accessed (I just took the code snipped from someone else) I think this
might be the right place now. I’ll copy my message (the one I originally
posted on the libpng-list) here now, hoping to find some help.

Willem Jan Palenstijn wrote:

I think the problem is caused by the following line:

#define SDL_SavePNG(surface, file) IMG_SavePNG_RW(surface,
SDL_RWFromFile(file, “wb”))

The SDL_RWops structure created by SDL_RWFromFile here is never closed
or freed, causing the file not to be closed.

Yes, that’s it! Thank you very, very much!

Greetings,
Joe