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 
32 namespace 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 
56 bool 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 
68 bool KDcraw::loadEmbeddedPreview(QImage& image, const QString& path)
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 
87 bool KDcraw::loadEmbeddedPreview(QByteArray& imgData, const QString& path)
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 
110 bool 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 
128 bool 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 
165 bool 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);
195  buffer.open(QIODevice::WriteOnly);
196  image.save(&buffer, "JPEG");
197 
198  return true;
199 }
200 
201 bool 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);
225  buffer.open(QIODevice::WriteOnly);
226  image.save(&buffer, "JPG");
227 
228  return true;
229 }
230 
231 bool 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 
323 bool 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  raw.imgdata.params.shot_select = shotSelect;
361  ret = raw.unpack();
362 
363  if (ret != LIBRAW_SUCCESS)
364  {
365  qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run unpack: " << libraw_strerror(ret);
366  raw.recycle();
367  return false;
368  }
369 
370  if (m_cancel)
371  {
372  raw.recycle();
373  return false;
374  }
375 
376  d->setProgress(0.4);
377 
378  ret = raw.raw2image();
379 
380  if (ret != LIBRAW_SUCCESS)
381  {
382  qCDebug(LIBKDCRAW_LOG) << "LibRaw: failed to run raw2image: " << libraw_strerror(ret);
383  raw.recycle();
384  return false;
385  }
386 
387  if (m_cancel)
388  {
389  raw.recycle();
390  return false;
391  }
392 
393  d->setProgress(0.6);
394 
395  KDcrawPrivate::fillIndentifyInfo(&raw, identify);
396 
397  if (m_cancel)
398  {
399  raw.recycle();
400  return false;
401  }
402 
403  d->setProgress(0.8);
404 
405  rawData = QByteArray();
406 
407  if (raw.imgdata.idata.filters == 0)
408  {
409  rawData.resize((int)(raw.imgdata.sizes.iwidth * raw.imgdata.sizes.iheight * raw.imgdata.idata.colors * sizeof(unsigned short)));
410 
411  unsigned short* output = reinterpret_cast<unsigned short*>(rawData.data());
412 
413  for (unsigned int row = 0; row < raw.imgdata.sizes.iheight; row++)
414  {
415  for (unsigned int col = 0; col < raw.imgdata.sizes.iwidth; col++)
416  {
417  for (int color = 0; color < raw.imgdata.idata.colors; color++)
418  {
419  *output = raw.imgdata.image[raw.imgdata.sizes.iwidth*row + col][color];
420  output++;
421  }
422  }
423  }
424  }
425  else
426  {
427  rawData.resize((int)(raw.imgdata.sizes.iwidth * raw.imgdata.sizes.iheight * sizeof(unsigned short)));
428 
429  unsigned short* output = reinterpret_cast<unsigned short*>(rawData.data());
430 
431  for (uint row = 0; row < raw.imgdata.sizes.iheight; row++)
432  {
433  for (uint col = 0; col < raw.imgdata.sizes.iwidth; col++)
434  {
435  *output = raw.imgdata.image[raw.imgdata.sizes.iwidth*row + col][raw.COLOR(row, col)];
436  output++;
437  }
438  }
439  }
440 
441  raw.recycle();
442  d->setProgress(1.0);
443 
444  return true;
445 }
446 
447 bool KDcraw::decodeHalfRAWImage(const QString& filePath, const RawDecodingSettings& rawDecodingSettings,
448  QByteArray& imageData, int& width, int& height, int& rgbmax)
449 {
450  m_rawDecodingSettings = rawDecodingSettings;
452  return (d->loadFromLibraw(filePath, imageData, width, height, rgbmax));
453 }
454 
455 bool KDcraw::decodeRAWImage(const QString& filePath, const RawDecodingSettings& rawDecodingSettings,
456  QByteArray& imageData, int& width, int& height, int& rgbmax)
457 {
458  m_rawDecodingSettings = rawDecodingSettings;
459  return (d->loadFromLibraw(filePath, imageData, width, height, rgbmax));
460 }
461 
463 {
464  return m_cancel;
465 }
466 
468 {
469 }
470 
471 const char* KDcraw::rawFiles()
472 {
473  return raw_file_extentions;
474 }
475 
477 {
479  return string.remove(QLatin1String("*.")).split(QLatin1Char(' '));
480 }
481 
483 {
484  return raw_file_extensions_version;
485 }
486 
488 {
489  QStringList camera;
490  const char** const list = LibRaw::cameraList();
491 
492  for (int i = 0; i < LibRaw::cameraCount(); i++)
493  camera.append(QString::fromUtf8(list[i]));
494 
495  return camera;
496 }
497 
499 {
500  return QString::fromLatin1(LIBRAW_VERSION_STR).remove(QLatin1String("-Release"));
501 }
502 
504 {
505 #ifdef LIBRAW_HAS_CONFIG
506 # ifdef LIBRAW_USE_OPENMP
507  return true;
508 # else
509  return false;
510 # endif
511 #else
512  return -1;
513 #endif
514 }
515 
517 {
518 #ifdef LIBRAW_HAS_CONFIG
519 # ifdef LIBRAW_USE_RAWSPEED
520  return true;
521 # else
522  return false;
523 # endif
524 #else
525  return -1;
526 #endif
527 }
528 
530 {
531 #ifdef LIBRAW_HAS_CONFIG
532 # ifdef LIBRAW_USE_DEMOSAIC_PACK_GPL2
533  return true;
534 # else
535  return false;
536 # endif
537 #else
538  return -1;
539 #endif
540 }
541 
543 {
544 #ifdef LIBRAW_HAS_CONFIG
545 # ifdef LIBRAW_USE_DEMOSAIC_PACK_GPL3
546  return true;
547 # else
548  return false;
549 # endif
550 #else
551  return -1;
552 #endif
553 }
554 
555 } // namespace KDcrawIface
bool halfSizeColorImage
Half-size color image decoding (twice as fast as "enableRAWQuality").
bool loadFromData(const uchar *data, int len, const char *format)
static QString librawVersion()
Return LibRaw version string.
Definition: kdcraw.cpp:498
QString toUpper() const const
static QString version()
Return a string version of libkdcraw release.
Definition: kdcraw.cpp:46
bool save(const QString &fileName, const char *format, int quality) const const
KDcraw()
Standard constructor.
Definition: kdcraw.cpp:35
A container for RAW image information.
bool m_cancel
Used internally to cancel RAW decoding operation.
Definition: kdcraw.h:214
bool sixteenBitsImage
Turn on RAW file decoding in 16 bits per color per pixel instead 8 bits.
RawDecodingSettings m_rawDecodingSettings
The settings container used to perform RAW pictures decoding.
Definition: kdcraw.h:219
QString & remove(int position, int n)
static int librawUseGomp()
Return true or false if LibRaw use parallel demosaicing or not (libgomp support). ...
Definition: kdcraw.cpp:503
virtual ~KDcraw()
Standard destructor.
Definition: kdcraw.cpp:41
static int librawUseGPL3DemosaicPack()
Return true or false if LibRaw use Demosaic Pack GPL3 or not.
Definition: kdcraw.cpp:542
static int rawFilesVersion()
Returns a version number for the list of supported RAW file types.
Definition: kdcraw.cpp:482
void resize(int size)
void append(const T &value)
static const char * rawFiles()
Return the string of all RAW file type mime supported.
Definition: kdcraw.cpp:471
QString fromUtf8(const char *str, int size)
list of RAW file extensions supported by libraw
bool isEmpty() const const
static bool loadFullImage(QImage &image, const QString &path, const RawDecodingSettings &settings=RawDecodingSettings())
Get the full decoded RAW picture.
Definition: kdcraw.cpp:231
virtual bool open(QIODevice::OpenMode flags) override
bool isDecodable
True is RAW file is decodable by dcraw.
const QByteArray & data() const const
bool exists() const const
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:467
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
virtual bool checkToCancelWaitingData()
Re-implement this method to control the cancelisation of loop witch wait data from RAW decoding proce...
Definition: kdcraw.cpp:462
static QStringList rawFilesList()
Return the list of all RAW file type mime supported, as a QStringList, without wildcard and suffix do...
Definition: kdcraw.cpp:476
bool extractRAWData(const QString &filePath, QByteArray &rawData, DcrawInfoContainer &identify, unsigned int shotSelect=0)
Extract Raw image data undemosaiced and without post processing from &#39;filePath&#39; picture file...
Definition: kdcraw.cpp:323
static bool rawFileIdentify(DcrawInfoContainer &identify, const QString &path)
Get the camera settings witch have taken RAW file.
Definition: kdcraw.cpp:286
QString suffix() const const
The wrapper class.
Definition: kdcraw.h:37
static int librawUseGPL2DemosaicPack()
Return true or false if LibRaw use Demosaic Pack GPL2 or not.
Definition: kdcraw.cpp:529
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 &#39;filePath&#39; picture file using &#39;rawDecodingSettings&#39; sett...
Definition: kdcraw.cpp:447
char * data()
uchar * bits()
QString fromLatin1(const char *str, int size)
void cancel()
To cancel &#39;decodeHalfRAWImage&#39; and &#39;decodeRAWImage&#39; methods running in a separate thread...
Definition: kdcraw.cpp:51
static bool loadRawPreview(QImage &image, const QString &path)
Get the preview of RAW picture as a QImage.
Definition: kdcraw.cpp:56
Main namespace of libKDcraw.
Settings for raw decoding.
static int librawUseRawSpeed()
Return true or false if LibRaw use RawSpeed codec or not.
Definition: kdcraw.cpp:516
int size() const const
static bool loadHalfPreview(QImage &image, const QString &path)
Get the half decoded RAW picture.
Definition: kdcraw.cpp:128
static QStringList supportedCamera()
Provide a list of supported RAW Camera name.
Definition: kdcraw.cpp:487
bool decodeRAWImage(const QString &filePath, const RawDecodingSettings &rawDecodingSettings, QByteArray &imageData, int &width, int &height, int &rgbmax)
Extract a full size of RAW data from &#39;filePath&#39; picture file using &#39;rawDecodingSettings&#39; settings...
Definition: kdcraw.cpp:455
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
QByteArray encodeName(const QString &fileName)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Sep 27 2021 22:36:14 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.