roo_e/thirdparty/grx249/addons/ctx2tiff.c
2022-05-16 17:59:47 -05:00

210 lines
5.5 KiB
C

/**
** CTX2TIFF.C ---- saves a context in a TIFF file
**
** Copyright (c) 1997 Hartmut Schirmer
**
** requires tifflib by Sam Leffler (sam@engr.sgi.com)
** available at ftp://ftp.sgi.com/graphics/tiff
**
** should work with every compiler supporting both,
** tifflib and GRX libraries
**/
#include <stdlib.h>
#include <grx20.h>
#include <tiffio.h>
#include <string.h>
#define SCALE(x) ((x)<<8)
#define puttobuf(r,x,depth,col) do { \
switch (depth) { \
case 1 : if (col) { \
int offset = (x) >> 3; \
int mask = 0x80 >> ((x) & 7); \
r[offset] |= mask; \
} \
break; \
case 8 : r[x] = (unsigned char)(col); break; \
case 24: r[3*(x)+0] = GrRGBcolorRed(col); \
r[3*(x)+1] = GrRGBcolorGreen(col); \
r[3*(x)+2] = GrRGBcolorBlue(col); \
break; \
} \
} while(0)
/*
** SaveContextToTiff - Dump a context in a TIFF file
**
** Arguments:
** ctx: Context to be saved (NULL -> use current context)
** tiffn: Name of tiff file
** compr: Compression method (see tiff.h), 0: automatic selection
** docn: string saved in the tiff file (DOCUMENTNAME tag)
**
** Returns 0 on success
** -1 on error
*/
int
SaveContextToTiff(GrContext *ctx, char *tiffn, unsigned compr, char *docn) {
int depth, i, res;
long row;
TIFF *tif;
long width, height, colors;
short photometric;
short samplesperpixel;
short bitspersample;
unsigned char *r;
unsigned short red[256], green[256], blue[256];
if (!ctx) ctx = (GrContext *)GrCurrentContext();
if (!ctx) return -1;
width = ctx->gc_xmax+1;
height = ctx->gc_ymax+1;
colors = GrNumColors();
if (colors < 2) return -1;
if (colors == 2) depth = 1; else
if (colors <= 256) depth = 8; else
if (colors <= 1L<<24) depth = 24; else return -1;
if (!compr) { /* compr == 0 -> auto select compression */
if (depth==1) compr = COMPRESSION_CCITTFAX4;
else compr = COMPRESSION_LZW;
}
switch (depth) {
case 1:
samplesperpixel = 1;
bitspersample = 1;
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 8:
samplesperpixel = 1;
bitspersample = 8;
photometric = PHOTOMETRIC_PALETTE;
break;
case 24:
samplesperpixel = 3;
bitspersample = 8;
photometric = PHOTOMETRIC_RGB;
break;
default:
return -1; /* shouldn't happen */
}
r = (unsigned char *) malloc( depth>1 ?
samplesperpixel*width*sizeof(unsigned char) :
(width+7)/8);
if (!r) return -1;
tif = TIFFOpen(tiffn, "w");
if (tif == NULL) {
free(r);
return -1;
}
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_COMPRESSION, compr);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
if (docn)
TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, docn);
TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "GRX saved context");
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, height);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
memset(red, 0, sizeof(red));
memset(green, 0, sizeof(green));
memset(blue, 0, sizeof(blue));
if (depth == 8) {
for (i = 0; i < colors; i++) {
int r, g, b;
GrQueryColor(i, &r, &g, &b);
red[i] = SCALE(r);
green[i] = SCALE(g);
blue[i] = SCALE(b);
}
TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
}
res = 0;
for (row = 0; row < height; row++) {
int x;
GrColor c;
#if GRX_VERSION_API-0 >= 0x229
const GrColor *rcb = GrGetScanlineC(ctx,0,width-1,row);
if (rcb) {
for (x=0; x < width; ++x) {
c = rcb[x];
puttobuf(r,x,depth,c);
}
} else
#endif
{
if (depth==1) memset (r,0,(width+7)/8);
for (x=0; x < width; ++x) {
c = GrPixelC(ctx,x,row);
puttobuf(r,x,depth,c);
}
}
if (TIFFWriteScanline(tif, r, row, 0) < 0) {
res = -1;
break;
}
}
TIFFFlushData(tif);
TIFFClose(tif);
free(r);
return res;
}
#ifdef TEST_CTX2TIFF
#include "../test/test.h"
TESTFUNC(wintest)
{
int x = GrSizeX();
int y = GrSizeY();
int ww = (x / 2) - 10;
int wh = (y / 2) - 10;
long c;
GrContext *w1 = GrCreateSubContext(5,5,ww+4,wh+4,NULL,NULL);
GrContext *w2 = GrCreateSubContext(15+ww,5,ww+ww+14,wh+4,NULL,NULL);
GrContext *w3 = GrCreateSubContext(5,15+wh,ww+4,wh+wh+14,NULL,NULL);
GrContext *w4 = GrCreateSubContext(15+ww,15+wh,ww+ww+14,wh+wh+14,NULL,NULL);
GrSetContext(w1);
c = GrAllocColor(200,100,100);
drawing(0,0,ww,wh,c,GrBlack());
c = GrAllocColor(100,50,50);
GrBox(0,0,ww-1,wh-1,c);
GrSetContext(w2);
c = GrAllocColor(100,200,200);
drawing(0,0,ww,wh,c,GrBlack());
c = GrAllocColor(50,100,100);
GrBox(0,0,ww-1,wh-1,c);
GrSetContext(w3);
c = GrAllocColor(200,200,0);
drawing(0,0,ww,wh,c,GrBlack());
c = GrAllocColor(100,100,0);
GrBox(0,0,ww-1,wh-1,c);
GrSetContext(w4);
c = GrAllocColor(0,100,200);
drawing(0,0,ww,wh,c,GrBlack());
c = GrAllocColor(255,0,100);
GrBox(0,0,ww-1,wh-1,c);
GrSetContext(NULL);
SaveContextToTiff(NULL, "test.tif", 0, "Context2TIFF test file");
getch();
}
#endif