@@ -140,16 +140,46 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
140
140
char * file_name ;
141
141
png_bytep image_ptr ;
142
142
int width , height , channels ;
143
- ckarg (5 );
143
+ pointer bg ;
144
+ ckarg2 (5 ,6 );
144
145
if (isstring (argv [0 ])) file_name = (char * )(argv [0 ]-> c .str .chars );
145
146
else error (E_NOSTRING );
146
147
width = ckintval (argv [1 ]);
147
148
height = ckintval (argv [2 ]);
148
149
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
+
150
179
FILE * fp = fopen (file_name , "wb" );
151
180
if (!fp ) {
152
181
error (E_OPENFILE );
182
+ if (bg != NIL ) {free (image_ptr );}
153
183
return (NIL );
154
184
}
155
185
@@ -161,12 +191,13 @@ pointer PNG_WRITE_IMAGE(register context *ctx, int n, register pointer *argv)
161
191
if (setjmp (png_jmpbuf (png_ptr ))) {
162
192
png_destroy_write_struct (& png_ptr , & info_ptr );
163
193
fclose (fp );
194
+ if (bg != NIL ) {free (image_ptr );}
164
195
error (E_EOF );
165
196
return (NIL );
166
197
}
167
198
168
199
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
170
201
PNG_INTERLACE_NONE , PNG_COMPRESSION_TYPE_BASE , PNG_FILTER_TYPE_BASE );
171
202
png_bytep * row_pointers = (png_bytep * ) malloc (sizeof (png_bytep ) * height );
172
203
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)
183
214
184
215
fclose (fp );
185
216
217
+ if (bg != NIL ) {free (image_ptr );}
186
218
return (T );
187
219
}
188
220
0 commit comments