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!