@@ -292,6 +292,131 @@ static int really_save_png(PACKFILE *fp, BITMAP *bmp, AL_CONST RGB *pal)
292
292
return -1 ;
293
293
}
294
294
295
+ /* save_memory_png:
296
+ * Writes a non-interlaced, no-frills PNG, taking the usual save_xyz
297
+ * parameters. Returns non-zero on error.
298
+ */
299
+ static int save_memory_png (void * buffer , BITMAP * bmp , AL_CONST RGB * pal )
300
+ {
301
+ jmp_buf jmpbuf ;
302
+ png_structp png_ptr = NULL ;
303
+ png_infop info_ptr = NULL ;
304
+ int depth ;
305
+ int colour_type ;
306
+
307
+ depth = bitmap_color_depth (bmp );
308
+ if (depth == 8 && !pal )
309
+ return -1 ;
310
+
311
+ /* Create and initialize the png_struct with the
312
+ * desired error handler functions.
313
+ */
314
+ png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING ,
315
+ (void * )NULL , NULL , NULL );
316
+ if (!png_ptr )
317
+ goto Error ;
318
+
319
+ /* Allocate/initialize the image information data. */
320
+ info_ptr = png_create_info_struct (png_ptr );
321
+ if (!info_ptr )
322
+ goto Error ;
323
+
324
+ /* Set error handling. */
325
+ if (setjmp (jmpbuf )) {
326
+ /* If we get here, we had a problem reading the file. */
327
+ goto Error ;
328
+ }
329
+ png_set_error_fn (png_ptr , jmpbuf , user_error_fn , NULL );
330
+
331
+ /* Use memory routines. */
332
+ png_set_write_fn (png_ptr , buffer , NULL , NULL );
333
+
334
+ /* Set the image information here. Width and height are up to 2^31,
335
+ * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
336
+ * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
337
+ * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
338
+ * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
339
+ * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
340
+ * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE.
341
+ */
342
+ if (depth == 8 )
343
+ colour_type = PNG_COLOR_TYPE_PALETTE ;
344
+ else if (depth == 32 )
345
+ colour_type = PNG_COLOR_TYPE_RGB_ALPHA ;
346
+ else
347
+ colour_type = PNG_COLOR_TYPE_RGB ;
348
+
349
+ /* Set compression level. */
350
+ png_set_compression_level (png_ptr , _png_compression_level );
351
+
352
+ png_set_IHDR (png_ptr , info_ptr , bmp -> w , bmp -> h , 8 , colour_type ,
353
+ PNG_INTERLACE_NONE , PNG_COMPRESSION_TYPE_BASE ,
354
+ PNG_FILTER_TYPE_BASE );
355
+
356
+ /* Set the palette if there is one. Required for indexed-color images. */
357
+ if (colour_type == PNG_COLOR_TYPE_PALETTE ) {
358
+ png_color palette [256 ];
359
+ int i ;
360
+
361
+ for (i = 0 ; i < 256 ; i ++ ) {
362
+ palette [i ].red = pal [i ].r ; /* 64 -> 256 */
363
+ palette [i ].green = pal [i ].g ;
364
+ palette [i ].blue = pal [i ].b ;
365
+ }
366
+
367
+ /* Set palette colors. */
368
+ png_set_PLTE (png_ptr , info_ptr , palette , 256 );
369
+ }
370
+
371
+ /* Optionally write comments into the image ... Nah. */
372
+
373
+ /* Write the file header information. */
374
+ png_write_info (png_ptr , info_ptr );
375
+
376
+ /* Once we write out the header, the compression type on the text
377
+ * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
378
+ * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
379
+ * at the end.
380
+ */
381
+
382
+ /* Save the data. */
383
+ switch (depth ) {
384
+ case 8 :
385
+ if (!save_indexed (png_ptr , bmp ))
386
+ goto Error ;
387
+ break ;
388
+ case 15 :
389
+ case 16 :
390
+ case 24 :
391
+ if (!save_rgb (png_ptr , bmp ))
392
+ goto Error ;
393
+ break ;
394
+ case 32 :
395
+ if (!save_rgba (png_ptr , bmp ))
396
+ goto Error ;
397
+ break ;
398
+ default :
399
+ ASSERT (FALSE);
400
+ goto Error ;
401
+ }
402
+
403
+ png_write_end (png_ptr , info_ptr );
404
+
405
+ png_destroy_write_struct (& png_ptr , & info_ptr );
406
+
407
+ return 0 ;
408
+
409
+ Error :
410
+
411
+ if (png_ptr ) {
412
+ if (info_ptr )
413
+ png_destroy_write_struct (& png_ptr , & info_ptr );
414
+ else
415
+ png_destroy_write_struct (& png_ptr , NULL );
416
+ }
417
+
418
+ return -1 ;
419
+ }
295
420
296
421
int save_png (AL_CONST char * filename , BITMAP * bmp , AL_CONST RGB * pal )
297
422
{
0 commit comments