@@ -140,16 +140,46 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
140140 char * file_name ;
141141 png_bytep image_ptr ;
142142 int width , height , channels ;
143- ckarg (5 );
143+ pointer bg ;
144+ ckarg2 (5 ,6 );
144145 if (isstring (argv [0 ])) file_name = (char * )(argv [0 ]-> c .str .chars );
145146 else error (E_NOSTRING );
146147 width = ckintval (argv [1 ]);
147148 height = ckintval (argv [2 ]);
148149 channels = ckintval (argv [3 ]);
149- image_ptr = (png_bytep )(argv [4 ]-> c .str .chars );
150+
151+ if (n == 6 && argv [5 ]!= NIL ) { /* set background color */
152+ bg = argv [5 ];
153+ if (!isfltvector (bg )) error (E_NOVECTOR );
154+ if (3 != vecsize (bg )) error (E_VECSIZE );
155+ }else {
156+ bg = NIL ;
157+ }
158+
159+ if (bg == NIL ) {
160+ image_ptr = (png_bytep )(argv [4 ]-> c .str .chars );
161+ } else {
162+ int x , y ;
163+ png_byte bg_r = bg -> c .fvec .fv [0 ]* 255 , bg_g = bg -> c .fvec .fv [1 ]* 255 , bg_b = bg -> c .fvec .fv [2 ]* 255 ;
164+ image_ptr = malloc (width * height * 4 );
165+ for (y = 0 ; y < height ; y ++ ) {
166+ for (x = 0 ; x < width ; x ++ ) {
167+ png_byte r , g , b ;
168+ r = ((png_bytep )(argv [4 ]-> c .str .chars ))[(y * width + x )* 3 + 0 ];
169+ g = ((png_bytep )(argv [4 ]-> c .str .chars ))[(y * width + x )* 3 + 1 ];
170+ b = ((png_bytep )(argv [4 ]-> c .str .chars ))[(y * width + x )* 3 + 2 ];
171+ image_ptr [(y * width + x )* 4 + 0 ] = r ;
172+ image_ptr [(y * width + x )* 4 + 1 ] = g ;
173+ image_ptr [(y * width + x )* 4 + 2 ] = b ;
174+ image_ptr [(y * width + x )* 4 + 3 ] = ((r == bg_r )&& (g == bg_g )&& (b == bg_b ))?0 :255 ;
175+ }
176+ }
177+ }
178+
150179 FILE * fp = fopen (file_name , "wb" );
151180 if (!fp ) {
152181 error (E_OPENFILE );
182+ if (bg != NIL ) {free (image_ptr );}
153183 return (NIL );
154184 }
155185
@@ -161,12 +191,13 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
161191 if (setjmp (png_jmpbuf (png_ptr ))) {
162192 png_destroy_write_struct (& png_ptr , & info_ptr );
163193 fclose (fp );
194+ if (bg != NIL ) {free (image_ptr );}
164195 error (E_EOF );
165196 return (NIL );
166197 }
167198
168199 png_init_io (png_ptr , fp );
169- png_set_IHDR (png_ptr , info_ptr , width , height , 8 , PNG_COLOR_TYPE_RGB , //GRAY
200+ png_set_IHDR (png_ptr , info_ptr , width , height , 8 , ( bg == NIL )? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA , //GRAY
170201 PNG_INTERLACE_NONE , PNG_COMPRESSION_TYPE_BASE , PNG_FILTER_TYPE_BASE );
171202 png_bytep * row_pointers = (png_bytep * ) malloc (sizeof (png_bytep ) * height );
172203 int y , byte_per_scanline = png_get_rowbytes (png_ptr , info_ptr );
@@ -183,6 +214,7 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
183214
184215 fclose (fp );
185216
217+ if (bg != NIL ) {free (image_ptr );}
186218 return (T );
187219}
188220
0 commit comments