2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % JJJJJ BBBB IIIII GGGG %
10 % JJJ BBBB IIIII GGG %
13 % Read/Write JBIG Image Format %
20 % Copyright 1999-2010 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 "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/blob-private.h"
45 #include "magick/cache.h"
46 #include "magick/color-private.h"
47 #include "magick/colorspace.h"
48 #include "magick/constitute.h"
49 #include "magick/exception.h"
50 #include "magick/exception-private.h"
51 #include "magick/geometry.h"
52 #include "magick/image.h"
53 #include "magick/image-private.h"
54 #include "magick/list.h"
55 #include "magick/magick.h"
56 #include "magick/memory_.h"
57 #include "magick/monitor.h"
58 #include "magick/monitor-private.h"
59 #include "magick/nt-feature.h"
60 #include "magick/quantum-private.h"
61 #include "magick/static.h"
62 #include "magick/string_.h"
63 #include "magick/module.h"
64 #if defined(MAGICKCORE_JBIG_DELEGATE)
71 #if defined(MAGICKCORE_JBIG_DELEGATE)
72 static MagickBooleanType
73 WriteJBIGImage(const ImageInfo *,Image *);
76 #if defined(MAGICKCORE_JBIG_DELEGATE)
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 % R e a d J B I G I m a g e %
86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88 % ReadJBIGImage() reads a JBIG image file and returns it. It
89 % allocates the memory necessary for the new Image structure and returns a
90 % pointer to the new image.
92 % The format of the ReadJBIGImage method is:
94 % Image *ReadJBIGImage(const ImageInfo *image_info,
95 % ExceptionInfo *exception)
97 % A description of each parameter follows:
99 % o image_info: the image info.
101 % o exception: return any errors or warnings in this structure.
104 static Image *ReadJBIGImage(const ImageInfo *image_info,
105 ExceptionInfo *exception)
129 register unsigned char
146 assert(image_info != (const ImageInfo *) NULL);
147 assert(image_info->signature == MagickSignature);
148 if (image_info->debug != MagickFalse)
149 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
150 image_info->filename);
151 assert(exception != (ExceptionInfo *) NULL);
152 assert(exception->signature == MagickSignature);
153 image=AcquireImage(image_info);
154 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
155 if (status == MagickFalse)
157 image=DestroyImageList(image);
158 return((Image *) NULL);
161 Initialize JBIG toolkit.
163 jbg_dec_init(&jbig_info);
164 jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns,(unsigned long)
166 image->columns=jbg_dec_getwidth(&jbig_info);
167 image->rows=jbg_dec_getheight(&jbig_info);
169 image->storage_class=PseudoClass;
174 buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
176 if (buffer == (unsigned char *) NULL)
177 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
181 length=(long) ReadBlob(image,MagickMaxBufferExtent,buffer);
186 while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
191 status=jbg_dec_in(&jbig_info,p,length,&count);
193 length-=(long) count;
195 } while ((status == JBG_EAGAIN) || (status == JBG_EOK));
199 image->columns=jbg_dec_getwidth(&jbig_info);
200 image->rows=jbg_dec_getheight(&jbig_info);
201 if (AcquireImageColormap(image,2) == MagickFalse)
203 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
204 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
206 image->colormap[0].red=0;
207 image->colormap[0].green=0;
208 image->colormap[0].blue=0;
209 image->colormap[1].red=QuantumRange;
210 image->colormap[1].green=QuantumRange;
211 image->colormap[1].blue=QuantumRange;
212 image->x_resolution=300;
213 image->y_resolution=300;
214 if (image_info->ping != MagickFalse)
216 (void) CloseBlob(image);
217 return(GetFirstImageInList(image));
220 Convert X bitmap image to pixel packets.
222 p=jbg_dec_getimage(&jbig_info,0);
223 for (y=0; y < (long) image->rows; y++)
225 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
226 if (q == (PixelPacket *) NULL)
228 indexes=GetAuthenticIndexQueue(image);
231 for (x=0; x < (long) image->columns; x++)
235 index=(byte & 0x80) ? 0 : 1;
241 *q++=image->colormap[(long) index];
243 if (SyncAuthenticPixels(image,exception) == MagickFalse)
245 status=SetImageProgress(image,LoadImageTag,y,image->rows);
246 if (status == MagickFalse)
252 jbg_dec_free(&jbig_info);
253 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
254 (void) CloseBlob(image);
255 return(GetFirstImageInList(image));
260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264 % R e g i s t e r J B I G I m a g e %
268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270 % RegisterJBIGImage() adds attributes for the JBIG image format to
271 % the list of supported formats. The attributes include the image format
272 % tag, a method to read and/or write the format, whether the format
273 % supports the saving of more than one frame to the same file or blob,
274 % whether the format supports native in-memory I/O, and a brief
275 % description of the format.
277 % The format of the RegisterJBIGImage method is:
279 % unsigned long RegisterJBIGImage(void)
282 ModuleExport unsigned long RegisterJBIGImage(void)
284 #define JBIGDescription "Joint Bi-level Image experts Group interchange format"
287 version[MaxTextExtent];
293 #if defined(JBG_VERSION)
294 (void) CopyMagickString(version,JBG_VERSION,MaxTextExtent);
296 entry=SetMagickInfo("BIE");
297 #if defined(MAGICKCORE_JBIG_DELEGATE)
298 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
299 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
301 entry->adjoin=MagickFalse;
302 entry->description=ConstantString(JBIGDescription);
303 if (*version != '\0')
304 entry->version=ConstantString(version);
305 entry->module=ConstantString("JBIG");
306 (void) RegisterMagickInfo(entry);
307 entry=SetMagickInfo("JBG");
308 #if defined(MAGICKCORE_JBIG_DELEGATE)
309 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
310 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
312 entry->description=ConstantString(JBIGDescription);
313 if (*version != '\0')
314 entry->version=ConstantString(version);
315 entry->module=ConstantString("JBIG");
316 (void) RegisterMagickInfo(entry);
317 entry=SetMagickInfo("JBIG");
318 #if defined(MAGICKCORE_JBIG_DELEGATE)
319 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
320 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
322 entry->description=ConstantString(JBIGDescription);
323 if (*version != '\0')
324 entry->version=ConstantString(version);
325 entry->module=ConstantString("JBIG");
326 (void) RegisterMagickInfo(entry);
327 return(MagickImageCoderSignature);
331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
335 % U n r e g i s t e r J B I G I m a g e %
339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341 % UnregisterJBIGImage() removes format registrations made by the
342 % JBIG module from the list of supported formats.
344 % The format of the UnregisterJBIGImage method is:
346 % UnregisterJBIGImage(void)
349 ModuleExport void UnregisterJBIGImage(void)
351 (void) UnregisterMagickInfo("BIE");
352 (void) UnregisterMagickInfo("JBG");
353 (void) UnregisterMagickInfo("JBIG");
356 #if defined(MAGICKCORE_JBIG_DELEGATE)
358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
362 % W r i t e J B I G I m a g e %
366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368 % WriteJBIGImage() writes an image in the JBIG encoded image format.
370 % The format of the WriteJBIGImage method is:
372 % MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,Image *image)
374 % A description of each parameter follows.
376 % o image_info: the image info.
378 % o image: The image.
383 static void JBIGEncode(unsigned char *pixels,size_t length,void *data)
388 image=(Image *) data;
389 (void) WriteBlob(image,length,pixels);
392 static MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,
407 register const IndexPacket
410 register const PixelPacket
416 register unsigned char
433 assert(image_info != (const ImageInfo *) NULL);
434 assert(image_info->signature == MagickSignature);
435 assert(image != (Image *) NULL);
436 assert(image->signature == MagickSignature);
437 if (image->debug != MagickFalse)
438 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
439 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
440 if (status == MagickFalse)
442 version=strtod(JBG_VERSION,(char **) NULL);
449 if (image->colorspace != RGBColorspace)
450 (void) TransformImageColorspace(image,RGBColorspace);
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);
461 for (y=0; y < (long) image->rows; y++)
463 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
464 if (p == (const PixelPacket *) NULL)
466 indexes=GetVirtualIndexQueue(image);
469 for (x=0; x < (long) image->columns; x++)
472 if (PixelIntensity(p) < (QuantumRange/2.0))
484 *q++=byte << (8-bit);
485 if (image->previous == (Image *) NULL)
487 status=SetImageProgress(image,SaveImageTag,y,image->rows);
488 if (status == MagickFalse)
493 Initialize JBIG info structure.
495 jbg_enc_init(&jbig_info,image->columns,image->rows,1,&pixels,
496 (void (*)(unsigned char *,size_t,void *)) JBIGEncode,image);
497 if (image_info->scene != 0)
498 jbg_enc_layers(&jbig_info,(int) image_info->scene);
511 if (image_info->density != (char *) NULL)
519 flags=ParseGeometry(image_info->density,&geometry_info);
520 x_resolution=geometry_info.rho;
521 y_resolution=geometry_info.sigma;
522 if ((flags & SigmaValue) == 0)
523 y_resolution=x_resolution;
525 if (image->units == PixelsPerCentimeterResolution)
530 (void) jbg_enc_lrlmax(&jbig_info,x_resolution,y_resolution);
532 (void) jbg_enc_lrange(&jbig_info,-1,-1);
533 jbg_enc_options(&jbig_info,JBG_ILEAVE | JBG_SMID,JBG_TPDON | JBG_TPBON |
534 JBG_DPON,version < 1.6 ? -1 : 0,-1,-1);
538 jbg_enc_out(&jbig_info);
539 jbg_enc_free(&jbig_info);
540 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
541 if (GetNextImageInList(image) == (Image *) NULL)
543 image=SyncNextImageInList(image);
544 status=SetImageProgress(image,SaveImagesTag,scene++,
545 GetImageListLength(image));
546 if (status == MagickFalse)
548 } while (image_info->adjoin != MagickFalse);
549 (void) CloseBlob(image);