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/constitute.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/geometry.h"
53 #include "MagickCore/image.h"
54 #include "MagickCore/image-private.h"
55 #include "MagickCore/list.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/monitor.h"
59 #include "MagickCore/monitor-private.h"
60 #include "MagickCore/nt-feature.h"
61 #include "MagickCore/pixel-accessor.h"
62 #include "MagickCore/quantum-private.h"
63 #include "MagickCore/static.h"
64 #include "MagickCore/string_.h"
65 #include "MagickCore/module.h"
66 #if defined(MAGICKCORE_JBIG_DELEGATE)
73 #if defined(MAGICKCORE_JBIG_DELEGATE)
74 static MagickBooleanType
75 WriteJBIGImage(const ImageInfo *,Image *);
78 #if defined(MAGICKCORE_JBIG_DELEGATE)
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % R e a d J B I G I m a g e %
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90 % ReadJBIGImage() reads a JBIG image file and returns it. It
91 % allocates the memory necessary for the new Image structure and returns a
92 % pointer to the new image.
94 % The format of the ReadJBIGImage method is:
96 % Image *ReadJBIGImage(const ImageInfo *image_info,
97 % ExceptionInfo *exception)
99 % A description of each parameter follows:
101 % o image_info: the image info.
103 % o exception: return any errors or warnings in this structure.
106 static Image *ReadJBIGImage(const ImageInfo *image_info,
107 ExceptionInfo *exception)
124 register unsigned char
142 assert(image_info != (const ImageInfo *) NULL);
143 assert(image_info->signature == MagickSignature);
144 if (image_info->debug != MagickFalse)
145 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
146 image_info->filename);
147 assert(exception != (ExceptionInfo *) NULL);
148 assert(exception->signature == MagickSignature);
149 image=AcquireImage(image_info);
150 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
151 if (status == MagickFalse)
153 image=DestroyImageList(image);
154 return((Image *) NULL);
157 Initialize JBIG toolkit.
159 jbg_dec_init(&jbig_info);
160 jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns,(unsigned long)
162 image->columns=jbg_dec_getwidth(&jbig_info);
163 image->rows=jbg_dec_getheight(&jbig_info);
165 image->storage_class=PseudoClass;
170 buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
172 if (buffer == (unsigned char *) NULL)
173 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
177 length=(ssize_t) ReadBlob(image,MagickMaxBufferExtent,buffer);
181 while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
186 status=jbg_dec_in(&jbig_info,p,length,&count);
188 length-=(ssize_t) count;
190 } while ((status == JBG_EAGAIN) || (status == JBG_EOK));
194 image->columns=jbg_dec_getwidth(&jbig_info);
195 image->rows=jbg_dec_getheight(&jbig_info);
196 image->compression=JBIG2Compression;
197 if (AcquireImageColormap(image,2) == MagickFalse)
199 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
200 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
202 image->colormap[0].red=0;
203 image->colormap[0].green=0;
204 image->colormap[0].blue=0;
205 image->colormap[1].red=QuantumRange;
206 image->colormap[1].green=QuantumRange;
207 image->colormap[1].blue=QuantumRange;
208 image->x_resolution=300;
209 image->y_resolution=300;
210 if (image_info->ping != MagickFalse)
212 (void) CloseBlob(image);
213 return(GetFirstImageInList(image));
216 Convert X bitmap image to pixel packets.
218 p=jbg_dec_getimage(&jbig_info,0);
219 for (y=0; y < (ssize_t) image->rows; y++)
221 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
222 if (q == (const Quantum *) NULL)
226 for (x=0; x < (ssize_t) image->columns; x++)
230 index=(byte & 0x80) ? 0 : 1;
235 SetPixelIndex(image,index,q);
236 SetPixelPacket(image,image->colormap+(ssize_t) index,q);
237 q+=GetPixelChannels(image);
239 if (SyncAuthenticPixels(image,exception) == MagickFalse)
241 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
243 if (status == MagickFalse)
249 jbg_dec_free(&jbig_info);
250 buffer=(unsigned char *) RelinquishMagickMemory(buffer);
251 (void) CloseBlob(image);
252 return(GetFirstImageInList(image));
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261 % R e g i s t e r J B I G I m a g e %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267 % RegisterJBIGImage() adds attributes for the JBIG image format to
268 % the list of supported formats. The attributes include the image format
269 % tag, a method to read and/or write the format, whether the format
270 % supports the saving of more than one frame to the same file or blob,
271 % whether the format supports native in-memory I/O, and a brief
272 % description of the format.
274 % The format of the RegisterJBIGImage method is:
276 % size_t RegisterJBIGImage(void)
279 ModuleExport size_t RegisterJBIGImage(void)
281 #define JBIGDescription "Joint Bi-level Image experts Group interchange format"
284 version[MaxTextExtent];
290 #if defined(JBG_VERSION)
291 (void) CopyMagickString(version,JBG_VERSION,MaxTextExtent);
293 entry=SetMagickInfo("BIE");
294 #if defined(MAGICKCORE_JBIG_DELEGATE)
295 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
296 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
298 entry->adjoin=MagickFalse;
299 entry->description=ConstantString(JBIGDescription);
300 if (*version != '\0')
301 entry->version=ConstantString(version);
302 entry->module=ConstantString("JBIG");
303 (void) RegisterMagickInfo(entry);
304 entry=SetMagickInfo("JBG");
305 #if defined(MAGICKCORE_JBIG_DELEGATE)
306 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
307 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
309 entry->description=ConstantString(JBIGDescription);
310 if (*version != '\0')
311 entry->version=ConstantString(version);
312 entry->module=ConstantString("JBIG");
313 (void) RegisterMagickInfo(entry);
314 entry=SetMagickInfo("JBIG");
315 #if defined(MAGICKCORE_JBIG_DELEGATE)
316 entry->decoder=(DecodeImageHandler *) ReadJBIGImage;
317 entry->encoder=(EncodeImageHandler *) WriteJBIGImage;
319 entry->description=ConstantString(JBIGDescription);
320 if (*version != '\0')
321 entry->version=ConstantString(version);
322 entry->module=ConstantString("JBIG");
323 (void) RegisterMagickInfo(entry);
324 return(MagickImageCoderSignature);
328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332 % U n r e g i s t e r J B I G I m a g e %
336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 % UnregisterJBIGImage() removes format registrations made by the
339 % JBIG module from the list of supported formats.
341 % The format of the UnregisterJBIGImage method is:
343 % UnregisterJBIGImage(void)
346 ModuleExport void UnregisterJBIGImage(void)
348 (void) UnregisterMagickInfo("BIE");
349 (void) UnregisterMagickInfo("JBG");
350 (void) UnregisterMagickInfo("JBIG");
353 #if defined(MAGICKCORE_JBIG_DELEGATE)
355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
359 % W r i t e J B I G I m a g e %
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
365 % WriteJBIGImage() writes an image in the JBIG encoded image format.
367 % The format of the WriteJBIGImage method is:
369 % MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,Image *image)
371 % A description of each parameter follows.
373 % o image_info: the image info.
375 % o image: The image.
380 static void JBIGEncode(unsigned char *pixels,size_t length,void *data)
385 image=(Image *) data;
386 (void) WriteBlob(image,length,pixels);
389 static MagickBooleanType WriteJBIGImage(const ImageInfo *image_info,
401 register const Quantum
407 register unsigned char
427 assert(image_info != (const ImageInfo *) NULL);
428 assert(image_info->signature == MagickSignature);
429 assert(image != (Image *) NULL);
430 assert(image->signature == MagickSignature);
431 if (image->debug != MagickFalse)
432 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
433 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
434 if (status == MagickFalse)
436 version=InterpretLocaleValue(JBG_VERSION,(char **) NULL);
443 if (image->colorspace != RGBColorspace)
444 (void) TransformImageColorspace(image,RGBColorspace);
445 number_packets=(image->columns+7)/8;
446 pixels=(unsigned char *) AcquireQuantumMemory(number_packets,
447 image->rows*sizeof(*pixels));
448 if (pixels == (unsigned char *) NULL)
449 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
451 Convert pixels to a bitmap.
453 (void) SetImageType(image,BilevelType);
455 for (y=0; y < (ssize_t) image->rows; y++)
457 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
458 if (p == (const Quantum *) NULL)
462 for (x=0; x < (ssize_t) image->columns; x++)
465 if (GetPixelIntensity(image,p) < (QuantumRange/2.0))
474 p+=GetPixelChannels(image);
477 *q++=byte << (8-bit);
478 if (image->previous == (Image *) NULL)
480 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
482 if (status == MagickFalse)
487 Initialize JBIG info structure.
489 jbg_enc_init(&jbig_info,(unsigned long) image->columns,(unsigned long)
490 image->rows,1,&pixels,(void (*)(unsigned char *,size_t,void *))
492 if (image_info->scene != 0)
493 jbg_enc_layers(&jbig_info,(int) image_info->scene);
502 if (image_info->density != (char *) NULL)
510 flags=ParseGeometry(image_info->density,&geometry_info);
511 x_resolution=geometry_info.rho;
512 y_resolution=geometry_info.sigma;
513 if ((flags & SigmaValue) == 0)
514 y_resolution=x_resolution;
516 if (image->units == PixelsPerCentimeterResolution)
518 x_resolution=(size_t) (100.0*2.54*x_resolution+0.5)/100.0;
519 y_resolution=(size_t) (100.0*2.54*y_resolution+0.5)/100.0;
521 (void) jbg_enc_lrlmax(&jbig_info,(unsigned long) x_resolution,
522 (unsigned long) y_resolution);
524 (void) jbg_enc_lrange(&jbig_info,-1,-1);
525 jbg_enc_options(&jbig_info,JBG_ILEAVE | JBG_SMID,JBG_TPDON | JBG_TPBON |
526 JBG_DPON,version < 1.6 ? -1 : 0,-1,-1);
530 jbg_enc_out(&jbig_info);
531 jbg_enc_free(&jbig_info);
532 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
533 if (GetNextImageInList(image) == (Image *) NULL)
535 image=SyncNextImageInList(image);
536 status=SetImageProgress(image,SaveImagesTag,scene++,
537 GetImageListLength(image));
538 if (status == MagickFalse)
540 } while (image_info->adjoin != MagickFalse);
541 (void) CloseBlob(image);