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