00001
00002
00003
00004
00005
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <assert.h>
00009 #include <sys/types.h>
00010 #include <dirent.h>
00011 #include <string.h>
00012 #include <ImfAttribute.h>
00013 #include <ImfInputFile.h>
00014 #include <ImfOutputFile.h>
00015 #include <ImfChannelList.h>
00016 #include <ImfFrameBuffer.h>
00017 #include <half.h>
00018
00019 using namespace Imf;
00020 using namespace Imath;
00021
00022 void WriteEXR(const char *name, half *rgba, int xRes, int yRes);
00023 half *ReadEXR(const char *name, int *x0, int *y0, int *xSize, int *ySize,
00024 int *xres, int *yres);
00025
00026 int main(int argc, char *argv[])
00027 {
00028 if (argc != 3) {
00029 fprintf(stderr, "usage: exrtogether [exr dir] [foo.exr]\n");
00030 return 1;
00031 }
00032
00033 const char *dirname = argv[1];
00034 const char *outname = argv[2];
00035
00036 int xres, yres;
00037 int ndone = 0;
00038 half *rgba = 0;
00039
00040 DIR *dir = opendir(dirname);
00041 struct dirent *d;
00042 while ((d = readdir(dir))) {
00043 if (!strstr(d->d_name, ".exr")) continue;
00044 int x0, y0, xr, yr, totx, toty;
00045 char fn[1024];
00046 sprintf(fn, "%s/%s", dirname, d->d_name);
00047 half *subpix = ReadEXR(fn, &x0, &y0, &xr, &yr, &totx, &toty);
00048 if (!subpix) {
00049 fprintf(stderr, "couldn't read exr file \"%s\"!\n", fn);
00050 continue;
00051 }
00052
00053 if (!rgba) {
00054 xres = totx;
00055 yres = toty;
00056 rgba = new half[xres*yres*4];
00057 memset(rgba, 0, xres*yres*4*sizeof(half));
00058 }
00059 else
00060 assert(xres == totx && yres == toty);
00061
00062 ndone += xr*yr;
00063 for (int i = 0; i < yr; ++i)
00064 memcpy(rgba + 4 * (x0 + xres * (y0 + i)),
00065 subpix + 4 * i * xr, 4 * xr * sizeof(half));
00066 delete[] subpix;
00067 }
00068 closedir(dir);
00069
00070 fprintf(stderr, "Got %f%% of image\n", 100.f * ndone / (xres *yres));
00071 WriteEXR(outname, rgba, xres, yres);
00072
00073 return 0;
00074 }
00075
00076 void WriteEXR(const char *name, half *rgba, int xRes, int yRes)
00077 {
00078 Header header(xRes, yRes);
00079 header.channels().insert("R", Channel (HALF));
00080 header.channels().insert("G", Channel (HALF));
00081 header.channels().insert("B", Channel (HALF));
00082 header.channels().insert("A", Channel (HALF));
00083
00084 int stride = 4;
00085
00086 FrameBuffer fb;
00087 fb.insert("R", Slice(HALF, (char *)rgba, stride*sizeof(half),
00088 stride*xRes*sizeof(half)));
00089 fb.insert("G", Slice(HALF, (char *)rgba+sizeof(half), stride*sizeof(half),
00090 stride*xRes*sizeof(half)));
00091 fb.insert("B", Slice(HALF, (char *)rgba+2*sizeof(half), stride*sizeof(half),
00092 stride*xRes*sizeof(half)));
00093 fb.insert("A", Slice(HALF, (char *)rgba+3*sizeof(half), stride*sizeof(half),
00094 stride*xRes*sizeof(half)));
00095
00096 OutputFile file(name, header);
00097 file.setFrameBuffer(fb);
00098 file.writePixels(yRes);
00099 }
00100
00101 half *ReadEXR(const char *name, int *x0, int *y0, int *xSize, int *ySize,
00102 int *totxres, int *totyres)
00103 {
00104 InputFile file(name);
00105 Box2i dw = file.header().dataWindow();
00106 Box2i totalImage = file.header().displayWindow();
00107
00108 *totxres = totalImage.max.x - totalImage.min.x + 1;
00109 *totyres = totalImage.max.y - totalImage.min.y + 1;
00110 *x0 = dw.min.x;
00111 *y0 = dw.min.y;
00112 *xSize = dw.max.x - dw.min.x + 1;
00113 *ySize = dw.max.y - dw.min.y + 1;
00114
00115 half *rgba = new half[4 * *xSize * *ySize];
00116
00117 half *rstart = rgba - (4 * (*x0 + *y0 * *xSize));
00118
00119 FrameBuffer frameBuffer;
00120 frameBuffer.insert("R", Slice(HALF, (char *)rstart,
00121 4*sizeof(half), *xSize * 4 * sizeof(half), 1, 1, 0.0));
00122 frameBuffer.insert("G", Slice(HALF, (char *)rstart+sizeof(half),
00123 4*sizeof(half), *xSize * 4 * sizeof(half), 1, 1, 0.0));
00124 frameBuffer.insert("B", Slice(HALF, (char *)rstart+2*sizeof(half),
00125 4*sizeof(half), *xSize * 4 * sizeof(half), 1, 1, 0.0));
00126 frameBuffer.insert("A", Slice(HALF, (char *)rstart+3*sizeof(half),
00127 4*sizeof(half), *xSize * 4 * sizeof(half), 1, 1, 1.0));
00128
00129 file.setFrameBuffer(frameBuffer);
00130 file.readPixels(dw.min.y, dw.max.y);
00131
00132 return rgba;
00133 }