blob: ddcef06dccfc5c450b1fd3b63ec387f4a785fb8f [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*/
42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/blob-private.h"
45#include "magick/constitute.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/magick.h"
49#include "magick/memory_.h"
cristyf2f27272009-12-17 14:48:46 +000050#include "magick/module.h"
cristy3ed852e2009-09-05 21:47:34 +000051#include "magick/monitor.h"
52#include "magick/monitor-private.h"
53#include "magick/profile.h"
54#include "magick/property.h"
55#include "magick/quantum-private.h"
56#include "magick/static.h"
57#include "magick/string_.h"
cristyf2f27272009-12-17 14:48:46 +000058#include "magick/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000059
60/*
61 Forward declarations.
62*/
63static MagickBooleanType
64 WriteTHUMBNAILImage(const ImageInfo *,Image *);
65
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,
142% Image *image)
143%
144% A description of each parameter follows.
145%
146% o image_info: the image info.
147%
148% o image: The image.
149%
150*/
151static MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info,
152 Image *image)
153{
154 const char
155 *property;
156
157 const StringInfo
158 *profile;
159
160 Image
161 *thumbnail_image;
162
163 ImageInfo
164 *write_info;
165
166 MagickBooleanType
167 status;
168
cristybb503372010-05-27 20:51:26 +0000169 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000170 i;
171
172 ssize_t
173 offset;
174
175 size_t
176 length;
177
178 unsigned char
179 magick[MaxTextExtent];
180
181 profile=GetImageProfile(image,"exif");
182 if (profile == (const StringInfo *) NULL)
183 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail");
184 property=GetImageProperty(image,"exif:JPEGInterchangeFormat");
185 if (property == (const char *) NULL)
186 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail");
cristyf2f27272009-12-17 14:48:46 +0000187 offset=(ssize_t) StringToLong(property);
cristy3ed852e2009-09-05 21:47:34 +0000188 property=GetImageProperty(image,"exif:JPEGInterchangeFormatLength");
189 if (property == (const char *) NULL)
190 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail");
cristyf2f27272009-12-17 14:48:46 +0000191 length=(size_t) StringToLong(property);
cristy3ed852e2009-09-05 21:47:34 +0000192 (void) ResetMagickMemory(magick,0,sizeof(magick));
cristybb503372010-05-27 20:51:26 +0000193 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +0000194 {
195 magick[0]=magick[1];
196 magick[1]=magick[2];
197 magick[2]=GetStringInfoDatum(profile)[offset+i];
198 if (memcmp(magick,"\377\330\377",3) == 0)
199 break;
200 }
201 thumbnail_image=BlobToImage(image_info,GetStringInfoDatum(profile)+offset+i-2,
202 length,&image->exception);
203 if (thumbnail_image == (Image *) NULL)
204 return(MagickFalse);
205 (void) SetImageType(thumbnail_image,thumbnail_image->matte == MagickFalse ?
206 TrueColorType : TrueColorMatteType);
207 (void) CopyMagickString(thumbnail_image->filename,image->filename,
208 MaxTextExtent);
209 write_info=CloneImageInfo(image_info);
cristyd965a422010-03-03 17:47:35 +0000210 (void) SetImageInfo(write_info,1,&image->exception);
cristy3ed852e2009-09-05 21:47:34 +0000211 if (LocaleCompare(write_info->magick,"THUMBNAIL") == 0)
212 (void) FormatMagickString(thumbnail_image->filename,MaxTextExtent,
213 "miff:%s",write_info->filename);
214 status=WriteImage(write_info,thumbnail_image);
215 thumbnail_image=DestroyImage(thumbnail_image);
216 write_info=DestroyImageInfo(write_info);
217 return(status);
218}