The R Project SVN R

Rev

Rev 51087 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 51087 Rev 55676
Line 80... Line 80...
80
__declspec(dllexport)
80
__declspec(dllexport)
81
int R_SaveAsPng(void  *d, int width, int height,
81
int R_SaveAsPng(void  *d, int width, int height,
82
		unsigned int (*gp)(void *, int, int),
82
		unsigned int (*gp)(void *, int, int),
83
		int bgr, FILE *fp, unsigned int transparent, int res)
83
		int bgr, FILE *fp, unsigned int transparent, int res)
84
{
84
{
-
 
85
    printf("transparent: %x\n", transparent);
85
    png_structp png_ptr;
86
    png_structp png_ptr;
86
    png_infop info_ptr;
87
    png_infop info_ptr;
87
    unsigned int  col, palette[256];
88
    unsigned int  col, palette[256];
88
    png_color pngpalette[256];
89
    png_color pngpalette[256];
-
 
90
    png_bytep pscanline;
89
    png_bytep pscanline, scanline = (png_bytep) calloc(3*width,sizeof(png_byte));
91
    png_bytep scanline = (png_bytep) calloc((size_t)(4*width),sizeof(png_byte));
90
    png_byte trans[256];
92
    png_byte trans[256];
91
    png_color_16 trans_values[1];
93
    png_color_16 trans_values[1];
92
    int i, j, r, ncols, mid, high, low, withpalette;
94
    int i, j, r, ncols, mid, high, low, withpalette, have_alpha;
93
    DECLARESHIFTS;
95
    volatile DECLARESHIFTS;
94
 
96
 
95
    /* Have we enough memory?*/
97
    /* Have we enough memory?*/
96
    if (scanline == NULL)
98
    if (scanline == NULL)
97
	return 0;
99
	return 0;
98
 
100
 
-
 
101
    if (fp == NULL) {
-
 
102
	free(scanline);
-
 
103
	return 0;
-
 
104
    }
-
 
105
 
99
    /* Create and initialize the png_struct with the desired error handler
106
    /* Create and initialize the png_struct with the desired error handler
100
     * functions.  If you want to use the default stderr and longjump method,
107
     * functions.  If you want to use the default stderr and longjump method,
101
     * you can supply NULL for the last three parameters.  We also check that
108
     * you can supply NULL for the last three parameters.  We also check that
102
     * the library version is compatible with the one used at compile time,
109
     * the library version is compatible with the one used at compile time,
103
     * in case we are using dynamically linked libraries.  REQUIRED.
110
     * in case we are using dynamically linked libraries.  REQUIRED.
Line 137... Line 144...
137
    /* Have we less than 256 different colors? */
144
    /* Have we less than 256 different colors? */
138
    ncols = 0;
145
    ncols = 0;
139
    if(transparent) palette[ncols++] = transparent & 0xFFFFFF;
146
    if(transparent) palette[ncols++] = transparent & 0xFFFFFF;
140
    mid = ncols;
147
    mid = ncols;
141
    withpalette = 1;
148
    withpalette = 1;
-
 
149
    have_alpha = 0;
142
    for (i = 0; (i < height) && withpalette ; i++) {
150
    for (i = 0; (i < height) && withpalette ; i++) {
143
	for (j = 0; (j < width) && withpalette ; j++) {
151
	for (j = 0; (j < width) && withpalette ; j++) {
144
	    col = gp(d,i,j) & 0xFFFFFF ;
152
	    col = gp(d,i,j);
-
 
153
	    if (GETALPHA(col) < 255) have_alpha = 1;
145
	    /* binary search the palette: */
154
	    /* binary search the palette: */
146
	    low = 0;
155
	    low = 0;
147
	    high = ncols - 1;
156
	    high = ncols - 1;
148
	    while (low <= high) {
157
	    while (low <= high) {
149
		mid = (low + high)/2;
158
		mid = (low + high)/2;
Line 163... Line 172...
163
		}
172
		}
164
	    }
173
	    }
165
	}
174
	}
166
    }
175
    }
167
 
176
 
-
 
177
    have_alpha &= (transparent == 0);
-
 
178
 
-
 
179
    printf("have_alpha: %d\n", have_alpha);
168
    /* Set the image information here.  Width and height are up to 2^31,
180
    /* Set the image information here.  Width and height are up to 2^31,
169
     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
181
     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
170
     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
182
     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
171
     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
183
     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
172
     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
184
     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
173
     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
185
     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
174
     * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
186
     * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
175
     */
187
     */
176
    png_set_IHDR(png_ptr, info_ptr, width, height, 8,
188
    png_set_IHDR(png_ptr, info_ptr, width, height, 8,
-
 
189
		 withpalette ? PNG_COLOR_TYPE_PALETTE :
177
		 withpalette ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_RGB,
190
		 (have_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB),
178
		 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
191
		 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
179
		 PNG_FILTER_TYPE_BASE);
192
		 PNG_FILTER_TYPE_BASE);
180
 
193
 
181
    if (withpalette) {
194
    if (withpalette) {
182
	for (i = 0; i < ncols ; i++) {
195
	for (i = 0; i < ncols ; i++) {
183
	    col = palette[i];
196
	    col = palette[i];
-
 
197
	    if(transparent) {
-
 
198
		trans[i] = (col == transparent) ? 0:255;
-
 
199
		pngpalette[i].red = GETRED(col);
-
 
200
		pngpalette[i].green = GETGREEN(col);
-
 
201
		pngpalette[i].blue = GETBLUE(col);
-
 
202
	    } else {
-
 
203
		/* PNG needs NON-premultiplied alpha */
-
 
204
		int a = GETALPHA(col);
-
 
205
		trans[i] = a;
-
 
206
		if(a == 255 || a == 0) {
184
	    pngpalette[i].red = GETRED(col);
207
		    pngpalette[i].red = GETRED(col);
185
	    pngpalette[i].green = GETGREEN(col);
208
		    pngpalette[i].green = GETGREEN(col);
186
	    pngpalette[i].blue = GETBLUE(col);
209
		    pngpalette[i].blue = GETBLUE(col);
-
 
210
		} else {
-
 
211
		    pngpalette[i].red = 0.49 + 255.0*GETRED(col)/a;
-
 
212
		    pngpalette[i].green = 0.49 + 255.0*GETGREEN(col)/a;
-
 
213
		    pngpalette[i].blue = 0.49 + 255.0*GETBLUE(col)/a;
-
 
214
 
-
 
215
		}
-
 
216
	    }
187
	}
217
	}
188
	png_set_PLTE(png_ptr, info_ptr, pngpalette, ncols);
218
	png_set_PLTE(png_ptr, info_ptr, pngpalette, ncols);
-
 
219
	if (transparent || have_alpha)
-
 
220
	    png_set_tRNS(png_ptr, info_ptr, trans, ncols, trans_values);
189
    }
221
    }
190
    /* Deal with transparency */
222
    /* Deal with transparency */
191
    if(transparent) {
223
    if(transparent && !withpalette) {
192
	if(withpalette) {
-
 
193
	    for (i = 0; i < ncols ; i++)
-
 
194
		trans[i] = (palette[i] == (transparent & 0xFFFFFF)) ? 0:255;
-
 
195
	} else {
-
 
196
	    trans_values[0].red = GETRED(transparent);
224
	trans_values[0].red = GETRED(transparent);
197
	    trans_values[0].blue = GETBLUE(transparent);
225
	trans_values[0].blue = GETBLUE(transparent);
198
	    trans_values[0].green = GETGREEN(transparent);
226
	trans_values[0].green = GETGREEN(transparent);
199
	}
-
 
200
	png_set_tRNS(png_ptr, info_ptr, trans, ncols, trans_values);
227
	png_set_tRNS(png_ptr, info_ptr, trans, ncols, trans_values);
201
    }
228
    }
202
 
229
 
203
    if(res > 0)
230
    if(res > 0)
204
	png_set_pHYs(png_ptr, info_ptr, res/0.0254, res/0.0254,
231
	png_set_pHYs(png_ptr, info_ptr, res/0.0254, res/0.0254,
Line 212... Line 239...
212
     */
239
     */
213
    for (i = 0 ; i < height ; i++) {
240
    for (i = 0 ; i < height ; i++) {
214
	/* Build the scanline */
241
	/* Build the scanline */
215
	pscanline = scanline;
242
	pscanline = scanline;
216
	for (j = 0 ; j < width ; j++) {
243
	for (j = 0 ; j < width ; j++) {
217
	    col = gp(d, i, j) & 0xFFFFFF;
244
	    col = gp(d, i, j);
218
	    if (withpalette) {
245
	    if (withpalette) {
219
		/* binary search the palette (the colour must be there): */
246
		/* binary search the palette (the colour must be there): */
220
		low = 0;  high = ncols - 1;
247
		low = 0;  high = ncols - 1;
221
		while (low <= high) {
248
		while (low <= high) {
222
		    mid = (low + high)/2;
249
		    mid = (low + high)/2;
Line 224... Line 251...
224
		    else if (col > palette[mid]) low  = mid + 1;
251
		    else if (col > palette[mid]) low  = mid + 1;
225
		    else break;
252
		    else break;
226
		}
253
		}
227
		*pscanline++ = mid;
254
		*pscanline++ = mid;
228
	    } else {
255
	    } else {
-
 
256
		if(have_alpha) {
-
 
257
		    /* PNG needs NON-premultiplied alpha */
-
 
258
		    int a = GETALPHA(col);
-
 
259
		    if(a == 255 || a == 0) {
229
		*pscanline++ = GETRED(col) ;
260
			*pscanline++ = GETRED(col) ;
230
		*pscanline++ = GETGREEN(col) ;
261
			*pscanline++ = GETGREEN(col) ;
231
		*pscanline++ = GETBLUE(col) ;
262
			*pscanline++ = GETBLUE(col) ;
-
 
263
			*pscanline++ =  a;
-
 
264
		    } else {
-
 
265
			*pscanline++ = 0.49 + 255.0*GETRED(col)/a ;
-
 
266
			*pscanline++ = 0.49 + 255.0*GETGREEN(col)/a ;
-
 
267
			*pscanline++ = 0.49 + 255.0*GETBLUE(col)/a ;
-
 
268
			*pscanline++ =  a;
-
 
269
		    }
-
 
270
		} else {
-
 
271
		    *pscanline++ = GETRED(col) ;
-
 
272
		    *pscanline++ = GETGREEN(col) ;
-
 
273
		    *pscanline++ = GETBLUE(col) ;
-
 
274
		}
232
	    }
275
	    }
233
	}
276
	}
234
	png_write_row(png_ptr, scanline);
277
	png_write_row(png_ptr, scanline);
235
    }
278
    }
236
 
279
 
Line 309... Line 352...
309
 
352
 
310
    /* Have we enough memory?*/
353
    /* Have we enough memory?*/
311
    if (scanline == NULL)
354
    if (scanline == NULL)
312
	return 0;
355
	return 0;
313
 
356
 
-
 
357
    if (outfile == NULL) {
-
 
358
	free(scanline);
-
 
359
	return 0;
-
 
360
    }
-
 
361
 
314
    /* Step 1: allocate and initialize JPEG compression object */
362
    /* Step 1: allocate and initialize JPEG compression object */
315
 
363
 
316
    /*
364
    /*
317
     * We set up the normal JPEG error routines, then override error_exit
365
     * We set up the normal JPEG error routines, then override error_exit
318
     * and output_message
366
     * and output_message
Line 400... Line 448...
400
    unsigned int col, i, j;
448
    unsigned int col, i, j;
401
    int have_alpha = 0;
449
    int have_alpha = 0;
402
 
450
 
403
    DECLARESHIFTS;
451
    DECLARESHIFTS;
404
 
452
 
405
#if 0
-
 
406
    for (i = 0; i < height; i++)
453
    for (i = 0; i < height; i++)
407
	for (j = 0; j < width; j++) {
454
	for (j = 0; j < width; j++) {
408
	    col = gp(d,i,j);
455
	    col = gp(d,i,j);
409
	    if (GETALPHA(col) < 255) {
456
	    if (GETALPHA(col) < 255) {
410
		have_alpha = 1;
457
		have_alpha = 1;
411
		break;
458
		break;
412
	    }
459
	    }
413
	}
460
	}
414
#endif
-
 
415
    sampleperpixel = 3 + have_alpha;
461
    sampleperpixel = 3 + have_alpha;
416
 
462
 
417
    out = TIFFOpen(outfile, "w");
463
    out = TIFFOpen(outfile, "w");
418
    if (!out) {
464
    if (!out) {
419
	warning("unable to open TIFF file '%s'", outfile);
465
	warning("unable to open TIFF file '%s'", outfile);
Line 495... Line 541...
495
    unsigned short wrd;
541
    unsigned short wrd;
496
    unsigned int dwrd;
542
    unsigned int dwrd;
497
    int lres;
543
    int lres;
498
    DECLARESHIFTS;
544
    DECLARESHIFTS;
499
 
545
 
-
 
546
    if (fp == NULL)
-
 
547
	return 0;
-
 
548
 
500
    /* Have we less than 256 different colors? */
549
    /* Have we less than 256 different colors? */
501
    ncols = mid = 0;
550
    ncols = mid = 0;
502
    withpalette = 1;
551
    withpalette = 1;
503
    for (i = 0; i < 256 ; i++) palette[i] = 0;
552
    for (i = 0; i < 256 ; i++) palette[i] = 0;
504
    for (i = 0; (i < height) && withpalette ; i++) {
553
    for (i = 0; (i < height) && withpalette ; i++) {