--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////\r
+//\r
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
+//\r
+// By downloading, copying, installing or using the software you agree to this license.\r
+// If you do not agree to this license, do not download, install,\r
+// copy or use the software.\r
+//\r
+//\r
+// License Agreement\r
+// For Open Source Computer Vision Library\r
+//\r
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.\r
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.\r
+// Third party copyrights are property of their respective owners.\r
+//\r
+// Redistribution and use in source and binary forms, with or without modification,\r
+// are permitted provided that the following conditions are met:\r
+//\r
+// * Redistribution's of source code must retain the above copyright notice,\r
+// this list of conditions and the following disclaimer.\r
+//\r
+// * Redistribution's in binary form must reproduce the above copyright notice,\r
+// this list of conditions and the following disclaimer in the documentation\r
+// and/or other materials provided with the distribution.\r
+//\r
+// * The name of the copyright holders may not be used to endorse or promote products\r
+// derived from this software without specific prior written permission.\r
+//\r
+// This software is provided by the copyright holders and contributors "as is" and\r
+// any express or implied warranties, including, but not limited to, the implied\r
+// warranties of merchantability and fitness for a particular purpose are disclaimed.\r
+// In no event shall the Intel Corporation or contributors be liable for any direct,\r
+// indirect, incidental, special, exemplary, or consequential damages\r
+// (including, but not limited to, procurement of substitute goods or services;\r
+// loss of use, data, or profits; or business interruption) however caused\r
+// and on any theory of liability, whether in contract, strict liability,\r
+// or tort (including negligence or otherwise) arising in any way out of\r
+// the use of this software, even if advised of the possibility of such damage.\r
+//\r
+//M*/\r
+\r
+#include "_highgui.h"\r
+\r
+#ifdef HAVE_ILMIMF\r
+\r
+#include <OpenEXR/ImfHeader.h>\r
+#include <OpenEXR/ImfInputFile.h>\r
+#include <OpenEXR/ImfOutputFile.h>\r
+#include <OpenEXR/ImfChannelList.h>\r
+#include <OpenEXR/ImfStandardAttributes.h>\r
+#include <OpenEXR/half.h>\r
+#include "grfmt_exr.h"\r
+\r
+#if defined _MSC_VER && _MSC_VER >= 1200\r
+#pragma comment(lib, "Half.lib")\r
+#pragma comment(lib, "Iex.lib")\r
+#pragma comment(lib, "IlmImf.lib")\r
+#pragma comment(lib, "IlmThread.lib")\r
+#pragma comment(lib, "Imath.lib")\r
+\r
+#undef UINT\r
+#define UINT ((Imf::PixelType)0)\r
+#undef HALF\r
+#define HALF ((Imf::PixelType)1)\r
+#undef FLOAT\r
+#define FLOAT ((Imf::PixelType)2)\r
+#undef uint\r
+#define uint unsigned\r
+\r
+#endif\r
+\r
+namespace cv\r
+{\r
+\r
+/////////////////////// ExrDecoder ///////////////////\r
+\r
+ExrDecoder::ExrDecoder()\r
+{\r
+ m_signature = "\x76\x2f\x31\x01";\r
+ m_file = new InputFile( filename );\r
+ m_red = m_green = m_blue = 0;\r
+}\r
+\r
+\r
+ExrDecoder::~ExrDecoder()\r
+{\r
+ close();\r
+}\r
+\r
+\r
+void ExrDecoder::close()\r
+{\r
+ if( m_file )\r
+ {\r
+ delete m_file;\r
+ m_file = 0;\r
+ }\r
+}\r
+\r
+bool ExrDecoder::readHeader()\r
+{\r
+ bool result = false;\r
+\r
+ if( !m_file ) // probably paranoid\r
+ return false;\r
+\r
+ m_datawindow = m_file->header().dataWindow();\r
+ m_width = m_datawindow.max.x - m_datawindow.min.x + 1;\r
+ m_height = m_datawindow.max.y - m_datawindow.min.y + 1;\r
+\r
+ // the type HALF is converted to 32 bit float\r
+ // and the other types supported by OpenEXR are 32 bit anyway\r
+ m_bit_depth = 32;\r
+\r
+ if( hasChromaticities( m_file->header() ))\r
+ m_chroma = chromaticities( m_file->header() );\r
+\r
+ const ChannelList &channels = m_file->header().channels();\r
+ m_red = channels.findChannel( "R" );\r
+ m_green = channels.findChannel( "G" );\r
+ m_blue = channels.findChannel( "B" );\r
+ if( m_red || m_green || m_blue )\r
+ {\r
+ m_iscolor = true;\r
+ m_ischroma = false;\r
+ result = true;\r
+ }\r
+ else\r
+ {\r
+ m_green = channels.findChannel( "Y" );\r
+ if( m_green )\r
+ {\r
+ m_ischroma = true;\r
+ m_red = channels.findChannel( "RY" );\r
+ m_blue = channels.findChannel( "BY" );\r
+ m_iscolor = (m_blue || m_red);\r
+ result = true;\r
+ }\r
+ else\r
+ result = false;\r
+ }\r
+\r
+ if( result )\r
+ {\r
+ int uintcnt = 0;\r
+ int chcnt = 0;\r
+ if( m_red )\r
+ {\r
+ chcnt++;\r
+ uintcnt += ( m_red->type == UINT );\r
+ }\r
+ if( m_green )\r
+ {\r
+ chcnt++;\r
+ uintcnt += ( m_green->type == UINT );\r
+ }\r
+ if( m_blue )\r
+ {\r
+ chcnt++;\r
+ uintcnt += ( m_blue->type == UINT );\r
+ }\r
+ m_type = (chcnt == uintcnt) ? UINT : FLOAT;\r
+ \r
+ m_isfloat = (m_type == FLOAT);\r
+ }\r
+\r
+ if( !result )\r
+ Close();\r
+\r
+ return result;\r
+}\r
+\r
+\r
+bool ExrDecoder::readData( Mat& img )\r
+{\r
+ bool color = img.channels() > 1;\r
+ uchar* data = img.data;\r
+ int step = img.step;\r
+ bool justcopy = m_native_depth;\r
+ bool chromatorgb = false;\r
+ bool rgbtogray = false;\r
+ bool result = true;\r
+ FrameBuffer frame;\r
+ int xsample[3] = {1, 1, 1};\r
+ char *buffer;\r
+ int xstep;\r
+ int ystep;\r
+\r
+ xstep = m_native_depth ? 4 : 1;\r
+\r
+ if( !m_native_depth || (!color && m_iscolor ))\r
+ {\r
+ buffer = (char *)new float[ m_width * 3 ];\r
+ ystep = 0;\r
+ }\r
+ else\r
+ {\r
+ buffer = (char *)data;\r
+ ystep = step;\r
+ }\r
+\r
+ if( m_ischroma )\r
+ {\r
+ if( color )\r
+ {\r
+ if( m_iscolor )\r
+ {\r
+ if( m_blue )\r
+ {\r
+ frame.insert( "BY", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,\r
+ 12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));\r
+ xsample[0] = m_blue->ySampling;\r
+ }\r
+ if( m_green )\r
+ {\r
+ frame.insert( "Y", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,\r
+ 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));\r
+ xsample[1] = m_green->ySampling;\r
+ }\r
+ if( m_red )\r
+ {\r
+ frame.insert( "RY", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,\r
+ 12, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));\r
+ xsample[2] = m_red->ySampling;\r
+ }\r
+ chromatorgb = true;\r
+ }\r
+ else\r
+ {\r
+ frame.insert( "Y", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,\r
+ 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));\r
+ frame.insert( "Y", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,\r
+ 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));\r
+ frame.insert( "Y", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,\r
+ 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));\r
+ xsample[0] = m_green->ySampling;\r
+ xsample[1] = m_green->ySampling;\r
+ xsample[2] = m_green->ySampling;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ frame.insert( "Y", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 4 - m_datawindow.min.y * ystep,\r
+ 4, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));\r
+ xsample[0] = m_green->ySampling;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if( m_blue )\r
+ {\r
+ frame.insert( "B", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,\r
+ 12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));\r
+ xsample[0] = m_blue->ySampling;\r
+ }\r
+ if( m_green )\r
+ {\r
+ frame.insert( "G", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,\r
+ 12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));\r
+ xsample[1] = m_green->ySampling;\r
+ }\r
+ if( m_red )\r
+ {\r
+ frame.insert( "R", Slice( m_type,\r
+ buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,\r
+ 12, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));\r
+ xsample[2] = m_red->ySampling;\r
+ }\r
+ if(color == 0)\r
+ {\r
+ rgbtogray = true;\r
+ justcopy = false;\r
+ }\r
+ }\r
+\r
+ m_file->setFrameBuffer( frame );\r
+ if( justcopy )\r
+ {\r
+ m_file->readPixels( m_datawindow.min.y, m_datawindow.max.y );\r
+\r
+ if( color )\r
+ {\r
+ if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) )\r
+ UpSample( data, 3, step / xstep, xsample[0], m_blue->ySampling );\r
+ if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )\r
+ UpSample( data + xstep, 3, step / xstep, xsample[1], m_green->ySampling );\r
+ if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )\r
+ UpSample( data + 2 * xstep, 3, step / xstep, xsample[2], m_red->ySampling );\r
+ }\r
+ else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )\r
+ UpSample( data, 1, step / xstep, xsample[0], m_green->ySampling );\r
+ }\r
+ else\r
+ {\r
+ uchar *out = data;\r
+ int x, y;\r
+ for( y = m_datawindow.min.y; y <= m_datawindow.max.y; y++ )\r
+ {\r
+ m_file->readPixels( y, y );\r
+\r
+ if( rgbtogray )\r
+ {\r
+ if( xsample[0] != 1 )\r
+ UpSampleX( (float *)buffer, 3, xsample[0] );\r
+ if( xsample[1] != 1 )\r
+ UpSampleX( (float *)buffer + 4, 3, xsample[1] );\r
+ if( xsample[2] != 1 )\r
+ UpSampleX( (float *)buffer + 8, 3, xsample[2] );\r
+\r
+ RGBToGray( (float *)buffer, (float *)out );\r
+ }\r
+ else\r
+ {\r
+ if( xsample[0] != 1 )\r
+ UpSampleX( (float *)buffer, 3, xsample[0] );\r
+ if( xsample[1] != 1 )\r
+ UpSampleX( (float *)(buffer + 4), 3, xsample[1] );\r
+ if( xsample[2] != 1 )\r
+ UpSampleX( (float *)(buffer + 8), 3, xsample[2] );\r
+\r
+ if( chromatorgb )\r
+ ChromaToBGR( (float *)buffer, 1, step );\r
+\r
+ if( m_type == FLOAT )\r
+ {\r
+ float *fi = (float *)buffer;\r
+ for( x = 0; x < m_width * 3; x++)\r
+ {\r
+ int t = cvRound(fi[x]*5);\r
+ out[x] = CV_CAST_8U(t);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ uint *ui = (uint *)buffer;\r
+ for( x = 0; x < m_width * 3; x++)\r
+ {\r
+ uint t = ui[x];\r
+ out[x] = CV_CAST_8U(t);\r
+ }\r
+ }\r
+ }\r
+\r
+ out += step;\r
+ }\r
+ if( color )\r
+ {\r
+ if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) )\r
+ UpSampleY( data, 3, step / xstep, m_blue->ySampling );\r
+ if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )\r
+ UpSampleY( data + xstep, 3, step / xstep, m_green->ySampling );\r
+ if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )\r
+ UpSampleY( data + 2 * xstep, 3, step / xstep, m_red->ySampling );\r
+ }\r
+ else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )\r
+ UpSampleY( data, 1, step / xstep, m_green->ySampling );\r
+ }\r
+\r
+ if( chromatorgb )\r
+ ChromaToBGR( (float *)data, m_height, step / xstep );\r
+\r
+ Close();\r
+\r
+ return result;\r
+}\r
+\r
+/**\r
+// on entry pixel values are stored packed in the upper left corner of the image\r
+// this functions expands them by duplication to cover the whole image\r
+ */\r
+void ExrDecoder::UpSample( uchar *data, int xstep, int ystep, int xsample, int ysample )\r
+{\r
+ for( int y = (m_height - 1) / ysample, yre = m_height - ysample; y >= 0; y--, yre -= ysample )\r
+ {\r
+ for( int x = (m_width - 1) / xsample, xre = m_width - xsample; x >= 0; x--, xre -= xsample )\r
+ {\r
+ for( int i = 0; i < ysample; i++ )\r
+ {\r
+ for( int n = 0; n < xsample; n++ )\r
+ {\r
+ if( !m_native_depth )\r
+ data[(yre + i) * ystep + (xre + n) * xstep] = data[y * ystep + x * xstep];\r
+ else if( m_type == FLOAT )\r
+ ((float *)data)[(yre + i) * ystep + (xre + n) * xstep] = ((float *)data)[y * ystep + x * xstep];\r
+ else\r
+ ((uint *)data)[(yre + i) * ystep + (xre + n) * xstep] = ((uint *)data)[y * ystep + x * xstep];\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+// on entry pixel values are stored packed in the upper left corner of the image\r
+// this functions expands them by duplication to cover the whole image\r
+ */\r
+void ExrDecoder::UpSampleX( float *data, int xstep, int xsample )\r
+{\r
+ for( int x = (m_width - 1) / xsample, xre = m_width - xsample; x >= 0; x--, xre -= xsample )\r
+ {\r
+ for( int n = 0; n < xsample; n++ )\r
+ {\r
+ if( m_type == FLOAT )\r
+ ((float *)data)[(xre + n) * xstep] = ((float *)data)[x * xstep];\r
+ else\r
+ ((uint *)data)[(xre + n) * xstep] = ((uint *)data)[x * xstep];\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+// on entry pixel values are stored packed in the upper left corner of the image\r
+// this functions expands them by duplication to cover the whole image\r
+ */\r
+void ExrDecoder::UpSampleY( uchar *data, int xstep, int ystep, int ysample )\r
+{\r
+ for( int y = m_height - ysample, yre = m_height - ysample; y >= 0; y -= ysample, yre -= ysample )\r
+ {\r
+ for( int x = 0; x < m_width; x++ )\r
+ {\r
+ for( int i = 1; i < ysample; i++ )\r
+ {\r
+ if( !m_native_depth )\r
+ data[(yre + i) * ystep + x * xstep] = data[y * ystep + x * xstep];\r
+ else if( m_type == FLOAT )\r
+ ((float *)data)[(yre + i) * ystep + x * xstep] = ((float *)data)[y * ystep + x * xstep];\r
+ else\r
+ ((uint *)data)[(yre + i) * ystep + x * xstep] = ((uint *)data)[y * ystep + x * xstep];\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+// algorithm from ImfRgbaYca.cpp\r
+ */\r
+void ExrDecoder::ChromaToBGR( float *data, int numlines, int step )\r
+{\r
+ int x, y, t;\r
+ \r
+ for( y = 0; y < numlines; y++ )\r
+ {\r
+ for( x = 0; x < m_width; x++ )\r
+ {\r
+ double b, Y, r;\r
+ if( !m_native_depth )\r
+ {\r
+ b = ((uchar *)data)[y * step + x * 3];\r
+ Y = ((uchar *)data)[y * step + x * 3 + 1];\r
+ r = ((uchar *)data)[y * step + x * 3 + 2];\r
+ }\r
+ else if( m_type == FLOAT )\r
+ {\r
+ b = data[y * step + x * 3];\r
+ Y = data[y * step + x * 3 + 1];\r
+ r = data[y * step + x * 3 + 2];\r
+ }\r
+ else\r
+ {\r
+ b = ((uint *)data)[y * step + x * 3];\r
+ Y = ((uint *)data)[y * step + x * 3 + 1];\r
+ r = ((uint *)data)[y * step + x * 3 + 2];\r
+ }\r
+ r = (r + 1) * Y;\r
+ b = (b + 1) * Y;\r
+ Y = (Y - b * m_chroma.blue[1] - r * m_chroma.red[1]) / m_chroma.green[1];\r
+\r
+ if( !m_native_depth )\r
+ {\r
+ int t = cvRound(b);\r
+ ((uchar *)data)[y * step + x * 3] = CV_CAST_8U(t);\r
+ t = cvRound(Y);\r
+ ((uchar *)data)[y * step + x * 3 + 1] = CV_CAST_8U(t);\r
+ t = cvRound(r);\r
+ ((uchar *)data)[y * step + x * 3 + 2] = CV_CAST_8U(t);\r
+ }\r
+ else if( m_type == FLOAT )\r
+ {\r
+ data[y * step + x * 3] = (float)b;\r
+ data[y * step + x * 3 + 1] = (float)Y;\r
+ data[y * step + x * 3 + 2] = (float)r;\r
+ }\r
+ else\r
+ {\r
+ int t = cvRound(b);\r
+ ((uint *)data)[y * step + x * 3] = (uint)MAX(t,0);\r
+ t = cvRound(Y);\r
+ ((uint *)data)[y * step + x * 3 + 1] = (uint)MAX(t,0);\r
+ t = cvRound(r);\r
+ ((uint *)data)[y * step + x * 3 + 2] = (uint)MAX(t,0);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/**\r
+// convert one row to gray\r
+*/\r
+void ExrDecoder::RGBToGray( float *in, float *out )\r
+{\r
+ if( m_type == FLOAT )\r
+ {\r
+ if( m_native_depth )\r
+ {\r
+ for( int i = 0, n = 0; i < m_width; i++, n += 3 )\r
+ out[i] = in[n] * m_chroma.blue[0] + in[n + 1] * m_chroma.green[0] + in[n + 2] * m_chroma.red[0];\r
+ }\r
+ else\r
+ {\r
+ uchar *o = (uchar *)out;\r
+ for( int i = 0, n = 0; i < m_width; i++, n += 3 )\r
+ o[i] = (uchar) (in[n] * m_chroma.blue[0] + in[n + 1] * m_chroma.green[0] + in[n + 2] * m_chroma.red[0]);\r
+ }\r
+ }\r
+ else // UINT\r
+ {\r
+ if( m_native_depth )\r
+ {\r
+ uint *ui = (uint *)in;\r
+ for( int i = 0; i < m_width * 3; i++ )\r
+ ui[i] -= 0x80000000;\r
+ int *si = (int *)in;\r
+ for( int i = 0, n = 0; i < m_width; i++, n += 3 )\r
+ ((int *)out)[i] = int(si[n] * m_chroma.blue[0] + si[n + 1] * m_chroma.green[0] + si[n + 2] * m_chroma.red[0]);\r
+ }\r
+ else // how to best convert float to uchar?\r
+ {\r
+ uint *ui = (uint *)in;\r
+ for( int i = 0, n = 0; i < m_width; i++, n += 3 )\r
+ ((uchar *)out)[i] = uchar((ui[n] * m_chroma.blue[0] + ui[n + 1] * m_chroma.green[0] + ui[n + 2] * m_chroma.red[0]) * (256.0 / 4294967296.0));\r
+ }\r
+ }\r
+}\r
+\r
+/////////////////////// ExrEncoder ///////////////////\r
+\r
+\r
+ExrEncoder::ExrEncoder()\r
+{\r
+ m_description = "OpenEXR Image files (*.exr)";\r
+}\r
+\r
+\r
+ExrEncoder::~ExrEncoder()\r
+{\r
+}\r
+\r
+\r
+bool ExrEncoder::isFormatSupported( int depth ) const\r
+{\r
+ return CV_MAT_DEPTH(depth) >= CV_8U && CV_MAT_DEPTH(depth) < CV_64F;\r
+}\r
+\r
+\r
+// TODO scale appropriately\r
+bool ExrEncoder::write( const Mat& img, const Vector<int>& )\r
+{\r
+ int width = img.cols, height = img.rows;\r
+ int depth = img.depth(), channels = img.channels();\r
+ bool result = false;\r
+ bool issigned = depth == CV_8S || depth == CV_16S || depth == CV_32S;\r
+ bool isfloat = depth == CV_32F || depth == CV_64F;\r
+ depth = CV_ELEM_SIZE1(depth)*8;\r
+ uchar* data = img.data;\r
+ int step = img.step;\r
+\r
+ Header header( width, height );\r
+ PixelType type;\r
+\r
+ if(depth == 8)\r
+ type = HALF;\r
+ else if(isfloat)\r
+ type = FLOAT;\r
+ else\r
+ type = UINT;\r
+\r
+ if( channels == 3 )\r
+ {\r
+ header.channels().insert( "R", Channel( type ));\r
+ header.channels().insert( "G", Channel( type ));\r
+ header.channels().insert( "B", Channel( type ));\r
+ //printf("bunt\n");\r
+ }\r
+ else\r
+ {\r
+ header.channels().insert( "Y", Channel( type ));\r
+ //printf("gray\n");\r
+ }\r
+\r
+ OutputFile file( m_filename.c_str(), header );\r
+\r
+ FrameBuffer frame;\r
+\r
+ char *buffer;\r
+ int bufferstep;\r
+ int size;\r
+ if( type == FLOAT && depth == 32 )\r
+ {\r
+ buffer = (char *)const_cast<uchar *>(data);\r
+ bufferstep = step;\r
+ size = 4;\r
+ }\r
+ else if( depth > 16 || type == UINT )\r
+ {\r
+ buffer = (char *)new uint[width * channels];\r
+ bufferstep = 0;\r
+ size = 4;\r
+ }\r
+ else\r
+ {\r
+ buffer = (char *)new half[width * channels];\r
+ bufferstep = 0;\r
+ size = 2;\r
+ }\r
+\r
+ //printf("depth %d %s\n", depth, types[type]);\r
+\r
+ if( channels == 3 )\r
+ {\r
+ frame.insert( "B", Slice( type, buffer, size * 3, bufferstep ));\r
+ frame.insert( "G", Slice( type, buffer + size, size * 3, bufferstep ));\r
+ frame.insert( "R", Slice( type, buffer + size * 2, size * 3, bufferstep ));\r
+ }\r
+ else\r
+ frame.insert( "Y", Slice( type, buffer, size, bufferstep ));\r
+\r
+ file.setFrameBuffer( frame );\r
+\r
+ int offset = issigned ? 1 << (depth - 1) : 0;\r
+\r
+ result = true;\r
+ if( type == FLOAT && depth == 32 )\r
+ {\r
+ try\r
+ {\r
+ file.writePixels( height );\r
+ }\r
+ catch(...)\r
+ {\r
+ result = false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // int scale = 1 << (32 - depth);\r
+ // printf("scale %d\n", scale);\r
+ for(int line = 0; line < height; line++)\r
+ {\r
+ if(type == UINT)\r
+ {\r
+ uint *buf = (uint *)buffer; // FIXME 64-bit problems\r
+\r
+ if( depth <= 8 )\r
+ {\r
+ for(int i = 0; i < width * channels; i++)\r
+ buf[i] = data[i] + offset;\r
+ }\r
+ else if( depth <= 16 )\r
+ {\r
+ unsigned short *sd = (unsigned short *)data;\r
+ for(int i = 0; i < width * channels; i++)\r
+ buf[i] = sd[i] + offset;\r
+ }\r
+ else\r
+ {\r
+ int *sd = (int *)data; // FIXME 64-bit problems\r
+ for(int i = 0; i < width * channels; i++)\r
+ buf[i] = (uint) sd[i] + offset;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ half *buf = (half *)buffer;\r
+\r
+ if( depth <= 8 )\r
+ {\r
+ for(int i = 0; i < width * channels; i++)\r
+ buf[i] = data[i];\r
+ }\r
+ else if( depth <= 16 )\r
+ {\r
+ unsigned short *sd = (unsigned short *)data;\r
+ for(int i = 0; i < width * channels; i++)\r
+ buf[i] = sd[i];\r
+ }\r
+ }\r
+ try\r
+ {\r
+ file.writePixels( 1 );\r
+ }\r
+ catch(...)\r
+ {\r
+ result = false;\r
+ break;\r
+ }\r
+ data += step;\r
+ }\r
+ delete buffer;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+}\r
+\r
+#endif\r
+\r
+/* End of file. */\r