void writeTiled1 (const char fileName[], Array2D<GZ> &pixels, int width, int height, int tileWidth, int tileHeight) { Header header (width, height); header.channels().insert ("G", Channel (HALF)); header.channels().insert ("Z", Channel (FLOAT)); header.setTileDescription (TileDescription (tileWidth, tileHeight, ONE_LEVEL)); TiledOutputFile out (fileName, header); FrameBuffer frameBuffer; frameBuffer.insert ("G", // name Slice (HALF, // type (char *) &pixels[0][0].g, // base sizeof (pixels[0][0]) * 1, // xStride sizeof (pixels[0][0]) * width)); // yStride frameBuffer.insert ("Z", // name Slice (FLOAT, // type (char *) &pixels[0][0].z, // base sizeof (pixels[0][0]) * 1, // xStride sizeof (pixels[0][0]) * width)); // yStride out.setFrameBuffer (frameBuffer); out.writeTiles (0, out.numXTiles() - 1, 0, out.numYTiles() - 1); }
void write_to_exr_file (const string& file_name_) { Header header (m_x_res, m_y_res); //edit the active zone. Box2i data_window (V2i (0, 0), V2i (m_x_res - 1, m_y_res - 1)); header.dataWindow() = data_window; //beuark. header.channels().insert ("R", Channel (HALF)); header.channels().insert ("G", Channel (HALF)); header.channels().insert ("B", Channel (HALF)); const int x_count = m_x_res; const int nb_pixels = m_x_res * m_y_res; half * half_rgb = new half[3 * nb_pixels]; int offset = 0; int num_pixel = 0; for (int y = 0; y < m_y_res; y++) { for (int x = 0; x < m_x_res; x++, num_pixel++) { Color color = pixel (x, y); for (int i = 0; i < 3; i++, offset++) { half_rgb[offset] = color[i]; } } } offset = 0; half_rgb -= 3 * offset; FrameBuffer fb; //there are 3 * sizeof(half) bytes between two R elements. fb.insert ("R", Slice (HALF, (char *)half_rgb, 3 * sizeof (half), 3 * x_count * sizeof (half))); //the first element of G is sizeof(half) after the first element of R. fb.insert ("G", Slice (HALF, (char *)half_rgb + sizeof(half), 3 * sizeof (half), 3 * x_count * sizeof (half))); //the first B element is 2 * sizeof (half) bytes after the first element of R. fb.insert ("B", Slice (HALF, (char *)half_rgb + 2 * sizeof(half), 3 * sizeof (half), 3 * x_count * sizeof (half))); try { OutputFile file (file_name_.c_str(), header); file.setFrameBuffer (fb); //y_count() rows to write file.writePixels (m_y_res); } catch (const std::exception &e) { std::cerr<<"Unable to write image file "<<file_name_<<" : "<<e.what()<<std::endl; } //release the memory, but come back to the real address before. delete[] (half_rgb + 3 * offset); }
static int imb_save_openexr_float(struct ImBuf *ibuf, const char *name, int flags) { int channels = ibuf->channels; int width = ibuf->x; int height = ibuf->y; int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize try { Header header (width, height); openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS); openexr_header_metadata(&header, ibuf); header.channels().insert ("R", Channel (FLOAT)); header.channels().insert ("G", Channel (FLOAT)); header.channels().insert ("B", Channel (FLOAT)); if (ibuf->depth==32 && channels >= 4) header.channels().insert ("A", Channel (FLOAT)); if (write_zbuf) header.channels().insert ("Z", Channel (FLOAT)); FrameBuffer frameBuffer; OutputFile *file = new OutputFile(name, header); int xstride = sizeof(float) * channels; int ystride = - xstride*width; float *rect[4] = {NULL, NULL, NULL, NULL}; /* last scanline, stride negative */ rect[0]= ibuf->rect_float + channels*(height-1)*width; rect[1]= rect[0]+1; rect[2]= rect[0]+2; rect[3]= (channels >= 4)? rect[0]+3:rect[0]; /* red as alpha, is this needed since alpha isnt written? */ frameBuffer.insert ("R", Slice (FLOAT, (char *)rect[0], xstride, ystride)); frameBuffer.insert ("G", Slice (FLOAT, (char *)rect[1], xstride, ystride)); frameBuffer.insert ("B", Slice (FLOAT, (char *)rect[2], xstride, ystride)); if (ibuf->depth==32 && channels >= 4) frameBuffer.insert ("A", Slice (FLOAT, (char *)rect[3], xstride, ystride)); if (write_zbuf) frameBuffer.insert ("Z", Slice (FLOAT, (char *) (ibuf->zbuf_float + (height-1)*width), sizeof(float), sizeof(float) * -width)); file->setFrameBuffer (frameBuffer); file->writePixels (height); delete file; } catch (const std::exception &exc) { printf("OpenEXR-save: ERROR: %s\n", exc.what()); if (ibuf) IMB_freeImBuf(ibuf); return (0); } return (1); // printf("OpenEXR-save: Done.\n"); }
void CompositeDeepScanLine::Data::check_valid(const Header & header) { bool has_z=false; bool has_alpha=false; // check good channel names for( ChannelList::ConstIterator i=header.channels().begin();i!=header.channels().end();++i) { std::string n(i.name()); if(n=="ZBack") { _zback=true; } else if(n=="Z") { has_z=true; } else if(n=="A") { has_alpha=true; } } if(!has_z) { throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine is missing a Z channel"); } if(!has_alpha) { throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine is missing an alpha channel"); } if(_part.size()==0 && _file.size()==0) { // first in - update and return _dataWindow = header.dataWindow(); return; } const Header * const match_header = _part.size()>0 ? &_part[0]->header() : &_file[0]->header(); // check the sizes match if(match_header->displayWindow() != header.displayWindow()) { throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine has a different displayWindow to previously provided data"); } _dataWindow.extendBy(header.dataWindow()); }
void saveEXRRGBA(const char* filename, int width, int height, float* data) { half *idr_r = new half[ width * height]; half *idr_g = new half[ width * height]; half *idr_b = new half[ width * height]; half *idr_a = new half[ width * height]; for(int j=0; j< height; j++) { int invj = height - 1 -j; for(int i=0; i< width; i++) { idr_r[j* width + i] = (half)data[(invj* width + i)*4]; idr_g[j* width + i] = (half)data[(invj* width + i)*4+1]; idr_b[j* width + i] = (half)data[(invj* width + i)*4+2]; idr_a[j* width + i] = (half)data[(invj* width + i)*4+3]; } } // write exr Header idrheader ( width, height); idrheader.channels().insert ("R", Channel (HALF)); idrheader.channels().insert ("G", Channel (HALF)); // 1 idrheader.channels().insert ("B", Channel (HALF)); idrheader.channels().insert ("A", Channel (HALF)); // 2 OutputFile idrfile (filename, idrheader); // 4 FrameBuffer idrframeBuffer; idrframeBuffer.insert ("R", // name // 6 Slice (HALF, // type // 7 (char *) idr_r, // base // 8 sizeof (*idr_r) * 1, // xStride// 9 sizeof (*idr_r) * width)); idrframeBuffer.insert ("G", // name // 6 Slice (HALF, // type // 7 (char *) idr_g, // base // 8 sizeof (*idr_g) * 1, // xStride// 9 sizeof (*idr_g) * width)); idrframeBuffer.insert ("B", // name // 6 Slice (HALF, // type // 7 (char *) idr_b, // base // 8 sizeof (*idr_b) * 1, // xStride// 9 sizeof (*idr_b) * width)); idrframeBuffer.insert ("A", // name // 6 Slice (HALF, // type // 7 (char *) idr_a, // base // 8 sizeof (*idr_a) * 1, // xStride// 9 sizeof (*idr_a) * width)); idrfile.setFrameBuffer (idrframeBuffer); // 16 idrfile.writePixels ( height); // cleanup delete[] idr_r; delete[] idr_g; delete[] idr_b; delete[] idr_a; }
void writeEXRHalf(OStream *ost, const float *pixels, int width, int height, int components) { //assert(components==3 || components==4); // TODO: throw std::exception if invalid number of components Header header (width, height); header.channels().insert ("R", Channel (HALF)); header.channels().insert ("G", Channel (HALF)); header.channels().insert ("B", Channel (HALF)); if(components==4) header.channels().insert ("A", Channel (HALF)); // Convert data to half half *data = new half [width*height*components]; std::copy(pixels, pixels+(width*height*components), data); // And save it OutputFile file (*ost, header); FrameBuffer frameBuffer; frameBuffer.insert("R", // name Slice (HALF, // type ((char *) data)+0, // base 2 * components, // xStride 2 * components * width)); // yStride frameBuffer.insert("G", // name Slice (HALF, // type ((char *) data)+2, // base 2 * components, // xStride 2 * components * width)); // yStride frameBuffer.insert("B", // name Slice (HALF, // type ((char *) data)+4, // base 2 * components, // xStride 2 * components * width)); // yStride if(components==4) { frameBuffer.insert("A", // name Slice (HALF, // type ((char *) data)+6, // base 2 * components, // xStride 2 * components * width)); // yStride } file.setFrameBuffer(frameBuffer); file.writePixels(height); delete data; }
RgbaOutputFile::RgbaOutputFile (const char name[], const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, RgbaChannels rgbaChannels, float pixelAspectRatio, const Imath::V2f screenWindowCenter, float screenWindowWidth, LineOrder lineOrder, Compression compression): _outputFile (0) { Header hd (displayWindow, dataWindow.isEmpty()? displayWindow: dataWindow, pixelAspectRatio, screenWindowCenter, screenWindowWidth, lineOrder, compression); ChannelList ch; if (rgbaChannels & WRITE_R) ch.insert ("R", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_G) ch.insert ("G", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_B) ch.insert ("B", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_A) ch.insert ("A", Channel (HALF, 1, 1)); hd.channels() = ch; _outputFile = new OutputFile (name, hd); }
RgbaOutputFile::RgbaOutputFile (const char name[], int width, int height, RgbaChannels rgbaChannels, float pixelAspectRatio, const Imath::V2f screenWindowCenter, float screenWindowWidth, LineOrder lineOrder, Compression compression): _outputFile (0) { Header hd (width, height, pixelAspectRatio, screenWindowCenter, screenWindowWidth, lineOrder, compression); ChannelList ch; if (rgbaChannels & WRITE_R) ch.insert ("R", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_G) ch.insert ("G", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_B) ch.insert ("B", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_A) ch.insert ("A", Channel (HALF, 1, 1)); hd.channels() = ch; _outputFile = new OutputFile (name, hd); }
void writeGZ2 (const char fileName[], const half *gPixels, const float *zPixels, int width, int height, const Box2i &dataWindow) { // // Write an image with only a G (green) and a Z (depth) channel, // using class OutputFile. Don't store the whole image in the // file, but crop it according to the given data window. // // - create a file header // - set the header's data window // - add G and Z channels to the header // - open the file, and store the header in the file // - describe the memory layout of the G anx Z pixels // - store the pixels in the file // Header header (width, height); header.dataWindow() = dataWindow; header.channels().insert ("G", Channel (IMF::HALF)); header.channels().insert ("Z", Channel (IMF::FLOAT)); OutputFile file (fileName, header); FrameBuffer frameBuffer; frameBuffer.insert ("G", // name Slice (IMF::HALF, // type (char *) gPixels, // base sizeof (*gPixels) * 1, // xStride sizeof (*gPixels) * width)); // yStride frameBuffer.insert ("Z", // name Slice (IMF::FLOAT, // type (char *) zPixels, // base sizeof (*zPixels) * 1, // xStride sizeof (*zPixels) * width)); // yStride file.setFrameBuffer (frameBuffer); file.writePixels (dataWindow.max.y - dataWindow.min.y + 1); }
//////////////////////////////////////////////////////////////////////////////// // Saves an EXR file from Array<Rgba> data. //////////////////////////////////////////////////////////////////////////////// static bool saveEXRFile (const char *filename, const int width, const int height, Array<Rgba>* imageData) { if (filename == NULL || imageData == NULL || width <= 0 || height <= 0) { printf("Cannot write EXR file: invalid filename or image data.\n"); return false; } // prepare header Header header (width, height); header.channels().insert ("R", Channel (HALF)); header.channels().insert ("G", Channel (HALF)); header.channels().insert ("B", Channel (HALF)); // create file OutputFile exrFile (filename, header); // insert frame buffer FrameBuffer frameBuffer; frameBuffer.insert ("R", // name Slice (HALF, // type (char *) &(((Rgba*)imageData[0])->r), // base sizeof (Rgba), // xStride sizeof (Rgba) * width)); // yStride frameBuffer.insert ("G", // name Slice (HALF, // type (char *) &(((Rgba*)imageData[0])->g), // base sizeof (Rgba), // xStride sizeof (Rgba) * width)); // yStride frameBuffer.insert ("B", // name Slice (HALF, // type (char *) &(((Rgba*)imageData[0])->b), // base sizeof (Rgba), // xStride sizeof (Rgba) * width)); // yStride exrFile.setFrameBuffer (frameBuffer); exrFile.writePixels (height); return true; }
void writeGZ1 (const char fileName[], const half *gPixels, const float *zPixels, int width, int height) { // // Write an image with only a G (green) and a Z (depth) channel, // using class OutputFile. // // - create a file header // - add G and Z channels to the header // - open the file, and store the header in the file // - describe the memory layout of the G anx Z pixels // - store the pixels in the file // Header header (width, height); header.channels().insert ("G", Channel (IMF::HALF)); header.channels().insert ("Z", Channel (IMF::FLOAT)); OutputFile file (fileName, header); FrameBuffer frameBuffer; frameBuffer.insert ("G", // name Slice (IMF::HALF, // type (char *) gPixels, // base sizeof (*gPixels) * 1, // xStride sizeof (*gPixels) * width)); // yStride frameBuffer.insert ("Z", // name Slice (IMF::FLOAT, // type (char *) zPixels, // base sizeof (*zPixels) * 1, // xStride sizeof (*zPixels) * width)); // yStride file.setFrameBuffer (frameBuffer); file.writePixels (height); }
size_t calculateBytesPerPixel (const Header &header) { const ChannelList &channels = header.channels(); size_t bytesPerPixel = 0; for (ChannelList::ConstIterator c = channels.begin(); c != channels.end(); ++c) { bytesPerPixel += pixelTypeSize (c.channel().type); } return bytesPerPixel; }
void ZFnEXR::saveCameraNZ(float* data, M44f mat, float fov, const char* filename, int width, int height) { Header header (width, height); header.insert ("fov", DoubleAttribute (fov)); header.insert ("cameraTransform", M44fAttribute (mat)); header.channels().insert ("R", Channel (FLOAT)); OutputFile file (filename, header); FrameBuffer frameBuffer; frameBuffer.insert ("R", Slice (FLOAT, (char *) data, sizeof (*data) * 1, sizeof (*data) * width)); file.setFrameBuffer (frameBuffer); file.writePixels (height); }
void writeMultiImageEXR (const char *fileName, float *zPixels, int width, int height, int nchan) { int nhnc = height*width; Header header (width, height); for(int i =0; i<nchan;i++) { char ch_name[10]; sprintf(ch_name,"Bin_%04d",i); header.channels().insert (ch_name, Channel (FLOAT)); } OutputFile file(fileName, header); FrameBuffer frameBuffer; for(int i =0; i<nchan;i++) { char ch_name[10]; sprintf(ch_name,"Bin_%04d",i); frameBuffer.insert (ch_name, // name Slice (FLOAT, // type (char *) &zPixels[i*nhnc], // base sizeof (*zPixels) * 1, // xStride sizeof (*zPixels) * width)); // yStride } file.setFrameBuffer (frameBuffer); file.writePixels (height); }
/* only used for writing temp. render results (not image files) */ void IMB_exr_begin_write(void *handle, const char *filename, int width, int height, int compress) { ExrHandle *data= (ExrHandle *)handle; Header header (width, height); ExrChannel *echan; data->width= width; data->height= height; for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) header.channels().insert (echan->name, Channel (FLOAT)); openexr_header_compression(&header, compress); // openexr_header_metadata(&header, ibuf); // no imbuf. cant write /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */ header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.55.1 and newer")); data->ofile = new OutputFile(filename, header); }
RgbaOutputFile::RgbaOutputFile (const char name[], const Header &header, RgbaChannels rgbaChannels): _outputFile (0) { Header hd (header); ChannelList ch; if (rgbaChannels & WRITE_R) ch.insert ("R", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_G) ch.insert ("G", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_B) ch.insert ("B", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_A) ch.insert ("A", Channel (HALF, 1, 1)); hd.channels() = ch; _outputFile = new OutputFile (name, hd); }
void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley) { ExrHandle *data= (ExrHandle *)handle; Header header (width, height); ExrChannel *echan; data->tilex= tilex; data->tiley= tiley; data->width= width; data->height= height; data->mipmap= mipmap; for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) header.channels().insert (echan->name, Channel (FLOAT)); header.setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL)); header.lineOrder() = RANDOM_Y; header.compression() = RLE_COMPRESSION; header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43")); data->tofile = new TiledOutputFile(filename, header); }
void GPUOctree::dumpIndirection(const char *filename) { m_idr = new short[INDIRECTIONPOOLSIZE*4]; m_dt = new float[DATAPOOLSIZE*4]; setIndirection(m_root); half *idr_r = new half[INDIRECTIONPOOLSIZE]; half *idr_g = new half[INDIRECTIONPOOLSIZE]; half *idr_b = new half[INDIRECTIONPOOLSIZE]; half *idr_a = new half[INDIRECTIONPOOLSIZE]; for(long i=0; i<INDIRECTIONPOOLSIZE; i++) { idr_r[i] = (half)m_idr[i*4]; idr_g[i] = (half)m_idr[i*4+1]; idr_b[i] = (half)m_idr[i*4+2]; idr_a[i] = (half)m_idr[i*4+3]; } // save indirection Header idrheader (INDIRECTIONPOOLWIDTH, INDIRECTIONPOOLWIDTH); idrheader.insert ("root_size", FloatAttribute (m_rootSize)); idrheader.insert ("root_center", V3fAttribute (Imath::V3f(m_rootCenter.x, m_rootCenter.y, m_rootCenter.z))); idrheader.channels().insert ("R", Channel (HALF)); idrheader.channels().insert ("G", Channel (HALF)); // 1 idrheader.channels().insert ("B", Channel (HALF)); idrheader.channels().insert ("A", Channel (HALF)); // 2 std::string idrname = filename; idrname += ".idr"; OutputFile idrfile (idrname.c_str(), idrheader); // 4 FrameBuffer idrframeBuffer; idrframeBuffer.insert ("R", // name // 6 Slice (HALF, // type // 7 (char *) idr_r, // base // 8 sizeof (*idr_r) * 1, // xStride// 9 sizeof (*idr_r) * INDIRECTIONPOOLWIDTH)); idrframeBuffer.insert ("G", // name // 6 Slice (HALF, // type // 7 (char *) idr_g, // base // 8 sizeof (*idr_g) * 1, // xStride// 9 sizeof (*idr_g) * INDIRECTIONPOOLWIDTH)); idrframeBuffer.insert ("B", // name // 6 Slice (HALF, // type // 7 (char *) idr_b, // base // 8 sizeof (*idr_b) * 1, // xStride// 9 sizeof (*idr_b) * INDIRECTIONPOOLWIDTH)); idrframeBuffer.insert ("A", // name // 6 Slice (HALF, // type // 7 (char *) idr_a, // base // 8 sizeof (*idr_a) * 1, // xStride// 9 sizeof (*idr_a) * INDIRECTIONPOOLWIDTH)); idrfile.setFrameBuffer (idrframeBuffer); // 16 idrfile.writePixels (INDIRECTIONPOOLWIDTH); delete[] idr_r; delete[] idr_g; delete[] idr_b; delete[] idr_a; // save data half *dt_r = new half[DATAPOOLSIZE]; half *dt_g = new half[DATAPOOLSIZE]; half *dt_b = new half[DATAPOOLSIZE]; half *dt_a = new half[DATAPOOLSIZE]; for(long i=0; i<DATAPOOLSIZE; i++) { dt_r[i] = (half)m_dt[i*4]; dt_g[i] = (half)m_dt[i*4+1]; dt_b[i] = (half)m_dt[i*4+2]; dt_a[i] = (half)m_dt[i*4+3]; } Header dtheader (DATAPOOLWIDTH, DATAPOOLWIDTH); dtheader.channels().insert ("R", Channel (HALF)); dtheader.channels().insert ("G", Channel (HALF)); // 1 dtheader.channels().insert ("B", Channel (HALF)); dtheader.channels().insert ("A", Channel (HALF)); // 2 std::string dtname = filename; dtname += ".exr"; OutputFile dtfile (dtname.c_str(), dtheader); // 4 FrameBuffer dtframeBuffer; dtframeBuffer.insert ("R", // name // 6 Slice (HALF, // type // 7 (char *) dt_r, // base // 8 sizeof (*dt_r) * 1, // xStride// 9 sizeof (*dt_r) * DATAPOOLWIDTH)); dtframeBuffer.insert ("G", // name // 6 Slice (HALF, // type // 7 (char *) dt_g, // base // 8 sizeof (*dt_g) * 1, // xStride// 9 sizeof (*dt_g) * DATAPOOLWIDTH)); dtframeBuffer.insert ("B", // name // 6 Slice (HALF, // type // 7 (char *) dt_b, // base // 8 sizeof (*dt_b) * 1, // xStride// 9 sizeof (*dt_b) * DATAPOOLWIDTH)); dtframeBuffer.insert ("A", // name // 6 Slice (HALF, // type // 7 (char *) dt_a, // base // 8 sizeof (*dt_a) * 1, // xStride// 9 sizeof (*dt_a) * DATAPOOLWIDTH)); dtfile.setFrameBuffer (dtframeBuffer); // 16 dtfile.writePixels (DATAPOOLWIDTH); delete[] dt_r; delete[] dt_g; delete[] dt_b; delete[] dt_a; }
static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags) { int channels = ibuf->channels; int width = ibuf->x; int height = ibuf->y; int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize try { Header header (width, height); openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS); openexr_header_metadata(&header, ibuf); header.channels().insert ("R", Channel (HALF)); header.channels().insert ("G", Channel (HALF)); header.channels().insert ("B", Channel (HALF)); if (ibuf->depth==32 && channels >= 4) header.channels().insert ("A", Channel (HALF)); if (write_zbuf) // z we do as float always header.channels().insert ("Z", Channel (FLOAT)); FrameBuffer frameBuffer; OutputFile *file = new OutputFile(name, header); /* we store first everything in half array */ RGBAZ *pixels = new RGBAZ[height * width]; RGBAZ *to = pixels; int xstride= sizeof (RGBAZ); int ystride= xstride*width; /* indicate used buffers */ frameBuffer.insert ("R", Slice (HALF, (char *) &pixels[0].r, xstride, ystride)); frameBuffer.insert ("G", Slice (HALF, (char *) &pixels[0].g, xstride, ystride)); frameBuffer.insert ("B", Slice (HALF, (char *) &pixels[0].b, xstride, ystride)); if (ibuf->depth==32 && channels >= 4) frameBuffer.insert ("A", Slice (HALF, (char *) &pixels[0].a, xstride, ystride)); if (write_zbuf) frameBuffer.insert ("Z", Slice (FLOAT, (char *)(ibuf->zbuf_float + (height-1)*width), sizeof(float), sizeof(float) * -width)); if(ibuf->rect_float) { float *from; /* OCIO TODO: do this before save in BKE image.c where colormanagement is available */ // if(ibuf->profile == IB_PROFILE_LINEAR_RGB) { for (int i = ibuf->y-1; i >= 0; i--) { from= ibuf->rect_float + channels*i*width; for (int j = ibuf->x; j > 0; j--) { to->r = from[0]; to->g = from[1]; to->b = from[2]; to->a = (channels >= 4)? from[3]: 1.0f; to++; from += 4; } } // } // else { // for (int i = ibuf->y-1; i >= 0; i--) // { // from= ibuf->rect_float + channels*i*width; // for (int j = ibuf->x; j > 0; j--) // { // to->r = srgb_to_linearrgb(from[0]); // to->g = srgb_to_linearrgb(from[1]); // to->b = srgb_to_linearrgb(from[2]); // to->a = (channels >= 4)? from[3]: 1.0f; // to++; from += 4; // } // } // } } else { unsigned char *from; // if(ibuf->profile == IB_PROFILE_LINEAR_RGB) { for (int i = ibuf->y-1; i >= 0; i--) { from= (unsigned char *)ibuf->rect + channels*i*width; for (int j = ibuf->x; j > 0; j--) { to->r = (float)(from[0])/255.0; to->g = (float)(from[1])/255.0; to->b = (float)(from[2])/255.0; to->a = (float)(channels >= 4) ? from[3]/255.0 : 1.0f; to++; from += 4; } } // } // else { // for (int i = ibuf->y-1; i >= 0; i--) // { // from= (unsigned char *)ibuf->rect + channels*i*width; // for (int j = ibuf->x; j > 0; j--) // { // to->r = srgb_to_linearrgb((float)from[0] / 255.0); // to->g = srgb_to_linearrgb((float)from[1] / 255.0); // to->b = srgb_to_linearrgb((float)from[2] / 255.0); // to->a = channels >= 4 ? (float)from[3]/255.0 : 1.0f; // to++; from += 4; // } // } // } } // printf("OpenEXR-save: Writing OpenEXR file of height %d.\n", height); file->setFrameBuffer (frameBuffer); file->writePixels (height); delete file; delete [] pixels; } catch (const std::exception &exc) { printf("OpenEXR-save: ERROR: %s\n", exc.what()); if (ibuf) IMB_freeImBuf(ibuf); return (0); } return (1); }
void makeMultiView (const vector <string> &viewNames, const vector <const char *> &inFileNames, const char *outFileName, Compression compression, bool verbose) { Header header; Image image; FrameBuffer outFb; // // Find the size of the dataWindow, check files // Box2i d; for (int i = 0; i < viewNames.size(); ++i) { InputFile in (inFileNames[i]); if (verbose) { cout << "reading file " << inFileNames[i] << " " "for " << viewNames[i] << " view" << endl; } if (hasMultiView (in.header())) { THROW (IEX_NAMESPACE::NoImplExc, "The image in file " << inFileNames[i] << " is already a " "multi-view image. Cannot combine multiple multi-view " "images."); } header = in.header(); if (i == 0) { d=header.dataWindow(); }else{ d.extendBy(header.dataWindow()); } } image.resize (d); header.dataWindow()=d; // blow away channels; we'll rebuild them header.channels()=ChannelList(); // // Read the input image files // for (int i = 0; i < viewNames.size(); ++i) { InputFile in (inFileNames[i]); if (verbose) { cout << "reading file " << inFileNames[i] << " " "for " << viewNames[i] << " view" << endl; } FrameBuffer inFb; for (ChannelList::ConstIterator j = in.header().channels().begin(); j != in.header().channels().end(); ++j) { const Channel &inChannel = j.channel(); string inChanName = j.name(); string outChanName = insertViewName (inChanName, viewNames, i); image.addChannel (outChanName, inChannel); image.channel(outChanName).black(); header.channels().insert (outChanName, inChannel); inFb.insert (inChanName, image.channel(outChanName).slice()); outFb.insert (outChanName, image.channel(outChanName).slice()); } in.setFrameBuffer (inFb); in.readPixels (in.header().dataWindow().min.y, in.header().dataWindow().max.y); } // // Write the output image file // { header.compression() = compression; addMultiView (header, viewNames); OutputFile out (outFileName, header); if (verbose) cout << "writing file " << outFileName << endl; out.setFrameBuffer (outFb); out.writePixels (header.dataWindow().max.y - header.dataWindow().min.y + 1); } }