// // SPDX-License-Identifier: BSD-3-Clause // Copyright (c) Contributors to the OpenEXR Project. // //----------------------------------------------------------------------------- // // Code examples that show how class RgbaInputFile and // class RgbaOutputFile can be used to read and write // OpenEXR image files with 16-bit floating-point red, // green, blue and alpha channels. // //----------------------------------------------------------------------------- #include #include #include #include #include "drawImage.h" #include #include #include "namespaceAlias.h" using namespace IMF; using namespace std; using namespace IMATH_NAMESPACE; void writeRgba1 (const char fileName[], const Rgba* pixels, int width, int height) { // // Write an RGBA image using class RgbaOutputFile. // // - open the file // - describe the memory layout of the pixels // - store the pixels in the file // RgbaOutputFile file (fileName, width, height, WRITE_RGBA); file.setFrameBuffer (pixels, 1, width); file.writePixels (height); } void writeRgba2 ( const char fileName[], const Rgba* pixels, int width, int height, const Box2i& dataWindow) { // // Write an RGBA image using class RgbaOutputFile. // Don't store the whole image in the file, but // crop it according to the given data window. // // - open the file // - describe the memory layout of the pixels // - store the pixels in the file // Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1)); RgbaOutputFile file (fileName, displayWindow, dataWindow, WRITE_RGBA); file.setFrameBuffer (pixels, 1, width); file.writePixels (dataWindow.max.y - dataWindow.min.y + 1); } void writeRgba3 ( const char fileName[], const Rgba* pixels, int width, int height, const char comments[], const M44f& cameraTransform) { // // Write an RGBA image using class RgbaOutputFile. // Store two extra attributes in the image header: // a string and a 4x4 transformation matrix. // // - open the file // - describe the memory layout of the pixels // - store the pixels in the file // Header header (width, height); header.insert ("comments", StringAttribute (comments)); header.insert ("cameraTransform", M44fAttribute (cameraTransform)); RgbaOutputFile file (fileName, header, WRITE_RGBA); file.setFrameBuffer (pixels, 1, width); file.writePixels (height); } void readRgba1 ( const char fileName[], Array2D& pixels, int& width, int& height) { // // Read an RGBA image using class RgbaInputFile: // // - open the file // - allocate memory for the pixels // - describe the memory layout of the pixels // - read the pixels from the file // RgbaInputFile file (fileName); Box2i dw = file.dataWindow (); width = dw.max.x - dw.min.x + 1; height = dw.max.y - dw.min.y + 1; pixels.resizeErase (height, width); file.setFrameBuffer (&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width); file.readPixels (dw.min.y, dw.max.y); } void readRgba2 (const char fileName[]) { // // Read an RGBA image using class RgbaInputFile. // Read the pixels, 10 scan lines at a time, and // store the pixel data in a buffer that is just // large enough to hold 10 scan lines worth of data. // // - open the file // - allocate memory for the pixels // - for each block of 10 scan lines, // describe the memory layout of the pixels, // read the pixels from the file, // process the pixels and discard them // RgbaInputFile file (fileName); Box2i dw = file.dataWindow (); int width = dw.max.x - dw.min.x + 1; Array2D pixels (10, width); while (dw.min.y <= dw.max.y) { file.setFrameBuffer ( &pixels[0][0] - dw.min.x - dw.min.y * width, 1, width); file.readPixels (dw.min.y, min (dw.min.y + 9, dw.max.y)); // processPixels (pixels) dw.min.y += 10; } } void readHeader (const char fileName[]) { // // Read an image's header from a file, and if the header // contains comments and camera transformation attributes, // print the values of those attributes. // // - open the file // - get the file header // - look for the attributes // RgbaInputFile file (fileName); const StringAttribute* comments = file.header ().findTypedAttribute ("comments"); const M44fAttribute* cameraTransform = file.header ().findTypedAttribute ("cameraTransform"); if (comments) cout << "comments\n " << comments->value () << endl; if (cameraTransform) cout << "cameraTransform\n" << cameraTransform->value () << flush; } void rgbaInterfaceExamples () { cout << "\nRGBA images\n" << endl; cout << "drawing image" << endl; int w = 800; int h = 600; Array2D p (h, w); drawImage1 (p, w, h); cout << "writing entire image" << endl; writeRgba1 ("rgba1.exr", &p[0][0], w, h); cout << "writing cropped image" << endl; writeRgba2 ( "rgba2.exr", &p[0][0], w, h, Box2i (V2i (w / 6, h / 6), V2i (w / 2, h / 2))); cout << "writing image with extra header attributes" << endl; writeRgba3 ("rgba3.exr", &p[0][0], w, h, "may contain peanuts", M44f ()); cout << "reading rgba file" << endl; readRgba1 ("rgba2.exr", p, w, h); cout << "reading rgba file into 10-scanline buffer" << endl; readRgba2 ("rgba2.exr"); cout << "reading extra file header attributes" << endl; readHeader ("rgba3.exr"); }