The R Project SVN R

Rev

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

Rev 42301 Rev 44496
Line 39... Line 39...
39
#include <stdlib.h>
39
#include <stdlib.h>
40
#include <setjmp.h>
40
#include <setjmp.h>
41
 
41
 
42
/* 8 bits red, green and blue channel */
42
/* 8 bits red, green and blue channel */
43
#define DECLARESHIFTS int RSHIFT=(bgr)?0:16, GSHIFT=8, BSHIFT=(bgr)?16:0
43
#define DECLARESHIFTS int RSHIFT=(bgr)?0:16, GSHIFT=8, BSHIFT=(bgr)?16:0
44
#define GETRED(col)    (((col) >> RSHIFT) & 0xFFUL)
44
#define GETRED(col)    (((col) >> RSHIFT) & 0xFFU)
45
#define GETGREEN(col)  (((col) >> GSHIFT) & 0xFFUL)
45
#define GETGREEN(col)  (((col) >> GSHIFT) & 0xFFU)
46
#define GETBLUE(col)   (((col) >> BSHIFT) & 0xFFUL)
46
#define GETBLUE(col)   (((col) >> BSHIFT) & 0xFFU)
47
 
47
 
48
#include <R_ext/Error.h>
48
#include <R_ext/Error.h>
49
 
49
 
50
#ifdef HAVE_PNG
50
#ifdef HAVE_PNG
51
 
51
 
Line 74... Line 74...
74
 
74
 
75
#define CN (100.0/2.54)
75
#define CN (100.0/2.54)
76
 
76
 
77
__declspec(dllexport)
77
__declspec(dllexport)
78
int R_SaveAsPng(void  *d, int width, int height, 
78
int R_SaveAsPng(void  *d, int width, int height, 
79
		unsigned long (*gp)(void *, int, int),
79
		unsigned int (*gp)(void *, int, int),
80
		int bgr, FILE *fp, unsigned int transparent, int res) 
80
		int bgr, FILE *fp, unsigned int transparent, int res) 
81
{
81
{
82
  png_structp png_ptr;
82
  png_structp png_ptr;
83
  png_infop info_ptr;
83
  png_infop info_ptr;
84
  unsigned long  col, palette[256];
84
  unsigned int  col, palette[256];
85
  png_color pngpalette[256];
85
  png_color pngpalette[256];
86
  png_bytep pscanline, scanline = calloc(3*width,sizeof(png_byte));
86
  png_bytep pscanline, scanline = calloc(3*width,sizeof(png_byte));
87
  png_byte trans[256];
87
  png_byte trans[256];
88
  png_color_16 trans_values[1];
88
  png_color_16 trans_values[1];
89
  int i, j, r, ncols, mid, high, low, withpalette;
89
  int i, j, r, ncols, mid, high, low, withpalette;
Line 131... Line 131...
131
  if(transparent) palette[ncols++] = transparent & 0xFFFFFFUL;
131
  if(transparent) palette[ncols++] = transparent & 0xFFFFFFUL;
132
  mid = ncols;
132
  mid = ncols;
133
  withpalette = 1;
133
  withpalette = 1;
134
  for (i = 0; (i < height) && withpalette ; i++) {
134
  for (i = 0; (i < height) && withpalette ; i++) {
135
    for (j = 0; (j < width) && withpalette ; j++) {
135
    for (j = 0; (j < width) && withpalette ; j++) {
136
      col = gp(d,i,j) & 0xFFFFFFUL ;
136
      col = gp(d,i,j) & 0xFFFFFFU ;
137
      /* binary search the palette: */
137
      /* binary search the palette: */
138
      low = 0;  
138
      low = 0;  
139
      high = ncols - 1;
139
      high = ncols - 1;
140
      while (low <= high) {
140
      while (low <= high) {
141
	mid = (low + high)/2;
141
	mid = (low + high)/2;
Line 181... Line 181...
181
  } 
181
  } 
182
  /* Deal with transparency */
182
  /* Deal with transparency */
183
  if(transparent) {
183
  if(transparent) {
184
      if(withpalette) {
184
      if(withpalette) {
185
	  for (i = 0; i < ncols ; i++)
185
	  for (i = 0; i < ncols ; i++)
186
	      trans[i] = (palette[i] == (transparent & 0xFFFFFFUL)) ? 0:255;
186
	      trans[i] = (palette[i] == (transparent & 0xFFFFFFU)) ? 0:255;
187
      } else {
187
      } else {
188
	  trans_values[0].red = GETRED(transparent);
188
	  trans_values[0].red = GETRED(transparent);
189
	  trans_values[0].blue = GETBLUE(transparent);
189
	  trans_values[0].blue = GETBLUE(transparent);
190
	  trans_values[0].green = GETGREEN(transparent);
190
	  trans_values[0].green = GETGREEN(transparent);
191
      }
191
      }
Line 204... Line 204...
204
   */
204
   */
205
  for (i=0 ; i<height ; i++) { 
205
  for (i=0 ; i<height ; i++) { 
206
    /* Build the scanline */
206
    /* Build the scanline */
207
    pscanline = scanline;
207
    pscanline = scanline;
208
    for ( j=0 ; j<width ; j++) {
208
    for ( j=0 ; j<width ; j++) {
209
      col = gp(d, i, j);
209
      col = gp(d, i, j) & 0xFFFFFFU;
210
      if (withpalette) { 
210
      if (withpalette) { 
211
	    /* binary search the palette (the colour must be there): */
211
	    /* binary search the palette (the colour must be there): */
212
	    low = 0;  high = ncols - 1;
212
	    low = 0;  high = ncols - 1;
213
	    while (low <= high) {
213
	    while (low <= high) {
214
		mid = (low + high)/2;
214
		mid = (low + high)/2;
Line 283... Line 283...
283
 
283
 
284
 
284
 
285
 
285
 
286
__declspec(dllexport)
286
__declspec(dllexport)
287
int R_SaveAsJpeg(void  *d, int width, int height, 
287
int R_SaveAsJpeg(void  *d, int width, int height, 
288
		unsigned long (*gp)(void *, int, int),
288
		unsigned int (*gp)(void *, int, int),
289
		int bgr, int quality, FILE *outfile, int res) 
289
		int bgr, int quality, FILE *outfile, int res) 
290
{
290
{
291
  struct jpeg_compress_struct cinfo;
291
  struct jpeg_compress_struct cinfo;
292
  struct my_error_mgr jerr;
292
  struct my_error_mgr jerr;
293
  /* More stuff */
293
  /* More stuff */
294
  JSAMPLE *pscanline, *scanline = calloc(3*width,sizeof(JSAMPLE));
294
  JSAMPLE *pscanline, *scanline = calloc(3*width,sizeof(JSAMPLE));
295
  int i, j;
295
  int i, j;
296
  unsigned long col;
296
  unsigned int col;
297
  DECLARESHIFTS;
297
  DECLARESHIFTS;
298
 
298
 
299
  /* Have we enough memory?*/
299
  /* Have we enough memory?*/
300
  if (scanline == NULL) 
300
  if (scanline == NULL) 
301
    return 0;
301
    return 0;
Line 347... Line 347...
347
  /*           jpeg_write_scanlines(...); */
347
  /*           jpeg_write_scanlines(...); */
348
  for (i=0 ; i<height ; i++) { 
348
  for (i=0 ; i<height ; i++) { 
349
  /* Build the scanline */
349
  /* Build the scanline */
350
    pscanline = scanline;
350
    pscanline = scanline;
351
    for ( j=0 ; j<width ; j++) {
351
    for ( j=0 ; j<width ; j++) {
352
      col = gp(d, i, j);
352
      col = gp(d, i, j) & 0xFFFFFFU;
353
      *pscanline++ = GETRED(col) ;
353
      *pscanline++ = GETRED(col) ;
354
      *pscanline++ = GETGREEN(col) ;
354
      *pscanline++ = GETGREEN(col) ;
355
      *pscanline++ = GETBLUE(col) ;
355
      *pscanline++ = GETBLUE(col) ;
356
    }
356
    }
357
    jpeg_write_scanlines(&cinfo, (JSAMPARRAY) &scanline, 1);
357
    jpeg_write_scanlines(&cinfo, (JSAMPARRAY) &scanline, 1);
Line 380... Line 380...
380
 * Return 1 on success, 0 on failure 
380
 * Return 1 on success, 0 on failure 
381
*/
381
*/
382
 
382
 
383
#define BMPERROR {R_ShowMessage("Problems writing to 'bmp' file");return 0;} 
383
#define BMPERROR {R_ShowMessage("Problems writing to 'bmp' file");return 0;} 
384
#define BMPW(a) {wrd=a;if(fwrite(&wrd,sizeof(unsigned short),1,fp)!=1) BMPERROR}
384
#define BMPW(a) {wrd=a;if(fwrite(&wrd,sizeof(unsigned short),1,fp)!=1) BMPERROR}
385
#define BMPDW(a) {dwrd=a;if(fwrite(&dwrd,sizeof(unsigned long),1,fp)!=1) BMPERROR}
385
#define BMPDW(a) {dwrd=a;if(fwrite(&dwrd,sizeof(unsigned int),1,fp)!=1) BMPERROR}
386
#define BMPLONG(a) {lng=a;if(fwrite(&lng,sizeof(long),1,fp)!=1) BMPERROR}
386
#define BMPLONG(a) {lng=a;if(fwrite(&lng,sizeof(long),1,fp)!=1) BMPERROR}
387
#define BMPPUTC(a) if(fputc(a,fp)==EOF) BMPERROR;
387
#define BMPPUTC(a) if(fputc(a,fp)==EOF) BMPERROR;
388
#define HEADERSIZE 54
388
#define HEADERSIZE 54
389
 
389
 
390
__declspec(dllexport)
390
__declspec(dllexport)
391
int R_SaveAsBmp(void  *d, int width, int height, 
391
int R_SaveAsBmp(void  *d, int width, int height, 
392
		unsigned long (*gp)(void *, int, int), int bgr, FILE *fp,
392
		unsigned int (*gp)(void *, int, int), int bgr, FILE *fp,
393
		int res) 
393
		int res) 
394
{
394
{
395
  unsigned long  col, palette[256];
395
  unsigned int  col, palette[256];
396
  int i, j, r, ncols, mid, high, low, withpalette;
396
  int i, j, r, ncols, mid, high, low, withpalette;
397
  int bfOffBits, bfSize, biBitCount, biClrUsed , pad;
397
  int bfOffBits, bfSize, biBitCount, biClrUsed , pad;
398
  unsigned short wrd;
398
  unsigned short wrd;
399
  unsigned long dwrd;
399
  unsigned int dwrd;
400
  long lng, lres;
400
  long lng, lres;
401
  DECLARESHIFTS;
401
  DECLARESHIFTS;
402
 
402
 
403
  /* Have we less than 256 different colors? */
403
  /* Have we less than 256 different colors? */
404
  ncols = mid = 0;
404
  ncols = mid = 0;
405
  withpalette = 1;
405
  withpalette = 1;
406
  for (i=0; i<256 ; i++) palette[i] = 0;
406
  for (i=0; i<256 ; i++) palette[i] = 0;
407
  for (i = 0; (i < height) && withpalette ; i++) {
407
  for (i = 0; (i < height) && withpalette ; i++) {
408
    for (j = 0; (j < width) && withpalette ; j++) {
408
    for (j = 0; (j < width) && withpalette ; j++) {
409
      col = gp(d,i,j) & 0xFFFFFFUL ;
409
      col = gp(d,i,j) & 0xFFFFFFU ;
410
      /* binary search the palette: */
410
      /* binary search the palette: */
411
      low = 0;  
411
      low = 0;  
412
      high = ncols - 1;
412
      high = ncols - 1;
413
      while (low <= high) {
413
      while (low <= high) {
414
	mid = (low + high)/2;
414
	mid = (low + high)/2;
Line 473... Line 473...
473
    /* Rows must be padded to 4-byte boundary */
473
    /* Rows must be padded to 4-byte boundary */
474
    for ( pad=0 ; ((width+pad) & 3) != 0; pad++);
474
    for ( pad=0 ; ((width+pad) & 3) != 0; pad++);
475
    /* and then the pixels */
475
    /* and then the pixels */
476
    for (i=height-1 ; i>=0 ; i--) { 
476
    for (i=height-1 ; i>=0 ; i--) { 
477
      for ( j=0 ; j<width ; j++) {
477
      for ( j=0 ; j<width ; j++) {
478
	col = gp(d, i, j)&0xFFFFFFUL;
478
	col = gp(d, i, j)&0xFFFFFFU;
479
	/* binary search the palette (the colour must be there): */
479
	/* binary search the palette (the colour must be there): */
480
	low = 0;  high = ncols - 1;
480
	low = 0;  high = ncols - 1;
481
	while (low <= high) {
481
	while (low <= high) {
482
	  mid = (low + high)/2;
482
	  mid = (low + high)/2;
483
	  if      (col < palette[mid]) high = mid - 1;
483
	  if      (col < palette[mid]) high = mid - 1;
Line 492... Line 492...
492
    /* 24 bits image */
492
    /* 24 bits image */
493
    BMPDW(0); /* null bmiColors */
493
    BMPDW(0); /* null bmiColors */
494
    for ( pad=0 ; ((3*width+pad) & 3) != 0; pad++); /*padding*/    
494
    for ( pad=0 ; ((3*width+pad) & 3) != 0; pad++); /*padding*/    
495
    for (i=height-1 ; i>=0 ; i--) { 
495
    for (i=height-1 ; i>=0 ; i--) { 
496
      for ( j=0 ; j<width ; j++) {
496
      for ( j=0 ; j<width ; j++) {
497
	col = gp(d, i, j)&0xFFFFFFUL;
497
	col = gp(d, i, j)&0xFFFFFFU;
498
	BMPPUTC(GETBLUE(col));
498
	BMPPUTC(GETBLUE(col));
499
	BMPPUTC(GETGREEN(col));
499
	BMPPUTC(GETGREEN(col));
500
	BMPPUTC(GETRED(col));
500
	BMPPUTC(GETRED(col));
501
      }
501
      }
502
      for (j=0; j<pad; j++) BMPPUTC(0);
502
      for (j=0; j<pad; j++) BMPPUTC(0);