@@ -115,6 +115,8 @@ static struct {
115
115
jmp_buf * (* png_set_longjmp_fn ) (png_structrp , png_longjmp_ptr , size_t );
116
116
#endif
117
117
#endif
118
+ int (* png_image_begin_read_from_memory ) (png_imagep image , png_const_voidp memory , size_t size );
119
+ int (* png_image_finish_read ) (png_imagep image , png_const_colorp background , void * buffer , png_int_32 row_stride , void * colormap );
118
120
#if SDL_IMAGE_SAVE_PNG
119
121
png_structp (* png_create_write_struct ) (png_const_charp user_png_ver , png_voidp error_ptr , png_error_ptr error_fn , png_error_ptr warn_fn );
120
122
void (* png_destroy_write_struct ) (png_structpp png_ptr_ptr , png_infopp info_ptr_ptr );
@@ -170,6 +172,8 @@ int IMG_InitPNG()
170
172
FUNCTION_LOADER (png_set_longjmp_fn , jmp_buf * (* ) (png_structrp , png_longjmp_ptr , size_t ))
171
173
#endif
172
174
#endif
175
+ FUNCTION_LOADER (png_image_begin_read_from_memory , int (* ) (png_imagep image , png_const_voidp memory , size_t size ))
176
+ FUNCTION_LOADER (png_image_finish_read , int (* ) (png_imagep image , png_const_colorp background , void * buffer , png_int_32 row_stride , void * colormap ))
173
177
#if SDL_IMAGE_SAVE_PNG
174
178
FUNCTION_LOADER (png_create_write_struct , png_structp (* ) (png_const_charp user_png_ver , png_voidp error_ptr , png_error_ptr error_fn , png_error_ptr warn_fn ))
175
179
FUNCTION_LOADER (png_destroy_write_struct , void (* ) (png_structpp png_ptr_ptr , png_infopp info_ptr_ptr ))
@@ -224,6 +228,118 @@ int IMG_isPNG(SDL_RWops *src)
224
228
return (is_PNG );
225
229
}
226
230
231
+ SDL_Surface * IMG_LoadPNG_RW (SDL_RWops * src ) {
232
+ png_image image ;
233
+ Sint64 src_length ;
234
+ Uint8 * raw_image_buffer ;
235
+ SDL_Surface * surface ;
236
+ SDL_Palette * palette = NULL ;
237
+ void * colormap = NULL ;
238
+ Uint32 pixelformat ;
239
+
240
+ if ( (IMG_Init (IMG_INIT_PNG ) & IMG_INIT_PNG ) == 0 ) {
241
+ return NULL ;
242
+ }
243
+
244
+ /* This function uses libpng's "Simplified API" to read a PNG.
245
+ * See https://github.com/pnggroup/libpng/blob/libpng16/libpng-manual.txt
246
+ * And https://github.com/pnggroup/libpng/blob/libpng16/contrib/examples/pngtopng.c
247
+ * For information about this and example usage, respectively. */
248
+
249
+ /* Only the image structure version number needs to be set. */
250
+ SDL_memset (& image , 0 , sizeof (image ));
251
+ image .version = PNG_IMAGE_VERSION ;
252
+
253
+ src_length = SDL_RWsize (src ); //todo error check
254
+
255
+ printf ("src_length=%i\n" , src_length );
256
+
257
+ raw_image_buffer = SDL_malloc (src_length ); // ec
258
+ SDL_RWseek (src , RW_SEEK_SET , 0 ); // ec
259
+ int objects_read = SDL_RWread (src , raw_image_buffer , 1 , src_length ); // ec
260
+
261
+ printf ("objects_read=%i\n" , objects_read );
262
+
263
+ if (lib .png_image_begin_read_from_memory (& image , raw_image_buffer , src_length )) {
264
+ /* If the image is natively encoded with a colormap, set the format to
265
+ /* PNG_FORMAT_RGBA_COLORMAP. This allows libpng to directly map into the
266
+ /* colors of an allocated SDL_Palette. Libpng handles mapping the native
267
+ /* colormap format into this consistent format. */
268
+
269
+ if (image .format & PNG_FORMAT_FLAG_COLORMAP ) {
270
+ image .format = PNG_FORMAT_RGBA_COLORMAP ;
271
+ pixelformat = SDL_PIXELFORMAT_INDEX8 ;
272
+
273
+ palette = SDL_AllocPalette (image .colormap_entries );
274
+ colormap = palette -> colors ;
275
+ SDL_assert (PNG_IMAGE_COLORMAP_SIZE (image ) == palette -> ncolors * 4 );
276
+ }
277
+
278
+ /* Otherwise, maps the existing PNG format to a SDL pixelformatenum.
279
+ /* If no mapping is found it falls down to a default, libpng handles
280
+ /* conversion. */
281
+ else {
282
+ switch (image .format ) {
283
+ case PNG_FORMAT_RGBA :
284
+ pixelformat = SDL_PIXELFORMAT_RGBA32 ;
285
+ break ;
286
+ case PNG_FORMAT_ARGB :
287
+ pixelformat = SDL_PIXELFORMAT_ARGB32 ;
288
+ break ;
289
+
290
+ /* Lets have grey alpha -> BGRA */
291
+ case PNG_FORMAT_GA :
292
+ image .format = PNG_FORMAT_BGRA ;
293
+ case PNG_FORMAT_BGRA :
294
+ pixelformat = SDL_PIXELFORMAT_BGRA32 ;
295
+ break ;
296
+
297
+ case PNG_FORMAT_ABGR :
298
+ pixelformat = SDL_PIXELFORMAT_ABGR32 ;
299
+ break ;
300
+
301
+ /* Lets have gray (no alpha) -> RGB */
302
+ case PNG_FORMAT_GRAY :
303
+ image .format = PNG_FORMAT_RGB ;
304
+ case PNG_FORMAT_RGB :
305
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
306
+ pixelformat = SDL_PIXELFORMAT_BGR24 ;
307
+ #else
308
+ pixelformat = SDL_PIXELFORMAT_RGB24 ;
309
+ #endif
310
+ break ;
311
+ case PNG_FORMAT_BGR :
312
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
313
+ pixelformat = SDL_PIXELFORMAT_RGB24 ;
314
+ #else
315
+ pixelformat = SDL_PIXELFORMAT_BGR24 ;
316
+ #endif
317
+ break ;
318
+
319
+ /* If it's another format, lets use BGRA by default */
320
+ default :
321
+ image .format = PNG_FORMAT_BGRA ;
322
+ pixelformat = SDL_PIXELFORMAT_BGRA32 ;
323
+ }
324
+ }
325
+
326
+ surface = SDL_CreateRGBSurfaceWithFormat (0 , image .width , image .height , 0 , pixelformat );
327
+
328
+ if (palette != NULL ) {
329
+ SDL_SetSurfacePalette (surface , palette );
330
+ }
331
+
332
+ lib .png_image_finish_read (& image , NULL , surface -> pixels , surface -> pitch , colormap );
333
+
334
+ return surface ;
335
+ }
336
+
337
+ printf ("image.message=%s\n" , image .message );
338
+
339
+ SDL_SetError ("FAILED" );
340
+ return NULL ;
341
+ }
342
+
227
343
/* Load a PNG type image from an SDL datasource */
228
344
static void png_read_data (png_structp ctx , png_bytep area , png_size_t size )
229
345
{
@@ -232,7 +348,7 @@ static void png_read_data(png_structp ctx, png_bytep area, png_size_t size)
232
348
src = (SDL_RWops * )lib .png_get_io_ptr (ctx );
233
349
SDL_RWread (src , area , size , 1 );
234
350
}
235
- SDL_Surface * IMG_LoadPNG_RW (SDL_RWops * src )
351
+ SDL_Surface * IMG_LoadPNG_RW2 (SDL_RWops * src )
236
352
{
237
353
Sint64 start ;
238
354
const char * error ;
@@ -315,9 +431,13 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
315
431
*/
316
432
lib .png_set_packing (png_ptr );
317
433
434
+ printf ("COLOR TYPE = %i\n" , color_type );
435
+
318
436
/* scale greyscale values to the range 0..255 */
319
- if (color_type == PNG_COLOR_TYPE_GRAY )
437
+ if (color_type == PNG_COLOR_TYPE_GRAY ) {
438
+ printf ("COLOR TYPE GRAY\n" );
320
439
lib .png_set_expand (png_ptr );
440
+ }
321
441
322
442
/* For images with a single "transparent colour", set colour key;
323
443
if more than one index has transparency, or if partially transparent
@@ -327,7 +447,9 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
327
447
int num_trans ;
328
448
Uint8 * trans ;
329
449
lib .png_get_tRNS (png_ptr , info_ptr , & trans , & num_trans , & transv );
450
+ printf ("here in the club\n" );
330
451
if (color_type == PNG_COLOR_TYPE_PALETTE ) {
452
+ printf ("wowowowo\n" );
331
453
/* Check if all tRNS entries are opaque except one */
332
454
int j , t = -1 ;
333
455
for (j = 0 ; j < num_trans ; j ++ ) {
@@ -352,6 +474,8 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
352
474
}
353
475
}
354
476
477
+ printf ("done with that stuff\n" );
478
+
355
479
if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
356
480
lib .png_set_gray_to_rgb (png_ptr );
357
481
@@ -363,6 +487,8 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
363
487
/* Allocate the SDL surface to hold the image */
364
488
num_channels = lib .png_get_channels (png_ptr , info_ptr );
365
489
490
+ printf ("bit_depth = %i, num_channels = %i\n" , bit_depth , num_channels );
491
+
366
492
format = SDL_PIXELFORMAT_UNKNOWN ;
367
493
if (num_channels == 3 ) {
368
494
format = SDL_PIXELFORMAT_RGB24 ;
@@ -402,6 +528,13 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
402
528
}
403
529
404
530
if (ckey != -1 ) {
531
+ if (color_type == PNG_COLOR_TYPE_GRAY ) {
532
+ /* FIXME: Should these be truncated or shifted down? */
533
+ ckey = SDL_MapRGB (surface -> format ,
534
+ (Uint8 )transv -> gray ,
535
+ (Uint8 )transv -> gray ,
536
+ (Uint8 )transv -> gray );
537
+ }
405
538
if (color_type != PNG_COLOR_TYPE_PALETTE ) {
406
539
/* FIXME: Should these be truncated or shifted down? */
407
540
ckey = SDL_MapRGB (surface -> format ,
0 commit comments