Coverage Report

Created: 2025-07-23 08:18

/src/graphicsmagick/coders/mono.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
% Copyright (C) 2003-2020 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
5
%
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
9
%
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11
%                                                                             %
12
%                                                                             %
13
%                                                                             %
14
%                         M   M   OOO   N   N   OOO                           %
15
%                         MM MM  O   O  NN  N  O   O                          %
16
%                         M M M  O   O  N N N  O   O                          %
17
%                         M   M  O   O  N  NN  O   O                          %
18
%                         M   M   OOO   N   N   OOO                           %
19
%                                                                             %
20
%                                                                             %
21
%                   Read/Write Raw Bi-Level Bitmap Format.                    %
22
%                                                                             %
23
%                                                                             %
24
%                              Software Design                                %
25
%                                John Cristy                                  %
26
%                                 July 1992                                   %
27
%                                                                             %
28
%                                                                             %
29
%                                                                             %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31
%
32
%
33
*/
34

35
/*
36
  Include declarations.
37
*/
38
#include "magick/studio.h"
39
#include "magick/blob.h"
40
#include "magick/colormap.h"
41
#include "magick/magick.h"
42
#include "magick/monitor.h"
43
#include "magick/pixel_cache.h"
44
#include "magick/utility.h"
45

46
/*
47
  Forward declarations.
48
*/
49
static unsigned int
50
  WriteMONOImage(const ImageInfo *,Image *);
51

52
/*
53
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54
%                                                                             %
55
%                                                                             %
56
%                                                                             %
57
%   R e a d M O N O I m a g e                                                 %
58
%                                                                             %
59
%                                                                             %
60
%                                                                             %
61
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62
%
63
%  Method ReadMONOImage reads an image of raw bytes in LSB order and returns
64
%  it.  It allocates the memory necessary for the new Image structure and
65
%  returns a pointer to the new image.
66
%
67
%  The format of the ReadMONOImage method is:
68
%
69
%      Image *ReadMONOImage(const ImageInfo *image_info,
70
%        ExceptionInfo *exception)
71
%
72
%  A description of each parameter follows:
73
%
74
%    o image:  Method ReadMONOImage returns a pointer to the image after
75
%      reading.  A null image is returned if there is a memory shortage or
76
%      if the image cannot be read.
77
%
78
%    o image_info: Specifies a pointer to a ImageInfo structure.
79
%
80
%    o exception: return any errors or warnings in this structure.
81
%
82
%
83
*/
84
static Image *ReadMONOImage(const ImageInfo *image_info,
85
  ExceptionInfo *exception)
86
23
{
87
23
  Image
88
23
    *image;
89
90
23
  long
91
23
    y;
92
93
23
  register IndexPacket
94
23
    *indexes;
95
96
23
  register long
97
23
    x;
98
99
23
  register PixelPacket
100
23
    *q;
101
102
23
  register long
103
23
    i;
104
105
23
  unsigned char
106
23
    bit,
107
23
    byte;
108
109
23
  unsigned int
110
23
    status;
111
112
  /*
113
    Open image file.
114
  */
115
23
  assert(image_info != (const ImageInfo *) NULL);
116
23
  assert(image_info->signature == MagickSignature);
117
23
  assert(exception != (ExceptionInfo *) NULL);
118
23
  assert(exception->signature == MagickSignature);
119
23
  image=AllocateImage(image_info);
120
23
  if ((image->columns == 0) || (image->rows == 0))
121
23
    ThrowReaderException(OptionError,MustSpecifyImageSize,image);
122
0
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
123
0
  if (status == False)
124
0
    ThrowReaderException(FileOpenError,UnableToOpenFile,image);
125
0
  for (i=0; i < image->offset; i++)
126
0
    {
127
0
      if (EOF == ReadBlobByte(image))
128
0
        ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
129
0
                       image->filename);
130
0
    }
131
  /*
132
    Initialize image colormap.
133
  */
134
0
  if (!AllocateImageColormap(image,2))
135
0
    ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
136
0
  if (image_info->ping)
137
0
    {
138
0
      CloseBlob(image);
139
0
      StopTimer(&image->timer);
140
0
      return(image);
141
0
    }
142
  /*
143
    Convert bi-level image to pixel packets.
144
  */
145
0
  for (y=0; y < (long) image->rows; y++)
146
0
  {
147
0
    q=SetImagePixels(image,0,y,image->columns,1);
148
0
    if (q == (PixelPacket *) NULL)
149
0
      break;
150
0
    indexes=AccessMutableIndexes(image);
151
0
    bit=0U;
152
0
    byte=0U;
153
0
    for (x=0; x < (long) image->columns; x++)
154
0
    {
155
0
      if (bit == 0U)
156
0
        byte=ReadBlobByte(image);
157
0
      indexes[x]=(byte & 0x01U) ? 0x01U : 0x00U;
158
0
      bit++;
159
0
      if (bit == 8U)
160
0
        bit=0U;
161
0
      byte>>=1U;
162
0
    }
163
0
    if (!SyncImagePixels(image))
164
0
      break;
165
0
    if (QuantumTick(y,image->rows))
166
0
      if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
167
0
                                  image->filename,
168
0
                                  image->columns,image->rows))
169
0
        break;
170
0
  }
171
0
  (void) SyncImage(image);
172
0
  if (EOFBlob(image))
173
0
    ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
174
0
      image->filename);
175
0
  CloseBlob(image);
176
0
  StopTimer(&image->timer);
177
0
  return(image);
178
0
}
179

180
/*
181
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182
%                                                                             %
183
%                                                                             %
184
%                                                                             %
185
%   R e g i s t e r M O N O I m a g e                                         %
186
%                                                                             %
187
%                                                                             %
188
%                                                                             %
189
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190
%
191
%  Method RegisterMONOImage adds attributes for the MONO image format to
192
%  the list of supported formats.  The attributes include the image format
193
%  tag, a method to read and/or write the format, whether the format
194
%  supports the saving of more than one frame to the same file or blob,
195
%  whether the format supports native in-memory I/O, and a brief
196
%  description of the format.
197
%
198
%  The format of the RegisterMONOImage method is:
199
%
200
%      RegisterMONOImage(void)
201
%
202
*/
203
ModuleExport void RegisterMONOImage(void)
204
1
{
205
1
  MagickInfo
206
1
    *entry;
207
208
1
  entry=SetMagickInfo("MONO");
209
1
  entry->decoder=(DecoderHandler) ReadMONOImage;
210
1
  entry->encoder=(EncoderHandler) WriteMONOImage;
211
1
  entry->adjoin=False;
212
1
  entry->description="Bi-level bitmap in least-significant-byte first order";
213
1
  entry->raw=True;
214
1
  entry->module="MONO";
215
1
  (void) RegisterMagickInfo(entry);
216
1
}
217

218
/*
219
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220
%                                                                             %
221
%                                                                             %
222
%                                                                             %
223
%   U n r e g i s t e r M O N O I m a g e                                     %
224
%                                                                             %
225
%                                                                             %
226
%                                                                             %
227
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228
%
229
%  Method UnregisterMONOImage removes format registrations made by the
230
%  MONO module from the list of supported formats.
231
%
232
%  The format of the UnregisterMONOImage method is:
233
%
234
%      UnregisterMONOImage(void)
235
%
236
*/
237
ModuleExport void UnregisterMONOImage(void)
238
0
{
239
0
  (void) UnregisterMagickInfo("MONO");
240
0
}
241

242
/*
243
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244
%                                                                             %
245
%                                                                             %
246
%                                                                             %
247
%   W r i t e M O N O I m a g e                                               %
248
%                                                                             %
249
%                                                                             %
250
%                                                                             %
251
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252
%
253
%  Method WriteMONOImage writes an image of raw bits in LSB order to a file.
254
%
255
%  The format of the WriteMONOImage method is:
256
%
257
%      unsigned int WriteMONOImage(const ImageInfo *image_info,Image *image)
258
%
259
%  A description of each parameter follows.
260
%
261
%    o status: Method WriteMONOImage return True if the image is written.
262
%      False is returned is there is a memory shortage or if the image file
263
%      fails to write.
264
%
265
%    o image_info: Specifies a pointer to a ImageInfo structure.
266
%
267
%    o image:  A pointer to an Image structure.
268
%
269
%
270
*/
271
static unsigned int WriteMONOImage(const ImageInfo *image_info,Image *image)
272
0
{
273
0
  long
274
0
    y;
275
276
0
  register const IndexPacket
277
0
    *indexes;
278
279
0
  register const PixelPacket
280
0
    *p;
281
282
0
  register long
283
0
    x;
284
285
0
  unsigned char
286
0
    bit,
287
0
    byte,
288
0
    polarity;
289
290
0
  unsigned int
291
0
    status;
292
293
  /*
294
    Open output image file.
295
  */
296
0
  assert(image_info != (const ImageInfo *) NULL);
297
0
  assert(image_info->signature == MagickSignature);
298
0
  assert(image != (Image *) NULL);
299
0
  assert(image->signature == MagickSignature);
300
0
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
301
0
  if (status == False)
302
0
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
303
0
  (void) TransformColorspace(image,RGBColorspace);
304
  /*
305
    Convert image to a bi-level image.
306
  */
307
0
  (void) SetImageType(image,BilevelType);
308
0
  polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
309
0
  if (image->colors == 2)
310
0
    polarity=PixelIntensityToQuantum(&image->colormap[0]) <
311
0
      PixelIntensityToQuantum(&image->colormap[1]);
312
0
  for (y=0; y < (long) image->rows; y++)
313
0
  {
314
0
    p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
315
0
    if (p == (const PixelPacket *) NULL)
316
0
      break;
317
0
    indexes=AccessImmutableIndexes(image);
318
0
    bit=0;
319
0
    byte=0;
320
0
    for (x=0; x < (long) image->columns; x++)
321
0
    {
322
0
      byte>>=1;
323
0
      if (indexes[x] == polarity)
324
0
        byte|=0x80;
325
0
      bit++;
326
0
      if (bit == 8)
327
0
        {
328
0
          (void) WriteBlobByte(image,byte);
329
0
          bit=0;
330
0
          byte=0;
331
0
        }
332
0
    }
333
0
    if (bit != 0)
334
0
      (void) WriteBlobByte(image,byte >> (8-bit));
335
0
    if (QuantumTick(y,image->rows))
336
0
      if (!MagickMonitorFormatted(y,image->rows,&image->exception,
337
0
                                  SaveImageText,image->filename,
338
0
                                  image->columns,image->rows))
339
0
        break;
340
0
  }
341
0
  status &= CloseBlob(image);
342
0
  return(status);
343
0
}