TonicTones
Src/Api/HdrImage.cpp
00001 //      HdrImage.cpp
00002 //      
00003 //      Copyright 2010 Jérémy Laumon <jeremy.laumon@gmail.com>
00004 //      
00005 //      This program is free software; you can redistribute it and/or modify
00006 //      it under the terms of the GNU General Public License as published by
00007 //      the Free Software Foundation; either version 2 of the License, or
00008 //      (at your option) any later version.
00009 //      
00010 //      This program is distributed in the hope that it will be useful,
00011 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //      GNU General Public License for more details.
00014 //      
00015 //      You should have received a copy of the GNU General Public License
00016 //      along with this program; if not, write to the Free Software
00017 //      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018 //      MA 02110-1301, USA.
00019 
00020 
00021 #include <HdrImage.h>
00022 #include <ImageLoaderManager.h>
00023 #include <Exceptions.h>
00024 
00025 #define tr(arg) QObject::tr(arg)
00026 
00040 int HdrImage::YIndices[] =
00041 {
00042     -1, // NONE
00043     -1, // RGB
00044      0  // Yxy
00045 };
00046 
00050 HdrImage::HdrImage() :
00051     width(0),
00052     height(0),
00053     data(NULL),
00054     null(true),
00055     space(HdrImage::NONE)
00056 {
00057     
00058 }
00059 
00063 HdrImage::HdrImage(const HdrImage& im)
00064 {
00065     width = im.width;
00066     height = im.height;
00067     null = im.null;
00068     space = im.space;
00069     
00070     data = new Color[width*height];
00071     for(int i=0; i<width*height; ++i)
00072         data[i] = im.data[i];
00073 }
00074 
00078 HdrImage::HdrImage(const QString& fileName) :
00079     width(0),
00080     height(0),
00081     data(NULL),
00082     null(true),
00083     space(HdrImage::NONE)
00084 {
00085     load(fileName);
00086 }
00087 
00088 HdrImage::~HdrImage()
00089 {
00090     delete[] data;
00091 }
00092 
00096 QSize HdrImage::size() const
00097 {
00098     return QSize(width, height);
00099 }
00100 
00104 HdrImage::ColorSpace HdrImage::colorSpace() const
00105 {
00106     return space;
00107 }
00108 
00112 HdrImage* HdrImage::toRgb(const float toRgbMatrix[3][3]) const
00113 {
00114     HdrImage* image = NULL;
00115     switch (space)
00116     {
00117         case HdrImage::Yxy :
00118             image = fromYxyToRgb(toRgbMatrix);
00119             break;
00120         case HdrImage::RGB:
00121             image = new HdrImage(*this);
00122             break;
00123         default:
00124             throw Exception(tr("Transformation from the current color space to RGB not implemented yet."));
00125             break;
00126     }
00127     return image;
00128 }
00129 
00133 HdrImage* HdrImage::fromYxyToRgb(const float matrix[3][3]) const
00134 {
00135 
00136     HdrImage* image = new HdrImage;
00137     image->resize(width, height);
00138     image->space = HdrImage::RGB;
00139     float xyz[3];
00140     #define X xyz[0]
00141     #define Y xyz[1]
00142     #define Z xyz[2]
00143     int ii, jj, maxI = width*height;
00144     for(int i=0; i<maxI; ++i)
00145     {
00146         Y = data[i][0];
00147         if((Y > 0.0) && (data[i][1] > 0.0) && (data[i][2] > 0.0))
00148         {
00149             X = (data[i][1] * Y) / data[i][2];
00150             Z = (X / data[i][1]) - X - Y;
00151         }
00152         else
00153             X = Z = 0.0;
00154         
00155         float rgb[3] = {0,0,0};
00156         for (ii = 0; ii < 3; ii++)
00157             for (jj = 0; jj < 3; jj++)
00158                 rgb[ii] += matrix[ii][jj] * xyz[jj];
00159         image->data[i].set(rgb[0],rgb[1],rgb[2]);
00160     }
00161     #undef X
00162     #undef Y
00163     #undef Z
00164     return image;
00165 }
00166 
00170 void HdrImage::resize(int w, int h) 
00171 {
00172     delete[] data;
00173     
00174     width = w;
00175     height = h;
00176     data = new Color[width * height];
00177     space = HdrImage::NONE;
00178     null = false;
00179 }
00180 
00184 void HdrImage::load(const QString& fileName) 
00185 {
00186     ImageLoaderPtr loader = ImageLoaderManager::instance()->getLoader(fileName);
00187     if (!loader->openFile())
00188         throw Exception(tr("Error while loading %1: %2 was unable to load the file.").arg(QDir(fileName).dirName()).arg(loader->name()));
00189     
00190     QSize size = loader->getSize();
00191     width = size.width();
00192     height = size.height();
00193     
00194     space = loader->getColorSpace();
00195     
00196     delete[] data;
00197     data = loader->getData();
00198     
00199     if (width < 1 || height < 1 || data == NULL)
00200     {
00201         width = 0;
00202         height = 0;
00203         delete[] data;
00204         null = true;
00205         space = HdrImage::NONE;
00206         throw Exception(tr("Error while loading %1: %2 was unable to load the file.").arg(QDir(fileName).dirName()).arg(loader->name()));
00207     }
00208     
00209     null = false;
00210     qDebug("%s loaded.", fileName.toStdString().c_str());
00211 }
00212 
00216 bool HdrImage::isNull() const
00217 {
00218     return null;
00219 }  
00220 
00224 Color* HdrImage::operator [](int i)
00225 {
00226     return &data[i*width];
00227 }
00228 
00232 const Color* HdrImage::operator [](int i) const
00233 {
00234     return &data[i*width];
00235 }
00236 
00240 bool HdrImage::hasY() const
00241 {
00242     return YIndices[space]>=0;
00243 }
00244 
00248 int HdrImage::YIndex() const
00249 {
00250     return YIndices[space];
00251 }
00252 
 All Classes Functions Variables