1 // ==========================================================
2 // RAW camera image loader
3 //
4 // Design and implementation by
5 // - Herv� Drolon (drolon@infonie.fr)
6 //
7 // This file is part of FreeImage 3
8 //
9 // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
10 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
11 // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
12 // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
13 // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
14 // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
15 // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
16 // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
17 // THIS DISCLAIMER.
18 //
19 // Use at your own risk!
20 // ==========================================================
21
22 #include "../LibRawLite/libraw/libraw.h"
23
24 #include "FreeImage.h"
25 #include "Utilities.h"
26 #include "../Metadata/FreeImageTag.h"
27
28 // ==========================================================
29 // Plugin Interface
30 // ==========================================================
31
32 static int s_format_id;
33
34 // ==========================================================
35 // Internal functions
36 // ==========================================================
37
38 // ----------------------------------------------------------
39 // FreeImage datastream wrapper
40 // ----------------------------------------------------------
41
42 class LibRaw_freeimage_datastream : public LibRaw_abstract_datastream {
43 private:
44 FreeImageIO *_io;
45 fi_handle _handle;
46 long _eof;
47 INT64 _fsize;
48
49 public:
LibRaw_freeimage_datastream(FreeImageIO * io,fi_handle handle)50 LibRaw_freeimage_datastream(FreeImageIO *io, fi_handle handle) : _io(io), _handle(handle) {
51 long start_pos = io->tell_proc(handle);
52 io->seek_proc(handle, 0, SEEK_END);
53 _eof = io->tell_proc(handle);
54 _fsize = _eof - start_pos;
55 io->seek_proc(handle, start_pos, SEEK_SET);
56 }
57
~LibRaw_freeimage_datastream()58 ~LibRaw_freeimage_datastream() {
59 }
60
valid()61 int valid() {
62 return (_io && _handle);
63 }
64
read(void * buffer,size_t size,size_t count)65 int read(void *buffer, size_t size, size_t count) {
66 if(substream) return substream->read(buffer, size, count);
67 return _io->read_proc(buffer, (unsigned)size, (unsigned)count, _handle);
68 }
69
seek(INT64 offset,int origin)70 int seek(INT64 offset, int origin) {
71 if(substream) return substream->seek(offset, origin);
72 return _io->seek_proc(_handle, (long)offset, origin);
73 }
74
tell()75 INT64 tell() {
76 if(substream) return substream->tell();
77 return _io->tell_proc(_handle);
78 }
79
size()80 INT64 size() {
81 return _fsize;
82 }
83
get_char()84 int get_char() {
85 int c = 0;
86 if(substream) return substream->get_char();
87 if(!_io->read_proc(&c, 1, 1, _handle)) return -1;
88 return c;
89 }
90
gets(char * buffer,int length)91 char* gets(char *buffer, int length) {
92 if (substream) return substream->gets(buffer, length);
93 memset(buffer, 0, length);
94 for(int i = 0; i < length; i++) {
95 if(!_io->read_proc(&buffer[i], 1, 1, _handle))
96 return NULL;
97 if(buffer[i] == 0x0A)
98 break;
99 }
100 return buffer;
101 }
102
scanf_one(const char * fmt,void * val)103 int scanf_one(const char *fmt, void* val) {
104 std::string buffer;
105 char element = 0;
106 bool bDone = false;
107 if(substream) return substream->scanf_one(fmt,val);
108 do {
109 if(_io->read_proc(&element, 1, 1, _handle) == 1) {
110 switch(element) {
111 case '0':
112 case '\n':
113 case ' ':
114 case '\t':
115 bDone = true;
116 break;
117 default:
118 break;
119 }
120 buffer.append(&element, 1);
121 } else {
122 return 0;
123 }
124 } while(!bDone);
125
126 return sscanf(buffer.c_str(), fmt, val);
127 }
128
eof()129 int eof() {
130 if(substream) return substream->eof();
131 return (_io->tell_proc(_handle) >= _eof);
132 }
133
make_jas_stream()134 void * make_jas_stream() {
135 return NULL;
136 }
137 };
138
139 // ----------------------------------------------------------
140
141 /**
142 Convert a processed raw data array to a FIBITMAP
143 @param RawProcessor LibRaw handle containing the processed raw image
144 @return Returns the converted dib if successfull, returns NULL otherwise
145 */
146 static FIBITMAP *
libraw_ConvertProcessedRawToDib(LibRaw * RawProcessor)147 libraw_ConvertProcessedRawToDib(LibRaw *RawProcessor) {
148 FIBITMAP *dib = NULL;
149 int width, height, colors, bpp;
150
151 try {
152 int bgr = 0; // pixel copy order: RGB if (bgr == 0) and BGR otherwise
153
154 // get image info
155 RawProcessor->get_mem_image_format(&width, &height, &colors, &bpp);
156
157 // only 3-color images supported...
158 if(colors != 3) {
159 throw "LibRaw : only 3-color images supported";
160 }
161
162 if(bpp == 16) {
163 // allocate output dib
164 dib = FreeImage_AllocateT(FIT_RGB16, width, height);
165 if(!dib) {
166 throw FI_MSG_ERROR_DIB_MEMORY;
167 }
168
169 } else if(bpp == 8) {
170 #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
171 bgr = 1; // only useful for FIT_BITMAP types
172 #endif
173
174 // allocate output dib
175 dib = FreeImage_AllocateT(FIT_BITMAP, width, height, 24);
176 if(!dib) {
177 throw FI_MSG_ERROR_DIB_MEMORY;
178 }
179 }
180
181 // copy post-processed bitmap data into FIBITMAP buffer
182 if(RawProcessor->copy_mem_image(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), bgr) != LIBRAW_SUCCESS) {
183 throw "LibRaw : failed to copy data into dib";
184 }
185
186 // flip vertically
187 FreeImage_FlipVertical(dib);
188
189 return dib;
190
191 } catch(const char *text) {
192 FreeImage_Unload(dib);
193 FreeImage_OutputMessageProc(s_format_id, text);
194 return NULL;
195 }
196 }
197
198
199 /**
200 Convert a processed raw image to a FIBITMAP
201 @param image Processed raw image
202 @return Returns the converted dib if successfull, returns NULL otherwise
203 @see libraw_LoadEmbeddedPreview
204 */
205 static FIBITMAP *
libraw_ConvertProcessedImageToDib(libraw_processed_image_t * image)206 libraw_ConvertProcessedImageToDib(libraw_processed_image_t *image) {
207 FIBITMAP *dib = NULL;
208
209 try {
210 unsigned width = image->width;
211 unsigned height = image->height;
212 unsigned bpp = image->bits;
213 if(bpp == 16) {
214 // allocate output dib
215 dib = FreeImage_AllocateT(FIT_RGB16, width, height);
216 if(!dib) {
217 throw FI_MSG_ERROR_DIB_MEMORY;
218 }
219 // write data
220 WORD *raw_data = (WORD*)image->data;
221 for(unsigned y = 0; y < height; y++) {
222 FIRGB16 *output = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
223 for(unsigned x = 0; x < width; x++) {
224 output[x].red = raw_data[0];
225 output[x].green = raw_data[1];
226 output[x].blue = raw_data[2];
227 raw_data += 3;
228 }
229 }
230 } else if(bpp == 8) {
231 // allocate output dib
232 dib = FreeImage_AllocateT(FIT_BITMAP, width, height, 24);
233 if(!dib) {
234 throw FI_MSG_ERROR_DIB_MEMORY;
235 }
236 // write data
237 BYTE *raw_data = (BYTE*)image->data;
238 for(unsigned y = 0; y < height; y++) {
239 RGBTRIPLE *output = (RGBTRIPLE*)FreeImage_GetScanLine(dib, height - 1 - y);
240 for(unsigned x = 0; x < width; x++) {
241 output[x].rgbtRed = raw_data[0];
242 output[x].rgbtGreen = raw_data[1];
243 output[x].rgbtBlue = raw_data[2];
244 raw_data += 3;
245 }
246 }
247 }
248
249 return dib;
250
251 } catch(const char *text) {
252 FreeImage_Unload(dib);
253 FreeImage_OutputMessageProc(s_format_id, text);
254 return NULL;
255 }
256 }
257
258 /**
259 Get the embedded JPEG preview image from RAW picture with included Exif Data.
260 @param RawProcessor Libraw handle
261 @param flags JPEG load flags
262 @return Returns the loaded dib if successfull, returns NULL otherwise
263 */
264 static FIBITMAP *
libraw_LoadEmbeddedPreview(LibRaw * RawProcessor,int flags)265 libraw_LoadEmbeddedPreview(LibRaw *RawProcessor, int flags) {
266 FIBITMAP *dib = NULL;
267 libraw_processed_image_t *thumb_image = NULL;
268
269 try {
270 // unpack data
271 if(RawProcessor->unpack_thumb() != LIBRAW_SUCCESS) {
272 // run silently "LibRaw : failed to run unpack_thumb"
273 return NULL;
274 }
275
276 // retrieve thumb image
277 int error_code = 0;
278 thumb_image = RawProcessor->dcraw_make_mem_thumb(&error_code);
279 if(thumb_image) {
280 if(thumb_image->type != LIBRAW_IMAGE_BITMAP) {
281 // attach the binary data to a memory stream
282 FIMEMORY *hmem = FreeImage_OpenMemory((BYTE*)thumb_image->data, (DWORD)thumb_image->data_size);
283 // get the file type
284 FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
285 if(fif == FIF_JPEG) {
286 // rotate according to Exif orientation
287 flags |= JPEG_EXIFROTATE;
288 }
289 // load an image from the memory stream
290 dib = FreeImage_LoadFromMemory(fif, hmem, flags);
291 // close the stream
292 FreeImage_CloseMemory(hmem);
293 } else if((flags & FIF_LOAD_NOPIXELS) != FIF_LOAD_NOPIXELS) {
294 // convert processed data to output dib
295 dib = libraw_ConvertProcessedImageToDib(thumb_image);
296 }
297 } else {
298 throw "LibRaw : failed to run dcraw_make_mem_thumb";
299 }
300
301 // clean-up and return
302 RawProcessor->dcraw_clear_mem(thumb_image);
303
304 return dib;
305
306 } catch(const char *text) {
307 // clean-up and return
308 if(thumb_image) {
309 RawProcessor->dcraw_clear_mem(thumb_image);
310 }
311 if(text != NULL) {
312 FreeImage_OutputMessageProc(s_format_id, text);
313 }
314 }
315
316 return NULL;
317 }
318 /**
319 Load raw data and convert to FIBITMAP
320 @param RawProcessor Libraw handle
321 @param bitspersample Output bitdepth (8- or 16-bit)
322 @return Returns the loaded dib if successfull, returns NULL otherwise
323 */
324 static FIBITMAP *
libraw_LoadRawData(LibRaw * RawProcessor,int bitspersample)325 libraw_LoadRawData(LibRaw *RawProcessor, int bitspersample) {
326 FIBITMAP *dib = NULL;
327
328 try {
329 // set decoding parameters
330 // -----------------------
331
332 // (-6) 16-bit or 8-bit
333 RawProcessor->imgdata.params.output_bps = bitspersample;
334 // (-g power toe_slope)
335 if(bitspersample == 16) {
336 // set -g 1 1 for linear curve
337 RawProcessor->imgdata.params.gamm[0] = 1;
338 RawProcessor->imgdata.params.gamm[1] = 1;
339 } else if(bitspersample == 8) {
340 // by default settings for rec. BT.709 are used: power 2.222 (i.e. gamm[0]=1/2.222) and slope 4.5
341 RawProcessor->imgdata.params.gamm[0] = 1/2.222;
342 RawProcessor->imgdata.params.gamm[1] = 4.5;
343 }
344 // (-W) Don't use automatic increase of brightness by histogram
345 RawProcessor->imgdata.params.no_auto_bright = 1;
346 // (-a) Use automatic white balance obtained after averaging over the entire image
347 RawProcessor->imgdata.params.use_auto_wb = 1;
348 // (-q 3) Adaptive homogeneity-directed demosaicing algorithm (AHD)
349 RawProcessor->imgdata.params.user_qual = 3;
350
351 // -----------------------
352
353 // unpack data
354 if(RawProcessor->unpack() != LIBRAW_SUCCESS) {
355 throw "LibRaw : failed to unpack data";
356 }
357
358 // process data (... most consuming task ...)
359 if(RawProcessor->dcraw_process() != LIBRAW_SUCCESS) {
360 throw "LibRaw : failed to process data";
361 }
362
363 // retrieve processed image
364 dib = libraw_ConvertProcessedRawToDib(RawProcessor);
365
366 return dib;
367
368 } catch(const char *text) {
369 FreeImage_OutputMessageProc(s_format_id, text);
370 return NULL;
371 }
372 }
373
374 /**
375 Load the Bayer matrix (unprocessed raw data) as a FIT_UINT16 image.
376 Note that some formats don't have a Bayer matrix (e.g. Foveon, Canon sRAW, demosaiced DNG files).
377 @param RawProcessor Libraw handle
378 @return Returns the loaded dib if successfull, returns NULL otherwise
379 */
380 static FIBITMAP *
libraw_LoadUnprocessedData(LibRaw * RawProcessor)381 libraw_LoadUnprocessedData(LibRaw *RawProcessor) {
382 FIBITMAP *dib = NULL;
383
384 try {
385 // unpack data
386 if(RawProcessor->unpack() != LIBRAW_SUCCESS) {
387 throw "LibRaw : failed to unpack data";
388 }
389
390 // check for a supported Bayer format
391 if(!(RawProcessor->imgdata.idata.filters || RawProcessor->imgdata.idata.colors == 1)) {
392 throw "LibRaw : only Bayer-pattern RAW files are supported";
393 }
394
395 // allocate output dib
396 const unsigned width = RawProcessor->imgdata.sizes.raw_width;
397 const unsigned height = RawProcessor->imgdata.sizes.raw_height;
398 const size_t line_size = width * sizeof(WORD);
399 const WORD *src_bits = (WORD*)RawProcessor->imgdata.rawdata.raw_image;
400
401 if(src_bits) {
402 dib = FreeImage_AllocateT(FIT_UINT16, width, height);
403 }
404 if(!dib) {
405 throw FI_MSG_ERROR_DIB_MEMORY;
406 }
407
408 // retrieve the raw image
409 for(unsigned y = 0; y < height; y++) {
410 WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
411 memcpy(dst_bits, src_bits, line_size);
412 src_bits += width;
413 }
414
415 // store metadata needed for post-processing
416 {
417 char value[512];
418
419 const libraw_image_sizes_t *sizes = &RawProcessor->imgdata.sizes;
420
421 // image output width & height
422 {
423 sprintf(value, "%d", sizes->iwidth);
424 FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Output.Width", value);
425
426 sprintf(value, "%d", sizes->iheight);
427 FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Output.Height", value);
428 }
429
430 // image output frame
431 {
432 const unsigned f_left = sizes->left_margin;
433 const unsigned f_top = sizes->top_margin;
434 const unsigned f_width = sizes->width;
435 const unsigned f_height = sizes->height;
436
437 sprintf(value, "%d", f_left);
438 FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Left", value);
439
440 sprintf(value, "%d", f_top);
441 FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Top", value);
442
443 sprintf(value, "%d", f_width);
444 FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Width", value);
445
446 sprintf(value, "%d", f_height);
447 FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.Frame.Height", value);
448 }
449
450 // Bayer pattern
451 // Mask describing the order of color pixels in the matrix.
452 // This field describe 16 pixels (8 rows with two pixels in each, from left to right and from top to bottom).
453
454 if(RawProcessor->imgdata.idata.filters) {
455 // description of colors numbered from 0 to 3 (RGBG,RGBE,GMCY, or GBTG)
456 char *cdesc = RawProcessor->imgdata.idata.cdesc;
457 if(!cdesc[3]) {
458 cdesc[3] = 'G';
459 }
460 char *pattern = &value[0];
461 for(int i = 0; i < 16; i++) {
462 pattern[i] = cdesc[ RawProcessor->fcol(i >> 1, i & 1) ];
463 }
464 pattern[16] = 0;
465
466 FreeImage_SetMetadataKeyValue(FIMD_COMMENTS, dib, "Raw.BayerPattern", value);
467 }
468 }
469
470 return dib;
471
472 } catch(const char *text) {
473 FreeImage_Unload(dib);
474 FreeImage_OutputMessageProc(s_format_id, text);
475 return NULL;
476 }
477 }
478
479 // ==========================================================
480 // Plugin Implementation
481 // ==========================================================
482
483 static const char * DLL_CALLCONV
Format()484 Format() {
485 return "RAW";
486 }
487
488 static const char * DLL_CALLCONV
Description()489 Description() {
490 return "RAW camera image";
491 }
492
493 static const char * DLL_CALLCONV
Extension()494 Extension() {
495 /**
496 Below are known RAW file extensions that you can check using FreeImage_GetFIFFromFormat.
497 If a file extension is not listed, that doesn't mean that you cannot load it.
498 Using FreeImage_GetFileType is the best way to know if a RAW file format is supported.
499 */
500 static const char *raw_extensions =
501 "3fr," // Hasselblad Digital Camera Raw Image Format.
502 "arw," // Sony Digital Camera Raw Image Format for Alpha devices.
503 "bay," // Casio Digital Camera Raw File Format.
504 "bmq," // NuCore Raw Image File.
505 "cap," // Phase One Digital Camera Raw Image Format.
506 "cine," // Phantom Software Raw Image File.
507 "cr2," // Canon Digital Camera RAW Image Format version 2.0. These images are based on the TIFF image standard.
508 "crw," // Canon Digital Camera RAW Image Format version 1.0.
509 "cs1," // Sinar Capture Shop Raw Image File.
510 "dc2," // Kodak DC25 Digital Camera File.
511 "dcr," // Kodak Digital Camera Raw Image Format for these models: Kodak DSC Pro SLR/c, Kodak DSC Pro SLR/n, Kodak DSC Pro 14N, Kodak DSC PRO 14nx.
512 "drf," // Kodak Digital Camera Raw Image Format.
513 "dsc," // Kodak Digital Camera Raw Image Format.
514 "dng," // Adobe Digital Negative: DNG is publicly available archival format for the raw files generated by digital cameras. By addressing the lack of an open standard for the raw files created by individual camera models, DNG helps ensure that photographers will be able to access their files in the future.
515 "erf," // Epson Digital Camera Raw Image Format.
516 "fff," // Imacon Digital Camera Raw Image Format.
517 "ia," // Sinar Raw Image File.
518 "iiq," // Phase One Digital Camera Raw Image Format.
519 "k25," // Kodak DC25 Digital Camera Raw Image Format.
520 "kc2," // Kodak DCS200 Digital Camera Raw Image Format.
521 "kdc," // Kodak Digital Camera Raw Image Format.
522 "mdc," // Minolta RD175 Digital Camera Raw Image Format.
523 "mef," // Mamiya Digital Camera Raw Image Format.
524 "mos," // Leaf Raw Image File.
525 "mrw," // Minolta Dimage Digital Camera Raw Image Format.
526 "nef," // Nikon Digital Camera Raw Image Format.
527 "nrw," // Nikon Digital Camera Raw Image Format.
528 "orf," // Olympus Digital Camera Raw Image Format.
529 "pef," // Pentax Digital Camera Raw Image Format.
530 "ptx," // Pentax Digital Camera Raw Image Format.
531 "pxn," // Logitech Digital Camera Raw Image Format.
532 "qtk," // Apple Quicktake 100/150 Digital Camera Raw Image Format.
533 "raf," // Fuji Digital Camera Raw Image Format.
534 "raw," // Panasonic Digital Camera Image Format.
535 "rdc," // Digital Foto Maker Raw Image File.
536 "rw2," // Panasonic LX3 Digital Camera Raw Image Format.
537 "rwl," // Leica Camera Raw Image Format.
538 "rwz," // Rawzor Digital Camera Raw Image Format.
539 "sr2," // Sony Digital Camera Raw Image Format.
540 "srf," // Sony Digital Camera Raw Image Format for DSC-F828 8 megapixel digital camera or Sony DSC-R1.
541 "srw," // Samsung Raw Image Format.
542 "sti," // Sinar Capture Shop Raw Image File.
543 "x3f"; // Sigma Digital Camera Raw Image Format for devices based on Foveon X3 direct image sensor.
544 return raw_extensions;
545 }
546
547 static const char * DLL_CALLCONV
RegExpr()548 RegExpr() {
549 return NULL;
550 }
551
552 static const char * DLL_CALLCONV
MimeType()553 MimeType() {
554 return "image/x-dcraw";
555 }
556
557 static BOOL
HasMagicHeader(FreeImageIO * io,fi_handle handle)558 HasMagicHeader(FreeImageIO *io, fi_handle handle) {
559 const unsigned signature_size = 32;
560 BYTE signature[signature_size] = { 0 };
561 /*
562 note: classic TIFF signature is
563 { 0x49, 0x49, 0x2A, 0x00 } Classic TIFF, little-endian
564 { 0x4D, 0x4D, 0x00, 0x2A } Classic TIFF, big-endian
565 */
566 // Canon (CR2), little-endian byte order
567 const BYTE CR2_II[] = { 0x49, 0x49, 0x2A, 0x00, 0x10, 0x00, 0x00, 0x00, 0x43, 0x52, 0x02, 0x00 };
568 // Canon (CRW), little-endian byte order
569 const BYTE CRW_II[] = { 0x49, 0x49, 0x1A, 0x00, 0x00, 0x00, 0x48, 0x45, 0x41, 0x50, 0x43, 0x43, 0x44, 0x52, 0x02, 0x00 };
570 // Minolta (MRW)
571 const BYTE MRW[] = { 0x00, 0x4D, 0x52, 0x4D, 0x00 };
572 // Olympus (ORF), little-endian byte order
573 const BYTE ORF_IIRS[] = { 0x49, 0x49, 0x52, 0x53, 0x08, 0x00, 0x00, 0x00 };
574 const BYTE ORF_IIRO[] = { 0x49, 0x49, 0x52, 0x4F, 0x08, 0x00, 0x00, 0x00 };
575 // Olympus (ORF), big-endian byte order
576 const BYTE ORF_MMOR[] = { 0x4D, 0x4D, 0x4F, 0x52, 0x00, 0x00, 0x00, 0x08 };
577 // Fujifilm (RAF)
578 const BYTE RAF[] = { 0x46, 0x55, 0x4A, 0x49, 0x46, 0x49, 0x4C, 0x4D, 0x43, 0x43, 0x44, 0x2D, 0x52, 0x41, 0x57, 0x20 };
579 // Panasonic (RW2) or Leica (RWL), little-endian byte order
580 const BYTE RWx_II[] = { 0x49, 0x49, 0x55, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0xE7, 0x74, 0xD8, 0xF8, 0x25, 0x1D, 0x4D, 0x94, 0x7A, 0x6E, 0x77, 0x82, 0x2B, 0x5D, 0x6A };
581 // Panasonic (RAW) or Leica (RAW), little-endian byte order
582 const BYTE RAW_II[] = { 0x49, 0x49, 0x55, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00 };
583 // Foveon (X3F)
584 const BYTE X3F[] = { 0x46, 0x4F, 0x56, 0x62 };
585
586 if(io->read_proc(signature, 1, signature_size, handle) != signature_size) {
587 return FALSE;
588 }
589 if(memcmp(CR2_II, signature, 12) == 0)
590 return TRUE;
591 if(memcmp(CRW_II, signature, 16) == 0)
592 return TRUE;
593 if(memcmp(MRW, signature, 5) == 0)
594 return TRUE;
595 if(memcmp(ORF_IIRS, signature, 8) == 0)
596 return TRUE;
597 if(memcmp(ORF_IIRO, signature, 8) == 0)
598 return TRUE;
599 if(memcmp(ORF_MMOR, signature, 8) == 0)
600 return TRUE;
601 if(memcmp(RAF, signature, 16) == 0)
602 return TRUE;
603 if(memcmp(RWx_II, signature, 24) == 0)
604 return TRUE;
605 if(memcmp(RAW_II, signature, 18) == 0)
606 return TRUE;
607 if(memcmp(X3F, signature, 4) == 0)
608 return TRUE;
609
610 return FALSE;
611 }
612
613 static BOOL DLL_CALLCONV
Validate(FreeImageIO * io,fi_handle handle)614 Validate(FreeImageIO *io, fi_handle handle) {
615 // some RAW files have a magic signature (most of them have a TIFF signature)
616 // try to check this in order to speed up the file identification
617 {
618 long tell = io->tell_proc(handle);
619 if( HasMagicHeader(io, handle) ) {
620 return TRUE;
621 } else {
622 io->seek_proc(handle, tell, SEEK_SET);
623 }
624 }
625
626 // no magic signature : we need to open the file (it will take more time to identify it)
627 // do not declare RawProcessor on the stack as it may be huge (300 KB)
628 {
629 LibRaw *RawProcessor = new(std::nothrow) LibRaw;
630
631 if(RawProcessor) {
632 BOOL bSuccess = TRUE;
633
634 // wrap the input datastream
635 LibRaw_freeimage_datastream datastream(io, handle);
636
637 // open the datastream
638 if(RawProcessor->open_datastream(&datastream) != LIBRAW_SUCCESS) {
639 bSuccess = FALSE; // LibRaw : failed to open input stream (unknown format)
640 }
641
642 // clean-up internal memory allocations
643 RawProcessor->recycle();
644 delete RawProcessor;
645
646 return bSuccess;
647 }
648 }
649
650 return FALSE;
651 }
652
653 static BOOL DLL_CALLCONV
SupportsExportDepth(int depth)654 SupportsExportDepth(int depth) {
655 return FALSE;
656 }
657
658 static BOOL DLL_CALLCONV
SupportsExportType(FREE_IMAGE_TYPE type)659 SupportsExportType(FREE_IMAGE_TYPE type) {
660 return FALSE;
661 }
662
663 static BOOL DLL_CALLCONV
SupportsICCProfiles()664 SupportsICCProfiles() {
665 return TRUE;
666 }
667
668 static BOOL DLL_CALLCONV
SupportsNoPixels()669 SupportsNoPixels() {
670 return TRUE;
671 }
672
673 // ----------------------------------------------------------
674
675 static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO * io,fi_handle handle,int page,int flags,void * data)676 Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
677 FIBITMAP *dib = NULL;
678 LibRaw *RawProcessor = NULL;
679
680 BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
681
682 try {
683 // do not declare RawProcessor on the stack as it may be huge (300 KB)
684 RawProcessor = new(std::nothrow) LibRaw;
685 if(!RawProcessor) {
686 throw FI_MSG_ERROR_MEMORY;
687 }
688
689 // wrap the input datastream
690 LibRaw_freeimage_datastream datastream(io, handle);
691
692 // set decoding parameters
693 // the following parameters affect data reading
694 // --------------------------------------------
695
696 // (-s [0..N-1]) Select one raw image from input file
697 RawProcessor->imgdata.params.shot_select = 0;
698 // (-w) Use camera white balance, if possible (otherwise, fallback to auto_wb)
699 RawProcessor->imgdata.params.use_camera_wb = 1;
700 // (-M) Use any color matrix from the camera metadata. This option only affects Olympus, Leaf, and Phase One cameras.
701 RawProcessor->imgdata.params.use_camera_matrix = 1;
702 // (-h) outputs the image in 50% size
703 RawProcessor->imgdata.params.half_size = ((flags & RAW_HALFSIZE) == RAW_HALFSIZE) ? 1 : 0;
704
705 // open the datastream
706 if(RawProcessor->open_datastream(&datastream) != LIBRAW_SUCCESS) {
707 throw "LibRaw : failed to open input stream (unknown format)";
708 }
709
710 if(header_only) {
711 // header only mode
712 dib = FreeImage_AllocateHeaderT(header_only, FIT_RGB16, RawProcessor->imgdata.sizes.width, RawProcessor->imgdata.sizes.height);
713 }
714 else if((flags & RAW_UNPROCESSED) == RAW_UNPROCESSED) {
715 // load raw data without post-processing (i.e. as a Bayer matrix)
716 dib = libraw_LoadUnprocessedData(RawProcessor);
717 }
718 else if((flags & RAW_PREVIEW) == RAW_PREVIEW) {
719 // try to get the embedded JPEG
720 dib = libraw_LoadEmbeddedPreview(RawProcessor, 0);
721 if(!dib) {
722 // no JPEG preview: try to load as 8-bit/sample (i.e. RGB 24-bit)
723 dib = libraw_LoadRawData(RawProcessor, 8);
724 }
725 }
726 else if((flags & RAW_DISPLAY) == RAW_DISPLAY) {
727 // load raw data as 8-bit/sample (i.e. RGB 24-bit)
728 dib = libraw_LoadRawData(RawProcessor, 8);
729 }
730 else {
731 // default: load raw data as linear 16-bit/sample (i.e. RGB 48-bit)
732 dib = libraw_LoadRawData(RawProcessor, 16);
733 }
734
735 // save ICC profile if present
736 if(dib && (NULL != RawProcessor->imgdata.color.profile)) {
737 FreeImage_CreateICCProfile(dib, RawProcessor->imgdata.color.profile, RawProcessor->imgdata.color.profile_length);
738 }
739
740 // try to get JPEG embedded Exif metadata
741 if(dib && !((flags & RAW_PREVIEW) == RAW_PREVIEW)) {
742 FIBITMAP *metadata_dib = libraw_LoadEmbeddedPreview(RawProcessor, FIF_LOAD_NOPIXELS);
743 if(metadata_dib) {
744 FreeImage_CloneMetadata(dib, metadata_dib);
745 FreeImage_Unload(metadata_dib);
746 }
747 }
748
749 // clean-up internal memory allocations
750 RawProcessor->recycle();
751 delete RawProcessor;
752
753 return dib;
754
755 } catch(const char *text) {
756 if(RawProcessor) {
757 RawProcessor->recycle();
758 delete RawProcessor;
759 }
760 if(dib) {
761 FreeImage_Unload(dib);
762 }
763 FreeImage_OutputMessageProc(s_format_id, text);
764 }
765
766 return NULL;
767 }
768
769 // ==========================================================
770 // Init
771 // ==========================================================
772
773 void DLL_CALLCONV
InitRAW(Plugin * plugin,int format_id)774 InitRAW(Plugin *plugin, int format_id) {
775 s_format_id = format_id;
776
777 plugin->format_proc = Format;
778 plugin->description_proc = Description;
779 plugin->extension_proc = Extension;
780 plugin->regexpr_proc = RegExpr;
781 plugin->open_proc = NULL;
782 plugin->close_proc = NULL;
783 plugin->pagecount_proc = NULL;
784 plugin->pagecapability_proc = NULL;
785 plugin->load_proc = Load;
786 plugin->save_proc = NULL;
787 plugin->validate_proc = Validate;
788 plugin->mime_proc = MimeType;
789 plugin->supports_export_bpp_proc = SupportsExportDepth;
790 plugin->supports_export_type_proc = SupportsExportType;
791 plugin->supports_icc_profiles_proc = SupportsICCProfiles;
792 plugin->supports_no_pixels_proc = SupportsNoPixels;
793 }
794