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-2016 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%    http://www.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/resource_.h"
57#include "MagickCore/quantum-private.h"
58#include "MagickCore/static.h"
59#include "MagickCore/string_.h"
60#include "MagickCore/module.h"
61#include "MagickCore/transform.h"
62#include "MagickCore/utility.h"
63#include "MagickCore/xml-tree.h"
64#include "MagickCore/xml-tree-private.h"
65
66/*
67%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68%                                                                             %
69%                                                                             %
70%                                                                             %
71%   R e a d D N G I m a g e                                                   %
72%                                                                             %
73%                                                                             %
74%                                                                             %
75%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76%
77%  ReadDNGImage() reads an binary file in the Digital Negative format and
78%  returns it.  It allocates the memory necessary for the new Image structure
79%  and returns a pointer to the new image.
80%
81%  The format of the ReadDNGImage method is:
82%
83%      Image *ReadDNGImage(const ImageInfo *image_info,
84%        ExceptionInfo *exception)
85%
86%  A description of each parameter follows:
87%
88%    o image_info: the image info.
89%
90%    o exception: return any errors or warnings in this structure.
91%
92*/
93static Image *ReadDNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
94{
95  ExceptionInfo
96    *sans_exception;
97
98  Image
99    *image;
100
101  ImageInfo
102    *read_info;
103
104  MagickBooleanType
105    status;
106
107  /*
108    Open image file.
109  */
110  assert(image_info != (const ImageInfo *) NULL);
111  assert(image_info->signature == MagickCoreSignature);
112  if (image_info->debug != MagickFalse)
113    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
114      image_info->filename);
115  assert(exception != (ExceptionInfo *) NULL);
116  assert(exception->signature == MagickCoreSignature);
117  image=AcquireImage(image_info,exception);
118  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
119  if (status == MagickFalse)
120    {
121      image=DestroyImageList(image);
122      return((Image *) NULL);
123    }
124  (void) CloseBlob(image);
125  (void) DestroyImageList(image);
126  /*
127    Convert DNG to PPM with delegate.
128  */
129  image=AcquireImage(image_info,exception);
130  read_info=CloneImageInfo(image_info);
131  SetImageInfoBlob(read_info,(void *) NULL,0);
132  (void) InvokeDelegate(read_info,image,"dng:decode",(char *) NULL,exception);
133  image=DestroyImage(image);
134  (void) FormatLocaleString(read_info->filename,MagickPathExtent,"%s.png",
135    read_info->unique);
136  sans_exception=AcquireExceptionInfo();
137  image=ReadImage(read_info,sans_exception);
138  sans_exception=DestroyExceptionInfo(sans_exception);
139  if (image == (Image *) NULL)
140    {
141      (void) FormatLocaleString(read_info->filename,MagickPathExtent,"%s.ppm",
142        read_info->unique);
143      image=ReadImage(read_info,exception);
144    }
145  (void) RelinquishUniqueFileResource(read_info->filename);
146  if (image != (Image *) NULL)
147    {
148      char
149        filename[MagickPathExtent],
150        *xml;
151
152      ExceptionInfo
153        *sans;
154
155      (void) CopyMagickString(image->magick,read_info->magick,MagickPathExtent);
156      (void) FormatLocaleString(filename,MagickPathExtent,"%s.ufraw",
157        read_info->unique);
158      sans=AcquireExceptionInfo();
159      xml=FileToString(filename,MagickPathExtent,sans);
160      (void) RelinquishUniqueFileResource(filename);
161      if (xml != (char *) NULL)
162        {
163          XMLTreeInfo
164            *ufraw;
165
166          /*
167            Inject
168          */
169          ufraw=NewXMLTree(xml,sans);
170          if (ufraw != (XMLTreeInfo *) NULL)
171            {
172              char
173                *content,
174                property[MagickPathExtent];
175
176              const char
177                *tag;
178
179              XMLTreeInfo
180                *next;
181
182              if (image->properties == (void *) NULL)
183                ((Image *) image)->properties=NewSplayTree(
184                  CompareSplayTreeString,RelinquishMagickMemory,
185                  RelinquishMagickMemory);
186              next=GetXMLTreeChild(ufraw,(const char *) NULL);
187              while (next != (XMLTreeInfo *) NULL)
188              {
189                tag=GetXMLTreeTag(next);
190                if (tag == (char *) NULL)
191                  tag="unknown";
192                (void) FormatLocaleString(property,MagickPathExtent,"dng:%s",tag);
193                content=ConstantString(GetXMLTreeContent(next));
194                StripString(content);
195                if ((LocaleCompare(tag,"log") != 0) &&
196                    (LocaleCompare(tag,"InputFilename") != 0) &&
197                    (LocaleCompare(tag,"OutputFilename") != 0) &&
198                    (LocaleCompare(tag,"OutputType") != 0) &&
199                    (strlen(content) != 0))
200                  (void) AddValueToSplayTree((SplayTreeInfo *)
201                    ((Image *) image)->properties,ConstantString(property),
202                    content);
203                next=GetXMLTreeSibling(next);
204              }
205              ufraw=DestroyXMLTree(ufraw);
206            }
207          xml=DestroyString(xml);
208        }
209      sans=DestroyExceptionInfo(sans);
210    }
211  read_info=DestroyImageInfo(read_info);
212  return(image);
213}
214
215/*
216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217%                                                                             %
218%                                                                             %
219%                                                                             %
220%   R e g i s t e r D N G I m a g e                                           %
221%                                                                             %
222%                                                                             %
223%                                                                             %
224%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225%
226%  RegisterDNGImage() adds attributes for the DNG image format to
227%  the list of supported formats.  The attributes include the image format
228%  tag, a method to read and/or write the format, whether the format
229%  supports the saving of more than one frame to the same file or blob,
230%  whether the format supports native in-memory I/O, and a brief
231%  description of the format.
232%
233%  The format of the RegisterDNGImage method is:
234%
235%      size_t RegisterDNGImage(void)
236%
237*/
238ModuleExport size_t RegisterDNGImage(void)
239{
240  MagickInfo
241    *entry;
242
243  entry=AcquireMagickInfo("DNG","3FR","Hasselblad CFV/H3D39II");
244  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
245  entry->flags^=CoderBlobSupportFlag;
246  entry->flags|=CoderSeekableStreamFlag;
247  entry->format_type=ExplicitFormatType;
248  (void) RegisterMagickInfo(entry);
249  entry=AcquireMagickInfo("DNG","ARW","Sony Alpha Raw Image Format");
250  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
251  entry->flags^=CoderBlobSupportFlag;
252  entry->flags|=CoderSeekableStreamFlag;
253  entry->format_type=ExplicitFormatType;
254  (void) RegisterMagickInfo(entry);
255  entry=AcquireMagickInfo("DNG","DNG","Digital Negative");
256  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
257  entry->flags^=CoderBlobSupportFlag;
258  entry->flags|=CoderSeekableStreamFlag;
259  entry->format_type=ExplicitFormatType;
260  (void) RegisterMagickInfo(entry);
261  entry=AcquireMagickInfo("DNG","CR2","Canon Digital Camera Raw Image Format");
262  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
263  entry->flags^=CoderBlobSupportFlag;
264  entry->flags|=CoderSeekableStreamFlag;
265  entry->format_type=ExplicitFormatType;
266  (void) RegisterMagickInfo(entry);
267  entry=AcquireMagickInfo("DNG","CRW","Canon Digital Camera Raw Image Format");
268  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
269  entry->flags^=CoderBlobSupportFlag;
270  entry->flags|=CoderSeekableStreamFlag;
271  entry->format_type=ExplicitFormatType;
272  (void) RegisterMagickInfo(entry);
273  entry=AcquireMagickInfo("DNG","DCR","Kodak Digital Camera Raw Image File");
274  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
275  entry->flags^=CoderBlobSupportFlag;
276  entry->flags|=CoderSeekableStreamFlag;
277  entry->format_type=ExplicitFormatType;
278  (void) RegisterMagickInfo(entry);
279  entry=AcquireMagickInfo("DNG","ERF","Epson RAW Format");
280  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
281  entry->flags^=CoderBlobSupportFlag;
282  entry->flags|=CoderSeekableStreamFlag;
283  entry->format_type=ExplicitFormatType;
284  (void) RegisterMagickInfo(entry);
285  entry=AcquireMagickInfo("DNG","IIQ","Phase One Raw Image Format");
286  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
287  entry->flags^=CoderBlobSupportFlag;
288  entry->flags|=CoderSeekableStreamFlag;
289  entry->format_type=ExplicitFormatType;
290  entry->module=ConstantString("DNG");
291  (void) RegisterMagickInfo(entry);
292  entry=AcquireMagickInfo("DNG","KDC","Kodak Digital Camera Raw Image Format");
293  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
294  entry->flags^=CoderBlobSupportFlag;
295  entry->flags|=CoderSeekableStreamFlag;
296  entry->format_type=ExplicitFormatType;
297  (void) RegisterMagickInfo(entry);
298  entry=AcquireMagickInfo("DNG","K25","Kodak Digital Camera Raw Image Format");
299  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
300  entry->flags^=CoderBlobSupportFlag;
301  entry->flags|=CoderSeekableStreamFlag;
302  entry->format_type=ExplicitFormatType;
303  (void) RegisterMagickInfo(entry);
304  entry=AcquireMagickInfo("DNG","MEF","Mamiya Raw Image File");
305  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
306  entry->flags^=CoderBlobSupportFlag;
307  entry->flags|=CoderSeekableStreamFlag;
308  entry->format_type=ExplicitFormatType;
309  (void) RegisterMagickInfo(entry);
310  entry=AcquireMagickInfo("DNG","MRW","Sony (Minolta) Raw Image File");
311  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
312  entry->flags^=CoderBlobSupportFlag;
313  entry->flags|=CoderSeekableStreamFlag;
314  entry->format_type=ExplicitFormatType;
315  (void) RegisterMagickInfo(entry);
316  entry=AcquireMagickInfo("DNG","NEF","Nikon Digital SLR Camera Raw Image File");
317  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
318  entry->flags^=CoderBlobSupportFlag;
319  entry->flags|=CoderSeekableStreamFlag;
320  entry->format_type=ExplicitFormatType;
321  (void) RegisterMagickInfo(entry);
322  entry=AcquireMagickInfo("DNG","NRW","Nikon Digital SLR Camera Raw Image File");
323  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
324  entry->flags^=CoderBlobSupportFlag;
325  entry->flags|=CoderSeekableStreamFlag;
326  entry->format_type=ExplicitFormatType;
327  (void) RegisterMagickInfo(entry);
328  entry=AcquireMagickInfo("DNG","ORF","Olympus Digital Camera Raw Image File");
329  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
330  entry->flags^=CoderBlobSupportFlag;
331  entry->flags|=CoderSeekableStreamFlag;
332  entry->format_type=ExplicitFormatType;
333  (void) RegisterMagickInfo(entry);
334  entry=AcquireMagickInfo("DNG","PEF","Pentax Electronic File");
335  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
336  entry->flags^=CoderBlobSupportFlag;
337  entry->flags|=CoderSeekableStreamFlag;
338  entry->format_type=ExplicitFormatType;
339  (void) RegisterMagickInfo(entry);
340  entry=AcquireMagickInfo("DNG","RAF","Fuji CCD-RAW Graphic File");
341  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
342  entry->flags^=CoderBlobSupportFlag;
343  entry->flags|=CoderSeekableStreamFlag;
344  entry->format_type=ExplicitFormatType;
345  (void) RegisterMagickInfo(entry);
346  entry=AcquireMagickInfo("DNG","RAW","Raw");
347  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
348  entry->flags^=CoderBlobSupportFlag;
349  entry->flags|=CoderSeekableStreamFlag;
350  entry->format_type=ExplicitFormatType;
351  (void) RegisterMagickInfo(entry);
352  entry=AcquireMagickInfo("DNG","RMF","Raw Media Format");
353  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
354  entry->flags^=CoderBlobSupportFlag;
355  entry->flags|=CoderSeekableStreamFlag;
356  entry->format_type=ExplicitFormatType;
357  (void) RegisterMagickInfo(entry);
358  entry=AcquireMagickInfo("DNG","RW2","Panasonic Lumix Raw Image");
359  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
360  entry->flags^=CoderBlobSupportFlag;
361  entry->flags|=CoderSeekableStreamFlag;
362  entry->format_type=ExplicitFormatType;
363  (void) RegisterMagickInfo(entry);
364  entry=AcquireMagickInfo("DNG","SRF","Sony Raw Format");
365  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
366  entry->flags^=CoderBlobSupportFlag;
367  entry->flags|=CoderSeekableStreamFlag;
368  entry->format_type=ExplicitFormatType;
369  (void) RegisterMagickInfo(entry);
370  entry=AcquireMagickInfo("DNG","SR2","Sony Raw Format 2");
371  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
372  entry->flags^=CoderBlobSupportFlag;
373  entry->flags|=CoderSeekableStreamFlag;
374  entry->format_type=ExplicitFormatType;
375  (void) RegisterMagickInfo(entry);
376  entry=AcquireMagickInfo("DNG","X3F","Sigma Camera RAW Picture File");
377  entry->decoder=(DecodeImageHandler *) ReadDNGImage;
378  entry->flags^=CoderBlobSupportFlag;
379  entry->flags|=CoderSeekableStreamFlag;
380  entry->format_type=ExplicitFormatType;
381  (void) RegisterMagickInfo(entry);
382  return(MagickImageCoderSignature);
383}
384
385/*
386%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387%                                                                             %
388%                                                                             %
389%                                                                             %
390%   U n r e g i s t e r D N G I m a g e                                       %
391%                                                                             %
392%                                                                             %
393%                                                                             %
394%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395%
396%  UnregisterDNGImage() removes format registrations made by the
397%  BIM module from the list of supported formats.
398%
399%  The format of the UnregisterBIMImage method is:
400%
401%      UnregisterDNGImage(void)
402%
403*/
404ModuleExport void UnregisterDNGImage(void)
405{
406  (void) UnregisterMagickInfo("X3F");
407  (void) UnregisterMagickInfo("SR2");
408  (void) UnregisterMagickInfo("SRF");
409  (void) UnregisterMagickInfo("RW2");
410  (void) UnregisterMagickInfo("RMF");
411  (void) UnregisterMagickInfo("RAF");
412  (void) UnregisterMagickInfo("PEF");
413  (void) UnregisterMagickInfo("ORF");
414  (void) UnregisterMagickInfo("NRW");
415  (void) UnregisterMagickInfo("NEF");
416  (void) UnregisterMagickInfo("MRW");
417  (void) UnregisterMagickInfo("MEF");
418  (void) UnregisterMagickInfo("K25");
419  (void) UnregisterMagickInfo("KDC");
420  (void) UnregisterMagickInfo("IIQ");
421  (void) UnregisterMagickInfo("ERF");
422  (void) UnregisterMagickInfo("DCR");
423  (void) UnregisterMagickInfo("CRW");
424  (void) UnregisterMagickInfo("CR2");
425  (void) UnregisterMagickInfo("DNG");
426  (void) UnregisterMagickInfo("ARW");
427  (void) UnregisterMagickInfo("3FR");
428}
429