Coverage Report

Created: 2025-12-31 07:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/coders/art.c
Line
Count
Source
1
/*
2
% Copyright (C) 2003-2025 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
%
5
% This program is covered by multiple licenses, which are described in
6
% Copyright.txt. You should have received a copy of Copyright.txt with this
7
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
8
%
9
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
%                                                                             %
11
%                                                                             %
12
%                             AAA   RRRR   TTTTT                              %
13
%                            A   A  R   R    T                                %
14
%                            AAAAA  RRRR     T                                %
15
%                            A   A  R R      T                                %
16
%                            A   A  R  R     T                                %
17
%                                                                             %
18
%                                                                             %
19
%                Read/Write PFS: 1st Publisher Image Format.                  %
20
%                                                                             %
21
%                                                                             %
22
%                              Software Design                                %
23
%                              Jaroslav Fojtik                                %
24
%                            January 2001 - 2007                              %
25
%                                                                             %
26
%                                                                             %
27
%                                                                             %
28
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29
%
30
%
31
*/
32

33
/*
34
  Include declarations.
35
*/
36
#include "magick/studio.h"
37
#include "magick/blob.h"
38
#include "magick/colormap.h"
39
#include "magick/constitute.h"
40
#include "magick/log.h"
41
#include "magick/magick.h"
42
#include "magick/monitor.h"
43
#include "magick/pixel_cache.h"
44
#include "magick/utility.h"
45
#include "magick/static.h"
46

47
/*
48
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49
%                                                                             %
50
%                                                                             %
51
%                                                                             %
52
%   R e a d A R T I m a g e                                                   %
53
%                                                                             %
54
%                                                                             %
55
%                                                                             %
56
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57
%
58
%  Method ReadARTImage reads an ART X image file and returns it.  It
59
%  allocates the memory necessary for the new Image structure and returns a
60
%  pointer to the new image.
61
%
62
%  The format of the ReadARTImage method is:
63
%
64
%      Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
65
%
66
%  A description of each parameter follows:
67
%
68
%    o image:  Method ReadARTImage returns a pointer to the image after
69
%      reading. A null image is returned if there is a memory shortage or if
70
%      the image cannot be read.
71
%
72
%    o image_info: Specifies a pointer to a ImageInfo structure.
73
%
74
%    o exception: return any errors or warnings in this structure.
75
%
76
%
77
*/
78
static Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
79
328
{
80
328
  Image *image;
81
328
  unsigned int i;
82
328
  unsigned int width,height,dummy;
83
328
  long ldblk;
84
328
  unsigned char *BImgBuff=NULL;
85
328
  unsigned char Padding;
86
328
  unsigned int status;
87
328
  const PixelPacket *q;
88
89
  /*
90
    Open image file.
91
  */
92
328
  assert(image_info != (const ImageInfo *) NULL);
93
328
  assert(image_info->signature == MagickSignature);
94
328
  assert(exception != (ExceptionInfo *) NULL);
95
328
  assert(exception->signature == MagickSignature);
96
328
  image=AllocateImage(image_info);
97
328
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
98
328
  if (status == False)
99
328
    ThrowReaderException(FileOpenError,UnableToOpenFile,image);
100
  /*
101
    Read ART image.
102
  */
103
328
  dummy=ReadBlobLSBShort(image);
104
328
  width=ReadBlobLSBShort(image);
105
328
  dummy=ReadBlobLSBShort(image);
106
328
  height=ReadBlobLSBShort(image);
107
108
328
  ldblk=(long) (((size_t) width+7) / 8);
109
328
  Padding=(unsigned char) ((-ldblk) & 0x01);
110
111
328
  image->columns=width;
112
328
  image->rows=height;
113
328
  if(GetBlobSize(image)!=(magick_off_t) (8+((size_t)ldblk+Padding)*image->rows))
114
240
    ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
115
240
  if (CheckImagePixelLimits(image, exception) != MagickPass)
116
209
    ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
117
209
  image->depth=1;
118
209
  image->colors=1l << image->depth;
119
120
  /* printf("ART header checked OK %d,%d\n",image->colors,image->depth); */
121
122
209
  if (!AllocateImageColormap(image,image->colors)) goto NoMemory;
123
124
  /* If ping is true, then only set image size and colors without reading any image data. */
125
209
  if (image_info->ping) goto DONE_READING;
126
127
209
  BImgBuff=MagickAllocateResourceLimitedMemory(unsigned char *,((size_t) ldblk));  /*Ldblk was set in the check phase*/
128
209
  if (BImgBuff==NULL)
129
0
  NoMemory:
130
209
    ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
131
132
63.7k
  for (i=0; i < height; i++)
133
63.5k
    {
134
63.5k
      if (ReadBlob(image,(size_t)ldblk,(char *)BImgBuff) != (size_t)ldblk)
135
0
        break;
136
63.5k
      if (ReadBlob(image,Padding,(char *)&dummy) != Padding)
137
0
        break;
138
139
63.5k
      q=SetImagePixelsEx(image,0,i,image->columns,1,exception);
140
63.5k
      if (q == (PixelPacket *)NULL) break;
141
63.5k
      (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0);
142
63.5k
      if (!SyncImagePixelsEx(image,exception)) break;
143
63.5k
    }
144
209
  MagickFreeResourceLimitedMemory(unsigned char *,BImgBuff);
145
146
209
  if (i != height)
147
209
    ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
148
149
209
 DONE_READING:
150
209
  CloseBlob(image);
151
209
  StopTimer(&image->timer);
152
209
  return(image);
153
209
}
154
155

156
/*
157
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158
%                                                                             %
159
%                                                                             %
160
%                                                                             %
161
%   W r i t e A R T I m a g e                                           %
162
%                                                                             %
163
%                                                                             %
164
%                                                                             %
165
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166
%
167
%  Function WriteARTImage writes an ART image to a file.
168
%
169
%  The format of the WriteARTImage method is:
170
%
171
%      unsigned int WriteARTImage(const ImageInfo *image_info,Image *image)
172
%
173
%  A description of each parameter follows.
174
%
175
%    o status: Function WriteARTImage return True if the image is written.
176
%      False is returned is there is a memory shortage or if the image file
177
%      fails to write.
178
%
179
%    o image_info: Specifies a pointer to a ImageInfo structure.
180
%
181
%    o image:  A pointer to an Image structure.
182
%
183
*/
184
static MagickPassFail WriteARTImage(const ImageInfo *image_info,Image *image)
185
209
{
186
209
  long y;
187
209
  unsigned dummy = 0;
188
209
  size_t DataSize;
189
209
  unsigned int status;
190
209
  unsigned char Padding;
191
209
  int logging;
192
209
  unsigned char *pixels;
193
194
  /*
195
    Open output image file.
196
  */
197
209
  assert(image_info != (const ImageInfo *) NULL);
198
209
  assert(image_info->signature == MagickSignature);
199
209
  assert(image != (Image *) NULL);
200
209
  assert(image->signature == MagickSignature);
201
209
  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ART");
202
209
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
203
209
  if (status == MagickFail)
204
209
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
205
206
209
  DataSize = (long)((image->columns+7) / 8);
207
209
  Padding = (unsigned char)((-(long) DataSize) & 0x01);
208
209
209
  pixels=MagickAllocateResourceLimitedMemory(unsigned char *,(size_t) (DataSize));
210
209
  if (pixels == (unsigned char *) NULL)
211
209
    ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
212
213
 /*
214
    Write ART hader.
215
  */
216
209
  (void) WriteBlobLSBShort(image,0);
217
209
  (void) WriteBlobLSBShort(image,image->columns);
218
209
  (void) WriteBlobLSBShort(image,0);
219
209
  (void) WriteBlobLSBShort(image,image->rows);
220
221
  /*
222
    Store image data.
223
  */
224
63.7k
  for(y=0; y<(long)image->rows; y++)
225
63.5k
  {
226
63.5k
    if (AcquireImagePixels(image,0,y,image->columns,1,&image->exception)
227
63.5k
        == (const PixelPacket *) NULL)
228
0
      {
229
0
        status=MagickFail;
230
0
        break;
231
0
      }
232
63.5k
    if (ExportImagePixelArea(image,GrayQuantum,1,pixels,0,0) != MagickPass)
233
0
      {
234
0
        status=MagickFail;
235
0
        break;
236
0
      }
237
63.5k
    if (WriteBlob(image,DataSize,pixels) != DataSize)
238
0
      {
239
0
        status=MagickFail;
240
0
        break;
241
0
      }
242
63.5k
    if (WriteBlob(image,Padding,(char *)&dummy) != Padding)
243
0
      {
244
0
        status=MagickFail;
245
0
        break;
246
0
      }
247
63.5k
  }
248
249
209
  status &= CloseBlob(image);
250
209
  MagickFreeResourceLimitedMemory(unsigned char *,pixels);
251
252
209
  if (logging)
253
0
    (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return ART");
254
255
209
  return(status);
256
209
}
257
258

259
/*
260
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261
%                                                                             %
262
%                                                                             %
263
%                                                                             %
264
%   R e g i s t e r A R T I m a g e                                           %
265
%                                                                             %
266
%                                                                             %
267
%                                                                             %
268
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269
%
270
%  Method RegisterARTImage adds attributes for the ART image format to
271
%  the list of supported formats.  The attributes include the image format
272
%  tag, a method to read and/or write the format, whether the format
273
%  supports the saving of more than one frame to the same file or blob,
274
%  whether the format supports native in-memory I/O, and a brief
275
%  description of the format.
276
%
277
%  The format of the RegisterARTImage method is:
278
%
279
%      RegisterARTImage(void)
280
%
281
*/
282
ModuleExport void RegisterARTImage(void)
283
1
{
284
1
  MagickInfo
285
1
    *entry;
286
287
1
  entry=SetMagickInfo("ART");
288
1
  entry->decoder = (DecoderHandler)ReadARTImage;
289
1
  entry->encoder = (EncoderHandler)WriteARTImage;
290
1
  entry->description="PFS: 1st Publisher";
291
1
  entry->module="ART";
292
1
  entry->adjoin=False;
293
1
  (void) RegisterMagickInfo(entry);
294
1
}
295

296
/*
297
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298
%                                                                             %
299
%                                                                             %
300
%                                                                             %
301
%   U n r e g i s t e r A R T I m a g e                                       %
302
%                                                                             %
303
%                                                                             %
304
%                                                                             %
305
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306
%
307
%  Method UnregisterARTImage removes format registrations made by the
308
%  ART module from the list of supported formats.
309
%
310
%  The format of the UnregisterARTImage method is:
311
%
312
%      UnregisterARTImage(void)
313
%
314
*/
315
ModuleExport void UnregisterARTImage(void)
316
0
{
317
0
  (void) UnregisterMagickInfo("ART");
318
0
}