Coverage Report

Created: 2026-03-31 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}