@@ -766,15 +766,61 @@ static int IMG_SavePNG_RW_miniz(SDL_Surface *surface, SDL_RWops *dst)
766
766
return IMG_SetError ("Passed NULL dst" );
767
767
}
768
768
769
- if (surface -> format -> format == png_format ) {
770
- png = tdefl_write_image_to_png_file_in_memory (surface -> pixels , surface -> w , surface -> h , surface -> format -> BytesPerPixel , surface -> pitch , & size );
771
- } else {
772
- SDL_Surface * cvt = SDL_ConvertSurfaceFormat (surface , png_format , 0 );
773
- if (cvt ) {
774
- png = tdefl_write_image_to_png_file_in_memory (cvt -> pixels , cvt -> w , cvt -> h , cvt -> format -> BytesPerPixel , cvt -> pitch , & size );
775
- SDL_FreeSurface (cvt );
769
+ /* miniz only supports RGB and RGBA, it does not support palette.
770
+ * So we:
771
+ * - pick RGBA if surface has per-pixel alpha or if a palette entry has alpha.
772
+ * - pick RGB in all other cases.
773
+ * Just like the libpng implementation, global alpha and colorkey gets
774
+ * ignored here for consistency.
775
+ */
776
+ int do_rgba = SDL_ISPIXELFORMAT_ALPHA (surface -> format -> format );
777
+ if (!do_rgba && SDL_ISPIXELFORMAT_INDEXED (surface -> format -> format )) {
778
+ SDL_Palette * pal = surface -> format -> palette ;
779
+ if (pal ) {
780
+ for (int i = 0 ; i < pal -> ncolors ; i ++ ) {
781
+ if (pal -> colors [i ].a != 255 ) {
782
+ do_rgba = 1 ;
783
+ break ;
784
+ }
785
+ }
776
786
}
777
787
}
788
+
789
+ Uint32 cvt_fmt = do_rgba ? png_format : SDL_PIXELFORMAT_RGB24 ;
790
+ SDL_Surface * cvt = NULL ;
791
+ Uint8 * pixels = surface -> pixels ;
792
+ int bpp = surface -> format -> BytesPerPixel ;
793
+ int pitch = surface -> pitch ;
794
+ if (surface -> format -> format != cvt_fmt ) {
795
+ cvt = SDL_ConvertSurfaceFormat (surface , cvt_fmt , 0 );
796
+ pixels = cvt ? cvt -> pixels : NULL ;
797
+ bpp = cvt ? cvt -> format -> BytesPerPixel : 0 ;
798
+ pitch = cvt ? cvt -> pitch : 0 ;
799
+ }
800
+ if (pixels ) {
801
+ int w = surface -> w ;
802
+ int h = surface -> h ;
803
+ int tightened_pitch = bpp * w ;
804
+ if (pitch != tightened_pitch ) {
805
+ /* There is extra padding that we need to get rid of, if we don't
806
+ * do this the miniz backend is going to generate corrupt PNGs */
807
+ Uint8 * tightened_pixels = SDL_malloc (tightened_pitch * h );
808
+ if (tightened_pixels ) {
809
+ for (int y = 0 ; y < h ; y ++ ) {
810
+ memcpy (tightened_pixels + y * tightened_pitch , pixels + y * pitch , tightened_pitch );
811
+ }
812
+ png = tdefl_write_image_to_png_file_in_memory (tightened_pixels , w , h , bpp , tightened_pitch , & size );
813
+ SDL_free (tightened_pixels );
814
+ }
815
+ }
816
+ else {
817
+ png = tdefl_write_image_to_png_file_in_memory (pixels , w , h , bpp , pitch , & size );
818
+ }
819
+ }
820
+ if (cvt ) {
821
+ SDL_FreeSurface (cvt );
822
+ }
823
+
778
824
if (png ) {
779
825
if (SDL_RWwrite (dst , png , size , 1 )) {
780
826
result = 0 ;
0 commit comments