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