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/colormap.h"
48 #include "magick/colorspace.h"
49 #include "magick/constitute.h"
50 #include "magick/exception.h"
51 #include "magick/exception-private.h"
52 #include "magick/geometry.h"
53 #include "magick/image.h"
54 #include "magick/image-private.h"
55 #include "magick/list.h"
56 #include "magick/magick.h"
57 #include "magick/memory_.h"
58 #include "magick/monitor.h"
59 #include "magick/monitor-private.h"
60 #include "magick/nt-feature.h"
61 #include "magick/quantum-private.h"
62 #include "magick/static.h"
63 #include "magick/string_.h"
64 #include "magick/module.h"
65 #if defined(MAGICKCORE_JBIG_DELEGATE)
72 #if defined(MAGICKCORE_JBIG_DELEGATE)
73 static MagickBooleanType
74 WriteJBIGImage(const ImageInfo *,Image *);
77 #if defined(MAGICKCORE_JBIG_DELEGATE)
79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 % R e a d J B I G I m a g e %
87 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 % ReadJBIGImage() reads a JBIG image file and returns it. It
90 % allocates the memory necessary for the new Image structure and returns a
91 % pointer to the new image.
93 % The format of the ReadJBIGImage method is:
95 % Image *ReadJBIGImage(const ImageInfo *image_info,
96 % ExceptionInfo *exception)
98 % A description of each parameter follows:
100 % o image_info: the image info.
102 % o exception: return any errors or warnings in this structure.
105 static Image *ReadJBIGImage(const ImageInfo *image_info,
106 ExceptionInfo *exception)
130 register unsigned char
147 assert(image_info != (const ImageInfo *) NULL);
148 assert(image_info->signature == MagickSignature);
149 if (image_info->debug != MagickFalse)
150 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
151 image_info->filename);
152 assert(exception != (ExceptionInfo *) NULL);
153 assert(exception->signature == MagickSignature);
154 image=AcquireImage(image_info);
155 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
156 if (status == MagickFalse)
158 image=DestroyImageList(image);
159 return((Image *) NULL);
162 Initialize JBIG toolkit.
164 jbg_dec_init(&jbig_info);
165 jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns,(unsigned long)
167 image->columns=jbg_dec_getwidth(&jbig_info);
168 image->rows=jbg_dec_getheight(&jbig_info);
170 image->storage_class=PseudoClass;
175 buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
177 if (buffer == (unsigned char *) NULL)
178 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
182 length=(long) ReadBlob(image,MagickMaxBufferExtent,buffer);
187 while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
192 status=jbg_dec_in(&jbig_info,p,length,&count);
194 length-=(long) count;
196 } while ((status == JBG_EAGAIN) || (status == JBG_EOK));
200 image->columns=jbg_dec_getwidth(&jbig_info);
201 image->rows=jbg_dec_getheight(&jbig_info);
202 if (AcquireImageColormap(image,2) == MagickFalse)
204 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
205 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
207 image->colormap[0].red=0;
208 image->colormap[0].green=0;
209 image->colormap[0].blue=0;
210 image->colormap[1].red=QuantumRange;
211 image->colormap[1].green=QuantumRange;
212 image->colormap[1].blue=QuantumRange;
213 image->x_resolution=300;
214 image->y_resolution=300;
215 if (image_info->ping != MagickFalse)
217 (void) CloseBlob(image);
218 return(GetFirstImageInList(image));
221 Convert X bitmap image to pixel packets.
223 p=jbg_dec_getimage(&jbig_info,0);
224 for (y=0; y < (long) image->rows; y++)
226 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
227 if (q == (PixelPacket *) NULL)
229 indexes=GetAuthenticIndexQueue(image);
232 for (x=0; x < (long) image->columns; x++)
236 index=(byte & 0x80) ? 0 : 1;
242 *q++=image->colormap[(long) index];
244 if (SyncAuthenticPixels(image,exception) == MagickFalse)
246 status=SetImageProgress(image,LoadImageTag,y,image->rows);
247 if (status == MagickFalse)
253 jbg_dec_free(&jbig_info);
254 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
255 (void) CloseBlob(image);
256 return(GetFirstImageInList(image));
261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265 % R e g i s t e r J B I G I m a g e %
269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271 % RegisterJBIGImage() adds attributes for the JBIG image format to
272 % the list of supported formats. The attributes include the image format
273 % tag, a method to read and/or write the format, whether the format
274 % supports the saving of more than one frame to the same file or blob,
275 % whether the format supports native in-memory I/O, and a brief
276 % description of the format.
278 % The format of the RegisterJBIGImage method is:
280 % unsigned long RegisterJBIGImage(void)
283 ModuleExport unsigned long RegisterJBIGImage(void)
285 #define JBIGDescription "Joint Bi-level Image experts Group interchange format"
288 version[MaxTextExtent];
294 #if defined(JBG_VERSION)
295 (void) CopyMagickString(version,JBG_VERSION,MaxTextExtent);
297 entry=SetMagickInfo("BIE");
298 #if defined(MAGICKCORE_JBIG_DELEGATE)
299 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
300 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
302 entry->adjoin=MagickFalse;
303 entry->description=ConstantString(JBIGDescription);
304 if (*version != '\0')
305 entry->version=ConstantString(version);
306 entry->module=ConstantString("JBIG");
307 (void) RegisterMagickInfo(entry);
308 entry=SetMagickInfo("JBG");
309 #if defined(MAGICKCORE_JBIG_DELEGATE)
310 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
311 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
313 entry->description=ConstantString(JBIGDescription);
314 if (*version != '\0')
315 entry->version=ConstantString(version);
316 entry->module=ConstantString("JBIG");
317 (void) RegisterMagickInfo(entry);
318 entry=SetMagickInfo("JBIG");
319 #if defined(MAGICKCORE_JBIG_DELEGATE)
320 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
321 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
323 entry->description=ConstantString(JBIGDescription);
324 if (*version != '\0')
325 entry->version=ConstantString(version);
326 entry->module=ConstantString("JBIG");
327 (void) RegisterMagickInfo(entry);
328 return(MagickImageCoderSignature);
332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
336 % U n r e g i s t e r J B I G I m a g e %
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
342 % UnregisterJBIGImage() removes format registrations made by the
343 % JBIG module from the list of supported formats.
345 % The format of the UnregisterJBIGImage method is:
347 % UnregisterJBIGImage(void)
350 ModuleExport void UnregisterJBIGImage(void)
352 (void) UnregisterMagickInfo("BIE");
353 (void) UnregisterMagickInfo("JBG");
354 (void) UnregisterMagickInfo("JBIG");
357 #if defined(MAGICKCORE_JBIG_DELEGATE)
359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363 % W r i t e J B I G I m a g e %
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369 % WriteJBIGImage() writes an image in the JBIG encoded image format.
371 % The format of the WriteJBIGImage method is:
373 % MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,Image *image)
375 % A description of each parameter follows.
377 % o image_info: the image info.
379 % o image: The image.
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,
408 register const IndexPacket
411 register const PixelPacket
417 register unsigned char
434 assert(image_info != (const ImageInfo *) NULL);
435 assert(image_info->signature == MagickSignature);
436 assert(image != (Image *) NULL);
437 assert(image->signature == MagickSignature);
438 if (image->debug != MagickFalse)
439 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
440 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
441 if (status == MagickFalse)
443 version=strtod(JBG_VERSION,(char **) NULL);
450 if (image->colorspace != RGBColorspace)
451 (void) TransformImageColorspace(image,RGBColorspace);
452 number_packets=(image->columns+7)/8;
453 pixels=(unsigned char *) AcquireQuantumMemory(number_packets,
454 image->rows*sizeof(*pixels));
455 if (pixels == (unsigned char *) NULL)
456 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
458 Convert pixels to a bitmap.
460 (void) SetImageType(image,BilevelType);
462 for (y=0; y < (long) image->rows; y++)
464 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
465 if (p == (const PixelPacket *) NULL)
467 indexes=GetVirtualIndexQueue(image);
470 for (x=0; x < (long) image->columns; x++)
473 if (PixelIntensity(p) < (QuantumRange/2.0))
485 *q++=byte << (8-bit);
486 if (image->previous == (Image *) NULL)
488 status=SetImageProgress(image,SaveImageTag,y,image->rows);
489 if (status == MagickFalse)
494 Initialize JBIG info structure.
496 jbg_enc_init(&jbig_info,image->columns,image->rows,1,&pixels,
497 (void (*)(unsigned char *,size_t,void *)) JBIGEncode,image);
498 if (image_info->scene != 0)
499 jbg_enc_layers(&jbig_info,(int) image_info->scene);
512 if (image_info->density != (char *) NULL)
520 flags=ParseGeometry(image_info->density,&geometry_info);
521 x_resolution=geometry_info.rho;
522 y_resolution=geometry_info.sigma;
523 if ((flags & SigmaValue) == 0)
524 y_resolution=x_resolution;
526 if (image->units == PixelsPerCentimeterResolution)
528 x_resolution=(unsigned long) (100.0*2.54*x_resolution+0.5)/100.0;
529 y_resolution=(unsigned long) (100.0*2.54*y_resolution+0.5)/100.0;
531 (void) jbg_enc_lrlmax(&jbig_info,x_resolution,y_resolution);
533 (void) jbg_enc_lrange(&jbig_info,-1,-1);
534 jbg_enc_options(&jbig_info,JBG_ILEAVE | JBG_SMID,JBG_TPDON | JBG_TPBON |
535 JBG_DPON,version < 1.6 ? -1 : 0,-1,-1);
539 jbg_enc_out(&jbig_info);
540 jbg_enc_free(&jbig_info);
541 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
542 if (GetNextImageInList(image) == (Image *) NULL)
544 image=SyncNextImageInList(image);
545 status=SetImageProgress(image,SaveImagesTag,scene++,
546 GetImageListLength(image));
547 if (status == MagickFalse)
549 } while (image_info->adjoin != MagickFalse);
550 (void) CloseBlob(image);