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

« back to all changes in this revision

Viewing changes to coders/jbig.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
%                        JJJJJ  BBBB   IIIII   GGGG                           %
 
15
%                          J    B   B    I    G                               %
 
16
%                          J    BBBB     I    G  GG                           %
 
17
%                        J J    B   B    I    G   G                           %
 
18
%                        JJJ    BBBB   IIIII   GGG                            %
 
19
%                                                                             %
 
20
%                                                                             %
 
21
%                       Read/Write JBIG Image 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
#if defined(HasJBIG)
 
49
static unsigned int
 
50
  WriteJBIGImage(const ImageInfo *,Image *);
 
51
#endif
 
52
 
 
53
#if defined(HasJBIG)
 
54
#include "jbig.h"
 
55
/*
 
56
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
57
%                                                                             %
 
58
%                                                                             %
 
59
%                                                                             %
 
60
%   R e a d J B I G I m a g e                                                 %
 
61
%                                                                             %
 
62
%                                                                             %
 
63
%                                                                             %
 
64
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
65
%
 
66
%  Method ReadJBIGImage reads a JBIG image file and returns it.  It
 
67
%  allocates the memory necessary for the new Image structure and returns a
 
68
%  pointer to the new image.
 
69
%
 
70
%  The format of the ReadJBIGImage method is:
 
71
%
 
72
%      Image *ReadJBIGImage(const ImageInfo *image_info,
 
73
%        ExceptionInfo *exception)
 
74
%
 
75
%  A description of each parameter follows:
 
76
%
 
77
%    o image:  Method ReadJBIGImage returns a pointer to the image after
 
78
%      reading.  A null image is returned if there is a memory shortage or
 
79
%      if the image cannot be read.
 
80
%
 
81
%    o image_info: Specifies a pointer to a ImageInfo structure.
 
82
%
 
83
%    o exception: return any errors or warnings in this structure.
 
84
%
 
85
%
 
86
*/
 
87
static Image *ReadJBIGImage(const ImageInfo *image_info,
 
88
  ExceptionInfo *exception)
 
89
{
 
90
#define MaxBufferSize  8192
 
91
 
 
92
  Image
 
93
    *image;
 
94
 
 
95
  IndexPacket
 
96
    index;
 
97
 
 
98
  int
 
99
    status;
 
100
 
 
101
  long
 
102
    length,
 
103
    y;
 
104
 
 
105
  register IndexPacket
 
106
    *indexes;
 
107
 
 
108
  register long
 
109
    x;
 
110
 
 
111
  register PixelPacket
 
112
    *q;
 
113
 
 
114
  register unsigned char
 
115
    *p;
 
116
 
 
117
  size_t
 
118
    count;
 
119
 
 
120
  struct jbg_dec_state
 
121
    jbig_info;
 
122
 
 
123
  unsigned char
 
124
    bit,
 
125
    *buffer;
 
126
 
 
127
  unsigned int
 
128
    byte;
 
129
 
 
130
  /*
 
131
    Open image file.
 
132
  */
 
133
  assert(image_info != (const ImageInfo *) NULL);
 
134
  assert(image_info->signature == MagickSignature);
 
135
  assert(exception != (ExceptionInfo *) NULL);
 
136
  assert(exception->signature == MagickSignature);
 
137
  image=AllocateImage(image_info);
 
138
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
 
139
  if (status == False)
 
140
    ThrowReaderException(FileOpenError,UnableToOpenFile,image);
 
141
  /*
 
142
    Initialize JBIG toolkit.
 
143
  */
 
144
  jbg_dec_init(&jbig_info);
 
145
  jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns,
 
146
    (unsigned long) image->rows);
 
147
  image->columns= jbg_dec_getwidth(&jbig_info);
 
148
  image->rows= jbg_dec_getheight(&jbig_info);
 
149
  image->depth=8;
 
150
  image->storage_class=PseudoClass;
 
151
  image->colors=2;
 
152
  /*
 
153
    Read JBIG file.
 
154
  */
 
155
  buffer=MagickAllocateMemory(unsigned char *,MaxBufferSize);
 
156
  if (buffer == (unsigned char *) NULL)
 
157
    ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
 
158
  status=JBG_EAGAIN;
 
159
  do
 
160
  {
 
161
    length=(long) ReadBlob(image,MaxBufferSize,(char *) buffer);
 
162
    if (length == 0)
 
163
      break;
 
164
    p=buffer;
 
165
    count=0;
 
166
    while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
 
167
    {
 
168
      status=jbg_dec_in(&jbig_info,p,length,&count);
 
169
      p+=count;
 
170
      length-=count;
 
171
    }
 
172
  } while ((status == JBG_EAGAIN) || (status == JBG_EOK));
 
173
  /*
 
174
    Create colormap.
 
175
  */
 
176
  image->columns=jbg_dec_getwidth(&jbig_info);
 
177
  image->rows=jbg_dec_getheight(&jbig_info);
 
178
  if (!AllocateImageColormap(image,2))
 
179
    {
 
180
      MagickFreeMemory(buffer);
 
181
      ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image)
 
182
    }
 
183
  image->colormap[0].red=0;
 
184
  image->colormap[0].green=0;
 
185
  image->colormap[0].blue=0;
 
186
  image->colormap[1].red=MaxRGB;
 
187
  image->colormap[1].green=MaxRGB;
 
188
  image->colormap[1].blue=MaxRGB;
 
189
  image->x_resolution=300;
 
190
  image->y_resolution=300;
 
191
  if (image_info->ping)
 
192
    {
 
193
      CloseBlob(image);
 
194
      return(image);
 
195
    }
 
196
  /*
 
197
    Convert X bitmap image to pixel packets.
 
198
  */
 
199
  p=jbg_dec_getimage(&jbig_info,0);
 
200
  for (y=0; y < (long) image->rows; y++)
 
201
  {
 
202
    q=SetImagePixels(image,0,y,image->columns,1);
 
203
    if (q == (PixelPacket *) NULL)
 
204
      break;
 
205
    indexes=GetIndexes(image);
 
206
    bit=0;
 
207
    byte=0;
 
208
    for (x=0; x < (long) image->columns; x++)
 
209
    {
 
210
      if (bit == 0)
 
211
        byte=(*p++);
 
212
      index=(byte & 0x80) ? 0 : 1;
 
213
      bit++;
 
214
      byte<<=1;
 
215
      if (bit == 8)
 
216
        bit=0;
 
217
      indexes[x]=index;
 
218
      *q++=image->colormap[index];
 
219
    }
 
220
    if (!SyncImagePixels(image))
 
221
      break;
 
222
    if (QuantumTick(y,image->rows))
 
223
      if (!MagickMonitor(LoadImageText,y,image->rows,exception))
 
224
        break;
 
225
  }
 
226
  /*
 
227
    Free scale resource.
 
228
  */
 
229
  jbg_dec_free(&jbig_info);
 
230
  MagickFreeMemory(buffer);
 
231
  CloseBlob(image);
 
232
  return(image);
 
233
}
 
234
#endif
 
235
 
 
236
/*
 
237
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
238
%                                                                             %
 
239
%                                                                             %
 
240
%                                                                             %
 
241
%   R e g i s t e r J B I G I m a g e                                         %
 
242
%                                                                             %
 
243
%                                                                             %
 
244
%                                                                             %
 
245
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
246
%
 
247
%  Method RegisterJBIGImage adds attributes for the JBIG image format to
 
248
%  the list of supported formats.  The attributes include the image format
 
249
%  tag, a method to read and/or write the format, whether the format
 
250
%  supports the saving of more than one frame to the same file or blob,
 
251
%  whether the format supports native in-memory I/O, and a brief
 
252
%  description of the format.
 
253
%
 
254
%  The format of the RegisterJBIGImage method is:
 
255
%
 
256
%      RegisterJBIGImage(void)
 
257
%
 
258
*/
 
259
ModuleExport void RegisterJBIGImage(void)
 
260
{
 
261
#define JBIGDescription  "Joint Bi-level Image experts Group interchange format"
 
262
 
 
263
  char
 
264
    version[MaxTextExtent];
 
265
 
 
266
  MagickInfo
 
267
    *entry;
 
268
 
 
269
  *version='\0';
 
270
#if defined(JBG_VERSION)
 
271
  (void) strncpy(version,JBG_VERSION,MaxTextExtent-1);
 
272
#endif
 
273
  entry=SetMagickInfo("BIE");
 
274
#if defined(HasJBIG)
 
275
  entry->decoder=(DecoderHandler) ReadJBIGImage;
 
276
  entry->encoder=(EncoderHandler) WriteJBIGImage;
 
277
#endif
 
278
  entry->adjoin=False;
 
279
  entry->description=AcquireString(JBIGDescription);
 
280
  if (*version != '\0')
 
281
    entry->version=AcquireString(version);
 
282
  entry->module=AcquireString("JBIG");
 
283
  (void) RegisterMagickInfo(entry);
 
284
  entry=SetMagickInfo("JBG");
 
285
#if defined(HasJBIG)
 
286
  entry->decoder=(DecoderHandler) ReadJBIGImage;
 
287
  entry->encoder=(EncoderHandler) WriteJBIGImage;
 
288
#endif
 
289
  entry->description=AcquireString(JBIGDescription);
 
290
  if (*version != '\0')
 
291
    entry->version=AcquireString(version);
 
292
  entry->module=AcquireString("JBIG");
 
293
  (void) RegisterMagickInfo(entry);
 
294
  entry=SetMagickInfo("JBIG");
 
295
#if defined(HasJBIG)
 
296
  entry->decoder=(DecoderHandler) ReadJBIGImage;
 
297
  entry->encoder=(EncoderHandler) WriteJBIGImage;
 
298
#endif
 
299
  entry->description=AcquireString(JBIGDescription);
 
300
  if (*version != '\0')
 
301
    entry->version=AcquireString(version);
 
302
  entry->module=AcquireString("JBIG");
 
303
  (void) RegisterMagickInfo(entry);
 
304
}
 
305
 
 
306
/*
 
307
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
308
%                                                                             %
 
309
%                                                                             %
 
310
%                                                                             %
 
311
%   U n r e g i s t e r J B I G I m a g e                                     %
 
312
%                                                                             %
 
313
%                                                                             %
 
314
%                                                                             %
 
315
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
316
%
 
317
%  Method UnregisterJBIGImage removes format registrations made by the
 
318
%  JBIG module from the list of supported formats.
 
319
%
 
320
%  The format of the UnregisterJBIGImage method is:
 
321
%
 
322
%      UnregisterJBIGImage(void)
 
323
%
 
324
*/
 
325
ModuleExport void UnregisterJBIGImage(void)
 
326
{
 
327
  (void) UnregisterMagickInfo("BIE");
 
328
  (void) UnregisterMagickInfo("JBG");
 
329
  (void) UnregisterMagickInfo("JBIG");
 
330
}
 
331
 
 
332
#if defined(HasJBIG)
 
333
/*
 
334
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
335
%                                                                             %
 
336
%                                                                             %
 
337
%                                                                             %
 
338
%   W r i t e J B I G I m a g e                                               %
 
339
%                                                                             %
 
340
%                                                                             %
 
341
%                                                                             %
 
342
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
343
%
 
344
%  Method WriteJBIGImage writes an image in the JBIG encoded image format.
 
345
%
 
346
%  The format of the WriteJBIGImage method is:
 
347
%
 
348
%      unsigned int WriteJBIGImage(const ImageInfo *image_info,Image *image)
 
349
%
 
350
%  A description of each parameter follows.
 
351
%
 
352
%    o status: Method WriteJBIGImage return True if the image is written.
 
353
%      False is returned is there is a memory shortage or if the image file
 
354
%      fails to write.
 
355
%
 
356
%    o image_info: Specifies a pointer to a ImageInfo structure.
 
357
%
 
358
%    o image:  A pointer to an Image structure.
 
359
%
 
360
%
 
361
*/
 
362
 
 
363
static void JBIGEncode(unsigned char *pixels,size_t length,void *data)
 
364
{
 
365
  Image
 
366
    *image;
 
367
 
 
368
  image=(Image *) data;
 
369
  (void) WriteBlob(image,length,pixels);
 
370
}
 
371
 
 
372
static unsigned int WriteJBIGImage(const ImageInfo *image_info,Image *image)
 
373
{
 
374
  double
 
375
    jbig_lib_version;
 
376
 
 
377
  long
 
378
    y;
 
379
 
 
380
  register const PixelPacket
 
381
    *p;
 
382
 
 
383
  register IndexPacket
 
384
    *indexes;
 
385
 
 
386
  register long
 
387
    x;
 
388
 
 
389
  register unsigned char
 
390
    *q;
 
391
 
 
392
  struct jbg_enc_state
 
393
    jbig_info;
 
394
 
 
395
  unsigned char
 
396
    bit,
 
397
    byte,
 
398
    *pixels,
 
399
    polarity;
 
400
 
 
401
  unsigned int
 
402
    status;
 
403
 
 
404
  unsigned long
 
405
    number_packets,
 
406
    scene;
 
407
 
 
408
  /*
 
409
    Open image file.
 
410
  */
 
411
  assert(image_info != (const ImageInfo *) NULL);
 
412
  assert(image_info->signature == MagickSignature);
 
413
  assert(image != (Image *) NULL);
 
414
  assert(image->signature == MagickSignature);
 
415
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
 
416
  if (status == False)
 
417
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
 
418
  jbig_lib_version=strtod(JBG_VERSION, (char **)NULL);
 
419
  scene=0;
 
420
  do
 
421
  {
 
422
    /*
 
423
      Allocate pixel data.
 
424
    */
 
425
    TransformColorspace(image,RGBColorspace);
 
426
    number_packets=((image->columns+7) >> 3)*image->rows;
 
427
    pixels=MagickAllocateMemory(unsigned char *,number_packets);
 
428
    if (pixels == (unsigned char *) NULL)
 
429
      ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
 
430
    /*
 
431
      Convert pixels to a bitmap.
 
432
    */
 
433
    SetImageType(image,BilevelType);
 
434
    polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
 
435
    if (image->colors == 2)
 
436
      polarity=PixelIntensityToQuantum(&image->colormap[0]) >
 
437
        PixelIntensityToQuantum(&image->colormap[1]);
 
438
    q=pixels;
 
439
    for (y=0; y < (long) image->rows; y++)
 
440
    {
 
441
      p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
 
442
      if (p == (const PixelPacket *) NULL)
 
443
        break;
 
444
      indexes=GetIndexes(image);
 
445
      bit=0;
 
446
      byte=0;
 
447
      for (x=0; x < (long) image->columns; x++)
 
448
      {
 
449
        byte<<=1;
 
450
        if (indexes[x] == polarity)
 
451
          byte|=0x01;
 
452
        bit++;
 
453
        if (bit == 8)
 
454
          {
 
455
            *q++=byte;
 
456
            bit=0;
 
457
            byte=0;
 
458
          }
 
459
       }
 
460
      if (bit != 0)
 
461
        *q++=byte << (8-bit);
 
462
      if (QuantumTick(y,image->rows))
 
463
        if (!MagickMonitor(SaveImageText,y,image->rows,&image->exception))
 
464
          break;
 
465
    }
 
466
    /*
 
467
      Initialize JBIG info structure.
 
468
    */
 
469
    jbg_enc_init(&jbig_info,image->columns,image->rows,1,&pixels,
 
470
      (void (*)(unsigned char *,size_t,void *)) JBIGEncode,image);
 
471
    if (image_info->subimage != 0)
 
472
      jbg_enc_layers(&jbig_info,(int) image_info->subimage);
 
473
    else
 
474
      {
 
475
        long
 
476
          sans_offset;
 
477
 
 
478
        unsigned long
 
479
          x_resolution,
 
480
          y_resolution;
 
481
 
 
482
        x_resolution=640;
 
483
        y_resolution=480;
 
484
        sans_offset=0;
 
485
        if (image_info->density != (char *) NULL)
 
486
          (void) GetGeometry(image_info->density,&sans_offset,&sans_offset,
 
487
            &x_resolution,&y_resolution);
 
488
        (void) jbg_enc_lrlmax(&jbig_info,x_resolution,y_resolution);
 
489
      }
 
490
    (void) jbg_enc_lrange(&jbig_info,-1,-1);
 
491
    jbg_enc_options(&jbig_info, /* Encoder state */
 
492
                    JBG_ILEAVE| JBG_SMID, /* Order */
 
493
                    JBG_TPDON | JBG_TPBON | JBG_DPON, /* Options */
 
494
                    /* Lines per stripe in resolution layer 0. (was -1)*/
 
495
                    (jbig_lib_version < 1.6 ? -1 : 0),
 
496
                    -1, /* mx */
 
497
                    -1); /* my */
 
498
    /*
 
499
      Write JBIG image.
 
500
    */
 
501
    jbg_enc_out(&jbig_info);
 
502
    jbg_enc_free(&jbig_info);
 
503
    MagickFreeMemory(pixels);
 
504
    if (image->next == (Image *) NULL)
 
505
      break;
 
506
    image=SyncNextImageInList(image);
 
507
    if (!MagickMonitor(SaveImagesText,scene++,GetImageListLength(image),&image->exception))
 
508
      break;
 
509
  } while (image_info->adjoin);
 
510
  if (image_info->adjoin)
 
511
    while (image->previous != (Image *) NULL)
 
512
      image=image->previous;
 
513
  CloseBlob(image);
 
514
  return(True);
 
515
}
 
516
#endif