Coverage Report

Created: 2025-11-14 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/imagemagick/coders/xbm.c
Line
Count
Source
1
/*
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%                                                                             %
4
%                                                                             %
5
%                                                                             %
6
%                            X   X  BBBB   M   M                              %
7
%                             X X   B   B  MM MM                              %
8
%                              X    BBBB   M M M                              %
9
%                             X X   B   B  M   M                              %
10
%                            X   X  BBBB   M   M                              %
11
%                                                                             %
12
%                                                                             %
13
%                  Read/Write X Windows System Bitmap 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/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/pixel-accessor.h"
61
#include "MagickCore/quantum-private.h"
62
#include "MagickCore/static.h"
63
#include "MagickCore/string_.h"
64
#include "MagickCore/string-private.h"
65
#include "MagickCore/module.h"
66
#include "MagickCore/utility.h"
67

68
/*
69
  Forward declarations.
70
*/
71
static MagickBooleanType
72
  WriteXBMImage(const ImageInfo *,Image *,ExceptionInfo *);
73

74
/*
75
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76
%                                                                             %
77
%                                                                             %
78
%                                                                             %
79
%   I s X B M                                                                 %
80
%                                                                             %
81
%                                                                             %
82
%                                                                             %
83
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84
%
85
%  IsXBM() returns MagickTrue if the image format type, identified by the
86
%  magick string, is XBM.
87
%
88
%  The format of the IsXBM method is:
89
%
90
%      MagickBooleanType IsXBM(const unsigned char *magick,const size_t length)
91
%
92
%  A description of each parameter follows:
93
%
94
%    o magick: compare image format pattern against these bytes.
95
%
96
%    o length: Specifies the length of the magick string.
97
%
98
*/
99
static MagickBooleanType IsXBM(const unsigned char *magick,const size_t length)
100
0
{
101
0
  if (length < 7)
102
0
    return(MagickFalse);
103
0
  if (memcmp(magick,"#define",7) == 0)
104
0
    return(MagickTrue);
105
0
  return(MagickFalse);
106
0
}
107

108
/*
109
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110
%                                                                             %
111
%                                                                             %
112
%                                                                             %
113
%   R e a d X B M I m a g e                                                   %
114
%                                                                             %
115
%                                                                             %
116
%                                                                             %
117
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118
%
119
%  ReadXBMImage() reads an X11 bitmap image file and returns it.  It
120
%  allocates the memory necessary for the new Image structure and returns a
121
%  pointer to the new image.
122
%
123
%  The format of the ReadXBMImage method is:
124
%
125
%      Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
126
%
127
%  A description of each parameter follows:
128
%
129
%    o image_info: the image info.
130
%
131
%    o exception: return any errors or warnings in this structure.
132
%
133
*/
134
135
static int XBMInteger(Image *image,short int *hex_digits)
136
52.5k
{
137
52.5k
  int
138
52.5k
    c;
139
140
52.5k
  unsigned int
141
52.5k
    value;
142
143
  /*
144
    Skip any leading whitespace.
145
  */
146
52.5k
  do
147
54.2k
  {
148
54.2k
    c=ReadBlobByte(image);
149
54.2k
    if (c == EOF)
150
234
      return(-1);
151
54.2k
  } while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
152
  /*
153
    Evaluate number.
154
  */
155
52.3k
  value=0;
156
52.3k
  do
157
57.3k
  {
158
57.3k
    if (value <= (unsigned int) (INT_MAX/16))
159
56.8k
      {
160
56.8k
        value*=16;
161
56.8k
        c&=0xff;
162
56.8k
        if (value <= (unsigned int) ((INT_MAX-1)-hex_digits[c]))
163
56.4k
          value+=(unsigned int) hex_digits[c];
164
56.8k
      }
165
57.3k
    c=ReadBlobByte(image);
166
57.3k
    if (c == EOF)
167
182
      return(-1);
168
57.3k
  } while (hex_digits[c & 0xff] >= 0);
169
52.1k
  return((int) value);
170
52.3k
}
171
172
static Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
173
1.53k
{
174
1.53k
  char
175
1.53k
    buffer[MagickPathExtent],
176
1.53k
    name[MagickPathExtent];
177
178
1.53k
  Image
179
1.53k
    *image;
180
181
1.53k
  int
182
1.53k
    c;
183
184
1.53k
  long
185
1.53k
    height,
186
1.53k
    width;
187
188
1.53k
  MagickBooleanType
189
1.53k
    status;
190
191
1.53k
  MagickOffsetType
192
1.53k
    offset;
193
194
1.53k
  Quantum
195
1.53k
    *q;
196
197
1.53k
  short int
198
1.53k
    hex_digits[256];
199
200
1.53k
  ssize_t
201
1.53k
    i,
202
1.53k
    x,
203
1.53k
    y;
204
205
1.53k
  unsigned char
206
1.53k
    *data,
207
1.53k
    *p;
208
209
1.53k
  unsigned int
210
1.53k
    bit,
211
1.53k
    byte,
212
1.53k
    bytes_per_line,
213
1.53k
    length,
214
1.53k
    padding,
215
1.53k
    version;
216
217
  /*
218
    Open image file.
219
  */
220
1.53k
  assert(image_info != (const ImageInfo *) NULL);
221
1.53k
  assert(image_info->signature == MagickCoreSignature);
222
1.53k
  assert(exception != (ExceptionInfo *) NULL);
223
1.53k
  assert(exception->signature == MagickCoreSignature);
224
1.53k
  if (IsEventLogging() != MagickFalse)
225
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
226
0
      image_info->filename);
227
1.53k
  image=AcquireImage(image_info,exception);
228
1.53k
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
229
1.53k
  if (status == MagickFalse)
230
0
    {
231
0
      image=DestroyImageList(image);
232
0
      return((Image *) NULL);
233
0
    }
234
  /*
235
    Read X bitmap header.
236
  */
237
1.53k
  width=0;
238
1.53k
  height=0;
239
1.53k
  *name='\0';
240
5.98k
  while (ReadBlobString(image,buffer) != (char *) NULL)
241
5.63k
    if (MagickSscanf(buffer,"#define %1024s %ld",name,&width) == 2)
242
2.57k
      if ((strlen(name) >= 6) &&
243
1.97k
          (LocaleCompare(name+strlen(name)-6,"_width") == 0))
244
1.17k
        break;
245
4.80k
  while (ReadBlobString(image,buffer) != (char *) NULL)
246
4.27k
    if (MagickSscanf(buffer,"#define %1024s %ld",name,&height) == 2)
247
2.60k
      if ((strlen(name) >= 7) &&
248
1.38k
          (LocaleCompare(name+strlen(name)-7,"_height") == 0))
249
996
        break;
250
1.53k
  if ((width <= 0) || (height <= 0) || (EOFBlob(image) != MagickFalse))
251
993
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
252
993
  image->columns=(size_t) width;
253
993
  image->rows=(size_t) height;
254
993
  image->depth=8;
255
993
  image->storage_class=PseudoClass;
256
993
  image->colors=2;
257
  /*
258
    Scan until hex digits.
259
  */
260
993
  version=11;
261
993
  offset=TellBlob(image);
262
6.15k
  while (ReadBlobString(image,buffer) != (char *) NULL)
263
5.82k
  {
264
5.82k
    if (MagickSscanf(buffer,"static short %1024s = {",name) == 1)
265
611
      version=10;
266
5.21k
    else if (MagickSscanf(buffer,"static unsigned char %1024s = {",name) == 1)
267
539
      version=11;
268
4.67k
    else if (MagickSscanf(buffer,"static char %1024s = {",name) == 1)
269
2.42k
      version=11;
270
2.25k
    else
271
2.25k
      {
272
2.25k
        offset=TellBlob(image);
273
2.25k
        continue;
274
2.25k
      }
275
3.57k
    p=(unsigned char *) strrchr(name,'_');
276
3.57k
    if (p == (unsigned char *) NULL)
277
3.24k
      p=(unsigned char *) name;
278
323
    else
279
323
      p++;
280
3.57k
    if (LocaleCompare("bits[]",(char *) p) == 0)
281
669
      break;
282
3.57k
  }
283
  /*
284
    Initialize image structure.
285
  */
286
993
  if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
287
993
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
288
  /*
289
    Initialize colormap.
290
  */
291
993
  image->colormap[0].red=(MagickRealType) QuantumRange;
292
993
  image->colormap[0].green=(MagickRealType) QuantumRange;
293
993
  image->colormap[0].blue=(MagickRealType) QuantumRange;
294
993
  image->colormap[1].red=0.0;
295
993
  image->colormap[1].green=0.0;
296
993
  image->colormap[1].blue=0.0;
297
993
  if (image_info->ping != MagickFalse)
298
25
    {
299
25
      (void) CloseBlob(image);
300
25
      return(GetFirstImageInList(image));
301
25
    }
302
968
  status=SetImageExtent(image,image->columns,image->rows,exception);
303
968
  if (status == MagickFalse)
304
187
    return(DestroyImageList(image));
305
781
  p=(unsigned char *) strrchr(buffer,'{');
306
781
  if (p != (unsigned char *) NULL)
307
26
    (void) SeekBlob(image,offset+((char *) p-buffer)+1,SEEK_SET);
308
  /*
309
    Initialize hex values.
310
  */
311
200k
  for (i=0; i < (ssize_t) (sizeof(hex_digits)/sizeof(*hex_digits)); i++)
312
199k
    hex_digits[i]=(-1);
313
781
  hex_digits[(int) '0']=0;
314
781
  hex_digits[(int) '1']=1;
315
781
  hex_digits[(int) '2']=2;
316
781
  hex_digits[(int) '3']=3;
317
781
  hex_digits[(int) '4']=4;
318
781
  hex_digits[(int) '5']=5;
319
781
  hex_digits[(int) '6']=6;
320
781
  hex_digits[(int) '7']=7;
321
781
  hex_digits[(int) '8']=8;
322
781
  hex_digits[(int) '9']=9;
323
781
  hex_digits[(int) 'A']=10;
324
781
  hex_digits[(int) 'B']=11;
325
781
  hex_digits[(int) 'C']=12;
326
781
  hex_digits[(int) 'D']=13;
327
781
  hex_digits[(int) 'E']=14;
328
781
  hex_digits[(int) 'F']=15;
329
781
  hex_digits[(int) 'a']=10;
330
781
  hex_digits[(int) 'b']=11;
331
781
  hex_digits[(int) 'c']=12;
332
781
  hex_digits[(int) 'd']=13;
333
781
  hex_digits[(int) 'e']=14;
334
781
  hex_digits[(int) 'f']=15;
335
781
  hex_digits[(int) 'x']=0;
336
781
  hex_digits[(int) ' ']=(-1);
337
781
  hex_digits[(int) ',']=(-1);
338
781
  hex_digits[(int) '}']=(-1);
339
781
  hex_digits[(int) '\n']=(-1);
340
781
  hex_digits[(int) '\t']=(-1);
341
  /*
342
    Read hex image data.
343
  */
344
781
  padding=0;
345
781
  if (((image->columns % 16) != 0) && ((image->columns % 16) < 9) &&
346
562
      (version == 10))
347
240
    padding=1;
348
781
  bytes_per_line=(unsigned int) (image->columns+7)/8+padding;
349
781
  length=(unsigned int) image->rows;
350
781
  data=(unsigned char *) AcquireQuantumMemory(length,bytes_per_line*
351
781
    sizeof(*data));
352
781
  if (data == (unsigned char *) NULL)
353
781
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
354
781
  p=data;
355
781
  if (version == 10)
356
50.5k
    for (i=0; i < (ssize_t) (bytes_per_line*image->rows); (i+=2))
357
50.3k
    {
358
50.3k
      c=XBMInteger(image,hex_digits);
359
50.3k
      if (c < 0)
360
164
        {
361
164
          data=(unsigned char *) RelinquishMagickMemory(data);
362
164
          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
363
0
        }
364
50.1k
      *p++=(unsigned char) c;
365
50.1k
      if ((padding == 0) || (((i+2) % bytes_per_line) != 0))
366
44.6k
        *p++=(unsigned char) (c >> 8);
367
50.1k
    }
368
359
  else
369
2.38k
    for (i=0; i < (ssize_t) (bytes_per_line*image->rows); i++)
370
2.28k
    {
371
2.28k
      c=XBMInteger(image,hex_digits);
372
2.28k
      if (c < 0)
373
259
        {
374
259
          data=(unsigned char *) RelinquishMagickMemory(data);
375
259
          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
376
0
        }
377
2.02k
      *p++=(unsigned char) c;
378
2.02k
    }
379
358
  if (EOFBlob(image) != MagickFalse)
380
0
    {
381
0
      data=(unsigned char *) RelinquishMagickMemory(data);
382
0
      ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
383
0
    }
384
  /*
385
    Convert X bitmap image to pixel packets.
386
  */
387
358
  p=data;
388
13.0k
  for (y=0; y < (ssize_t) image->rows; y++)
389
12.7k
  {
390
12.7k
    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
391
12.7k
    if (q == (Quantum *) NULL)
392
0
      break;
393
12.7k
    bit=0;
394
12.7k
    byte=0;
395
707k
    for (x=0; x < (ssize_t) image->columns; x++)
396
694k
    {
397
694k
      if (bit == 0)
398
93.1k
        byte=(unsigned int) (*p++);
399
694k
      SetPixelIndex(image,(Quantum) ((byte & 0x01) != 0 ? 0x01 : 0x00),q);
400
694k
      bit++;
401
694k
      byte>>=1;
402
694k
      if (bit == 8)
403
83.0k
        bit=0;
404
694k
      q+=(ptrdiff_t) GetPixelChannels(image);
405
694k
    }
406
12.7k
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
407
0
      break;
408
12.7k
    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
409
12.7k
      image->rows);
410
12.7k
    if (status == MagickFalse)
411
0
      break;
412
12.7k
  }
413
358
  data=(unsigned char *) RelinquishMagickMemory(data);
414
358
  (void) SyncImage(image,exception);
415
358
  if (CloseBlob(image) == MagickFalse)
416
0
    status=MagickFalse;
417
358
  if (status == MagickFalse)
418
0
    return(DestroyImageList(image));
419
358
  return(GetFirstImageInList(image));
420
358
}
421

422
/*
423
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424
%                                                                             %
425
%                                                                             %
426
%                                                                             %
427
%   R e g i s t e r X B M I m a g e                                           %
428
%                                                                             %
429
%                                                                             %
430
%                                                                             %
431
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432
%
433
%  RegisterXBMImage() adds attributes for the XBM image format to
434
%  the list of supported formats.  The attributes include the image format
435
%  tag, a method to read and/or write the format, whether the format
436
%  supports the saving of more than one frame to the same file or blob,
437
%  whether the format supports native in-memory I/O, and a brief
438
%  description of the format.
439
%
440
%  The format of the RegisterXBMImage method is:
441
%
442
%      size_t RegisterXBMImage(void)
443
%
444
*/
445
ModuleExport size_t RegisterXBMImage(void)
446
9
{
447
9
  MagickInfo
448
9
    *entry;
449
450
9
  entry=AcquireMagickInfo("XBM","XBM",
451
9
    "X Windows system bitmap (black and white)");
452
9
  entry->decoder=(DecodeImageHandler *) ReadXBMImage;
453
9
  entry->encoder=(EncodeImageHandler *) WriteXBMImage;
454
9
  entry->magick=(IsImageFormatHandler *) IsXBM;
455
9
  entry->flags|=CoderDecoderSeekableStreamFlag;
456
9
  entry->flags^=CoderAdjoinFlag;
457
9
  (void) RegisterMagickInfo(entry);
458
9
  return(MagickImageCoderSignature);
459
9
}
460

461
/*
462
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
463
%                                                                             %
464
%                                                                             %
465
%                                                                             %
466
%   U n r e g i s t e r X B M I m a g e                                       %
467
%                                                                             %
468
%                                                                             %
469
%                                                                             %
470
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
471
%
472
%  UnregisterXBMImage() removes format registrations made by the
473
%  XBM module from the list of supported formats.
474
%
475
%  The format of the UnregisterXBMImage method is:
476
%
477
%      UnregisterXBMImage(void)
478
%
479
*/
480
ModuleExport void UnregisterXBMImage(void)
481
0
{
482
0
  (void) UnregisterMagickInfo("XBM");
483
0
}
484

485
/*
486
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
487
%                                                                             %
488
%                                                                             %
489
%                                                                             %
490
%   W r i t e X B M I m a g e                                                 %
491
%                                                                             %
492
%                                                                             %
493
%                                                                             %
494
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
495
%
496
%  WriteXBMImage() writes an image to a file in the X bitmap format.
497
%
498
%  The format of the WriteXBMImage method is:
499
%
500
%      MagickBooleanType WriteXBMImage(const ImageInfo *image_info,
501
%        Image *image,ExceptionInfo *exception)
502
%
503
%  A description of each parameter follows.
504
%
505
%    o image_info: the image info.
506
%
507
%    o image:  The image.
508
%
509
%    o exception: return any errors or warnings in this structure.
510
%
511
*/
512
static MagickBooleanType WriteXBMImage(const ImageInfo *image_info,Image *image,
513
  ExceptionInfo *exception)
514
358
{
515
358
  char
516
358
    basename[MagickPathExtent],
517
358
    buffer[MagickPathExtent];
518
519
358
  MagickBooleanType
520
358
    status;
521
522
358
  const Quantum
523
358
    *p;
524
525
358
  ssize_t
526
358
    x;
527
528
358
  size_t
529
358
    bit,
530
358
    byte;
531
532
358
  ssize_t
533
358
    count,
534
358
    y;
535
536
  /*
537
    Open output image file.
538
  */
539
358
  assert(image_info != (const ImageInfo *) NULL);
540
358
  assert(image_info->signature == MagickCoreSignature);
541
358
  assert(image != (Image *) NULL);
542
358
  assert(image->signature == MagickCoreSignature);
543
358
  assert(exception != (ExceptionInfo *) NULL);
544
358
  assert(exception->signature == MagickCoreSignature);
545
358
  if (image->debug != MagickFalse)
546
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
547
358
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
548
358
  if (status == MagickFalse)
549
0
    return(status);
550
358
  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
551
0
    (void) TransformImageColorspace(image,sRGBColorspace,exception);
552
  /*
553
    Write X bitmap header.
554
  */
555
358
  GetPathComponent(image->filename,BasePath,basename);
556
358
  (void) FormatLocaleString(buffer,MagickPathExtent,"#define %s_width %.20g\n",
557
358
    basename,(double) image->columns);
558
358
  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
559
358
  (void) FormatLocaleString(buffer,MagickPathExtent,"#define %s_height %.20g\n",
560
358
    basename,(double) image->rows);
561
358
  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
562
358
  (void) FormatLocaleString(buffer,MagickPathExtent,
563
358
    "static char %s_bits[] = {\n",basename);
564
358
  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
565
358
  (void) CopyMagickString(buffer," ",MagickPathExtent);
566
358
  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
567
  /*
568
    Convert MIFF to X bitmap pixels.
569
  */
570
358
  (void) SetImageType(image,BilevelType,exception);
571
358
  bit=0;
572
358
  byte=0;
573
358
  count=0;
574
358
  x=0;
575
358
  y=0;
576
358
  (void) CopyMagickString(buffer," ",MagickPathExtent);
577
358
  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
578
13.0k
  for (y=0; y < (ssize_t) image->rows; y++)
579
12.7k
  {
580
12.7k
    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
581
12.7k
    if (p == (const Quantum *) NULL)
582
0
      break;
583
707k
    for (x=0; x < (ssize_t) image->columns; x++)
584
694k
    {
585
694k
      byte>>=1;
586
694k
      if (GetPixelLuma(image,p) < ((double) QuantumRange/2))
587
121k
        byte|=0x80;
588
694k
      bit++;
589
694k
      if (bit == 8)
590
83.0k
        {
591
          /*
592
            Write a bitmap byte to the image file.
593
          */
594
83.0k
          (void) FormatLocaleString(buffer,MagickPathExtent,"0x%02X, ",
595
83.0k
            (unsigned int) (byte & 0xff));
596
83.0k
          (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
597
83.0k
          count++;
598
83.0k
          if (count == 12)
599
6.16k
            {
600
6.16k
              (void) CopyMagickString(buffer,"\n  ",MagickPathExtent);
601
6.16k
              (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
602
6.16k
              count=0;
603
6.16k
            };
604
83.0k
          bit=0;
605
83.0k
          byte=0;
606
83.0k
        }
607
694k
      p+=(ptrdiff_t) GetPixelChannels(image);
608
694k
    }
609
12.7k
    if (bit != 0)
610
10.1k
      {
611
        /*
612
          Write a bitmap byte to the image file.
613
        */
614
10.1k
        byte>>=(8-bit);
615
10.1k
        (void) FormatLocaleString(buffer,MagickPathExtent,"0x%02X, ",
616
10.1k
          (unsigned int) (byte & 0xff));
617
10.1k
        (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
618
10.1k
        count++;
619
10.1k
        if (count == 12)
620
1.47k
          {
621
1.47k
            (void) CopyMagickString(buffer,"\n  ",MagickPathExtent);
622
1.47k
            (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
623
1.47k
            count=0;
624
1.47k
          };
625
10.1k
        bit=0;
626
10.1k
        byte=0;
627
10.1k
      };
628
12.7k
    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
629
12.7k
      image->rows);
630
12.7k
    if (status == MagickFalse)
631
0
      break;
632
12.7k
  }
633
358
  (void) CopyMagickString(buffer,"};\n",MagickPathExtent);
634
358
  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
635
358
  if (CloseBlob(image) == MagickFalse)
636
0
    status=MagickFalse;
637
358
  return(status);
638
358
}