Coverage Report

Created: 2026-09-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/imagemagick/coders/strimg.c
Line
Count
Source
1
/*
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%                                                                             %
4
%                                                                             %
5
%                                                                             %
6
%                  SSSSS  TTTTT  RRRR   IIIII  M   M   GGGG                   %
7
%                  SS       T    R   R    I    MM MM  G                       %
8
%                   SSS     T    RRRR     I    M M M  G  GG                   %
9
%                     SS    T    R  R     I    M   M  G   G                   %
10
%                  SSSSS    T    R   R  IIIII  M   M   GGG                    %
11
%                                                                             %
12
%                                                                             %
13
%                    String to Image and Image to Strings                     %
14
%                                                                             %
15
%                              Software Design                                %
16
%                                   Cristy                                    %
17
%                                 March 2022                                  %
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/cache.h"
47
#include "MagickCore/color-private.h"
48
#include "MagickCore/colormap.h"
49
#include "MagickCore/colorspace.h"
50
#include "MagickCore/colorspace-private.h"
51
#include "MagickCore/exception.h"
52
#include "MagickCore/exception-private.h"
53
#include "MagickCore/image.h"
54
#include "MagickCore/image-private.h"
55
#include "MagickCore/list.h"
56
#include "MagickCore/magick.h"
57
#include "MagickCore/memory_.h"
58
#include "MagickCore/monitor.h"
59
#include "MagickCore/monitor-private.h"
60
#include "MagickCore/property.h"
61
#include "MagickCore/quantum.h"
62
#include "MagickCore/quantum-private.h"
63
#include "MagickCore/static.h"
64
#include "MagickCore/string_.h"
65
#include "MagickCore/module.h"
66

67
/*
68
  Forward declarations.
69
*/
70
static MagickBooleanType
71
  WriteSTRIMGImage(const ImageInfo *,Image *,ExceptionInfo *);
72

73
/*
74
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75
%                                                                             %
76
%                                                                             %
77
%                                                                             %
78
%   R e a d S T R I M G I m a g e                                             %
79
%                                                                             %
80
%                                                                             %
81
%                                                                             %
82
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83
%
84
%  ReadSTRIMGImage() encodes the filename as an image.  It allocates the
85
%  memory necessary for the new Image structure and returns a pointer to the
86
%  new image.
87
%
88
%  The format of the ReadSTRIMGImage method is:
89
%
90
%      Image *ReadSTRIMGImage(const ImageInfo *image_info,
91
%        ExceptionInfo *exception)
92
%
93
%  A description of each parameter follows:
94
%
95
%    o image_info: the image info.
96
%
97
%    o exception: return any errors or warnings in this structure.
98
%
99
*/
100
static Image *ReadSTRIMGImage(const ImageInfo *image_info,
101
  ExceptionInfo *exception)
102
26
{
103
26
  char
104
26
    *string;
105
106
26
  Image
107
26
    *image;
108
109
26
  MagickBooleanType
110
26
    status;
111
112
26
  Quantum
113
26
    *q;
114
115
26
  ssize_t
116
26
    x;
117
118
  /*
119
    Open image file.
120
  */
121
26
  assert(image_info != (const ImageInfo *) NULL);
122
26
  assert(image_info->signature == MagickCoreSignature);
123
26
  assert(exception != (ExceptionInfo *) NULL);
124
26
  assert(exception->signature == MagickCoreSignature);
125
26
  if (IsEventLogging() != MagickFalse)
126
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
127
0
      image_info->filename);
128
26
  image=AcquireImage(image_info,exception);
129
26
  string=InterpretImageProperties((ImageInfo *) image_info,image,
130
26
    image_info->filename,exception);
131
26
  if (string == (char *) NULL)
132
0
    return(DestroyImageList(image));
133
26
  image->depth=8;
134
26
  image->colorspace=GRAYColorspace;
135
26
  image->columns=strlen(string);
136
26
  image->rows=1;
137
26
  if (image_info->ping != MagickFalse)
138
0
    {
139
0
      string=DestroyString(string);
140
0
      (void) CloseBlob(image);
141
0
      return(GetFirstImageInList(image));
142
0
    }
143
26
  status=SetImageExtent(image,image->columns,image->rows,exception);
144
26
  if (status == MagickFalse)
145
0
    {
146
0
      string=DestroyString(string);
147
0
      (void) CloseBlob(image);
148
0
      return(DestroyImageList(image));
149
0
    }
150
  /*
151
    Convert string to an image.
152
  */
153
26
  q=QueueAuthenticPixels(image,0,0,image->columns,1,exception);
154
26
  if (q == (Quantum *) NULL)
155
0
    {
156
0
      string=DestroyString(string);
157
0
      (void) CloseBlob(image);
158
0
      return(DestroyImageList(image));
159
0
    }
160
208
  for (x=0; x < (ssize_t) image->columns; x++)
161
182
    q[x]=ScaleCharToQuantum((unsigned char) string[x]);
162
26
  string=DestroyString(string);
163
26
  if (SyncAuthenticPixels(image,exception) == MagickFalse)
164
0
    {
165
0
      (void) CloseBlob(image);
166
0
      return(DestroyImageList(image));
167
0
    }
168
26
  if (CloseBlob(image) == MagickFalse)
169
0
    status=MagickFalse;
170
26
  if (status == MagickFalse)
171
0
    return(DestroyImageList(image));
172
26
  return(GetFirstImageInList(image));
173
26
}
174

175
/*
176
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177
%                                                                             %
178
%                                                                             %
179
%                                                                             %
180
%   R e g i s t e r S T R I M G I m a g e                                     %
181
%                                                                             %
182
%                                                                             %
183
%                                                                             %
184
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185
%
186
%  RegisterSTRIMGImage() adds attributes for the STRIMG image format to
187
%  the list of supported formats.  The attributes include the image format
188
%  tag, a method to read and/or write the format, whether the format
189
%  supports the saving of more than one frame to the same file or blob,
190
%  whether the format supports native in-memory I/O, and a brief
191
%  description of the format.
192
%
193
%  The format of the RegisterSTRIMGImage method is:
194
%
195
%      size_t RegisterSTRIMGImage(void)
196
%
197
*/
198
ModuleExport size_t RegisterSTRIMGImage(void)
199
2
{
200
2
  MagickInfo
201
2
    *entry;
202
203
2
  entry=AcquireMagickInfo("STRIMG","STRIMG","String to image and back");
204
2
  entry->decoder=(DecodeImageHandler *) ReadSTRIMGImage;
205
2
  entry->encoder=(EncodeImageHandler *) WriteSTRIMGImage;
206
2
  entry->flags|=CoderRawSupportFlag;
207
2
  entry->flags^=CoderAdjoinFlag;
208
2
  (void) RegisterMagickInfo(entry);
209
2
  return(MagickImageCoderSignature);
210
2
}
211

212
/*
213
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214
%                                                                             %
215
%                                                                             %
216
%                                                                             %
217
%   U n r e g i s t e r S T R I M G I m a g e                                 %
218
%                                                                             %
219
%                                                                             %
220
%                                                                             %
221
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222
%
223
%  UnregisterSTRIMGImage() removes format registrations made by the
224
%  STRIMG module from the list of supported formats.
225
%
226
%  The format of the UnregisterSTRIMGImage method is:
227
%
228
%      UnregisterSTRIMGImage(void)
229
%
230
*/
231
ModuleExport void UnregisterSTRIMGImage(void)
232
0
{
233
0
  (void) UnregisterMagickInfo("STRIMG");
234
0
}
235

236
/*
237
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238
%                                                                             %
239
%                                                                             %
240
%                                                                             %
241
%   W r i t e S T R I M G I m a g e                                           %
242
%                                                                             %
243
%                                                                             %
244
%                                                                             %
245
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246
%
247
%  WriteSTRIMGImage() writes an image as a string.
248
%
249
%  The format of the WriteSTRIMGImage method is:
250
%
251
%      MagickBooleanType WriteSTRIMGImage(const ImageInfo *image_info,
252
%        Image *image,ExceptionInfo *exception)
253
%
254
%  A description of each parameter follows.
255
%
256
%    o image_info: the image info.
257
%
258
%    o image:  The image.
259
%
260
%    o exception: return any errors or warnings in this structure.
261
%
262
*/
263
static MagickBooleanType WriteSTRIMGImage(const ImageInfo *image_info,
264
  Image *image,ExceptionInfo *exception)
265
26
{
266
26
  MagickBooleanType
267
26
    status;
268
269
26
  QuantumInfo
270
26
    *quantum_info;
271
272
26
  ssize_t
273
26
    y;
274
275
26
  unsigned char
276
26
    *pixels;
277
278
  /*
279
    Open output image file.
280
  */
281
26
  assert(image_info != (const ImageInfo *) NULL);
282
26
  assert(image_info->signature == MagickCoreSignature);
283
26
  assert(image != (Image *) NULL);
284
26
  assert(image->signature == MagickCoreSignature);
285
26
  assert(exception != (ExceptionInfo *) NULL);
286
26
  assert(exception->signature == MagickCoreSignature);
287
26
  if (IsEventLogging() != MagickFalse)
288
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
289
26
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
290
26
  if (status == MagickFalse)
291
0
    return(status);
292
  /*
293
    Convert image to a string.
294
  */
295
26
  quantum_info=AcquireQuantumInfo(image_info,image);
296
26
  if (quantum_info == (QuantumInfo *) NULL)
297
26
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
298
26
  if (SetQuantumDepth(image,quantum_info,8) == MagickFalse)
299
0
    {
300
0
      quantum_info=DestroyQuantumInfo(quantum_info);
301
0
      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
302
0
    }
303
26
  pixels=(unsigned char *) GetQuantumPixels(quantum_info);
304
52
  for (y=0; y < (ssize_t) image->rows; y++)
305
26
  {
306
26
    const Quantum
307
26
      *p;
308
309
26
    size_t
310
26
      length;
311
312
26
    ssize_t
313
26
      count;
314
315
26
    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
316
26
    if (p == (const Quantum *) NULL)
317
0
      break;
318
26
    length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
319
26
      GrayQuantum,pixels,exception);
320
26
    count=WriteBlob(image,length,pixels);
321
26
    if (count != (ssize_t) length)
322
0
      break;
323
26
    if (image->previous == (Image *) NULL)
324
26
      {
325
26
        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
326
26
          image->rows);
327
26
        if (status == MagickFalse)
328
0
          break;
329
26
      }
330
26
  }
331
26
  quantum_info=DestroyQuantumInfo(quantum_info);
332
26
  if (y < (ssize_t) image->rows)
333
26
    ThrowWriterException(CorruptImageError,"UnableToWriteImageData");
334
26
  if (CloseBlob(image) == MagickFalse)
335
0
    status=MagickFalse;
336
26
  return(status);
337
26
}