25 #include "OpenEXRInterface.hh"
27 #ifdef BIAS_HAVE_OPENEXR
29 # pragma warning( push, 1)
30 # define PLATFORM_WINDOWS
33 # include <ImfRgbaFile.h>
35 # include <ImfArray.h>
36 # include <ImathBox.h>
37 # include <ImfInputFile.h>
38 # include <ImfOutputFile.h>
39 # include <ImfChannelList.h>
40 # include <ImfPixelType.h>
41 # include <ImfStringAttribute.h>
43 # pragma warning( pop)
51 using namespace Imath;
66 const Imf::Compression& compression)
75 Header outHeader(exrwidth, exrheight);
76 outHeader.compression() = compression;
81 outHeader.insert(
"BIASMetaData", StringAttribute(sstr.str().c_str()));
85 outHeader.insert(
"BIASColorModel", StringAttribute(sstrCM.str().c_str()));
89 outHeader.insert(
"BIASStorageType", StringAttribute(sstrST.str().c_str()));
97 OutputFile outFile(FileName.c_str(), outHeader);
98 outFile.setFrameBuffer(fb);
99 outFile.writePixels(exrheight);
100 }
catch (Iex::BaseExc &error_ )
102 BIASERR(
"Writing "<<FileName<<
" with OpenEXR failed."<<endl
103 <<
" Caught exception: "<<endl
104 <<
" "<<error_.what()<<endl
119 PixelType pt = Imf::FLOAT;
124 #ifdef BUILD_IMAGE_UINT
141 #ifdef BUILD_IMAGE_UINT
144 if(!storageTypeString.empty()) {
158 const unsigned int& numChannels,
159 std::vector<std::string>& channelNames)
161 channelNames.clear();
162 channelNames.reserve(numChannels);
165 for(
unsigned int c=0; c<numChannels; c++) {
170 channelNames.push_back(sstr.str());
174 channelNames.push_back(
"Grey");
break;
175 case ImageBase::CM_RGB: channelNames.push_back(
"R"); channelNames.push_back(
"G"); channelNames.push_back(
"B");
break;
176 case ImageBase::CM_BGR: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
177 case ImageBase::CM_YUYV422: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
178 case ImageBase::CM_UYVY422: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
179 case ImageBase::CM_YUV420P: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
180 case ImageBase::CM_YUV444: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
181 case ImageBase::CM_YUV411: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
182 case ImageBase::CM_HSV: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
183 case ImageBase::CM_HSI_OBS: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
184 case ImageBase::CM_DV: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
186 channelNames.push_back(
"R");
187 channelNames.push_back(
"G");
188 channelNames.push_back(
"B");
189 channelNames.push_back(
"A");
break;
191 channelNames.push_back(
"Grey");
192 channelNames.push_back(
"A");
break;
194 channelNames.push_back(
"Bayer");
break;
196 channelNames.push_back(
"Bayer");
break;
198 channelNames.push_back(
"Bayer");
break;
200 channelNames.push_back(
"Bayer");
break;
201 case ImageBase::CM_HSL: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
202 case ImageBase::CM_hsL: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
204 case ImageBase::CM_BGRA: BIASERR(
"You have data to test this? Please implement!");
break;
205 case ImageBase::CM_RGBE: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
209 channelNames.push_back(
"disparity");
break;
211 channelNames.push_back(
"depth");
break;
212 case ImageBase::CM_YUYV: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
213 case ImageBase::CM_LUV: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
214 case ImageBase::CM_XYZ: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
215 case ImageBase::CM_I1I2I3: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
216 case ImageBase::CM_LAB: BIASERR(
"You have data to test this? Please implement!");
return -1;
break;
226 Imf::Header& outHeader,
227 Imf::FrameBuffer& fb,
236 vector<string> channelNames;
242 for(
unsigned int c=0; c<channelNames.size(); c++) {
243 outHeader.channels().insert(channelNames[c].c_str(), Channel(pt));
245 if(
AddSlice_(pt, width, height, channelNames[c], fb, c, &input)!=0) {
257 const int& exrheight,
258 const std::string& channelName,
259 Imf::FrameBuffer& fb,
260 unsigned int channel,
265 exrSlice.fillValue = 0.0;
266 exrSlice.xSampling = 1;
267 exrSlice.ySampling = 1;
276 float* pixelsFloat =
new float[exrwidth * exrheight];
278 exrSlice.type = Imf::FLOAT;
279 exrSlice.base = (
char*) pixelsFloat;
280 exrSlice.xStride =
sizeof(*pixelsFloat) * 1;
281 exrSlice.yStride =
sizeof(*pixelsFloat) * exrwidth;
284 ImageBase::GetChannel<float>(*input, channel, pixelsFloat);
290 half* pixelsHalf =
new half[exrwidth * exrheight];
292 exrSlice.type = Imf::HALF;
293 exrSlice.base = (
char*) pixelsHalf;
294 exrSlice.xStride =
sizeof(*pixelsHalf) * 1;
295 exrSlice.yStride =
sizeof(*pixelsHalf) * exrwidth;
304 #ifdef BUILD_IMAGE_UINT
306 unsigned int* pixelsUInt =
new unsigned int[exrwidth * exrheight];
308 exrSlice.type = Imf::UINT;
309 exrSlice.base = (
char*) pixelsUInt;
310 exrSlice.xStride =
sizeof(*pixelsUInt) * 1;
311 exrSlice.yStride =
sizeof(*pixelsUInt) * exrwidth;
318 BIASERR(
"unsigned integer type for ImageBase is not active, find alternative storage type");
324 BIASERR(
"unexpected disp store type!");
330 fb.insert(channelName.c_str(), exrSlice);
337 map<string, ChannelData>::iterator it=
channels_.begin();
339 it->second.ClearData();
352 InputFile exrInputFile( FileName.c_str() );
354 Box2i dw = exrInputFile.header().dataWindow();
355 int exrwidth = dw.max.x - dw.min.x + 1;
356 int exrheight = dw.max.y - dw.min.y + 1;
357 if(exrwidth == 0 || exrheight ==0 ) {
358 BIASERR(
"empty image");
363 unsigned int numChannels = 0;
364 PixelType commonPTType = Imf::UINT;
365 const ChannelList& channels = exrInputFile.header().channels();
366 for(ChannelList::ConstIterator i = channels.begin(); i!= channels.end(); i++) {
367 PixelType ptchannel = i.channel().type;
368 AddSlice_(ptchannel, exrwidth, exrheight, i.name(), fb);
370 commonPTType = ptchannel;
372 if(ptchannel == Imf::FLOAT) commonPTType = Imf::FLOAT;
373 if(ptchannel == Imf::HALF && commonPTType == Imf::UINT) commonPTType = Imf::FLOAT;
374 if(ptchannel == Imf::UINT && commonPTType == Imf::HALF) commonPTType = Imf::FLOAT;
380 BIASERR(
"no channels");
384 exrInputFile.setFrameBuffer(fb);
385 exrInputFile.readPixels(dw.min.y, dw.max.y);
388 vector<string> biasChannelNames;
390 const StringAttribute* colormodel =
391 exrInputFile.header().findTypedAttribute<StringAttribute>(
"BIASColorModel");
392 if(colormodel != NULL) {
395 numChannels = biasChannelNames.size();
398 const StringAttribute* storagetype =
399 exrInputFile.header().findTypedAttribute<StringAttribute>(
"BIASStorageType");
400 string storagetypestr =
"";
401 if(storagetype != NULL) {
402 storagetypestr = storagetype->value();
409 result.
Init(exrwidth, exrheight, numChannels, st,
true);
412 float* dataFloat = NULL;
413 half* dataHalf = NULL;
414 unsigned int* dataUInt = NULL;
415 if(colormodel != NULL) {
416 for(
unsigned int c=0; c<numChannels; c++) {
417 map<string, ChannelData>::const_iterator it =
channels_.find(biasChannelNames[c]);
419 switch(it->second.Get(dataFloat, dataHalf, dataUInt)) {
428 #ifdef BUILD_IMAGE_UINT
431 BIASERR(
"unsigned integer type for ImageBase is not active, find alternative storage type");
439 for(map<string, ChannelData>::const_iterator it=
channels_.begin(); it!=
channels_.end(); it++) {
440 switch(it->second.Get(dataFloat, dataHalf, dataUInt)) {
449 #ifdef BUILD_IMAGE_UINT
452 BIASERR(
"unsigned integer type for ImageBase is not active, find alternative storage type");
469 const StringAttribute* metadata =
470 exrInputFile.header().findTypedAttribute<StringAttribute>(
"BIASMetaData");
471 if(metadata != NULL) {
473 sstr<<metadata->value();
476 if(exrInputFile.header().lineOrder() == Imf::DECREASING_Y) result.
Flip();
478 #if defined(BIAS_DEBUG) && defined(ImageIO_DEBUG_IO)
479 catch (Iex::BaseExc &error_ ) {
480 BIASWARN(
"Reading "<<FileName<<
" with OpenEXR failed."<<endl
481 <<
" Caught exception: "<<endl
482 <<
" "<<error_.what()<<endl
485 catch (Iex::BaseExc & ) {
EColorModel
These are the most often used color models.
Imf::PixelType overridePT_
YUYV422, 2 channels, full luminance Y, subsampled half U,V.
Bayer_GRBG, 1 channel RGB image Bayer tile.
hsl, similar to HSL but euclidean (h,s) for CNCC
LAB, 3 channels, http://en.wikipedia.org/wiki/Lab_color_space.
static void SetChannel(const ImageBase &im, const unsigned int channelId, const inputType *channelIn)
Copy channel, determines the internal ImageBase type and casts the input type to the type foreseen in...
void SetOverridePixelTypeEXR(Imf::PixelType overridePT)
When exporting image this pixel type is used, not a derived one! Imf::HALF, Imf:FLOAT, Imf::INT are valid values.
int AddSlice_(Imf::PixelType pt, const int &exrwidth, const int &exrheight, const std::string &channelName, Imf::FrameBuffer &fb, unsigned int channel=0, const ImageBase *input=NULL)
HSL, similar to HSV but space is a double tipped cone.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
DV, color model used for digital video cameras such as Mini-DV.
Othe's principle component generalization for RGB based segmentation.
YUV411, 2 channles, full luminance, 1 U, 1 V.
Imf::PixelType MapStorageType_(const ImageBase::EStorageType &st)
void SetColorModel(EColorModel Model)
Bayer_RGGB, 1 channel RGB image Bayer tile.
ImageBase::EStorageType MapPixelType_(const Imf::PixelType &pt, const std::string &storageTypeString="")
XYZ, 3 channels, http://en.wikipedia.org/wiki/Xyz_color_space.
unsigned int GetWidth() const
YUV420P, 2 channels, full luminance Y, 1 U, 1 V. Y, U and V are grouped together for better compressi...
Todo: Conflict with YUVU model, what does it do?
PGR XB3 in format 7 mode 3 delivers an image that consists of 3 channels with 8bbp (overal 24bpp)...
invalid not set image storage type
color values, 3 channels, order: blue,green,red
Bayer_BGGR, 1 channel RGB image Bayer tile.
Disparity images Q: should disp and depth be treated separately, if not what would be a good name to ...
Bayer_GBRG, 1 channel RGB image Bayer tile.
int GetChannel(const ImageBase &source, const unsigned int channel)
copies one specific channel from source to Image can only be called from an planar image...
CM_YUV444, 3 channels, all channels have full data.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
color values, 3 channels, order: red,green,blue
int Import(const std::string &FileName, ImageBase &result)
CIELUV color space, 3 channels, http://en.wikipedia.org/wiki/CIELUV_color_space.
int Export(const std::string &FileName, const ImageBase &input, const Imf::Compression &compression=Imf::ZIP_COMPRESSION)
unsigned int GetHeight() const
static void StringToStorageType(const std::string &str, ImageBase::EStorageType &st)
UYVY422, 2 channels, full luminance Y, subsampled half U,V inverse order.
obsolete, HSI is unused and identical to HSL
int AddChannels_(const ImageBase::EColorModel &cm, const ImageBase::EStorageType &st, Imf::Header &outHeader, Imf::FrameBuffer &fb, const ImageBase &input)
SymTensor2x2 The image contains a 2x2 symmetric tensor.
RGBA, 4 channels, order: red,green,blue,alpha.
void Release(const bool reset_storage_type=false)
Free the allocated data structures Hands off: Do !!NOT!! change the default of reset_storage_type: Im...
enum EColorModel GetColorModel() const
static int GenerateChannelNames_(const ImageBase::EColorModel &cm, const unsigned int &numChannels, std::vector< std::string > &channelNames)
The order of the channel names in the vector is also the order of channels in the ImageBase represent...
RGBE color values, 4 channels, RADIANCE hdr format, four low dynamic channels meaning: 3x mantissa (r...
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
static void StringToColorModel(const std::string &str, ImageBase::EColorModel &cm)
invalid (not set) image format
enum EStorageType GetStorageType() const
(8bit) unsigned char image storage type
HSV, 3 channels, order: hue, sat , value.
int Flip()
flips the image vertically (row order is inverted) In place function return 0 in case of success...
std::map< std::string, ChannelData > channels_
Todo: Unclear, I think one channel float, why isn't grey used for that?
GreyA, 2 channels, grey plus Alpha.
This is the base class for images in BIAS.
Depth images A: separated for now.
BGRA color values, 4 channels, order: blue,green,red,alpha.
(32bit) unsigned integer image storage type