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