~ubuntu-branches/ubuntu/intrepid/graphicsmagick/intrepid

« back to all changes in this revision

Viewing changes to coders/xbm.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2006-05-06 16:28:08 UTC
  • Revision ID: james.westby@ubuntu.com-20060506162808-vt2ni3r5nytcszms
Tags: upstream-1.1.7
ImportĀ upstreamĀ versionĀ 1.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
% Copyright (C) 2003 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
%                            X   X  BBBB   M   M                              %
 
15
%                             X X   B   B  MM MM                              %
 
16
%                              X    BBBB   M M M                              %
 
17
%                             X X   B   B  M   M                              %
 
18
%                            X   X  BBBB   M   M                              %
 
19
%                                                                             %
 
20
%                                                                             %
 
21
%                 Read/Write X Windows System 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/cache.h"
 
41
#include "magick/magick.h"
 
42
#include "magick/monitor.h"
 
43
#include "magick/utility.h"
 
44
 
 
45
/*
 
46
  Forward declarations.
 
47
*/
 
48
static unsigned int
 
49
  WriteXBMImage(const ImageInfo *,Image *);
 
50
 
 
51
/*
 
52
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
53
%                                                                             %
 
54
%                                                                             %
 
55
%                                                                             %
 
56
%   I s X B M                                                                 %
 
57
%                                                                             %
 
58
%                                                                             %
 
59
%                                                                             %
 
60
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
61
%
 
62
%  Method IsXBM returns True if the image format type, identified by the
 
63
%  magick string, is XBM.
 
64
%
 
65
%  The format of the IsXBM method is:
 
66
%
 
67
%      unsigned int IsXBM(const unsigned char *magick,const size_t length)
 
68
%
 
69
%  A description of each parameter follows:
 
70
%
 
71
%    o status:  Method IsXBM returns True if the image format type is XBM.
 
72
%
 
73
%    o magick: This string is generally the first few bytes of an image file
 
74
%      or blob.
 
75
%
 
76
%    o length: Specifies the length of the magick string.
 
77
%
 
78
%
 
79
*/
 
80
static unsigned int IsXBM(const unsigned char *magick,const size_t length)
 
81
{
 
82
  if (length < 7)
 
83
    return(False);
 
84
  if (LocaleNCompare((char *) magick,"#define",7) == 0)
 
85
    return(True);
 
86
  return(False);
 
87
}
 
88
 
 
89
/*
 
90
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
91
%                                                                             %
 
92
%                                                                             %
 
93
%                                                                             %
 
94
%   R e a d X B M I m a g e                                                   %
 
95
%                                                                             %
 
96
%                                                                             %
 
97
%                                                                             %
 
98
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
99
%
 
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.
 
103
%
 
104
%  The format of the ReadXBMImage method is:
 
105
%
 
106
%      Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
 
107
%
 
108
%  A description of each parameter follows:
 
109
%
 
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.
 
113
%
 
114
%    o image_info: Specifies a pointer to a ImageInfo structure.
 
115
%
 
116
%    o exception: return any errors or warnings in this structure.
 
117
%
 
118
%
 
119
*/
 
120
 
 
121
static int XBMInteger(Image *image,short int *hex_digits)
 
122
{
 
123
  int
 
124
    c,
 
125
    flag,
 
126
    value;
 
127
 
 
128
  value=0;
 
129
  flag=0;
 
130
  for ( ; ; )
 
131
  {
 
132
    c=ReadBlobByte(image);
 
133
    if (c == EOF)
 
134
      {
 
135
        value=(-1);
 
136
        break;
 
137
      }
 
138
    c&=0xff;
 
139
    if (isxdigit(c))
 
140
      {
 
141
        value=(value << 4)+hex_digits[c];
 
142
        flag++;
 
143
        continue;
 
144
      }
 
145
    if ((hex_digits[c]) < 0 && flag)
 
146
      break;
 
147
  }
 
148
  return(value);
 
149
}
 
150
 
 
151
static Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
 
152
{
 
153
  char
 
154
    buffer[MaxTextExtent],
 
155
    name[MaxTextExtent];
 
156
 
 
157
  Image
 
158
    *image;
 
159
 
 
160
  int
 
161
    bit;
 
162
 
 
163
  long
 
164
    y;
 
165
 
 
166
  register IndexPacket
 
167
    *indexes;
 
168
 
 
169
  register long
 
170
    i,
 
171
    x;
 
172
 
 
173
  register PixelPacket
 
174
    *q;
 
175
 
 
176
  register unsigned char
 
177
    *p;
 
178
 
 
179
  short int
 
180
    hex_digits[256];
 
181
 
 
182
  unsigned char
 
183
    *data;
 
184
 
 
185
  unsigned int
 
186
    status;
 
187
 
 
188
  unsigned long
 
189
    byte,
 
190
    bytes_per_line,
 
191
    padding,
 
192
    value,
 
193
    version;
 
194
 
 
195
  /*
 
196
    Open image file.
 
197
  */
 
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);
 
204
  if (status == False)
 
205
    ThrowReaderException(FileOpenError,UnableToOpenFile,image);
 
206
  /*
 
207
    Read X bitmap header.
 
208
  */
 
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))
 
213
          break;
 
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))
 
218
          break;
 
219
  image->depth=8;
 
220
  image->storage_class=PseudoClass;
 
221
  image->colors=2;
 
222
  /*
 
223
    Scan until hex digits.
 
224
  */
 
225
  version=11;
 
226
  while (ReadBlobString(image,buffer) != (char *) NULL)
 
227
  {
 
228
    if (sscanf(buffer,"static short %s = {",name) == 1)
 
229
      version=10;
 
230
    else
 
231
      if (sscanf(buffer,"static unsigned char %s = {",name) == 1)
 
232
        version=11;
 
233
      else
 
234
        if (sscanf(buffer,"static char %s = {",name) == 1)
 
235
          version=11;
 
236
        else
 
237
          continue;
 
238
    p=(unsigned char *) strrchr(name,'_');
 
239
    if (p == (unsigned char *) NULL)
 
240
      p=(unsigned char *) name;
 
241
    else
 
242
      p++;
 
243
    if (LocaleCompare("bits[]",(char *) p) == 0)
 
244
      break;
 
245
  }
 
246
  if ((image->columns == 0) || (image->rows == 0) || EOFBlob(image))
 
247
    ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
 
248
  /*
 
249
    Initialize image structure.
 
250
  */
 
251
  if (!AllocateImageColormap(image,image->colors))
 
252
    ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
 
253
  padding=0;
 
254
  if ((image->columns % 16) && ((image->columns % 16) < 9)  && (version == 10))
 
255
    padding=1;
 
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);
 
260
  /*
 
261
    Initialize colormap.
 
262
  */
 
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)
 
270
    {
 
271
      CloseBlob(image);
 
272
      return(image);
 
273
    }
 
274
  /*
 
275
    Initialize hex values.
 
276
  */
 
277
  hex_digits['0']=0;
 
278
  hex_digits['1']=1;
 
279
  hex_digits['2']=2;
 
280
  hex_digits['3']=3;
 
281
  hex_digits['4']=4;
 
282
  hex_digits['5']=5;
 
283
  hex_digits['6']=6;
 
284
  hex_digits['7']=7;
 
285
  hex_digits['8']=8;
 
286
  hex_digits['9']=9;
 
287
  hex_digits['A']=10;
 
288
  hex_digits['B']=11;
 
289
  hex_digits['C']=12;
 
290
  hex_digits['D']=13;
 
291
  hex_digits['E']=14;
 
292
  hex_digits['F']=15;
 
293
  hex_digits['a']=10;
 
294
  hex_digits['b']=11;
 
295
  hex_digits['c']=12;
 
296
  hex_digits['d']=13;
 
297
  hex_digits['e']=14;
 
298
  hex_digits['f']=15;
 
299
  hex_digits['x']=0;
 
300
  hex_digits[' ']=(-1);
 
301
  hex_digits[',']=(-1);
 
302
  hex_digits['}']=(-1);
 
303
  hex_digits['\n']=(-1);
 
304
  hex_digits['\t']=(-1);
 
305
  /*
 
306
    Read hex image data.
 
307
  */
 
308
  p=data;
 
309
  if (version == 10)
 
310
    for (i=0; i < (long) (bytes_per_line*image->rows); (i+=2))
 
311
    {
 
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);
 
316
    }
 
317
  else
 
318
    for (i=0; i < (long) (bytes_per_line*image->rows); i++)
 
319
    {
 
320
      value=XBMInteger(image,hex_digits);
 
321
      *p++=(unsigned char) value;
 
322
    }
 
323
  /*
 
324
    Convert X bitmap image to pixel packets.
 
325
  */
 
326
  p=data;
 
327
  for (y=0; y < (long) image->rows; y++)
 
328
  {
 
329
    q=SetImagePixels(image,0,y,image->columns,1);
 
330
    if (q == (PixelPacket *) NULL)
 
331
      break;
 
332
    indexes=GetIndexes(image);
 
333
    bit=0;
 
334
    byte=0;
 
335
    for (x=0; x < (long) image->columns; x++)
 
336
    {
 
337
      if (bit == 0)
 
338
        byte=(*p++);
 
339
      indexes[x]=byte & 0x01 ? 0x01 : 0x00;
 
340
      bit++;
 
341
      byte>>=1;
 
342
      if (bit == 8)
 
343
        bit=0;
 
344
    }
 
345
    if (!SyncImagePixels(image))
 
346
      break;
 
347
    if (QuantumTick(y,image->rows))
 
348
       if (!MagickMonitor(LoadImageText,y,image->rows,exception))
 
349
         break;
 
350
  }
 
351
  MagickFreeMemory(data);
 
352
  SyncImage(image);
 
353
  CloseBlob(image);
 
354
  return(image);
 
355
}
 
356
 
 
357
/*
 
358
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
359
%                                                                             %
 
360
%                                                                             %
 
361
%                                                                             %
 
362
%   R e g i s t e r X B M I m a g e                                           %
 
363
%                                                                             %
 
364
%                                                                             %
 
365
%                                                                             %
 
366
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
367
%
 
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.
 
374
%
 
375
%  The format of the RegisterXBMImage method is:
 
376
%
 
377
%      RegisterXBMImage(void)
 
378
%
 
379
*/
 
380
ModuleExport void RegisterXBMImage(void)
 
381
{
 
382
  MagickInfo
 
383
    *entry;
 
384
 
 
385
  entry=SetMagickInfo("XBM");
 
386
  entry->decoder=(DecoderHandler) ReadXBMImage;
 
387
  entry->encoder=(EncoderHandler) WriteXBMImage;
 
388
  entry->magick=(MagickHandler) IsXBM;
 
389
  entry->adjoin=False;
 
390
  entry->description=
 
391
    AcquireString("X Windows system bitmap (black and white)");
 
392
  entry->module=AcquireString("XBM");
 
393
  (void) RegisterMagickInfo(entry);
 
394
}
 
395
 
 
396
/*
 
397
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
398
%                                                                             %
 
399
%                                                                             %
 
400
%                                                                             %
 
401
%   U n r e g i s t e r X B M I m a g e                                       %
 
402
%                                                                             %
 
403
%                                                                             %
 
404
%                                                                             %
 
405
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
406
%
 
407
%  Method UnregisterXBMImage removes format registrations made by the
 
408
%  XBM module from the list of supported formats.
 
409
%
 
410
%  The format of the UnregisterXBMImage method is:
 
411
%
 
412
%      UnregisterXBMImage(void)
 
413
%
 
414
*/
 
415
ModuleExport void UnregisterXBMImage(void)
 
416
{
 
417
  (void) UnregisterMagickInfo("XBM");
 
418
}
 
419
 
 
420
/*
 
421
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
422
%                                                                             %
 
423
%                                                                             %
 
424
%                                                                             %
 
425
%   W r i t e X B M I m a g e                                                 %
 
426
%                                                                             %
 
427
%                                                                             %
 
428
%                                                                             %
 
429
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
430
%
 
431
%  Procedure WriteXBMImage writes an image to a file in the X bitmap format.
 
432
%
 
433
%  The format of the WriteXBMImage method is:
 
434
%
 
435
%      unsigned int WriteXBMImage(const ImageInfo *image_info,Image *image)
 
436
%
 
437
%  A description of each parameter follows.
 
438
%
 
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
 
441
%      fails to write.
 
442
%
 
443
%    o image_info: Specifies a pointer to a ImageInfo structure.
 
444
%
 
445
%    o image:  A pointer to an Image structure.
 
446
%
 
447
%
 
448
*/
 
449
static unsigned int WriteXBMImage(const ImageInfo *image_info,Image *image)
 
450
{
 
451
  char
 
452
    basename[MaxTextExtent],
 
453
    buffer[MaxTextExtent];
 
454
 
 
455
  int
 
456
    y;
 
457
 
 
458
  register const PixelPacket
 
459
    *p;
 
460
 
 
461
  register long
 
462
    x;
 
463
 
 
464
  register IndexPacket
 
465
    *indexes;
 
466
 
 
467
  unsigned char
 
468
    bit,
 
469
    byte,
 
470
    polarity;
 
471
 
 
472
  unsigned int
 
473
    status;
 
474
 
 
475
  unsigned long
 
476
    count;
 
477
 
 
478
  /*
 
479
    Open output image file.
 
480
  */
 
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);
 
486
  if (status == False)
 
487
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
 
488
  TransformColorspace(image,RGBColorspace);
 
489
  /*
 
490
    Write X bitmap header.
 
491
  */
 
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);
 
501
  /*
 
502
    Convert MIFF to X bitmap pixels.
 
503
  */
 
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]));
 
509
  bit=0;
 
510
  byte=0;
 
511
  count=0;
 
512
  x=0;
 
513
  y=0;
 
514
  (void) strcpy(buffer," ");
 
515
  (void) WriteBlob(image,strlen(buffer),buffer);
 
516
  for (y=0; y < (long) image->rows; y++)
 
517
  {
 
518
    p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
 
519
    if (p == (const PixelPacket *) NULL)
 
520
      break;
 
521
    indexes=GetIndexes(image);
 
522
    for (x=0; x < (long) image->columns; x++)
 
523
    {
 
524
      byte>>=1;
 
525
      if (indexes[x] != polarity)
 
526
        byte|=0x80;
 
527
      bit++;
 
528
      if (bit == 8)
 
529
        {
 
530
          /*
 
531
            Write a bitmap byte to the image file.
 
532
          */
 
533
          FormatString(buffer,"0x%02X, ",(unsigned int) (byte & 0xff));
 
534
          (void) WriteBlob(image,strlen(buffer),buffer);
 
535
          count++;
 
536
          if (count == 12)
 
537
            {
 
538
              (void) strcpy(buffer,"\n  ");
 
539
              (void) WriteBlob(image,strlen(buffer),buffer);
 
540
              count=0;
 
541
            };
 
542
          bit=0;
 
543
          byte=0;
 
544
        }
 
545
        p++;
 
546
      }
 
547
    if (bit != 0)
 
548
      {
 
549
        /*
 
550
          Write a bitmap byte to the image file.
 
551
        */
 
552
        byte>>=(8-bit);
 
553
        FormatString(buffer,"0x%02X, ",(unsigned int) (byte & 0xff));
 
554
        (void) WriteBlob(image,strlen(buffer),buffer);
 
555
        count++;
 
556
        if (count == 12)
 
557
          {
 
558
            (void) strcpy(buffer,"\n  ");
 
559
            (void) WriteBlob(image,strlen(buffer),buffer);
 
560
            count=0;
 
561
          };
 
562
        bit=0;
 
563
        byte=0;
 
564
      };
 
565
    if (QuantumTick(y,image->rows))
 
566
      if (!MagickMonitor(SaveImageText,y,image->rows,&image->exception))
 
567
        break;
 
568
  }
 
569
  (void) strcpy(buffer,"};\n");
 
570
  (void) WriteBlob(image,strlen(buffer),buffer);
 
571
  CloseBlob(image);
 
572
  return(True);
 
573
}