SDL and libpng trouble continued

Hi,

thanks for the answers, unfortunately it still doesn’t work. My program
crashes as soon as libpng starts to write the image data.

I’ve tracked the crash location down to:

png_voidp PNGAPI
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,

png_uint_32 length)

{

png_size_t size;

size = (png_size_t)length;

if ((png_uint_32)size != length)

png_error(png_ptr,"Overflow in png_memcpy_check.");

// CRASH after the next line!

return(png_memcpy (s1, s2, size));

}

I’m using the libpng 1.25 source code on Windows XP, compiled with Visual
C++.NET, and a modified version of Chamaeleon’s function. I pass in a
SDL_Surface with a width of 900 and height of 680 pixels. Its bit depth: 8
bit. The pixel data is valid, I can save it properly as a BMP:

char WritePNG(char file, SDL_Surface Srf)
{
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 i, rowbytes;
png_bytepp row_pointers;
png_uint_32 width = Srf->w;
png_uint_32 height = Srf->h;

// Open PNG file for writting
FILE *fp = fopen(file, "wb");
if (!fp) return 4;

// Allocate basic libpng structures
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr) { fclose(fp); return 1; }

info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
    png_destroy_write_struct(&png_ptr, 0);
    fclose(fp); return 1;
}

// setjmp() must be called in every function
// that calls a PNG-reading libpng function
if (setjmp(png_ptr->jmpbuf))
{
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp); return 3;
}

png_init_io(png_ptr, fp);
// set the zlib compression level

png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
// write PNG info to structure

png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,

PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);

// !!!
// CRASH occurs after this line!
// !!!

png_write_info(png_ptr, info_ptr);

// setjmp() must be called in every function
// that calls a PNG-writing libpng function
if (setjmp(png_ptr->jmpbuf))
{
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp); return 3;
}

// Allocate pointers for each line
row_pointers = static_cast<png_bytepp>(malloc(height *

sizeof(png_bytep)));
if (!row_pointers)
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp); return 1;
}

// how many bytes in each row
rowbytes = png_get_rowbytes(png_ptr, info_ptr);

SDL_LockSurface(Srf);

// set the individual row_pointers to point at the correct offsets
for (i = 0; i < height; ++i) row_pointers[i] = (unsigned

char*)Srf->pixels + i * rowbytes;

SDL_UnlockSurface(Srf);

// now we can go ahead and just write the whole image
png_write_image(png_ptr, row_pointers);

png_write_end(png_ptr, 0);

png_destroy_write_struct(&png_ptr, &info_ptr);
free(row_pointers); fclose(fp);

return 0;

}

There’s also another problem: libpng doesn’t write to stderr :’( .

If this issue is not appropriate for this list, could anyone tell me where
to find a good png mailing list?

Any ideas how to fix both problems??
Again, many thanks in advance!

This line:
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);

sets LibPNG up for 8 bits per-per-color-channel (aka 24bit color)
You need PNG_COLOR_TYPE_PALETTE instead of PNG_COLOR_TYPE_RGB, and you’ll
need to give it the palette (using png_set_PLTE).> ----- Original Message -----

From: H. C.
To: sdl at libsdl.org
Sent: Thursday, August 14, 2003 5:43 PM
Subject: [SDL] SDL and libpng trouble continued

Hi,

thanks for the answers, unfortunately it still doesn’t work. My program
crashes as soon as libpng starts to write the image data.

I’ve tracked the crash location down to:

png_voidp PNGAPI
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,

png_uint_32 length)

{

png_size_t size;

size = (png_size_t)length;

if ((png_uint_32)size != length)

png_error(png_ptr,"Overflow in png_memcpy_check.");

// CRASH after the next line!

return(png_memcpy (s1, s2, size));

}

I’m using the libpng 1.25 source code on Windows XP, compiled with Visual
C++.NET, and a modified version of Chamaeleon’s function. I pass in a
SDL_Surface with a width of 900 and height of 680 pixels. Its bit depth: 8
bit. The pixel data is valid, I can save it properly as a BMP:

char WritePNG(char file, SDL_Surface Srf)
{
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 i, rowbytes;
png_bytepp row_pointers;
png_uint_32 width = Srf->w;
png_uint_32 height = Srf->h;

// Open PNG file for writting
FILE *fp = fopen(file, "wb");
if (!fp) return 4;

// Allocate basic libpng structures
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr) { fclose(fp); return 1; }

info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
    png_destroy_write_struct(&png_ptr, 0);
    fclose(fp); return 1;
}

// setjmp() must be called in every function
// that calls a PNG-reading libpng function
if (setjmp(png_ptr->jmpbuf))
{
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp); return 3;
}

png_init_io(png_ptr, fp);
// set the zlib compression level

png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
// write PNG info to structure

png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,

PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);

// !!!
// CRASH occurs after this line!
// !!!

png_write_info(png_ptr, info_ptr);

// setjmp() must be called in every function
// that calls a PNG-writing libpng function
if (setjmp(png_ptr->jmpbuf))
{
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp); return 3;
}

// Allocate pointers for each line
row_pointers = static_cast<png_bytepp>(malloc(height *

sizeof(png_bytep)));
if (!row_pointers)
{
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp); return 1;
}

// how many bytes in each row
rowbytes = png_get_rowbytes(png_ptr, info_ptr);

SDL_LockSurface(Srf);

// set the individual row_pointers to point at the correct offsets
for (i = 0; i < height; ++i) row_pointers[i] = (unsigned

char*)Srf->pixels + i * rowbytes;

SDL_UnlockSurface(Srf);

// now we can go ahead and just write the whole image
png_write_image(png_ptr, row_pointers);

png_write_end(png_ptr, 0);

png_destroy_write_struct(&png_ptr, &info_ptr);
free(row_pointers); fclose(fp);

return 0;

}

There’s also another problem: libpng doesn’t write to stderr :’( .

If this issue is not appropriate for this list, could anyone tell me where
to find a good png mailing list?

Any ideas how to fix both problems??
Again, many thanks in advance!