Krazy/EBN: fix i18n warnings
[kphotoalbum.git] / ImageManager / RawImageDecoder.cpp
blob3af4e527d3e169779fd7360aa26ca48358d6f91b
1 /* Copyright (C) 2003-2006 Jesper K. Pedersen <blackie@kde.org>
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
18 #include "RawImageDecoder.h"
20 #include <qfile.h>
21 #include <qimage.h>
22 #include "Settings/SettingsData.h"
23 #include <config-kpa-kdcraw.h>
24 #ifdef HAVE_KDCRAW
25 # include <libkdcraw/kdcraw.h>
26 # include <libkdcraw/rawfiles.h>
27 #endif
28 #include <kdebug.h>
30 namespace ImageManager
33 bool RAWImageDecoder::_decode( QImage *img, const QString& imageFile, QSize* fullSize, int dim)
35 /* width and height seem to be only hints, ignore */
36 Q_UNUSED( dim );
38 #ifdef HAVE_KDCRAW
39 if ( !KDcrawIface::KDcraw::loadDcrawPreview( *img, imageFile ) )
40 return false;
42 if ( Settings::SettingsData::instance()->useRawThumbnail() &&
43 img->width() >= Settings::SettingsData::instance()->useRawThumbnailSize().width() &&
44 img->height() >= Settings::SettingsData::instance()->useRawThumbnailSize().height() )
45 return true;
47 KDcrawIface::DcrawInfoContainer metadata;
49 if ( !KDcrawIface::KDcraw::rawFileIdentify( metadata, imageFile ) ||
50 ( img->width() < metadata.imageSize.width() * 0.8 ) ||
51 ( img->height() < metadata.imageSize.height() * 0.8 ) ) {
53 // let's try to get a better resolution
54 KDcrawIface::KDcraw decoder;
55 KDcrawIface::RawDecodingSettings rawDecodingSettings;
57 if ( rawDecodingSettings.sixteenBitsImage ) {
58 kDebug() << "16 bits per color channel is not supported yet";
59 return false;
60 } else {
61 QByteArray imageData; /* 3 bytes for each pixel, */
62 int width, height, rgbmax;
63 if ( !decoder.decodeRAWImage( imageFile, rawDecodingSettings, imageData, width, height, rgbmax ) )
64 return false;
66 // Now the funny part, how to turn this fugly QByteArray into an QImage. Yay!
67 *img = QImage(width, height, QImage::Format_RGB32);
68 if (img->isNull())
69 return false;
71 uchar* data = img->bits();
73 for ( int i = 0; i < imageData.size(); i += 3, data += 4 ) {
74 data[0] = imageData[i + 2]; // blue
75 data[1] = imageData[i + 1]; // green
76 data[2] = imageData[i]; // red
77 data[3] = 0xff; // alpha
82 if ( fullSize )
83 *fullSize = img->size();
85 return true;
86 #else /* HAVE_KDCRAW */
87 Q_UNUSED( img );
88 Q_UNUSED( imageFile );
89 Q_UNUSED( fullSize );
90 return false;
91 #endif /* HAVE_KDCRAW */
94 void RAWImageDecoder::_initializeExtensionLists( QStringList& rawExtensions, QStringList& standardExtensions, QStringList& ignoredExtensions ) const
96 static QStringList _rawExtensions, _standardExtensions, _ignoredExtensions;
97 static bool extensionListsInitialized = false;
98 if ( ! extensionListsInitialized ) {
99 #ifdef HAVE_KDCRAW
100 _rawExtensions = QString::fromAscii( raw_file_extentions ).split( QChar::fromLatin1(' '), QString::SkipEmptyParts );
101 #endif /* HAVE_KDCRAW */
102 for (QStringList::iterator it = _rawExtensions.begin(); it != _rawExtensions.end(); ++it)
103 (*it).remove( QString::fromAscii("*.") );
105 _standardExtensions << QString::fromLatin1("jpg")
106 << QString::fromLatin1("JPG")
107 << QString::fromLatin1("jpeg")
108 << QString::fromLatin1("JPEG")
109 << QString::fromLatin1("tif")
110 << QString::fromLatin1("TIF")
111 << QString::fromLatin1("tiff")
112 << QString::fromLatin1("TIFF")
113 << QString::fromLatin1("png")
114 << QString::fromLatin1("PNG");
115 _ignoredExtensions << QString::fromLatin1("thm") // Thumbnails
116 << QString::fromLatin1("THM")
117 << QString::fromLatin1("thumb") // thumbnail files
118 // from dcraw
119 << QString::fromLatin1("ctg") // Catalog files
120 << QString::fromLatin1("gz") // Compressed files
121 << QString::fromLatin1("Z")
122 << QString::fromLatin1("bz2")
123 << QString::fromLatin1("zip")
124 << QString::fromLatin1("xml")
125 << QString::fromLatin1("XML")
126 << QString::fromLatin1("html")
127 << QString::fromLatin1("HTML")
128 << QString::fromLatin1("htm")
129 << QString::fromLatin1("HTM");
131 QChar dot( QChar::fromLatin1('.') );
132 for ( QStringList::iterator it = _rawExtensions.begin(); it != _rawExtensions.end(); ++it )
133 if ( !(*it).startsWith( dot) )
134 *it = dot + *it;
135 for ( QStringList::iterator it = _standardExtensions.begin(); it != _standardExtensions.end(); ++it )
136 if ( !(*it).startsWith( dot) )
137 *it = dot + *it;
138 for ( QStringList::iterator it = _ignoredExtensions.begin(); it != _ignoredExtensions.end(); ++it )
139 if ( !(*it).startsWith( dot) )
140 *it = dot + *it;
142 extensionListsInitialized = true;
145 rawExtensions = _rawExtensions;
146 standardExtensions = _standardExtensions;
147 ignoredExtensions = _ignoredExtensions;
150 bool RAWImageDecoder::_fileExistsWithExtensions( const QString& fileName,
151 const QStringList& extensionList) const
153 QString baseFileName = fileName;
154 int extStart = fileName.lastIndexOf(QChar::fromLatin1('.'));
155 // We're interested in xxx.yyy, not .yyy
156 if (extStart <= 1) return false;
157 baseFileName.remove(extStart, baseFileName.length() - extStart);
158 for ( QStringList::ConstIterator it = extensionList.begin();
159 it != extensionList.end(); ++it ) {
160 if (QFile::exists(baseFileName + *it)) return true;
162 return false;
165 bool RAWImageDecoder::_fileIsKnownWithExtensions( const QSet<QString>& files,
166 const QString& fileName,
167 const QStringList& extensionList) const
169 QString baseFileName = fileName;
170 int extStart = fileName.lastIndexOf(QChar::fromLatin1('.'));
171 if (extStart <= 1) return false;
172 baseFileName.remove(extStart, baseFileName.length() - extStart);
173 for ( QStringList::ConstIterator it = extensionList.begin();
174 it != extensionList.end(); ++it ) {
175 if (files.contains(baseFileName + *it) ) return true;
177 return false;
180 bool RAWImageDecoder::_fileEndsWithExtensions( const QString& fileName,
181 const QStringList& extensionList) const
183 for ( QStringList::ConstIterator it = extensionList.begin();
184 it != extensionList.end(); ++it ) {
185 if( fileName.endsWith( *it, Qt::CaseInsensitive ) ) return true;
187 return false;
190 bool RAWImageDecoder::_mightDecode( const QString& imageFile )
192 QStringList _rawExtensions, _standardExtensions, _ignoredExtensions;
193 _initializeExtensionLists( _rawExtensions, _standardExtensions, _ignoredExtensions );
195 if (Settings::SettingsData::instance()->skipRawIfOtherMatches() &&
196 _fileExistsWithExtensions(imageFile, _standardExtensions)) return false;
197 if (_fileEndsWithExtensions(imageFile, _rawExtensions)) return true;
198 return false;
201 bool RAWImageDecoder::_skipThisFile( const QSet<QString>& loadedFiles, const QString& imageFile ) const
203 QStringList _rawExtensions, _standardExtensions, _ignoredExtensions;
204 _initializeExtensionLists( _rawExtensions, _standardExtensions, _ignoredExtensions );
206 // We're not interested in thumbnail and other files.
207 if (_fileEndsWithExtensions(imageFile, _ignoredExtensions)) return true;
209 // If we *are* interested in raw files even when other equivalent
210 // non-raw files are available, then we're interested in this file.
211 if (! (Settings::SettingsData::instance()->skipRawIfOtherMatches())) return false;
213 // If the file ends with something other than a known raw extension,
214 // we're interested in it.
215 if (! _fileEndsWithExtensions(imageFile, _rawExtensions)) return false;
217 // At this point, the file ends with a known raw extension, and we're
218 // not interested in raw files when other non-raw files are available.
219 // So search for an existing file with one of the standard
220 // extensions.
222 // This may not be the best way to do this, but it's using the
223 // same algorithm as _mightDecode above.
224 // -- Robert Krawitz rlk@alum.mit.edu 2007-07-22
226 return _fileIsKnownWithExtensions(loadedFiles, imageFile, _standardExtensions);