Coverage Report

Created: 2025-11-14 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/imagemagick/coders/mac.c
Line
Count
Source
1
/*
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%                                                                             %
4
%                                                                             %
5
%                                                                             %
6
%                            M   M   AAA    CCCC                              %
7
%                            MM MM  A   A  C                                  %
8
%                            M M M  AAAAA  C                                  %
9
%                            M   M  A   A  C                                  %
10
%                            M   M  A   A   CCCC                              %
11
%                                                                             %
12
%                                                                             %
13
%                         Read MacPaint Image Format                          %
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/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/blob.h"
44
#include "MagickCore/blob-private.h"
45
#include "MagickCore/cache.h"
46
#include "MagickCore/colormap.h"
47
#include "MagickCore/colorspace.h"
48
#include "MagickCore/exception.h"
49
#include "MagickCore/exception-private.h"
50
#include "MagickCore/image.h"
51
#include "MagickCore/image-private.h"
52
#include "MagickCore/list.h"
53
#include "MagickCore/magick.h"
54
#include "MagickCore/memory_.h"
55
#include "MagickCore/monitor.h"
56
#include "MagickCore/monitor-private.h"
57
#include "MagickCore/pixel-accessor.h"
58
#include "MagickCore/quantum-private.h"
59
#include "MagickCore/static.h"
60
#include "MagickCore/string_.h"
61
#include "MagickCore/module.h"
62

63
/*
64
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65
%                                                                             %
66
%                                                                             %
67
%                                                                             %
68
%   R e a d M A C I m a g e                                                   %
69
%                                                                             %
70
%                                                                             %
71
%                                                                             %
72
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73
%
74
%  ReadMACImage() reads an MacPaint image file and returns it.  It
75
%  allocates the memory necessary for the new Image structure and returns a
76
%  pointer to the new image.
77
%
78
%  The format of the ReadMACImage method is:
79
%
80
%      Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
81
%
82
%  A description of each parameter follows:
83
%
84
%    o image_info: the image info.
85
%
86
%    o exception: return any errors or warnings in this structure.
87
%
88
*/
89
static Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
90
309
{
91
309
  Image
92
309
    *image;
93
94
309
  MagickBooleanType
95
309
    status;
96
97
309
  Quantum
98
309
    *q;
99
100
309
  ssize_t
101
309
    x;
102
103
309
  unsigned char
104
309
    *p;
105
106
309
  size_t
107
309
    length;
108
109
309
  ssize_t
110
309
    offset,
111
309
    y;
112
113
309
  unsigned char
114
309
    count,
115
309
    bit,
116
309
    byte,
117
309
    *pixels;
118
119
  /*
120
    Open image file.
121
  */
122
309
  assert(image_info != (const ImageInfo *) NULL);
123
309
  assert(image_info->signature == MagickCoreSignature);
124
309
  assert(exception != (ExceptionInfo *) NULL);
125
309
  assert(exception->signature == MagickCoreSignature);
126
309
  if (IsEventLogging() != MagickFalse)
127
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
128
0
      image_info->filename);
129
309
  image=AcquireImage(image_info,exception);
130
309
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
131
309
  if (status == MagickFalse)
132
51
    {
133
51
      image=DestroyImageList(image);
134
51
      return((Image *) NULL);
135
51
    }
136
  /*
137
    Read MAC X image.
138
  */
139
258
  length=ReadBlobLSBShort(image);
140
258
  if ((length & 0xff) != 0)
141
245
    ThrowReaderException(CorruptImageError,"CorruptImage");
142
245
  if (length == 0)
143
210
    {
144
70.6k
      for (x=0; x < (ssize_t) 510; x++)
145
70.5k
        if (ReadBlobByte(image) == EOF)
146
134
          ThrowReaderException(CorruptImageError,"CorruptImage");
147
134
    }
148
35
  else
149
2.62k
    for (x=0; x < (ssize_t) 638; x++)
150
2.62k
      if (ReadBlobByte(image) == EOF)
151
137
        ThrowReaderException(CorruptImageError,"CorruptImage");
152
137
  image->columns=576;
153
137
  image->rows=720;
154
137
  image->depth=1;
155
137
  if (AcquireImageColormap(image,2,exception) == MagickFalse)
156
137
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
157
137
  if (image_info->ping != MagickFalse)
158
0
    {
159
0
      (void) CloseBlob(image);
160
0
      return(GetFirstImageInList(image));
161
0
    }
162
137
  status=SetImageExtent(image,image->columns,image->rows,exception);
163
137
  if (status == MagickFalse)
164
0
    return(DestroyImageList(image));
165
137
  status=ResetImagePixels(image,exception);
166
137
  if (status == MagickFalse)
167
0
    return(DestroyImageList(image));
168
  /*
169
    Convert MAC raster image to pixel packets.
170
  */
171
137
  length=(image->columns+7)/8;
172
137
  pixels=(unsigned char *) AcquireQuantumMemory(length+257,sizeof(*pixels));
173
137
  if (pixels == (unsigned char *) NULL) 
174
137
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
175
137
  (void) memset(pixels,0,(length+257)*sizeof(*pixels));
176
137
  p=pixels;
177
137
  offset=0;
178
21.5k
  for (y=0; y < (ssize_t) image->rows; )
179
21.5k
  {
180
21.5k
    count=(unsigned char) ReadBlobByte(image);
181
21.5k
    if (EOFBlob(image) != MagickFalse)
182
125
      break;
183
21.4k
    if ((count <= 0) || (count >= 128))
184
18.2k
      {
185
18.2k
        byte=(unsigned char) (~ReadBlobByte(image));
186
18.2k
        count=(~count)+2;
187
1.24M
        while (count != 0)
188
1.22M
        {
189
1.22M
          *p++=byte;
190
1.22M
          offset++;
191
1.22M
          count--;
192
1.22M
          if (offset >= (ssize_t) length)
193
16.2k
            {
194
16.2k
              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
195
16.2k
              if (q == (Quantum *) NULL)
196
4
                break;
197
16.2k
              p=pixels;
198
16.2k
              bit=0;
199
16.2k
              byte=0;
200
9.34M
              for (x=0; x < (ssize_t) image->columns; x++)
201
9.33M
              {
202
9.33M
                if (bit == 0)
203
1.16M
                  byte=(*p++);
204
9.33M
                SetPixelIndex(image,(Quantum) ((byte & 0x80) != 0 ? 0x01 : 0x00),q);
205
9.33M
                bit++;
206
9.33M
                byte<<=1;
207
9.33M
                if (bit == 8)
208
1.16M
                  bit=0;
209
9.33M
                q+=(ptrdiff_t) GetPixelChannels(image);
210
9.33M
              }
211
16.2k
              if (SyncAuthenticPixels(image,exception) == MagickFalse)
212
0
                break;
213
16.2k
              offset=0;
214
16.2k
              p=pixels;
215
16.2k
              y++;
216
16.2k
            }
217
1.22M
        }
218
18.2k
        continue;
219
18.2k
      }
220
3.22k
    count++;
221
71.0k
    while (count != 0)
222
67.7k
    {
223
67.7k
      byte=(unsigned char) (~ReadBlobByte(image));
224
67.7k
      *p++=byte;
225
67.7k
      offset++;
226
67.7k
      count--;
227
67.7k
      if (offset >= (ssize_t) length)
228
1.76k
        {
229
1.76k
          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
230
1.76k
          if (q == (Quantum *) NULL)
231
2
            break;
232
1.76k
          p=pixels;
233
1.76k
          bit=0;
234
1.76k
          byte=0;
235
1.01M
          for (x=0; x < (ssize_t) image->columns; x++)
236
1.01M
          {
237
1.01M
            if (bit == 0)
238
126k
              byte=(*p++);
239
1.01M
            SetPixelIndex(image,(Quantum) ((byte & 0x80) != 0 ? 0x01 : 0x00),q);
240
1.01M
            bit++;
241
1.01M
            byte<<=1;
242
1.01M
            if (bit == 8)
243
126k
              bit=0;
244
1.01M
            q+=(ptrdiff_t) GetPixelChannels(image);
245
1.01M
          }
246
1.76k
          if (SyncAuthenticPixels(image,exception) == MagickFalse)
247
0
            break;
248
1.76k
          offset=0;
249
1.76k
          p=pixels;
250
1.76k
          y++;
251
1.76k
        }
252
67.7k
    }
253
3.22k
  }
254
137
  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
255
137
  (void) SyncImage(image,exception);
256
137
  if (CloseBlob(image) == MagickFalse)
257
0
    status=MagickFalse;
258
137
  if (status == MagickFalse)
259
0
    return(DestroyImageList(image));
260
137
  return(GetFirstImageInList(image));
261
137
}
262

263
/*
264
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265
%                                                                             %
266
%                                                                             %
267
%                                                                             %
268
%   R e g i s t e r M A C I m a g e                                           %
269
%                                                                             %
270
%                                                                             %
271
%                                                                             %
272
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273
%
274
%  RegisterMACImage() adds attributes for the MAC X image format to the list
275
%  of supported formats.  The attributes include the image format tag, a
276
%  method to read and/or write the format, whether the format supports the
277
%  saving of more than one frame to the same file or blob, whether the format
278
%  supports native in-memory I/O, and a brief description of the format.
279
%
280
%  The format of the RegisterMACImage method is:
281
%
282
%      size_t RegisterMACImage(void)
283
%
284
*/
285
ModuleExport size_t RegisterMACImage(void)
286
8
{
287
8
  MagickInfo
288
8
    *entry;
289
290
8
  entry=AcquireMagickInfo("MAC","MAC","MAC Paint");
291
8
  entry->decoder=(DecodeImageHandler *) ReadMACImage;
292
8
  (void) RegisterMagickInfo(entry);
293
8
  return(MagickImageCoderSignature);
294
8
}
295

296
/*
297
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298
%                                                                             %
299
%                                                                             %
300
%                                                                             %
301
%   U n r e g i s t e r M A C I m a g e                                       %
302
%                                                                             %
303
%                                                                             %
304
%                                                                             %
305
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306
%
307
%  UnregisterMACImage() removes format registrations made by the
308
%  MAC module from the list of supported formats.
309
%
310
%  The format of the UnregisterMACImage method is:
311
%
312
%      UnregisterMACImage(void)
313
%
314
*/
315
ModuleExport void UnregisterMACImage(void)
316
0
{
317
0
  (void) UnregisterMagickInfo("MAC");
318
0
}