1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                            DDDD   N   N   GGGG                              %
7 %                            D   D  NN  N  GS                                 %
8 %                            D   D  N N N  G  GG                              %
9 %                            D   D  N  NN  G   G                              %
10 %                            DDDD   N   N   GGGG                              %
11 %                                                                             %
12 %                                                                             %
13 %                  Read the Digital Negative Image Format                     %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                   Cristy                                    %
17 %                                 July 1999                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    https://imagemagick.org/script/license.php                               %
27 %                                                                             %
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.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 */
38 /*
39   Include declarations.
40 */
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/option.h"
60 #include "MagickCore/pixel-accessor.h"
61 #include "MagickCore/profile.h"
62 #include "MagickCore/property.h"
63 #include "MagickCore/quantum-private.h"
64 #include "MagickCore/resource_.h"
65 #include "MagickCore/static.h"
66 #include "MagickCore/string_.h"
67 #include "MagickCore/string-private.h"
68 #include "MagickCore/module.h"
69 #include "MagickCore/transform.h"
70 #include "MagickCore/utility.h"
71 #include "MagickCore/xml-tree.h"
72 #include "MagickCore/xml-tree-private.h"
73 #if defined(MAGICKCORE_RAW_R_DELEGATE)
74 #include <libraw.h>
75 #endif
76 
77 
78 /*
79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 %                                                                             %
81 %                                                                             %
82 %                                                                             %
83 %   R e a d D N G I m a g e                                                   %
84 %                                                                             %
85 %                                                                             %
86 %                                                                             %
87 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88 %
89 %  ReadDNGImage() reads an binary file in the Digital Negative format and
90 %  returns it.  It allocates the memory necessary for the new Image structure
91 %  and returns a pointer to the new image.
92 %
93 %  The format of the ReadDNGImage method is:
94 %
95 %      Image *ReadDNGImage(const ImageInfo *image_info,
96 %        ExceptionInfo *exception)
97 %
98 %  A description of each parameter follows:
99 %
100 %    o image_info: the image info.
101 %
102 %    o exception: return any errors or warnings in this structure.
103 %
104 */
105 
106 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && defined(MAGICKCORE_OPENCL_SUPPORT)
InitializeDcrawOpenCL(ExceptionInfo * exception)107 static void InitializeDcrawOpenCL(ExceptionInfo *exception)
108 {
109   MagickCLDevice
110     *devices;
111 
112   size_t
113     length;
114 
115   ssize_t
116     i;
117 
118   (void) SetEnvironmentVariable("DCR_CL_PLATFORM",NULL);
119   (void) SetEnvironmentVariable("DCR_CL_DEVICE",NULL);
120   (void) SetEnvironmentVariable("DCR_CL_DISABLED",NULL);
121   if (GetOpenCLEnabled() == MagickFalse)
122     {
123       (void) SetEnvironmentVariable("DCR_CL_DISABLED","1");
124       return;
125     }
126   devices=GetOpenCLDevices(&length,exception);
127   if (devices == (MagickCLDevice *) NULL)
128     return;
129   for (i=0; i < (ssize_t) length; i++)
130   {
131     const char
132       *name;
133 
134     MagickCLDevice
135       device;
136 
137     device=devices[i];
138     if (GetOpenCLDeviceEnabled(device) == MagickFalse)
139       continue;
140     name=GetOpenCLDeviceVendorName(device);
141     if (name != (const char *) NULL)
142       (void) SetEnvironmentVariable("DCR_CL_PLATFORM",name);
143     name=GetOpenCLDeviceName(device);
144     if (name != (const char *) NULL)
145       (void) SetEnvironmentVariable("DCR_CL_DEVICE",name);
146     return;
147   }
148 }
149 #else
InitializeDcrawOpenCL(ExceptionInfo * magick_unused (exception))150 static void InitializeDcrawOpenCL(ExceptionInfo *magick_unused(exception))
151 {
152   magick_unreferenced(exception);
153 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
154   (void) SetEnvironmentVariable("DCR_CL_DISABLED","1");
155 #endif
156 }
157 #endif
158 
159 #if defined(MAGICKCORE_RAW_R_DELEGATE)
SetDNGProperties(Image * image,const libraw_data_t * raw_info,ExceptionInfo * exception)160 static void SetDNGProperties(Image *image,const libraw_data_t *raw_info,
161   ExceptionInfo *exception)
162 {
163   char
164     timestamp[MagickTimeExtent];
165 
166   (void) SetImageProperty(image,"dng:make",raw_info->idata.make,exception);
167   (void) SetImageProperty(image,"dng:camera.model.name",raw_info->idata.model,
168     exception);
169   (void) FormatMagickTime(raw_info->other.timestamp,sizeof(timestamp),timestamp);
170   (void) SetImageProperty(image,"dng:create.date",timestamp,exception);
171   (void) FormatImageProperty(image,"dng:iso.setting","%0.1f",
172     raw_info->other.iso_speed);
173 #if LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0,18)
174   (void) SetImageProperty(image,"dng:software",raw_info->idata.software,
175     exception);
176   if (*raw_info->shootinginfo.BodySerial != '\0')
177     (void) SetImageProperty(image,"dng:serial.number",
178       raw_info->shootinginfo.BodySerial,exception);
179   (void) FormatImageProperty(image,"dng:exposure.time","1/%0.1f",
180     PerceptibleReciprocal(raw_info->other.shutter));
181   (void) FormatImageProperty(image,"dng:f.number","%0.1f",
182     raw_info->other.aperture);
183   (void) FormatImageProperty(image,"dng:max.aperture.value","%0.1f",
184     raw_info->lens.EXIF_MaxAp);
185   (void) FormatImageProperty(image,"dng:ocal.length","%0.1f",
186     raw_info->other.focal_len);
187   (void) FormatImageProperty(image,"dng:wb.rb.levels","%f %f %f %f",
188     raw_info->color.cam_mul[0],raw_info->color.cam_mul[2],
189     raw_info->color.cam_mul[1],raw_info->color.cam_mul[3]);
190   (void) SetImageProperty(image,"dng:lens.type",
191     raw_info->lens.makernotes.LensFeatures_suf,exception);
192   (void) FormatImageProperty(image,"dng:lens","%0.1f-%0.1fmm f/%0.1f-%0.1f",
193     raw_info->lens.makernotes.MinFocal,raw_info->lens.makernotes.MaxFocal,
194     raw_info->lens.makernotes.MaxAp4MinFocal,
195     raw_info->lens.makernotes.MaxAp4MaxFocal);
196   (void) FormatImageProperty(image,"dng:lens.f.stops","%0.2f",
197     raw_info->lens.makernotes.LensFStops);
198   (void) FormatImageProperty(image,"dng:min.focal.length","%0.1f mm",
199     raw_info->lens.makernotes.MinFocal);
200   (void) FormatImageProperty(image,"dng:max.focal.length","%0.1f mm",
201     raw_info->lens.makernotes.MaxFocal);
202   (void) FormatImageProperty(image,"dng:max.aperture.at.min.focal","%0.1f",
203     raw_info->lens.makernotes.MaxAp4MinFocal);
204   (void) FormatImageProperty(image,"dng:max.aperture.at.max.focal","%0.1f",
205     raw_info->lens.makernotes.MaxAp4MaxFocal);
206   (void) FormatImageProperty(image,"dng:focal.length.in.35mm.format","%d mm",
207     raw_info->lens.FocalLengthIn35mmFormat);
208 #endif
209 }
210 #endif
211 
InvokeDNGDelegate(const ImageInfo * image_info,Image * image,ExceptionInfo * exception)212 static Image *InvokeDNGDelegate(const ImageInfo *image_info,Image *image,
213   ExceptionInfo *exception)
214 {
215   ExceptionInfo
216     *sans_exception;
217 
218   ImageInfo
219     *read_info;
220 
221   /*
222     Convert DNG to PPM with delegate.
223   */
224   (void) DestroyImageList(image);
225   InitializeDcrawOpenCL(exception);
226   image=AcquireImage(image_info,exception);
227   read_info=CloneImageInfo(image_info);
228   SetImageInfoBlob(read_info,(void *) NULL,0);
229   (void) InvokeDelegate(read_info,image,"dng:decode",(char *) NULL,exception);
230   image=DestroyImage(image);
231   (void) FormatLocaleString(read_info->filename,MagickPathExtent,"%s.png",
232     read_info->unique);
233   sans_exception=AcquireExceptionInfo();
234   image=ReadImage(read_info,sans_exception);
235   sans_exception=DestroyExceptionInfo(sans_exception);
236   if (image == (Image *) NULL)
237     {
238       (void) FormatLocaleString(read_info->filename,MagickPathExtent,"%s.ppm",
239         read_info->unique);
240       image=ReadImage(read_info,exception);
241     }
242   (void) RelinquishUniqueFileResource(read_info->filename);
243   if (image != (Image *) NULL)
244     {
245       char
246         filename[MagickPathExtent],
247         *xml;
248 
249       ExceptionInfo
250         *sans;
251 
252       (void) CopyMagickString(image->magick,read_info->magick,
253         MagickPathExtent);
254       (void) FormatLocaleString(filename,MagickPathExtent,"%s.ufraw",
255         read_info->unique);
256       sans=AcquireExceptionInfo();
257       xml=FileToString(filename,MagickPathExtent,sans);
258       (void) RelinquishUniqueFileResource(filename);
259       if (xml != (char *) NULL)
260         {
261           XMLTreeInfo
262             *ufraw;
263 
264           /*
265             Inject.
266           */
267           ufraw=NewXMLTree(xml,sans);
268           if (ufraw != (XMLTreeInfo *) NULL)
269             {
270               char
271                 *content,
272                 property[MagickPathExtent];
273 
274               const char
275                 *tag;
276 
277               XMLTreeInfo
278                 *next;
279 
280               if (image->properties == (void *) NULL)
281                 image->properties=NewSplayTree(CompareSplayTreeString,
282                   RelinquishMagickMemory,RelinquishMagickMemory);
283               next=GetXMLTreeChild(ufraw,(const char *) NULL);
284               while (next != (XMLTreeInfo *) NULL)
285               {
286                 tag=GetXMLTreeTag(next);
287                 if (tag == (char *) NULL)
288                   tag="unknown";
289                 (void) FormatLocaleString(property,MagickPathExtent,"dng:%s",
290                   tag);
291                 content=ConstantString(GetXMLTreeContent(next));
292                 (void) StripMagickString(content);
293                 if ((LocaleCompare(tag,"log") != 0) &&
294                     (LocaleCompare(tag,"InputFilename") != 0) &&
295                     (LocaleCompare(tag,"OutputFilename") != 0) &&
296                     (LocaleCompare(tag,"OutputType") != 0) &&
297                     (strlen(content) != 0))
298                   (void) AddValueToSplayTree((SplayTreeInfo *)
299                     image->properties,ConstantString(property),content);
300                 next=GetXMLTreeSibling(next);
301               }
302               ufraw=DestroyXMLTree(ufraw);
303             }
304           xml=DestroyString(xml);
305         }
306       sans=DestroyExceptionInfo(sans);
307     }
308   read_info=DestroyImageInfo(read_info);
309   return(image);
310 }
311 
312 #if defined(MAGICKCORE_RAW_R_DELEGATE)
SetLibRawParams(const ImageInfo * image_info,Image * image,libraw_data_t * raw_info)313 static void SetLibRawParams(const ImageInfo *image_info,Image *image,
314   libraw_data_t *raw_info)
315 {
316   const char
317     *option;
318 
319   raw_info->params.output_bps=16;
320   option=GetImageOption(image_info,"dng:use-camera-wb");
321   if (option == (const char *) NULL)
322     option=GetImageOption(image_info,"dng:use_camera_wb");
323   if (option != (const char *) NULL)
324     raw_info->params.use_camera_wb=IsStringTrue(option);
325   option=GetImageOption(image_info,"dng:use-auto-wb");
326   if (option == (const char *) NULL)
327     option=GetImageOption(image_info,"dng:use_auto_wb");
328   if (option != (const char *) NULL)
329     raw_info->params.use_auto_wb=IsStringTrue(option);
330   option=GetImageOption(image_info,"dng:no-auto-bright");
331   if (option == (const char *) NULL)
332     option=GetImageOption(image_info,"dng:no_auto_bright");
333   if (option != (const char *) NULL)
334     raw_info->params.no_auto_bright=IsStringTrue(option);
335   option=GetImageOption(image_info,"dng:output-color");
336   if (option == (const char *) NULL)
337     option=GetImageOption(image_info,"dng:output_color");
338   if (option != (const char *) NULL)
339     {
340       raw_info->params.output_color=StringToInteger(option);
341       if (raw_info->params.output_color == 5)
342         image->colorspace=XYZColorspace;
343     }
344   option=GetImageOption(image_info,"dng:interpolation-quality");
345   if (option != (const char *) NULL)
346     {
347       int
348         value;
349 
350       value=StringToInteger(option);
351       if (value == -1)
352         raw_info->params.no_interpolation=1;
353       else
354         raw_info->params.user_qual=value;
355     }
356 }
357 
LibRawDataError(void * data,const char * magick_unused (file),const int offset)358 static void LibRawDataError(void *data,const char *magick_unused(file),
359   const int offset)
360 {
361   magick_unreferenced(file);
362   /* Value below zero is an EOF and an exception will be raised instead */
363   if (offset >= 0)
364     {
365       ExceptionInfo
366         *exception;
367 
368       exception=(ExceptionInfo *) data;
369       (void) ThrowMagickException(exception,GetMagickModule(),
370         CorruptImageWarning,"Data corrupted at","`%d'",offset);
371   }
372 }
373 
ReadLibRawThumbnail(const ImageInfo * image_info,Image * image,libraw_data_t * raw_info,ExceptionInfo * exception)374 static void ReadLibRawThumbnail(const ImageInfo *image_info,Image *image,
375   libraw_data_t *raw_info,ExceptionInfo *exception)
376 {
377   const char
378     *option;
379 
380   int
381     errcode;
382 
383   libraw_processed_image_t
384     *thumbnail;
385 
386   option=GetImageOption(image_info,"dng:read-thumbnail");
387   if (IsStringTrue(option) == MagickFalse)
388     return;
389   errcode=libraw_unpack_thumb(raw_info);
390   if (errcode != LIBRAW_SUCCESS)
391     return;
392   thumbnail=libraw_dcraw_make_mem_thumb(raw_info,&errcode);
393   if (errcode == LIBRAW_SUCCESS)
394     {
395       StringInfo
396         *profile;
397 
398       profile=BlobToStringInfo(thumbnail->data,thumbnail->data_size);
399       (void) SetImageProfile(image,"dng:thumbnail",profile,exception);
400     }
401   if (thumbnail != (libraw_processed_image_t *) NULL)
402     libraw_dcraw_clear_mem(thumbnail);
403 }
404 
405 #endif
406 
ReadDNGImage(const ImageInfo * image_info,ExceptionInfo * exception)407 static Image *ReadDNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
408 {
409   Image
410     *image;
411 
412   MagickBooleanType
413     status;
414 
415   /*
416     Open image file.
417   */
418   assert(image_info != (const ImageInfo *) NULL);
419   assert(image_info->signature == MagickCoreSignature);
420   if (image_info->debug != MagickFalse)
421     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
422       image_info->filename);
423   assert(exception != (ExceptionInfo *) NULL);
424   assert(exception->signature == MagickCoreSignature);
425   image=AcquireImage(image_info,exception);
426   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
427   if (status == MagickFalse)
428     {
429       image=DestroyImageList(image);
430       return((Image *) NULL);
431     }
432   (void) CloseBlob(image);
433   if (LocaleCompare(image_info->magick,"DCRAW") == 0)
434     return(InvokeDNGDelegate(image_info,image,exception));
435 #if defined(MAGICKCORE_RAW_R_DELEGATE)
436   {
437     int
438       errcode;
439 
440     libraw_data_t
441       *raw_info;
442 
443     libraw_processed_image_t
444       *raw_image;
445 
446     ssize_t
447       y;
448 
449     StringInfo
450       *profile;
451 
452     unsigned short
453       *p;
454 
455     errcode=0;
456     raw_info=libraw_init(LIBRAW_OPIONS_NO_MEMERR_CALLBACK |
457       LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
458     if (raw_info == (libraw_data_t *) NULL)
459       {
460         (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
461           libraw_strerror(errcode),"`%s'",image->filename);
462         libraw_close(raw_info);
463         return(DestroyImageList(image));
464       }
465     libraw_set_dataerror_handler(raw_info,LibRawDataError,exception);
466 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1310)
467     {
468       wchar_t
469         fileName[MagickPathExtent];
470 
471       MultiByteToWideChar(CP_UTF8,0,image->filename,-1,fileName,
472         MagickPathExtent);
473       errcode=libraw_open_wfile(raw_info,fileName);
474     }
475 #else
476     errcode=libraw_open_file(raw_info,image->filename);
477 #endif
478     if (errcode != LIBRAW_SUCCESS)
479       {
480         (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
481           libraw_strerror(errcode),"`%s'",image->filename);
482         libraw_close(raw_info);
483         return(DestroyImageList(image));
484       }
485     image->columns=raw_info->sizes.width;
486     image->rows=raw_info->sizes.height;
487     image->page.width=raw_info->sizes.raw_width;
488     image->page.height=raw_info->sizes.raw_height;
489     image->page.x=raw_info->sizes.left_margin;
490     image->page.y=raw_info->sizes.top_margin;
491     ReadLibRawThumbnail(image_info,image,raw_info,exception);
492     if (image_info->ping != MagickFalse)
493       {
494         libraw_close(raw_info);
495         return(image);
496       }
497     status=SetImageExtent(image,image->columns,image->rows,exception);
498     if (status == MagickFalse)
499       {
500         libraw_close(raw_info);
501         return(image);
502       }
503     errcode=libraw_unpack(raw_info);
504     if (errcode != LIBRAW_SUCCESS)
505       {
506         (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
507           libraw_strerror(errcode),"`%s'",image->filename);
508         libraw_close(raw_info);
509         return(DestroyImageList(image));
510       }
511     SetLibRawParams(image_info,image,raw_info);
512     errcode=libraw_dcraw_process(raw_info);
513     if (errcode != LIBRAW_SUCCESS)
514       {
515         (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
516           libraw_strerror(errcode),"`%s'",image->filename);
517         libraw_close(raw_info);
518         return(DestroyImageList(image));
519       }
520     raw_image=libraw_dcraw_make_mem_image(raw_info,&errcode);
521     if ((errcode != LIBRAW_SUCCESS) ||
522         (raw_image == (libraw_processed_image_t *) NULL) ||
523         (raw_image->type != LIBRAW_IMAGE_BITMAP) || (raw_image->bits != 16) ||
524         (raw_image->colors < 3) || (raw_image->colors > 4))
525       {
526         if (raw_image != (libraw_processed_image_t *) NULL)
527           libraw_dcraw_clear_mem(raw_image);
528         (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
529           libraw_strerror(errcode),"`%s'",image->filename);
530         libraw_close(raw_info);
531         return(DestroyImageList(image));
532       }
533     image->columns=raw_image->width;
534     image->rows=raw_image->height;
535     image->depth=raw_image->bits;
536     status=SetImageExtent(image,image->columns,image->rows,exception);
537     if (status == MagickFalse)
538       {
539         libraw_dcraw_clear_mem(raw_image);
540         libraw_close(raw_info);
541         return(DestroyImageList(image));
542       }
543     p=(unsigned short *) raw_image->data;
544     for (y=0; y < (ssize_t) image->rows; y++)
545     {
546       Quantum
547         *q;
548 
549       ssize_t
550         x;
551 
552       q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
553       if (q == (Quantum *) NULL)
554         break;
555       for (x=0; x < (ssize_t) image->columns; x++)
556       {
557         SetPixelRed(image,ScaleShortToQuantum(*p++),q);
558         SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
559         SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
560         if (raw_image->colors > 3)
561           SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
562         q+=GetPixelChannels(image);
563       }
564       if (SyncAuthenticPixels(image,exception) == MagickFalse)
565         break;
566       if (image->previous == (Image *) NULL)
567         {
568           status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
569             image->rows);
570           if (status == MagickFalse)
571             break;
572         }
573     }
574     libraw_dcraw_clear_mem(raw_image);
575     /*
576       Set DNG image metadata.
577     */
578     if (raw_info->color.profile != NULL)
579       {
580         profile=BlobToStringInfo(raw_info->color.profile,
581           raw_info->color.profile_length);
582         if (profile != (StringInfo *) NULL)
583           {
584             SetImageProfile(image,"ICC",profile,exception);
585             profile=DestroyStringInfo(profile);
586           }
587       }
588 #if LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0,18)
589     if (raw_info->idata.xmpdata != NULL)
590       {
591         profile=BlobToStringInfo(raw_info->idata.xmpdata,
592           raw_info->idata.xmplen);
593         if (profile != (StringInfo *) NULL)
594           {
595             SetImageProfile(image,"XMP",profile,exception);
596             profile=DestroyStringInfo(profile);
597           }
598       }
599 #endif
600     SetDNGProperties(image,raw_info,exception);
601     libraw_close(raw_info);
602     return(image);
603   }
604 #else
605   return(InvokeDNGDelegate(image_info,image,exception));
606 #endif
607 }
608 
609 
610 /*
611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
612 %                                                                             %
613 %                                                                             %
614 %                                                                             %
615 %   R e g i s t e r D N G I m a g e                                           %
616 %                                                                             %
617 %                                                                             %
618 %                                                                             %
619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620 %
621 %  RegisterDNGImage() adds attributes for the DNG image format to
622 %  the list of supported formats.  The attributes include the image format
623 %  tag, a method to read and/or write the format, whether the format
624 %  supports the saving of more than one frame to the same file or blob,
625 %  whether the format supports native in-memory I/O, and a brief
626 %  description of the format.
627 %
628 %  The format of the RegisterDNGImage method is:
629 %
630 %      size_t RegisterDNGImage(void)
631 %
632 */
RegisterDNGImage(void)633 ModuleExport size_t RegisterDNGImage(void)
634 {
635   MagickInfo
636     *entry;
637 
638   entry=AcquireMagickInfo("DNG","3FR","Hasselblad CFV/H3D39II");
639   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
640   entry->flags|=CoderDecoderSeekableStreamFlag;
641   entry->flags^=CoderBlobSupportFlag;
642   entry->format_type=ExplicitFormatType;
643   (void) RegisterMagickInfo(entry);
644   entry=AcquireMagickInfo("DNG","ARW","Sony Alpha Raw Image Format");
645   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
646   entry->flags|=CoderDecoderSeekableStreamFlag;
647   entry->flags^=CoderBlobSupportFlag;
648   entry->format_type=ExplicitFormatType;
649   (void) RegisterMagickInfo(entry);
650   entry=AcquireMagickInfo("DNG","DNG","Digital Negative");
651   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
652   entry->flags|=CoderDecoderSeekableStreamFlag;
653   entry->flags^=CoderBlobSupportFlag;
654   entry->format_type=ExplicitFormatType;
655   (void) RegisterMagickInfo(entry);
656   entry=AcquireMagickInfo("DNG","CR2","Canon Digital Camera Raw Image Format");
657   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
658   entry->flags|=CoderDecoderSeekableStreamFlag;
659   entry->flags^=CoderBlobSupportFlag;
660   entry->format_type=ExplicitFormatType;
661   (void) RegisterMagickInfo(entry);
662   entry=AcquireMagickInfo("DNG","CR3","Canon Digital Camera Raw Image Format");
663   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
664   entry->flags|=CoderDecoderSeekableStreamFlag;
665   entry->flags^=CoderBlobSupportFlag;
666   entry->format_type=ExplicitFormatType;
667   (void) RegisterMagickInfo(entry);
668   entry=AcquireMagickInfo("DNG","CRW","Canon Digital Camera Raw Image Format");
669   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
670   entry->flags|=CoderDecoderSeekableStreamFlag;
671   entry->flags^=CoderBlobSupportFlag;
672   entry->format_type=ExplicitFormatType;
673   (void) RegisterMagickInfo(entry);
674   entry=AcquireMagickInfo("DNG","DCR","Kodak Digital Camera Raw Image File");
675   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
676   entry->flags|=CoderDecoderSeekableStreamFlag;
677   entry->flags^=CoderBlobSupportFlag;
678   entry->format_type=ExplicitFormatType;
679   (void) RegisterMagickInfo(entry);
680   entry=AcquireMagickInfo("DNG","DCRAW","Raw Photo Decoder (dcraw)");
681   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
682   entry->flags|=CoderDecoderSeekableStreamFlag;
683   entry->flags^=CoderBlobSupportFlag;
684   entry->format_type=ExplicitFormatType;
685   (void) RegisterMagickInfo(entry);
686   entry=AcquireMagickInfo("DNG","ERF","Epson RAW Format");
687   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
688   entry->flags|=CoderDecoderSeekableStreamFlag;
689   entry->flags^=CoderBlobSupportFlag;
690   entry->format_type=ExplicitFormatType;
691   (void) RegisterMagickInfo(entry);
692   entry=AcquireMagickInfo("DNG","IIQ","Phase One Raw Image Format");
693   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
694   entry->flags|=CoderDecoderSeekableStreamFlag;
695   entry->flags^=CoderBlobSupportFlag;
696   entry->format_type=ExplicitFormatType;
697   (void) RegisterMagickInfo(entry);
698   entry=AcquireMagickInfo("DNG","KDC","Kodak Digital Camera Raw Image Format");
699   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
700   entry->flags|=CoderDecoderSeekableStreamFlag;
701   entry->flags^=CoderBlobSupportFlag;
702   entry->format_type=ExplicitFormatType;
703   (void) RegisterMagickInfo(entry);
704   entry=AcquireMagickInfo("DNG","K25","Kodak Digital Camera Raw Image Format");
705   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
706   entry->flags|=CoderDecoderSeekableStreamFlag;
707   entry->flags^=CoderBlobSupportFlag;
708   entry->format_type=ExplicitFormatType;
709   (void) RegisterMagickInfo(entry);
710   entry=AcquireMagickInfo("DNG","MEF","Mamiya Raw Image File");
711   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
712   entry->flags|=CoderDecoderSeekableStreamFlag;
713   entry->flags^=CoderBlobSupportFlag;
714   entry->format_type=ExplicitFormatType;
715   (void) RegisterMagickInfo(entry);
716   entry=AcquireMagickInfo("DNG","MRW","Sony (Minolta) Raw Image File");
717   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
718   entry->flags|=CoderDecoderSeekableStreamFlag;
719   entry->flags^=CoderBlobSupportFlag;
720   entry->format_type=ExplicitFormatType;
721   (void) RegisterMagickInfo(entry);
722   entry=AcquireMagickInfo("DNG","NEF",
723     "Nikon Digital SLR Camera Raw Image File");
724   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
725   entry->flags|=CoderDecoderSeekableStreamFlag;
726   entry->flags^=CoderBlobSupportFlag;
727   entry->format_type=ExplicitFormatType;
728   (void) RegisterMagickInfo(entry);
729   entry=AcquireMagickInfo("DNG","NRW",
730     "Nikon Digital SLR Camera Raw Image File");
731   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
732   entry->flags|=CoderDecoderSeekableStreamFlag;
733   entry->flags^=CoderBlobSupportFlag;
734   entry->format_type=ExplicitFormatType;
735   (void) RegisterMagickInfo(entry);
736   entry=AcquireMagickInfo("DNG","ORF","Olympus Digital Camera Raw Image File");
737   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
738   entry->flags|=CoderDecoderSeekableStreamFlag;
739   entry->flags^=CoderBlobSupportFlag;
740   entry->format_type=ExplicitFormatType;
741   (void) RegisterMagickInfo(entry);
742   entry=AcquireMagickInfo("DNG","PEF","Pentax Electronic File");
743   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
744   entry->flags|=CoderDecoderSeekableStreamFlag;
745   entry->flags^=CoderBlobSupportFlag;
746   entry->format_type=ExplicitFormatType;
747   (void) RegisterMagickInfo(entry);
748   entry=AcquireMagickInfo("DNG","RAF","Fuji CCD-RAW Graphic File");
749   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
750   entry->flags|=CoderDecoderSeekableStreamFlag;
751   entry->flags^=CoderBlobSupportFlag;
752   entry->format_type=ExplicitFormatType;
753   (void) RegisterMagickInfo(entry);
754   entry=AcquireMagickInfo("DNG","RAW","Raw");
755   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
756   entry->flags|=CoderDecoderSeekableStreamFlag;
757   entry->flags^=CoderBlobSupportFlag;
758   entry->format_type=ExplicitFormatType;
759   (void) RegisterMagickInfo(entry);
760   entry=AcquireMagickInfo("DNG","RMF","Raw Media Format");
761   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
762   entry->flags|=CoderDecoderSeekableStreamFlag;
763   entry->flags^=CoderBlobSupportFlag;
764   entry->format_type=ExplicitFormatType;
765   (void) RegisterMagickInfo(entry);
766   entry=AcquireMagickInfo("DNG","RW2","Panasonic Lumix Raw Image");
767   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
768   entry->flags|=CoderDecoderSeekableStreamFlag;
769   entry->flags^=CoderBlobSupportFlag;
770   entry->format_type=ExplicitFormatType;
771   (void) RegisterMagickInfo(entry);
772   entry=AcquireMagickInfo("DNG","SRF","Sony Raw Format");
773   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
774   entry->flags|=CoderDecoderSeekableStreamFlag;
775   entry->flags^=CoderBlobSupportFlag;
776   entry->format_type=ExplicitFormatType;
777   (void) RegisterMagickInfo(entry);
778   entry=AcquireMagickInfo("DNG","SR2","Sony Raw Format 2");
779   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
780   entry->flags|=CoderDecoderSeekableStreamFlag;
781   entry->flags^=CoderBlobSupportFlag;
782   entry->format_type=ExplicitFormatType;
783   (void) RegisterMagickInfo(entry);
784   entry=AcquireMagickInfo("DNG","X3F","Sigma Camera RAW Picture File");
785   entry->decoder=(DecodeImageHandler *) ReadDNGImage;
786   entry->flags|=CoderDecoderSeekableStreamFlag;
787   entry->flags^=CoderBlobSupportFlag;
788   entry->format_type=ExplicitFormatType;
789   (void) RegisterMagickInfo(entry);
790   return(MagickImageCoderSignature);
791 }
792 
793 
794 /*
795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796 %                                                                             %
797 %                                                                             %
798 %                                                                             %
799 %   U n r e g i s t e r D N G I m a g e                                       %
800 %                                                                             %
801 %                                                                             %
802 %                                                                             %
803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804 %
805 %  UnregisterDNGImage() removes format registrations made by the
806 %  BIM module from the list of supported formats.
807 %
808 %  The format of the UnregisterBIMImage method is:
809 %
810 %      UnregisterDNGImage(void)
811 %
812 */
UnregisterDNGImage(void)813 ModuleExport void UnregisterDNGImage(void)
814 {
815   (void) UnregisterMagickInfo("X3F");
816   (void) UnregisterMagickInfo("SR2");
817   (void) UnregisterMagickInfo("SRF");
818   (void) UnregisterMagickInfo("RW2");
819   (void) UnregisterMagickInfo("RMF");
820   (void) UnregisterMagickInfo("RAF");
821   (void) UnregisterMagickInfo("PEF");
822   (void) UnregisterMagickInfo("ORF");
823   (void) UnregisterMagickInfo("NRW");
824   (void) UnregisterMagickInfo("NEF");
825   (void) UnregisterMagickInfo("MRW");
826   (void) UnregisterMagickInfo("MEF");
827   (void) UnregisterMagickInfo("K25");
828   (void) UnregisterMagickInfo("KDC");
829   (void) UnregisterMagickInfo("IIQ");
830   (void) UnregisterMagickInfo("ERF");
831   (void) UnregisterMagickInfo("DCR");
832   (void) UnregisterMagickInfo("CRW");
833   (void) UnregisterMagickInfo("CR3");
834   (void) UnregisterMagickInfo("CR2");
835   (void) UnregisterMagickInfo("DNG");
836   (void) UnregisterMagickInfo("ARW");
837   (void) UnregisterMagickInfo("3FR");
838 }
839