TonicTones
|
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