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/* 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*/ 64static 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*/ 90ModuleExport size_t RegisterTHUMBNAILImage(void) 91{ 92 MagickInfo 93 *entry; 94 95 entry=AcquireMagickInfo("THUMBNAIL","THUMBNAIL","EXIF Profile Thumbnail"); 96 entry->encoder=(EncodeImageHandler *) WriteTHUMBNAILImage; 97 (void) RegisterMagickInfo(entry); 98 return(MagickImageCoderSignature); 99} 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*/ 120ModuleExport void UnregisterTHUMBNAILImage(void) 121{ 122 (void) UnregisterMagickInfo("THUMBNAIL"); 123} 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*/ 152static MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info, 153 Image *image,ExceptionInfo *exception) 154{ 155 const char 156 *property; 157 158 const StringInfo 159 *profile; 160 161 Image 162 *thumbnail_image; 163 164 ImageInfo 165 *write_info; 166 167 MagickBooleanType 168 status; 169 170 register ssize_t 171 i; 172 173 size_t 174 length; 175 176 ssize_t 177 offset; 178 179 unsigned char 180 magick[MagickPathExtent]; 181 182 profile=GetImageProfile(image,"exif"); 183 if (profile == (const StringInfo *) NULL) 184 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); 185 property=GetImageProperty(image,"exif:JPEGInterchangeFormat",exception); 186 if (property == (const char *) NULL) 187 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); 188 offset=(ssize_t) StringToLong(property); 189 property=GetImageProperty(image,"exif:JPEGInterchangeFormatLength",exception); 190 if (property == (const char *) NULL) 191 ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); 192 length=(size_t) StringToLong(property); 193 (void) ResetMagickMemory(magick,0,sizeof(magick)); 194 for (i=0; i < (ssize_t) length; i++) 195 { 196 magick[0]=magick[1]; 197 magick[1]=magick[2]; 198 magick[2]=GetStringInfoDatum(profile)[offset+i]; 199 if (memcmp(magick,"\377\330\377",3) == 0) 200 break; 201 } 202 thumbnail_image=BlobToImage(image_info,GetStringInfoDatum(profile)+offset+i-2, 203 length,exception); 204 if (thumbnail_image == (Image *) NULL) 205 return(MagickFalse); 206 (void) SetImageType(thumbnail_image,thumbnail_image->alpha_trait == 207 UndefinedPixelTrait ? TrueColorType : TrueColorAlphaType,exception); 208 (void) CopyMagickString(thumbnail_image->filename,image->filename, 209 MagickPathExtent); 210 write_info=CloneImageInfo(image_info); 211 *write_info->magick='\0'; 212 (void) SetImageInfo(write_info,1,exception); 213 if ((*write_info->magick == '\0') || 214 (LocaleCompare(write_info->magick,"THUMBNAIL") == 0)) 215 (void) FormatLocaleString(thumbnail_image->filename,MagickPathExtent, 216 "miff:%s",write_info->filename); 217 status=WriteImage(write_info,thumbnail_image,exception); 218 thumbnail_image=DestroyImage(thumbnail_image); 219 write_info=DestroyImageInfo(write_info); 220 return(status); 221} 222