2
% Copyright (C) 2003 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
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.
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21
% Read/Write X Windows System Bitmap Format. %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38
#include "magick/studio.h"
39
#include "magick/blob.h"
40
#include "magick/cache.h"
41
#include "magick/magick.h"
42
#include "magick/monitor.h"
43
#include "magick/utility.h"
49
WriteXBMImage(const ImageInfo *,Image *);
52
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62
% Method IsXBM returns True if the image format type, identified by the
63
% magick string, is XBM.
65
% The format of the IsXBM method is:
67
% unsigned int IsXBM(const unsigned char *magick,const size_t length)
69
% A description of each parameter follows:
71
% o status: Method IsXBM returns True if the image format type is XBM.
73
% o magick: This string is generally the first few bytes of an image file
76
% o length: Specifies the length of the magick string.
80
static unsigned int IsXBM(const unsigned char *magick,const size_t length)
84
if (LocaleNCompare((char *) magick,"#define",7) == 0)
90
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94
% R e a d X B M I m a g e %
98
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100
% Method ReadXBMImage reads an X11 bitmap image file and returns it. It
101
% allocates the memory necessary for the new Image structure and returns a
102
% pointer to the new image.
104
% The format of the ReadXBMImage method is:
106
% Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
108
% A description of each parameter follows:
110
% o image: Method ReadXBMImage returns a pointer to the image after
111
% reading. A null image is returned if there is a memory shortage or
112
% if the image cannot be read.
114
% o image_info: Specifies a pointer to a ImageInfo structure.
116
% o exception: return any errors or warnings in this structure.
121
static int XBMInteger(Image *image,short int *hex_digits)
132
c=ReadBlobByte(image);
141
value=(value << 4)+hex_digits[c];
145
if ((hex_digits[c]) < 0 && flag)
151
static Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
154
buffer[MaxTextExtent],
176
register unsigned char
198
assert(image_info != (const ImageInfo *) NULL);
199
assert(image_info->signature == MagickSignature);
200
assert(exception != (ExceptionInfo *) NULL);
201
assert(exception->signature == MagickSignature);
202
image=AllocateImage(image_info);
203
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
205
ThrowReaderException(FileOpenError,UnableToOpenFile,image);
207
Read X bitmap header.
209
while (ReadBlobString(image,buffer) != (char *) NULL)
210
if (sscanf(buffer,"#define %s %lu",name,&image->columns) == 2)
211
if ((strlen(name) >= 6) &&
212
(LocaleCompare(name+strlen(name)-6,"_width") == 0))
214
while (ReadBlobString(image,buffer) != (char *) NULL)
215
if (sscanf(buffer,"#define %s %lu",name,&image->rows) == 2)
216
if ((strlen(name) >= 7) &&
217
(LocaleCompare(name+strlen(name)-7,"_height") == 0))
220
image->storage_class=PseudoClass;
223
Scan until hex digits.
226
while (ReadBlobString(image,buffer) != (char *) NULL)
228
if (sscanf(buffer,"static short %s = {",name) == 1)
231
if (sscanf(buffer,"static unsigned char %s = {",name) == 1)
234
if (sscanf(buffer,"static char %s = {",name) == 1)
238
p=(unsigned char *) strrchr(name,'_');
239
if (p == (unsigned char *) NULL)
240
p=(unsigned char *) name;
243
if (LocaleCompare("bits[]",(char *) p) == 0)
246
if ((image->columns == 0) || (image->rows == 0) || EOFBlob(image))
247
ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
249
Initialize image structure.
251
if (!AllocateImageColormap(image,image->colors))
252
ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
254
if ((image->columns % 16) && ((image->columns % 16) < 9) && (version == 10))
256
bytes_per_line=(image->columns+7)/8+padding;
257
data=MagickAllocateMemory(unsigned char *,bytes_per_line*image->rows);
258
if (data == (unsigned char *) NULL)
259
ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
263
image->colormap[0].red=MaxRGB;
264
image->colormap[0].green=MaxRGB;
265
image->colormap[0].blue=MaxRGB;
266
image->colormap[1].red=0;
267
image->colormap[1].green=0;
268
image->colormap[1].blue=0;
269
if (image_info->ping)
275
Initialize hex values.
300
hex_digits[' ']=(-1);
301
hex_digits[',']=(-1);
302
hex_digits['}']=(-1);
303
hex_digits['\n']=(-1);
304
hex_digits['\t']=(-1);
310
for (i=0; i < (long) (bytes_per_line*image->rows); (i+=2))
312
value=XBMInteger(image,hex_digits);
313
*p++=(unsigned char) value;
314
if (!padding || ((i+2) % bytes_per_line))
315
*p++=(unsigned char) (value >> 8);
318
for (i=0; i < (long) (bytes_per_line*image->rows); i++)
320
value=XBMInteger(image,hex_digits);
321
*p++=(unsigned char) value;
324
Convert X bitmap image to pixel packets.
327
for (y=0; y < (long) image->rows; y++)
329
q=SetImagePixels(image,0,y,image->columns,1);
330
if (q == (PixelPacket *) NULL)
332
indexes=GetIndexes(image);
335
for (x=0; x < (long) image->columns; x++)
339
indexes[x]=byte & 0x01 ? 0x01 : 0x00;
345
if (!SyncImagePixels(image))
347
if (QuantumTick(y,image->rows))
348
if (!MagickMonitor(LoadImageText,y,image->rows,exception))
351
MagickFreeMemory(data);
358
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
362
% R e g i s t e r X B M I m a g e %
366
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368
% Method RegisterXBMImage adds attributes for the XBM image format to
369
% the list of supported formats. The attributes include the image format
370
% tag, a method to read and/or write the format, whether the format
371
% supports the saving of more than one frame to the same file or blob,
372
% whether the format supports native in-memory I/O, and a brief
373
% description of the format.
375
% The format of the RegisterXBMImage method is:
377
% RegisterXBMImage(void)
380
ModuleExport void RegisterXBMImage(void)
385
entry=SetMagickInfo("XBM");
386
entry->decoder=(DecoderHandler) ReadXBMImage;
387
entry->encoder=(EncoderHandler) WriteXBMImage;
388
entry->magick=(MagickHandler) IsXBM;
391
AcquireString("X Windows system bitmap (black and white)");
392
entry->module=AcquireString("XBM");
393
(void) RegisterMagickInfo(entry);
397
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401
% U n r e g i s t e r X B M I m a g e %
405
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407
% Method UnregisterXBMImage removes format registrations made by the
408
% XBM module from the list of supported formats.
410
% The format of the UnregisterXBMImage method is:
412
% UnregisterXBMImage(void)
415
ModuleExport void UnregisterXBMImage(void)
417
(void) UnregisterMagickInfo("XBM");
421
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
425
% W r i t e X B M I m a g e %
429
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431
% Procedure WriteXBMImage writes an image to a file in the X bitmap format.
433
% The format of the WriteXBMImage method is:
435
% unsigned int WriteXBMImage(const ImageInfo *image_info,Image *image)
437
% A description of each parameter follows.
439
% o status: Method WriteXBMImage return True if the image is written.
440
% False is returned is there is a memory shortage or if the image file
443
% o image_info: Specifies a pointer to a ImageInfo structure.
445
% o image: A pointer to an Image structure.
449
static unsigned int WriteXBMImage(const ImageInfo *image_info,Image *image)
452
basename[MaxTextExtent],
453
buffer[MaxTextExtent];
458
register const PixelPacket
479
Open output image file.
481
assert(image_info != (const ImageInfo *) NULL);
482
assert(image_info->signature == MagickSignature);
483
assert(image != (Image *) NULL);
484
assert(image->signature == MagickSignature);
485
status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
487
ThrowWriterException(FileOpenError,UnableToOpenFile,image);
488
TransformColorspace(image,RGBColorspace);
490
Write X bitmap header.
492
GetPathComponent(image->filename,BasePath,basename);
493
FormatString(buffer,"#define %.1024s_width %lu\n",basename,image->columns);
494
(void) WriteBlob(image,strlen(buffer),buffer);
495
FormatString(buffer,"#define %.1024s_height %lu\n",basename,image->rows);
496
(void) WriteBlob(image,strlen(buffer),buffer);
497
FormatString(buffer,"static char %.1024s_bits[] = {\n",basename);
498
(void) WriteBlob(image,strlen(buffer),buffer);
499
(void) strcpy(buffer," ");
500
(void) WriteBlob(image,strlen(buffer),buffer);
502
Convert MIFF to X bitmap pixels.
504
SetImageType(image,BilevelType);
505
polarity=(PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2));
506
if (image->colors == 2)
507
polarity=(PixelIntensityToQuantum(&image->colormap[0]) <
508
PixelIntensityToQuantum(&image->colormap[1]));
514
(void) strcpy(buffer," ");
515
(void) WriteBlob(image,strlen(buffer),buffer);
516
for (y=0; y < (long) image->rows; y++)
518
p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
519
if (p == (const PixelPacket *) NULL)
521
indexes=GetIndexes(image);
522
for (x=0; x < (long) image->columns; x++)
525
if (indexes[x] != polarity)
531
Write a bitmap byte to the image file.
533
FormatString(buffer,"0x%02X, ",(unsigned int) (byte & 0xff));
534
(void) WriteBlob(image,strlen(buffer),buffer);
538
(void) strcpy(buffer,"\n ");
539
(void) WriteBlob(image,strlen(buffer),buffer);
550
Write a bitmap byte to the image file.
553
FormatString(buffer,"0x%02X, ",(unsigned int) (byte & 0xff));
554
(void) WriteBlob(image,strlen(buffer),buffer);
558
(void) strcpy(buffer,"\n ");
559
(void) WriteBlob(image,strlen(buffer),buffer);
565
if (QuantumTick(y,image->rows))
566
if (!MagickMonitor(SaveImageText,y,image->rows,&image->exception))
569
(void) strcpy(buffer,"};\n");
570
(void) WriteBlob(image,strlen(buffer),buffer);