Coverage Report

Created: 2026-01-20 07:37

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