2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read the Digital Negative Image Format %
20 % Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % https://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 #include "MagickCore/studio.h"
42 #include "MagickCore/blob.h"
43 #include "MagickCore/blob-private.h"
44 #include "MagickCore/constitute.h"
45 #include "MagickCore/delegate.h"
46 #include "MagickCore/exception.h"
47 #include "MagickCore/exception-private.h"
48 #include "MagickCore/geometry.h"
49 #include "MagickCore/image.h"
50 #include "MagickCore/image-private.h"
51 #include "MagickCore/layer.h"
52 #include "MagickCore/list.h"
53 #include "MagickCore/log.h"
54 #include "MagickCore/magick.h"
55 #include "MagickCore/memory_.h"
56 #include "MagickCore/monitor.h"
57 #include "MagickCore/monitor-private.h"
58 #include "MagickCore/opencl.h"
59 #include "MagickCore/pixel-accessor.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/resource_.h"
62 #include "MagickCore/static.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/transform.h"
66 #include "MagickCore/utility.h"
67 #include "MagickCore/xml-tree.h"
68 #include "MagickCore/xml-tree-private.h"
69 #if defined(MAGICKCORE_RAW_R_DELEGATE)
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 % R e a d D N G I m a g e %
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % ReadDNGImage() reads an binary file in the Digital Negative format and
85 % returns it. It allocates the memory necessary for the new Image structure
86 % and returns a pointer to the new image.
88 % The format of the ReadDNGImage method is:
90 % Image *ReadDNGImage(const ImageInfo *image_info,
91 % ExceptionInfo *exception)
93 % A description of each parameter follows:
95 % o image_info: the image info.
97 % o exception: return any errors or warnings in this structure.
101 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && defined(MAGICKCORE_OPENCL_SUPPORT)
102 static void InitializeDcrawOpenCL(ExceptionInfo *exception)
116 (void) SetEnvironmentVariable("DCR_CL_PLATFORM",NULL);
117 (void) SetEnvironmentVariable("DCR_CL_DEVICE",NULL);
118 (void) SetEnvironmentVariable("DCR_CL_DISABLED",NULL);
119 if (GetOpenCLEnabled() == MagickFalse)
121 (void) SetEnvironmentVariable("DCR_CL_DISABLED","1");
124 devices=GetOpenCLDevices(&length,exception);
125 if (devices == (MagickCLDevice *) NULL)
127 for (i=0; i < (ssize_t) length; i++)
136 if (GetOpenCLDeviceEnabled(device) == MagickFalse)
138 name=GetOpenCLDeviceVendorName(device);
139 if (name != (const char *) NULL)
140 (void) SetEnvironmentVariable("DCR_CL_PLATFORM",name);
141 name=GetOpenCLDeviceName(device);
142 if (name != (const char *) NULL)
143 (void) SetEnvironmentVariable("DCR_CL_DEVICE",name);
148 #if !defined(MAGICKCORE_RAW_R_DELEGATE)
149 static void InitializeDcrawOpenCL(ExceptionInfo *magick_unused(exception))
151 magick_unreferenced(exception);
152 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
153 (void) SetEnvironmentVariable("DCR_CL_DISABLED","1");
159 static Image *ReadDNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
170 assert(image_info != (const ImageInfo *) NULL);
171 assert(image_info->signature == MagickCoreSignature);
172 if (image_info->debug != MagickFalse)
173 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
174 image_info->filename);
175 assert(exception != (ExceptionInfo *) NULL);
176 assert(exception->signature == MagickCoreSignature);
177 image=AcquireImage(image_info,exception);
178 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
179 if (status == MagickFalse)
181 image=DestroyImageList(image);
182 return((Image *) NULL);
184 (void) CloseBlob(image);
185 #if defined(MAGICKCORE_RAW_R_DELEGATE)
193 libraw_processed_image_t
203 raw_info=libraw_init(0);
204 if (raw_info == (libraw_data_t *) NULL)
206 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
207 libraw_strerror(errcode),"`%s'",image->filename);
208 return(DestroyImageList(image));
210 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1310)
213 fileName[MagickPathExtent];
215 MultiByteToWideChar(CP_UTF8,0,image->filename,-1,fileName,
217 errcode=libraw_open_wfile(raw_info,fileName);
220 errcode=libraw_open_file(raw_info,image->filename);
222 if (errcode != LIBRAW_SUCCESS)
224 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
225 libraw_strerror(errcode),"`%s'",image->filename);
226 return(DestroyImageList(image));
228 errcode=libraw_unpack(raw_info);
229 if (errcode != LIBRAW_SUCCESS)
231 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
232 libraw_strerror(errcode),"`%s'",image->filename);
233 libraw_close(raw_info);
234 return(DestroyImageList(image));
236 raw_info->params.output_bps=16;
237 errcode=libraw_dcraw_process(raw_info);
238 if (errcode != LIBRAW_SUCCESS)
240 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
241 libraw_strerror(errcode),"`%s'",image->filename);
242 libraw_close(raw_info);
243 return(DestroyImageList(image));
245 raw_image=libraw_dcraw_make_mem_image(raw_info,&errcode);
246 if ((errcode != LIBRAW_SUCCESS) ||
247 (raw_image == (libraw_processed_image_t *) NULL) ||
248 (raw_image->type != LIBRAW_IMAGE_BITMAP) || (raw_image->bits != 16) ||
249 (raw_image->colors < 3) || (raw_image->colors > 4))
251 if (raw_image != (libraw_processed_image_t *) NULL)
252 libraw_dcraw_clear_mem(raw_image);
253 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
254 libraw_strerror(errcode),"`%s'",image->filename);
255 libraw_close(raw_info);
256 return(DestroyImageList(image));
258 image->columns=raw_image->width;
259 image->rows=raw_image->height;
261 status=SetImageExtent(image,image->columns,image->rows,exception);
262 if (status == MagickFalse)
264 libraw_dcraw_clear_mem(raw_image);
265 libraw_close(raw_info);
266 return(DestroyImageList(image));
268 if (image_info->ping != MagickFalse)
270 libraw_dcraw_clear_mem(raw_image);
271 libraw_close(raw_info);
274 p=(unsigned short *) raw_image->data;
275 for (y=0; y < (ssize_t) image->rows; y++)
283 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
284 if (q == (Quantum *) NULL)
286 for (x=0; x < (ssize_t) image->columns; x++)
288 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
289 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
290 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
291 if (raw_image->colors > 3)
292 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
293 q+=GetPixelChannels(image);
295 if (SyncAuthenticPixels(image,exception) == MagickFalse)
297 if (image->previous == (Image *) NULL)
299 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
301 if (status == MagickFalse)
305 libraw_dcraw_clear_mem(raw_image);
306 libraw_close(raw_info);
318 Convert DNG to PPM with delegate.
320 (void) DestroyImageList(image);
321 InitializeDcrawOpenCL(exception);
322 image=AcquireImage(image_info,exception);
323 read_info=CloneImageInfo(image_info);
324 SetImageInfoBlob(read_info,(void *) NULL,0);
325 (void) InvokeDelegate(read_info,image,"dng:decode",(char *) NULL,exception);
326 image=DestroyImage(image);
327 (void) FormatLocaleString(read_info->filename,MagickPathExtent,"%s.png",
329 sans_exception=AcquireExceptionInfo();
330 image=ReadImage(read_info,sans_exception);
331 sans_exception=DestroyExceptionInfo(sans_exception);
332 if (image == (Image *) NULL)
334 (void) FormatLocaleString(read_info->filename,MagickPathExtent,"%s.ppm",
336 image=ReadImage(read_info,exception);
338 (void) RelinquishUniqueFileResource(read_info->filename);
339 if (image != (Image *) NULL)
342 filename[MagickPathExtent],
348 (void) CopyMagickString(image->magick,read_info->magick,
350 (void) FormatLocaleString(filename,MagickPathExtent,"%s.ufraw",
352 sans=AcquireExceptionInfo();
353 xml=FileToString(filename,MagickPathExtent,sans);
354 (void) RelinquishUniqueFileResource(filename);
355 if (xml != (char *) NULL)
363 ufraw=NewXMLTree(xml,sans);
364 if (ufraw != (XMLTreeInfo *) NULL)
368 property[MagickPathExtent];
376 if (image->properties == (void *) NULL)
377 ((Image *) image)->properties=NewSplayTree(
378 CompareSplayTreeString,RelinquishMagickMemory,
379 RelinquishMagickMemory);
380 next=GetXMLTreeChild(ufraw,(const char *) NULL);
381 while (next != (XMLTreeInfo *) NULL)
383 tag=GetXMLTreeTag(next);
384 if (tag == (char *) NULL)
386 (void) FormatLocaleString(property,MagickPathExtent,"dng:%s",
388 content=ConstantString(GetXMLTreeContent(next));
389 StripString(content);
390 if ((LocaleCompare(tag,"log") != 0) &&
391 (LocaleCompare(tag,"InputFilename") != 0) &&
392 (LocaleCompare(tag,"OutputFilename") != 0) &&
393 (LocaleCompare(tag,"OutputType") != 0) &&
394 (strlen(content) != 0))
395 (void) AddValueToSplayTree((SplayTreeInfo *)
396 ((Image *) image)->properties,ConstantString(property),
398 next=GetXMLTreeSibling(next);
400 ufraw=DestroyXMLTree(ufraw);
402 xml=DestroyString(xml);
404 sans=DestroyExceptionInfo(sans);
406 read_info=DestroyImageInfo(read_info);
413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
417 % R e g i s t e r D N G I m a g e %
421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 % RegisterDNGImage() adds attributes for the DNG image format to
424 % the list of supported formats. The attributes include the image format
425 % tag, a method to read and/or write the format, whether the format
426 % supports the saving of more than one frame to the same file or blob,
427 % whether the format supports native in-memory I/O, and a brief
428 % description of the format.
430 % The format of the RegisterDNGImage method is:
432 % size_t RegisterDNGImage(void)
435 ModuleExport size_t RegisterDNGImage(void)
440 entry=AcquireMagickInfo("DNG","3FR","Hasselblad CFV/H3D39II");
441 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
442 entry->flags|=CoderDecoderSeekableStreamFlag;
443 entry->flags^=CoderBlobSupportFlag;
444 entry->format_type=ExplicitFormatType;
445 (void) RegisterMagickInfo(entry);
446 entry=AcquireMagickInfo("DNG","ARW","Sony Alpha Raw Image Format");
447 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
448 entry->flags|=CoderDecoderSeekableStreamFlag;
449 entry->flags^=CoderBlobSupportFlag;
450 entry->format_type=ExplicitFormatType;
451 (void) RegisterMagickInfo(entry);
452 entry=AcquireMagickInfo("DNG","DNG","Digital Negative");
453 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
454 entry->flags|=CoderDecoderSeekableStreamFlag;
455 entry->flags^=CoderBlobSupportFlag;
456 entry->format_type=ExplicitFormatType;
457 (void) RegisterMagickInfo(entry);
458 entry=AcquireMagickInfo("DNG","CR2","Canon Digital Camera Raw Image Format");
459 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
460 entry->flags|=CoderDecoderSeekableStreamFlag;
461 entry->flags^=CoderBlobSupportFlag;
462 entry->format_type=ExplicitFormatType;
463 (void) RegisterMagickInfo(entry);
464 entry=AcquireMagickInfo("DNG","CRW","Canon Digital Camera Raw Image Format");
465 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
466 entry->flags|=CoderDecoderSeekableStreamFlag;
467 entry->flags^=CoderBlobSupportFlag;
468 entry->format_type=ExplicitFormatType;
469 (void) RegisterMagickInfo(entry);
470 entry=AcquireMagickInfo("DNG","DCR","Kodak Digital Camera Raw Image File");
471 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
472 entry->flags|=CoderDecoderSeekableStreamFlag;
473 entry->flags^=CoderBlobSupportFlag;
474 entry->format_type=ExplicitFormatType;
475 (void) RegisterMagickInfo(entry);
476 entry=AcquireMagickInfo("DNG","ERF","Epson RAW Format");
477 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
478 entry->flags|=CoderDecoderSeekableStreamFlag;
479 entry->flags^=CoderBlobSupportFlag;
480 entry->format_type=ExplicitFormatType;
481 (void) RegisterMagickInfo(entry);
482 entry=AcquireMagickInfo("DNG","IIQ","Phase One Raw Image Format");
483 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
484 entry->flags|=CoderDecoderSeekableStreamFlag;
485 entry->flags^=CoderBlobSupportFlag;
486 entry->format_type=ExplicitFormatType;
487 (void) RegisterMagickInfo(entry);
488 entry=AcquireMagickInfo("DNG","KDC","Kodak Digital Camera Raw Image Format");
489 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
490 entry->flags|=CoderDecoderSeekableStreamFlag;
491 entry->flags^=CoderBlobSupportFlag;
492 entry->format_type=ExplicitFormatType;
493 (void) RegisterMagickInfo(entry);
494 entry=AcquireMagickInfo("DNG","K25","Kodak Digital Camera Raw Image Format");
495 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
496 entry->flags|=CoderDecoderSeekableStreamFlag;
497 entry->flags^=CoderBlobSupportFlag;
498 entry->format_type=ExplicitFormatType;
499 (void) RegisterMagickInfo(entry);
500 entry=AcquireMagickInfo("DNG","MEF","Mamiya Raw Image File");
501 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
502 entry->flags|=CoderDecoderSeekableStreamFlag;
503 entry->flags^=CoderBlobSupportFlag;
504 entry->format_type=ExplicitFormatType;
505 (void) RegisterMagickInfo(entry);
506 entry=AcquireMagickInfo("DNG","MRW","Sony (Minolta) Raw Image File");
507 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
508 entry->flags|=CoderDecoderSeekableStreamFlag;
509 entry->flags^=CoderBlobSupportFlag;
510 entry->format_type=ExplicitFormatType;
511 (void) RegisterMagickInfo(entry);
512 entry=AcquireMagickInfo("DNG","NEF",
513 "Nikon Digital SLR Camera Raw Image File");
514 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
515 entry->flags|=CoderDecoderSeekableStreamFlag;
516 entry->flags^=CoderBlobSupportFlag;
517 entry->format_type=ExplicitFormatType;
518 (void) RegisterMagickInfo(entry);
519 entry=AcquireMagickInfo("DNG","NRW",
520 "Nikon Digital SLR Camera Raw Image File");
521 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
522 entry->flags|=CoderDecoderSeekableStreamFlag;
523 entry->flags^=CoderBlobSupportFlag;
524 entry->format_type=ExplicitFormatType;
525 (void) RegisterMagickInfo(entry);
526 entry=AcquireMagickInfo("DNG","ORF","Olympus Digital Camera Raw Image File");
527 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
528 entry->flags|=CoderDecoderSeekableStreamFlag;
529 entry->flags^=CoderBlobSupportFlag;
530 entry->format_type=ExplicitFormatType;
531 (void) RegisterMagickInfo(entry);
532 entry=AcquireMagickInfo("DNG","PEF","Pentax Electronic File");
533 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
534 entry->flags|=CoderDecoderSeekableStreamFlag;
535 entry->flags^=CoderBlobSupportFlag;
536 entry->format_type=ExplicitFormatType;
537 (void) RegisterMagickInfo(entry);
538 entry=AcquireMagickInfo("DNG","RAF","Fuji CCD-RAW Graphic File");
539 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
540 entry->flags|=CoderDecoderSeekableStreamFlag;
541 entry->flags^=CoderBlobSupportFlag;
542 entry->format_type=ExplicitFormatType;
543 (void) RegisterMagickInfo(entry);
544 entry=AcquireMagickInfo("DNG","RAW","Raw");
545 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
546 entry->flags|=CoderDecoderSeekableStreamFlag;
547 entry->flags^=CoderBlobSupportFlag;
548 entry->format_type=ExplicitFormatType;
549 (void) RegisterMagickInfo(entry);
550 entry=AcquireMagickInfo("DNG","RMF","Raw Media Format");
551 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
552 entry->flags|=CoderDecoderSeekableStreamFlag;
553 entry->flags^=CoderBlobSupportFlag;
554 entry->format_type=ExplicitFormatType;
555 (void) RegisterMagickInfo(entry);
556 entry=AcquireMagickInfo("DNG","RW2","Panasonic Lumix Raw Image");
557 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
558 entry->flags|=CoderDecoderSeekableStreamFlag;
559 entry->flags^=CoderBlobSupportFlag;
560 entry->format_type=ExplicitFormatType;
561 (void) RegisterMagickInfo(entry);
562 entry=AcquireMagickInfo("DNG","SRF","Sony Raw Format");
563 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
564 entry->flags|=CoderDecoderSeekableStreamFlag;
565 entry->flags^=CoderBlobSupportFlag;
566 entry->format_type=ExplicitFormatType;
567 (void) RegisterMagickInfo(entry);
568 entry=AcquireMagickInfo("DNG","SR2","Sony Raw Format 2");
569 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
570 entry->flags|=CoderDecoderSeekableStreamFlag;
571 entry->flags^=CoderBlobSupportFlag;
572 entry->format_type=ExplicitFormatType;
573 (void) RegisterMagickInfo(entry);
574 entry=AcquireMagickInfo("DNG","X3F","Sigma Camera RAW Picture File");
575 entry->decoder=(DecodeImageHandler *) ReadDNGImage;
576 entry->flags|=CoderDecoderSeekableStreamFlag;
577 entry->flags^=CoderBlobSupportFlag;
578 entry->format_type=ExplicitFormatType;
579 (void) RegisterMagickInfo(entry);
580 return(MagickImageCoderSignature);
584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588 % U n r e g i s t e r D N G I m a g e %
592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
594 % UnregisterDNGImage() removes format registrations made by the
595 % BIM module from the list of supported formats.
597 % The format of the UnregisterBIMImage method is:
599 % UnregisterDNGImage(void)
602 ModuleExport void UnregisterDNGImage(void)
604 (void) UnregisterMagickInfo("X3F");
605 (void) UnregisterMagickInfo("SR2");
606 (void) UnregisterMagickInfo("SRF");
607 (void) UnregisterMagickInfo("RW2");
608 (void) UnregisterMagickInfo("RMF");
609 (void) UnregisterMagickInfo("RAF");
610 (void) UnregisterMagickInfo("PEF");
611 (void) UnregisterMagickInfo("ORF");
612 (void) UnregisterMagickInfo("NRW");
613 (void) UnregisterMagickInfo("NEF");
614 (void) UnregisterMagickInfo("MRW");
615 (void) UnregisterMagickInfo("MEF");
616 (void) UnregisterMagickInfo("K25");
617 (void) UnregisterMagickInfo("KDC");
618 (void) UnregisterMagickInfo("IIQ");
619 (void) UnregisterMagickInfo("ERF");
620 (void) UnregisterMagickInfo("DCR");
621 (void) UnregisterMagickInfo("CRW");
622 (void) UnregisterMagickInfo("CR2");
623 (void) UnregisterMagickInfo("DNG");
624 (void) UnregisterMagickInfo("ARW");
625 (void) UnregisterMagickInfo("3FR");