blob: 2037dc562c874cb488024886162bc144cce4a62f [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% TTTTT H H U U M M BBBB N N AAA IIIII L %
7% T H H U U MM MM B B NN N A A I L %
8% T HHHHH U U M M M BBBB N N N AAAAA I L %
9% T H H U U M M B B N NN A A I L %
10% T H H UUU M M BBBB N N A A IIIII LLLLL %
11% %
12% %
13% Write EXIF Thumbnail To File. %
14% %
15% Software Design %
16% John Cristy %
17% July 1992 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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/*
40 Include declarations.
41*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/constitute.h"
46#include "MagickCore/exception.h"
47#include "MagickCore/exception-private.h"
48#include "MagickCore/magick.h"
49#include "MagickCore/memory_.h"
50#include "MagickCore/module.h"
51#include "MagickCore/monitor.h"
52#include "MagickCore/monitor-private.h"
53#include "MagickCore/profile.h"
54#include "MagickCore/property.h"
55#include "MagickCore/quantum-private.h"
56#include "MagickCore/static.h"
57#include "MagickCore/string_.h"
58#include "MagickCore/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000059
60/*
61 Forward declarations.
62*/
63static MagickBooleanType
cristy3a37efd2011-08-28 20:31:03 +000064 WriteTHUMBNAILImage(const ImageInfo *,Image *,ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +000065
66/*
67%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68% %
69% %
70% %
71% R e g i s t e r T H U M B N A I L I m a g e %
72% %
73% %
74% %
75%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76%
77% RegisterTHUMBNAILImage() adds attributes for the THUMBNAIL image format to
78% the list of supported formats. The attributes include the image format
79% tag, a method to read and/or write the format, whether the format
80% supports the saving of more than one frame to the same file or blob,
81% whether the format supports native in-memory I/O, and a brief
82% description of the format.
83%
84% The format of the RegisterTHUMBNAILImage method is:
85%
cristybb503372010-05-27 20:51:26 +000086% size_t RegisterTHUMBNAILImage(void)
cristy3ed852e2009-09-05 21:47:34 +000087%
88*/
cristybb503372010-05-27 20:51:26 +000089ModuleExport size_t RegisterTHUMBNAILImage(void)
cristy3ed852e2009-09-05 21:47:34 +000090{
91 MagickInfo
92 *entry;
93
94 entry=SetMagickInfo("THUMBNAIL");
95 entry->encoder=(EncodeImageHandler *) WriteTHUMBNAILImage;
96 entry->description=ConstantString("EXIF Profile Thumbnail");
97 entry->module=ConstantString("THUMBNAIL");
98 (void) RegisterMagickInfo(entry);
99 return(MagickImageCoderSignature);
100}
101
102/*
103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104% %
105% %
106% %
107% U n r e g i s t e r T H U M B N A I L I m a g e %
108% %
109% %
110% %
111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112%
113% UnregisterTHUMBNAILImage() removes format registrations made by the
114% THUMBNAIL module from the list of supported formats.
115%
116% The format of the UnregisterTHUMBNAILImage method is:
117%
118% UnregisterTHUMBNAILImage(void)
119%
120*/
121ModuleExport void UnregisterTHUMBNAILImage(void)
122{
123 (void) UnregisterMagickInfo("THUMBNAIL");
124}
125
126/*
127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128% %
129% %
130% %
131% W r i t e T H U M B N A I L I m a g e %
132% %
133% %
134% %
135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136%
137% WriteTHUMBNAILImage() extracts the EXIF thumbnail image and writes it.
138%
139% The format of the WriteTHUMBNAILImage method is:
140%
141% MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info,
cristy3a37efd2011-08-28 20:31:03 +0000142% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000143%
144% A description of each parameter follows.
145%
146% o image_info: the image info.
147%
148% o image: The image.
149%
cristy3a37efd2011-08-28 20:31:03 +0000150% o exception: return any errors or warnings in this structure.
151%
cristy3ed852e2009-09-05 21:47:34 +0000152*/
153static MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info,
cristy3a37efd2011-08-28 20:31:03 +0000154 Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000155{
156 const char
157 *property;
158
159 const StringInfo
160 *profile;
161
162 Image
163 *thumbnail_image;
164
165 ImageInfo
166 *write_info;
167
168 MagickBooleanType
169 status;
170
cristybb503372010-05-27 20:51:26 +0000171 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000172 i;
173
cristy3ed852e2009-09-05 21:47:34 +0000174 size_t
175 length;
176
cristyc6da28e2011-04-28 01:41:35 +0000177 ssize_t
178 offset;
179
cristy3ed852e2009-09-05 21:47:34 +0000180 unsigned char
181 magick[MaxTextExtent];
182
183 profile=GetImageProfile(image,"exif");
184 if (profile == (const StringInfo *) NULL)
185 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail");
186 property=GetImageProperty(image,"exif:JPEGInterchangeFormat");
187 if (property == (const char *) NULL)
188 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail");
cristyf2f27272009-12-17 14:48:46 +0000189 offset=(ssize_t) StringToLong(property);
cristy3ed852e2009-09-05 21:47:34 +0000190 property=GetImageProperty(image,"exif:JPEGInterchangeFormatLength");
191 if (property == (const char *) NULL)
192 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail");
cristyf2f27272009-12-17 14:48:46 +0000193 length=(size_t) StringToLong(property);
cristy3ed852e2009-09-05 21:47:34 +0000194 (void) ResetMagickMemory(magick,0,sizeof(magick));
cristybb503372010-05-27 20:51:26 +0000195 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +0000196 {
197 magick[0]=magick[1];
198 magick[1]=magick[2];
199 magick[2]=GetStringInfoDatum(profile)[offset+i];
200 if (memcmp(magick,"\377\330\377",3) == 0)
201 break;
202 }
203 thumbnail_image=BlobToImage(image_info,GetStringInfoDatum(profile)+offset+i-2,
cristy3a37efd2011-08-28 20:31:03 +0000204 length,exception);
cristy3ed852e2009-09-05 21:47:34 +0000205 if (thumbnail_image == (Image *) NULL)
206 return(MagickFalse);
207 (void) SetImageType(thumbnail_image,thumbnail_image->matte == MagickFalse ?
cristy018f07f2011-09-04 21:15:19 +0000208 TrueColorType : TrueColorMatteType,exception);
cristy3ed852e2009-09-05 21:47:34 +0000209 (void) CopyMagickString(thumbnail_image->filename,image->filename,
210 MaxTextExtent);
211 write_info=CloneImageInfo(image_info);
cristy3a37efd2011-08-28 20:31:03 +0000212 (void) SetImageInfo(write_info,1,exception);
cristy3ed852e2009-09-05 21:47:34 +0000213 if (LocaleCompare(write_info->magick,"THUMBNAIL") == 0)
cristyb51dff52011-05-19 16:55:47 +0000214 (void) FormatLocaleString(thumbnail_image->filename,MaxTextExtent,
cristy3ed852e2009-09-05 21:47:34 +0000215 "miff:%s",write_info->filename);
cristy3a37efd2011-08-28 20:31:03 +0000216 status=WriteImage(write_info,thumbnail_image,exception);
cristy3ed852e2009-09-05 21:47:34 +0000217 thumbnail_image=DestroyImage(thumbnail_image);
218 write_info=DestroyImageInfo(write_info);
219 return(status);
220}