00001
00002
00003
00004
00005
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <tiffio.h>
00009 #include <ImfOutputFile.h>
00010 #include <ImfChannelList.h>
00011 #include <ImfFrameBuffer.h>
00012 #include <half.h>
00013
00014 using namespace Imf;
00015 using namespace Imath;
00016
00017 #define INV_255 .00392156862745098039f
00018
00019 static void WriteEXR(const char *name, float *rgba, int xRes, int yRes, bool hasAlpha);
00020 static bool ReadTIFF(const char *name, float *&rgba, int &xRes, int &yRes, bool &hasAlpha);
00021
00022 int main(int argc, char *argv[])
00023 {
00024 if (argc != 3) {
00025 fprintf(stderr, "usage: tifftoexr [foo.tiff] [foo.exr]\n");
00026 return 1;
00027 }
00028
00029 float *rgba;
00030 int xRes, yRes;
00031 bool hasAlpha;
00032 if (ReadTIFF(argv[1], rgba, xRes, yRes, hasAlpha))
00033 WriteEXR(argv[2], rgba, xRes, yRes, hasAlpha);
00034 return 0;
00035 }
00036
00037 void WriteEXR(const char *name, float *frgba, int xRes, int yRes, bool hasAlpha)
00038 {
00039 Header header(xRes, yRes);
00040 header.channels().insert("R", Channel (HALF));
00041 header.channels().insert("G", Channel (HALF));
00042 header.channels().insert("B", Channel (HALF));
00043 if (hasAlpha)
00044 header.channels().insert("A", Channel (HALF));
00045 int stride = hasAlpha ? 4 : 3;
00046
00047 half *rgba = new half[xRes*yRes * stride];
00048 for (int i = 0; i < xRes*yRes * stride; ++i)
00049 rgba[i] = frgba[i];
00050
00051 FrameBuffer fb;
00052 fb.insert("R", Slice(HALF, (char *)rgba, stride*sizeof(half),
00053 stride*xRes*sizeof(half)));
00054 fb.insert("G", Slice(HALF, (char *)rgba+sizeof(half), stride*sizeof(half),
00055 stride*xRes*sizeof(half)));
00056 fb.insert("B", Slice(HALF, (char *)rgba+2*sizeof(half), stride*sizeof(half),
00057 stride*xRes*sizeof(half)));
00058 if (hasAlpha)
00059 fb.insert("A", Slice(HALF, (char *)rgba+3*sizeof(half), stride*sizeof(half),
00060 stride*xRes*sizeof(half)));
00061
00062 OutputFile file(name, header);
00063 file.setFrameBuffer(fb);
00064 file.writePixels(yRes);
00065 }
00066
00067 static bool ReadTIFF(const char *name, float *&rgba, int &xRes, int &yRes,
00068 bool &hasAlpha)
00069 {
00070
00071 TIFF *tiff = TIFFOpen(name, "r");
00072 if (!tiff) {
00073 fprintf(stderr, "Unable to open TIFF %s", name);
00074 return false;
00075 }
00076
00077 short int nSamples;
00078 int xSize, ySize;
00079 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &xSize);
00080 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &ySize);
00081 TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &nSamples);
00082 if (nSamples != 3 && nSamples != 4) {
00083 fprintf(stderr, "Sorry, only handle 3 and 4 sample TIFFs...\n");
00084 return false;
00085 }
00086 hasAlpha = (nSamples == 4);
00087 xRes = xSize;
00088 yRes = ySize;
00089
00090
00091 short int bitsPerSample, sampleFormat = SAMPLEFORMAT_UINT;
00092 if (!TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample)) {
00093 fprintf(stderr, "TIFFRead: bits per sample not set in TIFF");
00094 TIFFClose(tiff);
00095 return false;
00096 }
00097
00098 if (!TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &sampleFormat)) {
00099 if (bitsPerSample == 32)
00100 sampleFormat = SAMPLEFORMAT_IEEEFP;
00101 else
00102 sampleFormat = SAMPLEFORMAT_UINT;
00103 }
00104
00105 if (bitsPerSample == 32) {
00106 if (sampleFormat != SAMPLEFORMAT_IEEEFP) {
00107 fprintf(stderr, "TIFFRead: 32 bit TIFF not stored in floating point format");
00108 TIFFClose(tiff);
00109 return false;
00110 }
00111 }
00112 else {
00113 if (bitsPerSample != 8 && bitsPerSample != 32) {
00114 fprintf(stderr, "TIFFRead: only 8 and 32 bits per sample supported");
00115 TIFFClose(tiff);
00116 return false;
00117 }
00118 if (sampleFormat != SAMPLEFORMAT_UINT) {
00119 fprintf(stderr, "TIFFRead: 8 bit TIFFs must be stored as unsigned ints");
00120 TIFFClose(tiff);
00121 return false;
00122 }
00123 }
00124
00125 int bytesPerSample = bitsPerSample / 8;
00126 if (nSamples * xRes * bytesPerSample != TIFFScanlineSize(tiff)) {
00127 fprintf(stderr, "TIFFRead: RGB not interleaved in TIFF %s", name);
00128 TIFFClose(tiff);
00129 return false;
00130 }
00131
00132
00133 rgba = new float[nSamples * xRes * yRes];
00134 float *p = rgba;
00135 unsigned char *ubuf = NULL;
00136 if (bitsPerSample == 8) ubuf = new unsigned char[nSamples * xRes];
00137
00138 for (int y = 0; y < yRes; ++y) {
00139 if (ubuf) {
00140
00141 if (TIFFReadScanline(tiff, ubuf, y, 1) == -1) {
00142 TIFFClose(tiff);
00143 return false;
00144 }
00145 for (int x = 0; x < nSamples*xRes; ++x)
00146 *p++ = ubuf[x] * INV_255;
00147 }
00148 else {
00149
00150 if (TIFFReadScanline(tiff, p, y, 1) == -1) {
00151 TIFFClose(tiff);
00152 return false;
00153 }
00154 p += nSamples * xRes;
00155 }
00156 }
00157
00158 delete[] ubuf;
00159 TIFFClose(tiff);
00160 return rgba;
00161 }
00162