1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2006-12-09
7  * Description : a tread-safe libraw Qt interface
8  *
9  * Copyright (C) 2006-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10  * Copyright (C) 2006-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
11  * Copyright (C) 2007-2008 by Guillaume Castagnino <casta at xwing dot info>
12  *
13  * This program is free software; you can redistribute it
14  * and/or modify it under the terms of the GNU General
15  * Public License as published by the Free Software Foundation;
16  * either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * ============================================================ */
25 
26 #ifndef DIGIKAM_DRAW_DECODER_H
27 #define DIGIKAM_DRAW_DECODER_H
28 
29 // C++ includes
30 
31 #include <cmath>
32 
33 // Qt includes
34 
35 #include <QBuffer>
36 #include <QString>
37 #include <QObject>
38 #include <QImage>
39 
40 // Local includes
41 
42 #include "drawdecodersettings.h"
43 #include "drawinfo.h"
44 #include "digikam_export.h"
45 
46 namespace Digikam
47 {
48 
49 class DIGIKAM_EXPORT DRawDecoder : public QObject
50 {
51     Q_OBJECT
52 
53 public:
54 
55     /**
56      * Standard constructor.
57      */
58     DRawDecoder();
59 
60     /**
61      * Standard destructor.
62      */
63     ~DRawDecoder() override;
64 
65 public:
66 
67     /**
68      * Get the preview of RAW picture as a QImage.
69      * It tries loadEmbeddedPreview() first and if it fails, calls loadHalfPreview().
70      */
71     static bool loadRawPreview(QImage& image, const QString& path);
72 
73     /**
74      * Get the preview of RAW picture as a QByteArray holding JPEG data.
75      * It tries loadEmbeddedPreview() first and if it fails, calls loadHalfPreview().
76      */
77     static bool loadRawPreview(QByteArray& imgData, const QString& path);
78 
79     /**
80      * Get the preview of RAW picture passed in QBuffer as a QByteArray holding JPEG data.
81      * It tries loadEmbeddedPreview() first and if it fails, calls loadHalfPreview().
82      */
83     static bool loadRawPreview(QByteArray& imgData, const QBuffer& inBuffer);
84 
85     /**
86      * Get the embedded JPEG preview image from RAW picture as a QByteArray which will include Exif Data.
87      * This is fast and non cancelable. This method does not require a class instance to run.
88      */
89     static bool loadEmbeddedPreview(QByteArray& imgData, const QString& path);
90 
91     /**
92      * Get the embedded JPEG preview image from RAW picture as a QImage. This is fast and non cancelable
93      * This method does not require a class instance to run.
94      */
95     static bool loadEmbeddedPreview(QImage& image, const QString& path);
96 
97     /**
98      * Get the embedded JPEG preview image from RAW image passed in QBuffer as a QByteArray which will include Exif Data.
99      * This is fast and non cancelable. This method does not require a class instance to run.
100      */
101     static bool loadEmbeddedPreview(QByteArray& imgData, const QBuffer& inBuffer);
102 
103     /**
104      * Get the half decoded RAW picture. This is slower than loadEmbeddedPreview() method
105      * and non cancelable. This method does not require a class instance to run.
106      */
107     static bool loadHalfPreview(QImage& image, const QString& path);
108 
109     /**
110      * Get the half decoded RAW picture as JPEG data in QByteArray. This is slower than loadEmbeddedPreview()
111      * method and non cancelable. This method does not require a class instance to run.
112      */
113     static bool loadHalfPreview(QByteArray& imgData, const QString& path);
114 
115     /**
116      * Get the half decoded RAW picture passed in QBuffer as JPEG data in QByteArray. This is slower than loadEmbeddedPreview()
117      * method and non cancelable. This method does not require a class instance to run.
118      */
119     static bool loadHalfPreview(QByteArray& imgData, const QBuffer& inBuffer);
120 
121     /**
122      * Get the full decoded RAW picture. This is a more slower than loadHalfPreview() method
123      * and non cancelable. This method does not require a class instance to run.
124      */
125     static bool loadFullImage(QImage& image,
126                               const QString& path,
127                               const DRawDecoderSettings& settings = DRawDecoderSettings());
128 
129     /**
130      * Get the camera settings which have taken RAW file. Look into rawinfo.h
131      * for more details. This is a fast and non cancelable method which do not require
132      * a class instance to run.
133      */
134     static bool rawFileIdentify(DRawInfo& identify, const QString& path);
135 
136     /**
137      * Return the string of all RAW file type mime supported.
138      */
139     static QString rawFiles();
140 
141     /**
142      * Return the list of all RAW file type mime supported,
143      * as a QStringList, without wildcard and suffix dot.
144      */
145     static QStringList rawFilesList();
146 
147     /**
148      * Returns a version number for the list of supported RAW file types.
149      * This version is incremented if the list of supported formats has changed
150      * between library releases.
151      */
152     static int rawFilesVersion();
153 
154     /**
155      * Provide a list of supported RAW Camera name.
156      */
157     static QStringList supportedCamera();
158 
159     /**
160      * Return LibRaw version string.
161      */
162     static QString librawVersion();
163 
164     /**
165      * Return true or false if LibRaw use parallel demosaicing or not (libgomp support).
166      * Return -1 if undefined.
167      */
168     static int librawUseGomp();
169 
170     static bool isRawFile(const QUrl& url);
171 
172 public:
173 
174     /**
175      * Extract Raw image data undemosaiced and without post processing from 'filePath' picture file.
176      * This is a cancelable method which require a class instance to run because RAW pictures loading
177      * can take a while.
178      *
179      * This method return:
180      *
181      *     - A byte array container 'rawData' with raw data.
182      *     - All info about Raw image into 'identify' container.
183      *     - 'false' is returned if loading failed, else 'true'.
184      */
185     bool extractRAWData(const QString& filePath,
186                         QByteArray& rawData,
187                         DRawInfo& identify,
188                         unsigned int shotSelect=0);
189 
190     /**
191      * Extract a small size of decode RAW data from 'filePath' picture file using
192      * 'DRawDecoderSettings' settings. This is a cancelable method which require
193      * a class instance to run because RAW pictures decoding can take a while.
194      *
195      * This method return:
196      *
197      *     - A byte array container 'imageData' with picture data. Pixels order is RGB.
198      *       Color depth can be 8 or 16. In 8 bits you can access to color component
199      *       using (uchar*), in 16 bits using (ushort*).
200      *
201      *     - Size size of image in number of pixels ('width' and 'height').
202      *     - The max average of RGB components from decoded picture.
203      *     - 'false' is returned if decoding failed, else 'true'.
204      */
205     bool decodeHalfRAWImage(const QString& filePath,
206                             const DRawDecoderSettings& DRawDecoderSettings,
207                             QByteArray& imageData,
208                             int& width,
209                             int& height,
210                             int& rgbmax);
211 
212     /**
213      * Extract a full size of RAW data from 'filePath' picture file using
214      * 'DRawDecoderSettings' settings. This is a cancelable method which require
215      * a class instance to run because RAW pictures decoding can take a while.
216      *
217      * This method return:
218      *
219      *     - A byte array container 'imageData' with picture data. Pixels order is RGB.
220      *       Color depth can be 8 or 16. In 8 bits you can access to color component
221      *       using (uchar*), in 16 bits using (ushort*).
222      *
223      *     - Size size of image in number of pixels ('width' and 'height').
224      *     - The max average of RGB components from decoded picture.
225      *     - 'false' is returned if decoding failed, else 'true'.
226      */
227     bool decodeRAWImage(const QString& filePath,
228                         const DRawDecoderSettings& DRawDecoderSettings,
229                         QByteArray& imageData,
230                         int& width,
231                         int& height,
232                         int& rgbmax);
233 
234     /**
235      * To cancel 'decodeHalfRAWImage' and 'decodeRAWImage' methods running
236      * in a separate thread.
237      */
238     void cancel();
239 
240 protected:
241 
242     /**
243      * Used internally to cancel RAW decoding operation. Normally, you don't need to use it
244      * directly, excepted if you derivated this class. Usual way is to use cancel() method
245      */
246     bool                m_cancel;
247 
248     /**
249      * The settings container used to perform RAW pictures decoding. See 'drawdecodingsetting.h'
250      * for details.
251      */
252     DRawDecoderSettings m_decoderSettings;
253 
254 protected:
255 
256     /**
257      * Re-implement this method to control the cancelisation of loop which wait data
258      * from RAW decoding process with your proper environment.
259      * By default, this method check if m_cancel is true.
260      */
261     virtual bool checkToCancelWaitingData();
262 
263     /**
264      * Re-implement this method to control the pseudo progress value during RAW decoding (when dcraw run with an
265      * internal loop without feedback) with your proper environment. By default, this method does nothing.
266      * Progress value average for this stage is 0%-n%, with 'n' == 40% max (see setWaitingDataProgress() method).
267      */
268     virtual void setWaitingDataProgress(double value);
269 
270 public:
271 
272     // NOTE: declared public to be called externally by s_progressCallbackForLibRaw() static method.
273     class Private;
274 
275 private:
276 
277     // Disabled
278     explicit DRawDecoder(QObject*) = delete;
279 
280     Private* const d;
281 
282     friend class Private;
283 };
284 
285 } // namespace Digikam
286 
287 #endif // DIGIKAM_DRAW_DECODER_H
288