1994.06.16 23:08 "Re: RGB to TIFF", by Dan McCoy
. . . I have used TIFFReadRGBAImage and the TIFFGetR/G/B routines to read a tiff file into a RGBA format. Now after the processing is done I need to restore it to the original TIFF form from the RGBA format. I could not find any obvious routine to do this.
Following is the routine we use around here when we get lazy.
Dan McCoy Pixar mccoy@pixar.com
PS. Sam, do you want this one?
----------------save.c----------------
#include <stdio.h>
#include <stdlib.h>
#include "tiffio.h"
/*
* TIFFSaveRGBImage is a utility routine that will write an image
* array out as a TIFF file. It is meant for programs that don't
* want to deal with a lot of options. All TIFF options will be
* set to "reasonable" defaults.
*
* filename will be the name of the created file.
* inorder specifies the location of the color fields in the uint32.
* 0: abgr where a is the most significant byte.
* 1: rgba where r is the most significant byte.
* 2: argb where a is the most significant byte.
* 3: bgra where b is the most significant byte.
* sendalpha controls whether the alpha channel is written.
* 0: only r, g, and b are written.
* 1: alpha is written as well.
* orientation specifies how the scanlines are arranged in the array.
* 0: top of image is first in the array.
* 1: bottom of image is first in the array.
* width the width of the image in pixels.
* height the height of the image in pixels.
* image is a pointer to width*height uint32's containing the pixels
* of the image in scanline order.
*
* The file will be LZW compressed.
*
* Returns 1 for success, o for failure.
*/
int
TIFFSaveRGBImage(filename, inorder, sendalpha, orientation, width, height, image)
char *filename;
int inorder; /* 0: abgr, 1: rgba, 2: argb, 3: bgra */
int sendalpha; /* 0: rgb, 1: rgba */
int orientation; /* 0: top to bottom, 1: bottom to top */
int width;
int height;
uint32 *image;
{
int bytesperscan;
int rows;
int samples;
unsigned char *scan;
TIFF *tif;
rows = 1;
scan = (unsigned char *) &rows;
if (*scan) {
/* Little endian machine, reverse sense of inorder. */
switch (inorder) {
case 0: inorder = 1; break;
case 1: inorder = 0; break;
case 2: inorder = 3; break;
case 3: inorder = 2; break;
}
}
if (sendalpha)
samples = 4;
else
samples = 3;
bytesperscan = width * samples;
scan = (unsigned char *) malloc(bytesperscan);
if (scan == NULL)
return 0;
tif = TIFFOpen(filename, "w");
if (tif == NULL)
{
free(scan);
return 0;
}
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, (uint32) 0);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32) width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32) height);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
if (sendalpha)
TIFFSetField(tif, TIFFTAG_MATTEING, 1);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
rows = 8192 / bytesperscan;
if (rows < 1) rows = 1;
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, (uint32) rows);
/*
* The file is open, all parameters are set,
* write the image array into the file a scan at a time.
*/
{
register int npixels;
register unsigned char *ip;
register unsigned char *op;
unsigned int r, g, b, a;
int y;
for (y=0; y<height; y++) {
if (orientation) {
ip = (unsigned char *) (image + (height - y - 1) * width);
} else {
ip = (unsigned char *) (image + y * width);
}
npixels = width;
op = scan;
while (--npixels >= 0) {
switch (inorder) {
case 0:
a = *ip++;
b = *ip++;
g = *ip++;
r = *ip++;
break;
case 1:
r = *ip++;
g = *ip++;
b = *ip++;
a = *ip++;
break;
case 2:
a = *ip++;
r = *ip++;
g = *ip++;
b = *ip++;
break;
case 3:
b = *ip++;
g = *ip++;
r = *ip++;
a = *ip++;
break;
}
*op++ = r;
*op++ = g;
*op++ = b;
if (sendalpha)
*op++ = a;
}
if (TIFFWriteScanline(tif, scan, y, 0) < 0)
goto omigosh;
}
}
(void) TIFFClose(tif);
free(scan);
return 1;
omigosh:
free(scan);
(void) TIFFClose(tif);
return 0;
}