/src/imagemagick/coders/thumbnail.c
Line | Count | Source |
1 | | /* |
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 | | % Cristy % |
17 | | % July 1992 % |
18 | | % % |
19 | | % % |
20 | | % Copyright @ 1999 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/license/ % |
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 "MagickCore/studio.h" |
43 | | #include "MagickCore/attribute.h" |
44 | | #include "MagickCore/blob.h" |
45 | | #include "MagickCore/blob-private.h" |
46 | | #include "MagickCore/constitute.h" |
47 | | #include "MagickCore/exception.h" |
48 | | #include "MagickCore/exception-private.h" |
49 | | #include "MagickCore/magick.h" |
50 | | #include "MagickCore/memory_.h" |
51 | | #include "MagickCore/module.h" |
52 | | #include "MagickCore/monitor.h" |
53 | | #include "MagickCore/monitor-private.h" |
54 | | #include "MagickCore/profile.h" |
55 | | #include "MagickCore/property.h" |
56 | | #include "MagickCore/quantum-private.h" |
57 | | #include "MagickCore/static.h" |
58 | | #include "MagickCore/string_.h" |
59 | | #include "MagickCore/string-private.h" |
60 | | |
61 | | /* |
62 | | Forward declarations. |
63 | | */ |
64 | | static MagickBooleanType |
65 | | WriteTHUMBNAILImage(const ImageInfo *,Image *,ExceptionInfo *); |
66 | | |
67 | | /* |
68 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
69 | | % % |
70 | | % % |
71 | | % % |
72 | | % R e g i s t e r T H U M B N A I L I m a g e % |
73 | | % % |
74 | | % % |
75 | | % % |
76 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
77 | | % |
78 | | % RegisterTHUMBNAILImage() adds attributes for the THUMBNAIL image format to |
79 | | % the list of supported formats. The attributes include the image format |
80 | | % tag, a method to read and/or write the format, whether the format |
81 | | % supports the saving of more than one frame to the same file or blob, |
82 | | % whether the format supports native in-memory I/O, and a brief |
83 | | % description of the format. |
84 | | % |
85 | | % The format of the RegisterTHUMBNAILImage method is: |
86 | | % |
87 | | % size_t RegisterTHUMBNAILImage(void) |
88 | | % |
89 | | */ |
90 | | ModuleExport size_t RegisterTHUMBNAILImage(void) |
91 | 8 | { |
92 | 8 | MagickInfo |
93 | 8 | *entry; |
94 | | |
95 | 8 | entry=AcquireMagickInfo("THUMBNAIL","THUMBNAIL","EXIF Profile Thumbnail"); |
96 | 8 | entry->encoder=(EncodeImageHandler *) WriteTHUMBNAILImage; |
97 | 8 | (void) RegisterMagickInfo(entry); |
98 | 8 | return(MagickImageCoderSignature); |
99 | 8 | } |
100 | | |
101 | | /* |
102 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
103 | | % % |
104 | | % % |
105 | | % % |
106 | | % U n r e g i s t e r T H U M B N A I L I m a g e % |
107 | | % % |
108 | | % % |
109 | | % % |
110 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
111 | | % |
112 | | % UnregisterTHUMBNAILImage() removes format registrations made by the |
113 | | % THUMBNAIL module from the list of supported formats. |
114 | | % |
115 | | % The format of the UnregisterTHUMBNAILImage method is: |
116 | | % |
117 | | % UnregisterTHUMBNAILImage(void) |
118 | | % |
119 | | */ |
120 | | ModuleExport void UnregisterTHUMBNAILImage(void) |
121 | 0 | { |
122 | 0 | (void) UnregisterMagickInfo("THUMBNAIL"); |
123 | 0 | } |
124 | | |
125 | | /* |
126 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
127 | | % % |
128 | | % % |
129 | | % % |
130 | | % W r i t e T H U M B N A I L I m a g e % |
131 | | % % |
132 | | % % |
133 | | % % |
134 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
135 | | % |
136 | | % WriteTHUMBNAILImage() extracts the EXIF thumbnail image and writes it. |
137 | | % |
138 | | % The format of the WriteTHUMBNAILImage method is: |
139 | | % |
140 | | % MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info, |
141 | | % Image *image,ExceptionInfo *exception) |
142 | | % |
143 | | % A description of each parameter follows. |
144 | | % |
145 | | % o image_info: the image info. |
146 | | % |
147 | | % o image: The image. |
148 | | % |
149 | | % o exception: return any errors or warnings in this structure. |
150 | | % |
151 | | */ |
152 | | static MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info, |
153 | | Image *image,ExceptionInfo *exception) |
154 | 0 | { |
155 | 0 | const char |
156 | 0 | *property; |
157 | |
|
158 | 0 | const MagickInfo |
159 | 0 | *magick_info; |
160 | |
|
161 | 0 | const StringInfo |
162 | 0 | *profile; |
163 | |
|
164 | 0 | Image |
165 | 0 | *thumbnail_image; |
166 | |
|
167 | 0 | ImageInfo |
168 | 0 | *write_info; |
169 | |
|
170 | 0 | MagickBooleanType |
171 | 0 | status; |
172 | |
|
173 | 0 | ssize_t |
174 | 0 | i; |
175 | |
|
176 | 0 | size_t |
177 | 0 | length; |
178 | |
|
179 | 0 | ssize_t |
180 | 0 | offset; |
181 | |
|
182 | 0 | unsigned char |
183 | 0 | *q; |
184 | |
|
185 | 0 | profile=GetImageProfile(image,"exif"); |
186 | 0 | if (profile == (const StringInfo *) NULL) |
187 | 0 | ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); |
188 | 0 | property=GetImageProperty(image,"exif:thumbnail:JPEGInterchangeFormat", |
189 | 0 | exception); |
190 | 0 | if (property == (const char *) NULL) |
191 | 0 | ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); |
192 | 0 | offset=(ssize_t) StringToLong(property); |
193 | 0 | if (offset < 0) |
194 | 0 | ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); |
195 | 0 | property=GetImageProperty(image,"exif:thumbnail:JPEGInterchangeFormatLength", |
196 | 0 | exception); |
197 | 0 | if (property == (const char *) NULL) |
198 | 0 | ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); |
199 | 0 | length=(size_t) StringToLong(property); |
200 | 0 | q=GetStringInfoDatum(profile)+offset; |
201 | 0 | for (i=offset; i < (ssize_t) GetStringInfoLength(profile) - 3; i++) |
202 | 0 | { |
203 | 0 | if (memcmp(q,"\377\330\377",3) == 0) |
204 | 0 | break; |
205 | 0 | q++; |
206 | 0 | } |
207 | 0 | if ((q > (GetStringInfoDatum(profile)+GetStringInfoLength(profile))) || |
208 | 0 | ((ssize_t) length > (GetStringInfoDatum(profile)+GetStringInfoLength(profile)-q))) |
209 | 0 | ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); |
210 | 0 | write_info=CloneImageInfo(image_info); |
211 | 0 | *write_info->magick='\0'; |
212 | 0 | thumbnail_image=BlobToImage(write_info,q,length,exception); |
213 | 0 | if (thumbnail_image == (Image *) NULL) |
214 | 0 | { |
215 | 0 | write_info=DestroyImageInfo(write_info); |
216 | 0 | return(MagickFalse); |
217 | 0 | } |
218 | 0 | (void) SetImageType(thumbnail_image,thumbnail_image->alpha_trait == |
219 | 0 | UndefinedPixelTrait ? TrueColorType : TrueColorAlphaType,exception); |
220 | 0 | (void) CopyMagickString(thumbnail_image->filename,image->filename, |
221 | 0 | MagickPathExtent); |
222 | 0 | *write_info->magick='\0'; |
223 | 0 | (void) SetImageInfo(write_info,1,exception); |
224 | 0 | magick_info=GetMagickInfo(write_info->magick,exception); |
225 | 0 | if ((magick_info == (const MagickInfo*) NULL) || |
226 | 0 | (LocaleCompare(magick_info->magick_module,"THUMBNAIL") == 0)) |
227 | 0 | (void) FormatLocaleString(thumbnail_image->filename,MagickPathExtent, |
228 | 0 | "miff:%s",write_info->filename); |
229 | 0 | status=WriteImage(write_info,thumbnail_image,exception); |
230 | 0 | thumbnail_image=DestroyImage(thumbnail_image); |
231 | 0 | write_info=DestroyImageInfo(write_info); |
232 | 0 | return(status); |
233 | 0 | } |