00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef WIN32
00026 #define hypotf hypot // For the OpenEXR headers
00027 #endif
00028
00029 #include <ImfInputFile.h>
00030 #include <ImfOutputFile.h>
00031 #include <ImfChannelList.h>
00032 #include <ImfFrameBuffer.h>
00033 #include <half.h>
00034 #include "pbrt.h"
00035 #include "color.h"
00036 using namespace Imf;
00037 using namespace Imath;
00038
00039 COREDLL Spectrum *ReadImage(const string &name, int *width, int *height) {
00040 try {
00041 InputFile file(name.c_str());
00042 Box2i dw = file.header().dataWindow();
00043 *width = dw.max.x - dw.min.x + 1;
00044 *height = dw.max.y - dw.min.y + 1;
00045
00046 half *rgb = new half[3 * *width * *height];
00047
00048 FrameBuffer frameBuffer;
00049 frameBuffer.insert("R", Slice(HALF, (char *)rgb,
00050 3*sizeof(half), *width * 3 * sizeof(half), 1, 1, 0.0));
00051 frameBuffer.insert("G", Slice(HALF, (char *)rgb+sizeof(half),
00052 3*sizeof(half), *width * 3 * sizeof(half), 1, 1, 0.0));
00053 frameBuffer.insert("B", Slice(HALF, (char *)rgb+2*sizeof(half),
00054 3*sizeof(half), *width * 3 * sizeof(half), 1, 1, 0.0));
00055
00056 file.setFrameBuffer(frameBuffer);
00057 file.readPixels(dw.min.y, dw.max.y);
00058
00059 Spectrum *ret = new Spectrum[*width * *height];
00060
00061 for (int i = 0; i < *width * *height; ++i) {
00062 float c[3] = { rgb[3*i], rgb[3*i+1], rgb[3*i+2] };
00063 ret[i] = Spectrum(c);
00064 }
00065 delete[] rgb;
00066 return ret;
00067 } catch (const std::exception &e) {
00068 Error("Unable to read image file \"%s\": %s", name.c_str(),
00069 e.what());
00070 return NULL;
00071 }
00072 }
00073
00074 COREDLL void WriteRGBAImage(const string &name, float *pixels,
00075 float *alpha, int xRes, int yRes,
00076 int totalXRes, int totalYRes,
00077 int xOffset, int yOffset) {
00078 Header header(totalXRes, totalYRes);
00079 Box2i dataWindow(V2i(xOffset, yOffset), V2i(xOffset + xRes - 1, yOffset + yRes - 1));
00080 header.dataWindow() = dataWindow;
00081 header.channels().insert("R", Channel (HALF));
00082 header.channels().insert("G", Channel (HALF));
00083 header.channels().insert("B", Channel (HALF));
00084 header.channels().insert("A", Channel (HALF));
00085
00086 half *hrgb = new half[3 * xRes * yRes];
00087 for (int i = 0; i < 3 * xRes * yRes; ++i)
00088 hrgb[i] = pixels[i];
00089 half *ha = new half[xRes * yRes];
00090 for (int i = 0; i < xRes * yRes; ++i)
00091 ha[i] = alpha[i];
00092
00093 hrgb -= 3 * (xOffset + yOffset * xRes);
00094 ha -= (xOffset + yOffset * xRes);
00095
00096 FrameBuffer fb;
00097 fb.insert("R", Slice(HALF, (char *)hrgb, 3*sizeof(half),
00098 3*xRes*sizeof(half)));
00099 fb.insert("G", Slice(HALF, (char *)hrgb+sizeof(half), 3*sizeof(half),
00100 3*xRes*sizeof(half)));
00101 fb.insert("B", Slice(HALF, (char *)hrgb+2*sizeof(half), 3*sizeof(half),
00102 3*xRes*sizeof(half)));
00103 fb.insert("A", Slice(HALF, (char *)ha, sizeof(half), xRes*sizeof(half)));
00104
00105 OutputFile file(name.c_str(), header);
00106 file.setFrameBuffer(fb);
00107 try {
00108 file.writePixels(yRes);
00109 }
00110 catch (const std::exception &e) {
00111 Error("Unable to write image file \"%s\": %s", name.c_str(),
00112 e.what());
00113 }
00114
00115 delete[] (hrgb + 3 * (xOffset + yOffset * xRes));
00116 delete[] (ha + (xOffset + yOffset * xRes));
00117 }