2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % JJJJJ BBBB IIIII GGGG %
10 % JJJ BBBB IIIII GGG %
13 % Read/Write JBIG Image Format %
20 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/color-private.h"
47 #include "MagickCore/colormap.h"
48 #include "MagickCore/colorspace.h"
49 #include "MagickCore/colorspace-private.h"
50 #include "MagickCore/constitute.h"
51 #include "MagickCore/exception.h"
52 #include "MagickCore/exception-private.h"
53 #include "MagickCore/geometry.h"
54 #include "MagickCore/image.h"
55 #include "MagickCore/image-private.h"
56 #include "MagickCore/list.h"
57 #include "MagickCore/magick.h"
58 #include "MagickCore/memory_.h"
59 #include "MagickCore/monitor.h"
60 #include "MagickCore/monitor-private.h"
61 #include "MagickCore/nt-base-private.h"
62 #include "MagickCore/pixel-accessor.h"
63 #include "MagickCore/quantum-private.h"
64 #include "MagickCore/static.h"
65 #include "MagickCore/string_.h"
66 #include "MagickCore/string-private.h"
67 #include "MagickCore/module.h"
68 #if defined(MAGICKCORE_JBIG_DELEGATE)
75 #if defined(MAGICKCORE_JBIG_DELEGATE)
76 static MagickBooleanType
77 WriteJBIGImage(const ImageInfo *,Image *,ExceptionInfo *);
80 #if defined(MAGICKCORE_JBIG_DELEGATE)
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 % R e a d J B I G I m a g e %
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 % ReadJBIGImage() reads a JBIG image file and returns it. It
93 % allocates the memory necessary for the new Image structure and returns a
94 % pointer to the new image.
96 % The format of the ReadJBIGImage method is:
98 % Image *ReadJBIGImage(const ImageInfo *image_info,
99 % ExceptionInfo *exception)
101 % A description of each parameter follows:
103 % o image_info: the image info.
105 % o exception: return any errors or warnings in this structure.
108 static Image *ReadJBIGImage(const ImageInfo *image_info,
109 ExceptionInfo *exception)
126 register unsigned char
144 assert(image_info != (const ImageInfo *) NULL);
145 assert(image_info->signature == MagickSignature);
146 if (image_info->debug != MagickFalse)
147 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
148 image_info->filename);
149 assert(exception != (ExceptionInfo *) NULL);
150 assert(exception->signature == MagickSignature);
151 image=AcquireImage(image_info,exception);
152 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
153 if (status == MagickFalse)
155 image=DestroyImageList(image);
156 return((Image *) NULL);
159 Initialize JBIG toolkit.
161 jbg_dec_init(&jbig_info);
162 jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns,(unsigned long)
164 image->columns=jbg_dec_getwidth(&jbig_info);
165 image->rows=jbg_dec_getheight(&jbig_info);
167 image->storage_class=PseudoClass;
172 buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
174 if (buffer == (unsigned char *) NULL)
175 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
179 length=(ssize_t) ReadBlob(image,MagickMaxBufferExtent,buffer);
183 while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
188 status=jbg_dec_in(&jbig_info,p,length,&count);
190 length-=(ssize_t) count;
192 } while ((status == JBG_EAGAIN) || (status == JBG_EOK));
196 image->columns=jbg_dec_getwidth(&jbig_info);
197 image->rows=jbg_dec_getheight(&jbig_info);
198 image->compression=JBIG2Compression;
199 if (AcquireImageColormap(image,2,exception) == MagickFalse)
201 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
202 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
204 image->colormap[0].red=0;
205 image->colormap[0].green=0;
206 image->colormap[0].blue=0;
207 image->colormap[1].red=QuantumRange;
208 image->colormap[1].green=QuantumRange;
209 image->colormap[1].blue=QuantumRange;
210 image->resolution.x=300;
211 image->resolution.y=300;
212 if (image_info->ping != MagickFalse)
214 (void) CloseBlob(image);
215 return(GetFirstImageInList(image));
218 Convert X bitmap image to pixel packets.
220 p=jbg_dec_getimage(&jbig_info,0);
221 for (y=0; y < (ssize_t) image->rows; y++)
223 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
224 if (q == (Quantum *) NULL)
228 for (x=0; x < (ssize_t) image->columns; x++)
232 index=(byte & 0x80) ? 0 : 1;
237 SetPixelIndex(image,index,q);
238 SetPixelInfoPixel(image,image->colormap+(ssize_t) index,q);
239 q+=GetPixelChannels(image);
241 if (SyncAuthenticPixels(image,exception) == MagickFalse)
243 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
245 if (status == MagickFalse)
251 jbg_dec_free(&jbig_info);
252 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
253 (void) CloseBlob(image);
254 return(GetFirstImageInList(image));
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
263 % R e g i s t e r J B I G I m a g e %
267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269 % RegisterJBIGImage() adds attributes for the JBIG image format to
270 % the list of supported formats. The attributes include the image format
271 % tag, a method to read and/or write the format, whether the format
272 % supports the saving of more than one frame to the same file or blob,
273 % whether the format supports native in-memory I/O, and a brief
274 % description of the format.
276 % The format of the RegisterJBIGImage method is:
278 % size_t RegisterJBIGImage(void)
281 ModuleExport size_t RegisterJBIGImage(void)
283 #define JBIGDescription "Joint Bi-level Image experts Group interchange format"
286 version[MaxTextExtent];
292 #if defined(JBG_VERSION)
293 (void) CopyMagickString(version,JBG_VERSION,MaxTextExtent);
295 entry=SetMagickInfo("BIE");
296 #if defined(MAGICKCORE_JBIG_DELEGATE)
297 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
298 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
300 entry->adjoin=MagickFalse;
301 entry->description=ConstantString(JBIGDescription);
302 if (*version != '\0')
303 entry->version=ConstantString(version);
304 entry->module=ConstantString("JBIG");
305 (void) RegisterMagickInfo(entry);
306 entry=SetMagickInfo("JBG");
307 #if defined(MAGICKCORE_JBIG_DELEGATE)
308 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
309 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
311 entry->description=ConstantString(JBIGDescription);
312 if (*version != '\0')
313 entry->version=ConstantString(version);
314 entry->module=ConstantString("JBIG");
315 (void) RegisterMagickInfo(entry);
316 entry=SetMagickInfo("JBIG");
317 #if defined(MAGICKCORE_JBIG_DELEGATE)
318 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
319 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
321 entry->description=ConstantString(JBIGDescription);
322 if (*version != '\0')
323 entry->version=ConstantString(version);
324 entry->module=ConstantString("JBIG");
325 (void) RegisterMagickInfo(entry);
326 return(MagickImageCoderSignature);
330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
334 % U n r e g i s t e r J B I G I m a g e %
338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 % UnregisterJBIGImage() removes format registrations made by the
341 % JBIG module from the list of supported formats.
343 % The format of the UnregisterJBIGImage method is:
345 % UnregisterJBIGImage(void)
348 ModuleExport void UnregisterJBIGImage(void)
350 (void) UnregisterMagickInfo("BIE");
351 (void) UnregisterMagickInfo("JBG");
352 (void) UnregisterMagickInfo("JBIG");
355 #if defined(MAGICKCORE_JBIG_DELEGATE)
357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361 % W r i t e J B I G I m a g e %
365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 % WriteJBIGImage() writes an image in the JBIG encoded image format.
369 % The format of the WriteJBIGImage method is:
371 % MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,
372 % Image *image,ExceptionInfo *exception)
374 % A description of each parameter follows.
376 % o image_info: the image info.
378 % o image: The image.
380 % o exception: return any errors or warnings in this structure.
384 static void JBIGEncode(unsigned char *pixels,size_t length,void *data)
389 image=(Image *) data;
390 (void) WriteBlob(image,length,pixels);
393 static MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,
394 Image *image,ExceptionInfo *exception)
405 register const Quantum
411 register unsigned char
431 assert(image_info != (const ImageInfo *) NULL);
432 assert(image_info->signature == MagickSignature);
433 assert(image != (Image *) NULL);
434 assert(image->signature == MagickSignature);
435 if (image->debug != MagickFalse)
436 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
437 assert(exception != (ExceptionInfo *) NULL);
438 assert(exception->signature == MagickSignature);
439 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
440 if (status == MagickFalse)
442 version=StringToDouble(JBG_VERSION,(char **) NULL);
449 if (IsRGBColorspace(image->colorspace) == MagickFalse)
450 (void) TransformImageColorspace(image,RGBColorspace,exception);
451 number_packets=(image->columns+7)/8;
452 pixels=(unsigned char *) AcquireQuantumMemory(number_packets,
453 image->rows*sizeof(*pixels));
454 if (pixels == (unsigned char *) NULL)
455 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
457 Convert pixels to a bitmap.
459 (void) SetImageType(image,BilevelType,exception);
461 for (y=0; y < (ssize_t) image->rows; y++)
463 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
464 if (p == (const Quantum *) NULL)
468 for (x=0; x < (ssize_t) image->columns; x++)
471 if (GetPixelIntensity(image,p) < (QuantumRange/2.0))
480 p+=GetPixelChannels(image);
483 *q++=byte << (8-bit);
484 if (image->previous == (Image *) NULL)
486 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
488 if (status == MagickFalse)
493 Initialize JBIG info structure.
495 jbg_enc_init(&jbig_info,(unsigned long) image->columns,(unsigned long)
496 image->rows,1,&pixels,(void (*)(unsigned char *,size_t,void *))
498 if (image_info->scene != 0)
499 jbg_enc_layers(&jbig_info,(int) image_info->scene);
508 if (image_info->density != (char *) NULL)
516 flags=ParseGeometry(image_info->density,&geometry_info);
517 x_resolution=geometry_info.rho;
518 y_resolution=geometry_info.sigma;
519 if ((flags & SigmaValue) == 0)
520 y_resolution=x_resolution;
522 if (image->units == PixelsPerCentimeterResolution)
524 x_resolution=(size_t) (100.0*2.54*x_resolution+0.5)/100.0;
525 y_resolution=(size_t) (100.0*2.54*y_resolution+0.5)/100.0;
527 (void) jbg_enc_lrlmax(&jbig_info,(unsigned long) x_resolution,
528 (unsigned long) y_resolution);
530 (void) jbg_enc_lrange(&jbig_info,-1,-1);
531 jbg_enc_options(&jbig_info,JBG_ILEAVE | JBG_SMID,JBG_TPDON | JBG_TPBON |
532 JBG_DPON,version < 1.6 ? -1 : 0,-1,-1);
536 jbg_enc_out(&jbig_info);
537 jbg_enc_free(&jbig_info);
538 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
539 if (GetNextImageInList(image) == (Image *) NULL)
541 image=SyncNextImageInList(image);
542 status=SetImageProgress(image,SaveImagesTag,scene++,
543 GetImageListLength(image));
544 if (status == MagickFalse)
546 } while (image_info->adjoin != MagickFalse);
547 (void) CloseBlob(image);