KDcraw

kdcraw.cpp
1/*
2 SPDX-FileCopyrightText: 2006-2015 Gilles Caulier <caulier dot gilles at gmail dot com>
3 SPDX-FileCopyrightText: 2006-2013 Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
4 SPDX-FileCopyrightText: 2007-2008 Guillaume Castagnino <casta at xwing dot info>
5
6 SPDX-License-Identifier: GPL-2.0-or-later
7*/
8
9#include "kdcraw.h"
10#include "kdcraw_p.h"
11
12// Qt includes
13
14#include <QFile>
15#include <QFileInfo>
16#include <QStringList>
17
18// LibRaw includes
19
20#include <libraw_version.h>
21
22#ifdef LIBRAW_HAS_CONFIG
23#include <libraw_config.h>
24#endif
25
26// Local includes
27
28#include "libkdcraw_debug.h"
29#include "libkdcraw_version.h"
30#include "rawfiles.h"
31
32namespace KDcrawIface
33{
34
36 : d(new KDcrawPrivate(this))
37{
38 m_cancel = false;
39}
40
42{
43 cancel();
44}
45
47{
48 return QString::fromLatin1(KDCRAW_VERSION_STRING);
49}
50
52{
53 m_cancel = true;
54}
55
56bool KDcraw::loadRawPreview(QImage& image, const QString& path)
57{
58 // In first, try to extract the embedded JPEG preview. Very fast.
59 bool ret = loadEmbeddedPreview(image, path);
60
61 if (ret)
62 return true;
63
64 // In second, decode and half size of RAW picture. More slow.
65 return (loadHalfPreview(image, path));
66}
67
69{
70 QByteArray imgData;
71
72 if ( loadEmbeddedPreview(imgData, path) )
73 {
74 qCDebug(LIBKDCRAW_LOG) << "Preview data size:" << imgData.size();
75
76 if (image.loadFromData( imgData ))
77 {
78 qCDebug(LIBKDCRAW_LOG) << "Using embedded RAW preview extraction";
79 return true;
80 }
81 }
82
83 qCDebug(LIBKDCRAW_LOG) << "Failed to load embedded RAW preview";
84 return false;
85}
86
88{
89 QFileInfo fileInfo(path);
90 QString rawFilesExt = QString::fromUtf8(rawFiles());
91 QString ext = fileInfo.suffix().toUpper();
92
93 if (!fileInfo.exists() || ext.isEmpty() || !rawFilesExt.toUpper().contains(ext))
94 return false;
95
96 LibRaw raw;
97
98 int ret = raw.open_file((const char*)(QFile::encodeName(path)).constData());
99
100 if (ret != LIBRAW_SUCCESS)
101 {
102 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run open_file: " << libraw_strerror(ret);
103 raw.recycle();
104 return false;
105 }
106
107 return (KDcrawPrivate::loadEmbeddedPreview(imgData, raw));
108}
109
110bool KDcraw::loadEmbeddedPreview(QByteArray& imgData, const QBuffer& buffer)
111{
112 QString rawFilesExt = QString::fromUtf8(rawFiles());
113 LibRaw raw;
114
115 QByteArray inData = buffer.data();
116 int ret = raw.open_buffer((void*) inData.data(), (size_t) inData.size());
117
118 if (ret != LIBRAW_SUCCESS)
119 {
120 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run open_buffer: " << libraw_strerror(ret);
121 raw.recycle();
122 return false;
123 }
124
125 return (KDcrawPrivate::loadEmbeddedPreview(imgData, raw));
126}
127
128bool KDcraw::loadHalfPreview(QImage& image, const QString& path)
129{
130 QFileInfo fileInfo(path);
131 QString rawFilesExt = QString::fromUtf8(rawFiles());
132 QString ext = fileInfo.suffix().toUpper();
133
134 if (!fileInfo.exists() || ext.isEmpty() || !rawFilesExt.toUpper().contains(ext))
135 return false;
136
137 qCDebug(LIBKDCRAW_LOG) << "Try to use reduced RAW picture extraction";
138
139 LibRaw raw;
140 raw.imgdata.params.use_auto_wb = 1; // Use automatic white balance.
141 raw.imgdata.params.use_camera_wb = 1; // Use camera white balance, if possible.
142 raw.imgdata.params.half_size = 1; // Half-size color image (3x faster than -q).
143
144 int ret = raw.open_file((const char*)(QFile::encodeName(path)).constData());
145
146 if (ret != LIBRAW_SUCCESS)
147 {
148 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run open_file: " << libraw_strerror(ret);
149 raw.recycle();
150 return false;
151 }
152
153
154 if(!KDcrawPrivate::loadHalfPreview(image, raw))
155 {
156 qCDebug(LIBKDCRAW_LOG) << "Failed to get half preview from LibRaw!";
157 return false;
158 }
159
160 qCDebug(LIBKDCRAW_LOG) << "Using reduced RAW picture extraction";
161
162 return true;
163}
164
165bool KDcraw::loadHalfPreview(QByteArray& imgData, const QString& path)
166{
167 QFileInfo fileInfo(path);
168 QString rawFilesExt = QString::fromUtf8(rawFiles());
169 QString ext = fileInfo.suffix().toUpper();
170
171 if (!fileInfo.exists() || ext.isEmpty() || !rawFilesExt.toUpper().contains(ext))
172 return false;
173
174 qCDebug(LIBKDCRAW_LOG) << "Try to use reduced RAW picture extraction";
175
176 LibRaw raw;
177 int ret = raw.open_file((const char*)(QFile::encodeName(path)).constData());
178
179 if (ret != LIBRAW_SUCCESS)
180 {
181 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run dcraw_process: " << libraw_strerror(ret);
182 raw.recycle();
183 return false;
184 }
185
186 QImage image;
187
188 if (!KDcrawPrivate::loadHalfPreview(image, raw))
189 {
190 qCDebug(LIBKDCRAW_LOG) << "KDcraw: failed to get half preview: " << libraw_strerror(ret);
191 return false;
192 }
193
194 QBuffer buffer(&imgData);
196 image.save(&buffer, "JPEG");
197
198 return true;
199}
200
201bool KDcraw::loadHalfPreview(QByteArray& imgData, const QBuffer& inBuffer)
202{
203 QString rawFilesExt = QString::fromUtf8(rawFiles());
204 LibRaw raw;
205
206 QByteArray inData = inBuffer.data();
207 int ret = raw.open_buffer((void*) inData.data(), (size_t) inData.size());
208
209 if (ret != LIBRAW_SUCCESS)
210 {
211 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run dcraw_make_mem_image: " << libraw_strerror(ret);
212 raw.recycle();
213 return false;
214 }
215
216 QImage image;
217
218 if (!KDcrawPrivate::loadHalfPreview(image, raw))
219 {
220 qCDebug(LIBKDCRAW_LOG) << "KDcraw: failed to get half preview: " << libraw_strerror(ret);
221 return false;
222 }
223
224 QBuffer buffer(&imgData);
226 image.save(&buffer, "JPG");
227
228 return true;
229}
230
231bool KDcraw::loadFullImage(QImage& image, const QString& path, const RawDecodingSettings& settings)
232{
233 QFileInfo fileInfo(path);
234 QString rawFilesExt = QString::fromUtf8(rawFiles());
235 QString ext = fileInfo.suffix().toUpper();
236
237 if (!fileInfo.exists() || ext.isEmpty() || !rawFilesExt.toUpper().contains(ext))
238 return false;
239
240 qCDebug(LIBKDCRAW_LOG) << "Try to load full RAW picture...";
241
242 RawDecodingSettings prm = settings;
243 prm.sixteenBitsImage = false;
244 QByteArray imgData;
245 int width, height, rgbmax;
246
247 KDcraw decoder;
248 bool ret = decoder.decodeRAWImage(path, prm, imgData, width, height, rgbmax);
249
250 if (!ret)
251 {
252 qCDebug(LIBKDCRAW_LOG) << "Failed to load full RAW picture";
253 return false;
254 }
255
256 uchar* sptr = (uchar*)imgData.data();
257 uchar tmp8[2];
258
259 // Set RGB color components.
260 for (int i = 0 ; i < width * height ; ++i)
261 {
262 // Swap Red and Blue
263 tmp8[0] = sptr[2];
264 tmp8[1] = sptr[0];
265 sptr[0] = tmp8[0];
266 sptr[2] = tmp8[1];
267
268 sptr += 3;
269 }
270
271 image = QImage(width, height, QImage::Format_ARGB32);
272 uint* dptr = reinterpret_cast<uint*>(image.bits());
273 sptr = (uchar*)imgData.data();
274
275 for (int i = 0 ; i < width * height ; ++i)
276 {
277 *dptr++ = qRgba(sptr[2], sptr[1], sptr[0], 0xFF);
278 sptr += 3;
279 }
280
281 qCDebug(LIBKDCRAW_LOG) << "Load full RAW picture done";
282
283 return true;
284}
285
287{
288 QFileInfo fileInfo(path);
289 QString rawFilesExt = QString::fromUtf8(rawFiles());
290 QString ext = fileInfo.suffix().toUpper();
291 identify.isDecodable = false;
292
293 if (!fileInfo.exists() || ext.isEmpty() || !rawFilesExt.toUpper().contains(ext))
294 return false;
295
296 LibRaw raw;
297
298 int ret = raw.open_file((const char*)(QFile::encodeName(path)).constData());
299
300 if (ret != LIBRAW_SUCCESS)
301 {
302 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run open_file: " << libraw_strerror(ret);
303 raw.recycle();
304 return false;
305 }
306
307 ret = raw.adjust_sizes_info_only();
308
309 if (ret != LIBRAW_SUCCESS)
310 {
311 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run adjust_sizes_info_only: " << libraw_strerror(ret);
312 raw.recycle();
313 return false;
314 }
315
316 KDcrawPrivate::fillIndentifyInfo(&raw, identify);
317 raw.recycle();
318 return true;
319}
320
321// ----------------------------------------------------------------------------------
322
323bool KDcraw::extractRAWData(const QString& filePath, QByteArray& rawData, DcrawInfoContainer& identify, unsigned int shotSelect)
324{
325 QFileInfo fileInfo(filePath);
326 QString rawFilesExt = QString::fromUtf8(rawFiles());
327 QString ext = fileInfo.suffix().toUpper();
328 identify.isDecodable = false;
329
330 if (!fileInfo.exists() || ext.isEmpty() || !rawFilesExt.toUpper().contains(ext))
331 return false;
332
333 if (m_cancel)
334 return false;
335
336 d->setProgress(0.1);
337
338 LibRaw raw;
339 // Set progress call back function.
340 raw.set_progress_handler(callbackForLibRaw, d.get());
341
342 int ret = raw.open_file((const char*)(QFile::encodeName(filePath)).constData());
343
344 if (ret != LIBRAW_SUCCESS)
345 {
346 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run open_file: " << libraw_strerror(ret);
347 raw.recycle();
348 return false;
349 }
350
351 if (m_cancel)
352 {
353 raw.recycle();
354 return false;
355 }
356
357 d->setProgress(0.3);
358
359 raw.imgdata.params.output_bps = 16;
360#if LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 21)
361 raw.imgdata.rawparams.shot_select = shotSelect;
362#else
363 raw.imgdata.params.shot_select = shotSelect;
364#endif
365 ret = raw.unpack();
366
367 if (ret != LIBRAW_SUCCESS)
368 {
369 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run unpack: " << libraw_strerror(ret);
370 raw.recycle();
371 return false;
372 }
373
374 if (m_cancel)
375 {
376 raw.recycle();
377 return false;
378 }
379
380 d->setProgress(0.4);
381
382 ret = raw.raw2image();
383
384 if (ret != LIBRAW_SUCCESS)
385 {
386 qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run raw2image: " << libraw_strerror(ret);
387 raw.recycle();
388 return false;
389 }
390
391 if (m_cancel)
392 {
393 raw.recycle();
394 return false;
395 }
396
397 d->setProgress(0.6);
398
399 KDcrawPrivate::fillIndentifyInfo(&raw, identify);
400
401 if (m_cancel)
402 {
403 raw.recycle();
404 return false;
405 }
406
407 d->setProgress(0.8);
408
409 rawData = QByteArray();
410
411 if (raw.imgdata.idata.filters == 0)
412 {
413 rawData.resize((int)(raw.imgdata.sizes.iwidth * raw.imgdata.sizes.iheight * raw.imgdata.idata.colors * sizeof(unsigned short)));
414
415 unsigned short* output = reinterpret_cast<unsigned short*>(rawData.data());
416
417 for (unsigned int row = 0; row < raw.imgdata.sizes.iheight; row++)
418 {
419 for (unsigned int col = 0; col < raw.imgdata.sizes.iwidth; col++)
420 {
421 for (int color = 0; color < raw.imgdata.idata.colors; color++)
422 {
423 *output = raw.imgdata.image[raw.imgdata.sizes.iwidth*row + col][color];
424 output++;
425 }
426 }
427 }
428 }
429 else
430 {
431 rawData.resize((int)(raw.imgdata.sizes.iwidth * raw.imgdata.sizes.iheight * sizeof(unsigned short)));
432
433 unsigned short* output = reinterpret_cast<unsigned short*>(rawData.data());
434
435 for (uint row = 0; row < raw.imgdata.sizes.iheight; row++)
436 {
437 for (uint col = 0; col < raw.imgdata.sizes.iwidth; col++)
438 {
439 *output = raw.imgdata.image[raw.imgdata.sizes.iwidth*row + col][raw.COLOR(row, col)];
440 output++;
441 }
442 }
443 }
444
445 raw.recycle();
446 d->setProgress(1.0);
447
448 return true;
449}
450
451bool KDcraw::decodeHalfRAWImage(const QString& filePath, const RawDecodingSettings& rawDecodingSettings,
452 QByteArray& imageData, int& width, int& height, int& rgbmax)
453{
454 m_rawDecodingSettings = rawDecodingSettings;
456 return (d->loadFromLibraw(filePath, imageData, width, height, rgbmax));
457}
458
459bool KDcraw::decodeRAWImage(const QString& filePath, const RawDecodingSettings& rawDecodingSettings,
460 QByteArray& imageData, int& width, int& height, int& rgbmax)
461{
462 m_rawDecodingSettings = rawDecodingSettings;
463 return (d->loadFromLibraw(filePath, imageData, width, height, rgbmax));
464}
465
467{
468 return m_cancel;
469}
470
472{
473}
474
475const char* KDcraw::rawFiles()
476{
477 return raw_file_extentions;
478}
479
481{
483 return string.remove(QLatin1String("*.")).split(QLatin1Char(' '));
484}
485
487{
488 return raw_file_extensions_version;
489}
490
492{
494 const char** const list = LibRaw::cameraList();
495
496 for (int i = 0; i < LibRaw::cameraCount(); i++)
498
499 return camera;
500}
501
503{
504 return QString::fromLatin1(LIBRAW_VERSION_STR).remove(QLatin1String("-Release"));
505}
506
508{
509#ifdef LIBRAW_HAS_CONFIG
510# ifdef LIBRAW_USE_OPENMP
511 return true;
512# else
513 return false;
514# endif
515#else
516 return -1;
517#endif
518}
519
521{
522#ifdef LIBRAW_HAS_CONFIG
523# ifdef LIBRAW_USE_RAWSPEED
524 return true;
525# else
526 return false;
527# endif
528#else
529 return -1;
530#endif
531}
532
534{
535#ifdef LIBRAW_HAS_CONFIG
536# ifdef LIBRAW_USE_DEMOSAIC_PACK_GPL2
537 return true;
538# else
539 return false;
540# endif
541#else
542 return -1;
543#endif
544}
545
547{
548#ifdef LIBRAW_HAS_CONFIG
549# ifdef LIBRAW_USE_DEMOSAIC_PACK_GPL3
550 return true;
551# else
552 return false;
553# endif
554#else
555 return -1;
556#endif
557}
558
559} // namespace KDcrawIface
560
561#include "moc_kdcraw.cpp"
A container for RAW image information.
bool isDecodable
True is RAW file is decodable by dcraw.
The wrapper class.
Definition kdcraw.h:38
void cancel()
To cancel 'decodeHalfRAWImage' and 'decodeRAWImage' methods running in a separate thread.
Definition kdcraw.cpp:51
KDcraw()
Standard constructor.
Definition kdcraw.cpp:35
bool extractRAWData(const QString &filePath, QByteArray &rawData, DcrawInfoContainer &identify, unsigned int shotSelect=0)
Extract Raw image data undemosaiced and without post processing from 'filePath' picture file.
Definition kdcraw.cpp:323
static bool loadRawPreview(QImage &image, const QString &path)
Get the preview of RAW picture as a QImage.
Definition kdcraw.cpp:56
virtual ~KDcraw()
Standard destructor.
Definition kdcraw.cpp:41
static int rawFilesVersion()
Returns a version number for the list of supported RAW file types.
Definition kdcraw.cpp:486
virtual bool checkToCancelWaitingData()
Re-implement this method to control the cancelisation of loop witch wait data from RAW decoding proce...
Definition kdcraw.cpp:466
RawDecodingSettings m_rawDecodingSettings
The settings container used to perform RAW pictures decoding.
Definition kdcraw.h:219
virtual void setWaitingDataProgress(double value)
Re-implement this method to control the pseudo progress value during RAW decoding (when dcraw run wit...
Definition kdcraw.cpp:471
static QStringList supportedCamera()
Provide a list of supported RAW Camera name.
Definition kdcraw.cpp:491
static bool rawFileIdentify(DcrawInfoContainer &identify, const QString &path)
Get the camera settings witch have taken RAW file.
Definition kdcraw.cpp:286
static int librawUseGPL3DemosaicPack()
Return true or false if LibRaw use Demosaic Pack GPL3 or not.
Definition kdcraw.cpp:546
static const char * rawFiles()
Return the string of all RAW file type mime supported.
Definition kdcraw.cpp:475
static bool loadFullImage(QImage &image, const QString &path, const RawDecodingSettings &settings=RawDecodingSettings())
Get the full decoded RAW picture.
Definition kdcraw.cpp:231
static int librawUseGomp()
Return true or false if LibRaw use parallel demosaicing or not (libgomp support).
Definition kdcraw.cpp:507
static QStringList rawFilesList()
Return the list of all RAW file type mime supported, as a QStringList, without wildcard and suffix do...
Definition kdcraw.cpp:480
static QString version()
Return a string version of libkdcraw release.
Definition kdcraw.cpp:46
static int librawUseGPL2DemosaicPack()
Return true or false if LibRaw use Demosaic Pack GPL2 or not.
Definition kdcraw.cpp:533
static bool loadHalfPreview(QImage &image, const QString &path)
Get the half decoded RAW picture.
Definition kdcraw.cpp:128
static int librawUseRawSpeed()
Return true or false if LibRaw use RawSpeed codec or not.
Definition kdcraw.cpp:520
bool decodeHalfRAWImage(const QString &filePath, const RawDecodingSettings &rawDecodingSettings, QByteArray &imageData, int &width, int &height, int &rgbmax)
Extract a small size of decode RAW data from 'filePath' picture file using 'rawDecodingSettings' sett...
Definition kdcraw.cpp:451
bool decodeRAWImage(const QString &filePath, const RawDecodingSettings &rawDecodingSettings, QByteArray &imageData, int &width, int &height, int &rgbmax)
Extract a full size of RAW data from 'filePath' picture file using 'rawDecodingSettings' settings.
Definition kdcraw.cpp:459
static bool loadEmbeddedPreview(QByteArray &imgData, const QString &path)
Get the embedded JPEG preview image from RAW picture as a QByteArray which will include Exif Data.
Definition kdcraw.cpp:87
static QString librawVersion()
Return LibRaw version string.
Definition kdcraw.cpp:502
bool m_cancel
Used internally to cancel RAW decoding operation.
Definition kdcraw.h:214
bool halfSizeColorImage
Half-size color image decoding (twice as fast as "enableRAWQuality").
bool sixteenBitsImage
Turn on RAW file decoding in 16 bits per color per pixel instead 8 bits.
Q_SCRIPTABLE QString camera()
Main namespace of libKDcraw.
const QByteArray & data() const const
virtual bool open(OpenMode flags) override
char * data()
void resize(qsizetype newSize, char c)
qsizetype size() const const
QByteArray encodeName(const QString &fileName)
bool exists(const QString &path)
QString suffix() const const
uchar * bits()
bool loadFromData(QByteArrayView data, const char *format)
bool save(QIODevice *device, const char *format, int quality) const const
QString & append(QChar ch)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString fromLatin1(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString toUpper() const const
list of RAW file extensions supported by libraw
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 24 2024 11:56:21 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.