/src/graphicsmagick/coders/jbig.c
Line | Count | Source |
1 | | /* |
2 | | % Copyright (C) 2003-2026 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/colormap.h" |
41 | | #include "magick/constitute.h" |
42 | | #include "magick/log.h" |
43 | | #include "magick/magick.h" |
44 | | #include "magick/monitor.h" |
45 | | #include "magick/pixel_cache.h" |
46 | | #include "magick/resource.h" |
47 | | #include "magick/utility.h" |
48 | | #include "magick/static.h" |
49 | | |
50 | | /* |
51 | | Forward declarations. |
52 | | */ |
53 | | #if defined(HasJBIG) |
54 | | static unsigned int |
55 | | WriteJBIGImage(const ImageInfo *,Image *); |
56 | | #endif |
57 | | |
58 | | #if defined(HasJBIG) |
59 | | #if defined(__cplusplus) || defined(c_plusplus) |
60 | | extern "C" { |
61 | | #endif |
62 | | #include "jbig.h" |
63 | | #if defined(__cplusplus) || defined(c_plusplus) |
64 | | } |
65 | | #endif |
66 | | /* |
67 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
68 | | % % |
69 | | % % |
70 | | % % |
71 | | % R e a d J B I G I m a g e % |
72 | | % % |
73 | | % % |
74 | | % % |
75 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
76 | | % |
77 | | % Method ReadJBIGImage reads a JBIG image file and returns it. It |
78 | | % allocates the memory necessary for the new Image structure and returns a |
79 | | % pointer to the new image. |
80 | | % |
81 | | % The format of the ReadJBIGImage method is: |
82 | | % |
83 | | % Image *ReadJBIGImage(const ImageInfo *image_info, |
84 | | % ExceptionInfo *exception) |
85 | | % |
86 | | % A description of each parameter follows: |
87 | | % |
88 | | % o image: Method ReadJBIGImage returns a pointer to the image after |
89 | | % reading. A null image is returned if there is a memory shortage or |
90 | | % if the image cannot be read. |
91 | | % |
92 | | % o image_info: Specifies a pointer to a ImageInfo structure. |
93 | | % |
94 | | % o exception: return any errors or warnings in this structure. |
95 | | % |
96 | | % |
97 | | */ |
98 | | static Image *ReadJBIGImage(const ImageInfo *image_info, |
99 | | ExceptionInfo *exception) |
100 | 2.88k | { |
101 | 9.04k | #define MaxBufferSize 8192 |
102 | | |
103 | 2.88k | Image |
104 | 2.88k | *image; |
105 | | |
106 | 2.88k | int |
107 | 2.88k | status; |
108 | | |
109 | 2.88k | size_t |
110 | 2.88k | length; |
111 | | |
112 | 2.88k | unsigned long |
113 | 2.88k | y; |
114 | | |
115 | 2.88k | register PixelPacket |
116 | 2.88k | *q; |
117 | | |
118 | 2.88k | register unsigned char |
119 | 2.88k | *p; |
120 | | |
121 | 2.88k | size_t |
122 | 2.88k | count; |
123 | | |
124 | 2.88k | struct jbg_dec_state |
125 | 2.88k | jbig_info; |
126 | | |
127 | 2.88k | unsigned char |
128 | 2.88k | *buffer; |
129 | | |
130 | | /* |
131 | | Open image file. |
132 | | */ |
133 | 2.88k | assert(image_info != (const ImageInfo *) NULL); |
134 | 2.88k | assert(image_info->signature == MagickSignature); |
135 | 2.88k | assert(exception != (ExceptionInfo *) NULL); |
136 | 2.88k | assert(exception->signature == MagickSignature); |
137 | 2.88k | image=AllocateImage(image_info); |
138 | 2.88k | status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
139 | 2.88k | if (status == False) |
140 | 2.88k | ThrowReaderException(FileOpenError,UnableToOpenFile,image); |
141 | | /* |
142 | | Initialize JBIG toolkit. |
143 | | */ |
144 | 2.88k | jbg_dec_init(&jbig_info); |
145 | | |
146 | | /* |
147 | | Attempt to set maximum image dimensions based on resource limits. |
148 | | |
149 | | This does work in normal cases, but in other cases the first call |
150 | | to jbg_dec_in() takes a very long time, and it returns large image |
151 | | dimensions anyway. |
152 | | */ |
153 | 2.88k | { |
154 | 2.88k | magick_int64_t |
155 | 2.88k | width_limit, |
156 | 2.88k | height_limit, |
157 | 2.88k | pixels_limit; |
158 | | |
159 | 2.88k | width_limit = GetMagickResourceLimit(WidthResource); |
160 | 2.88k | height_limit = GetMagickResourceLimit(HeightResource); |
161 | 2.88k | pixels_limit = GetMagickResourceLimit(PixelsResource); |
162 | | |
163 | 2.88k | if (MagickResourceInfinity != width_limit) |
164 | 2.88k | if ((image->columns == 0) || (image->columns > (unsigned long) width_limit)) |
165 | 2.88k | image->columns = (unsigned long) width_limit; |
166 | | |
167 | 2.88k | if (MagickResourceInfinity != height_limit) |
168 | 2.88k | if ((image->rows == 0) || (image->rows > (unsigned long) height_limit)) |
169 | 2.88k | image->rows = (unsigned long) height_limit; |
170 | | |
171 | 2.88k | if ((MagickResourceInfinity != pixels_limit) && |
172 | 2.88k | ((magick_int64_t) (image->columns*image->rows)) > pixels_limit) |
173 | 0 | { |
174 | 0 | magick_int64_t max_dimension = sqrt((double) pixels_limit); |
175 | 0 | image->columns = (unsigned long) max_dimension; |
176 | 0 | image->rows = (unsigned long) max_dimension; |
177 | 0 | } |
178 | | |
179 | 2.88k | if (image->logging) |
180 | 2.88k | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
181 | 2.88k | "JBIG: Setting maximum dimensions %lux%lu", |
182 | 2.88k | image->columns, image->rows); |
183 | 2.88k | jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns, |
184 | 2.88k | (unsigned long) image->rows); |
185 | 2.88k | } |
186 | | |
187 | 2.88k | image->depth=1; |
188 | | /* |
189 | | Read JBIG file. |
190 | | */ |
191 | 2.88k | buffer=MagickAllocateMemory(unsigned char *,MaxBufferSize); |
192 | 2.88k | if (buffer == (unsigned char *) NULL) |
193 | 2.88k | ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
194 | 2.88k | status=JBG_EAGAIN; |
195 | | /* FIXME: Should handle JBG_EOK_INTR for multi-resolution support */ |
196 | 2.88k | if (image->logging) |
197 | 2.88k | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
198 | 2.88k | "JBIG: Entering jbg_dec_in() decode loop..."); |
199 | 2.88k | do |
200 | 9.04k | { |
201 | 9.04k | length=(long) ReadBlob(image,MaxBufferSize,(char *) buffer); |
202 | 9.04k | if (length == 0) |
203 | 1.23k | break; |
204 | 7.81k | p=buffer; |
205 | 7.81k | count=0; |
206 | 15.6k | while ((length > 0) && (status == JBG_EAGAIN)) |
207 | 7.81k | { |
208 | 7.81k | status=jbg_dec_in(&jbig_info,p,length,&count); |
209 | 7.81k | if (image->logging) |
210 | 7.81k | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
211 | 7.81k | "JBIG: jbg_dec_in() returns 0x%02x (\"%s\")", |
212 | 7.81k | status, jbg_strerror(status)); |
213 | 7.81k | p+=count; |
214 | 7.81k | length-=count; |
215 | 7.81k | } |
216 | 7.81k | } while (status == JBG_EAGAIN); |
217 | 2.88k | if (JBG_EOK != status) |
218 | 2.00k | { |
219 | 2.00k | jbg_dec_free(&jbig_info); |
220 | 2.00k | MagickFreeMemory(buffer); |
221 | 2.00k | ThrowReaderException(CorruptImageError,CorruptImage,image); |
222 | 0 | } |
223 | | /* |
224 | | Create colormap. |
225 | | */ |
226 | 885 | image->columns=jbg_dec_getwidth(&jbig_info); |
227 | 885 | image->rows=jbg_dec_getheight(&jbig_info); |
228 | 885 | if ((image_info->type != GrayscaleType) && |
229 | 885 | (image_info->type != TrueColorType)) |
230 | 885 | { |
231 | 885 | if (image->logging) |
232 | 885 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
233 | 885 | "Allocating colormap..."); |
234 | 885 | if (!AllocateImageColormap(image,2)) |
235 | 0 | { |
236 | 0 | MagickFreeMemory(buffer); |
237 | |
|
238 | 0 | } |
239 | 885 | image->colormap[0].red=0; |
240 | 885 | image->colormap[0].green=0; |
241 | 885 | image->colormap[0].blue=0; |
242 | 885 | image->colormap[0].opacity=0; |
243 | 885 | image->colormap[1].red=MaxRGB; |
244 | 885 | image->colormap[1].green=MaxRGB; |
245 | 885 | image->colormap[1].blue=MaxRGB; |
246 | 885 | image->colormap[1].opacity=0; |
247 | 885 | } |
248 | 885 | image->x_resolution=300; |
249 | 885 | image->y_resolution=300; |
250 | 885 | image->is_grayscale=MagickTrue; |
251 | 885 | image->is_monochrome=MagickTrue; |
252 | 885 | image->colorspace=GRAYColorspace; |
253 | 885 | if (image->logging) |
254 | 885 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
255 | 885 | "JBIG: %lux%lu, resolution %gx%g", |
256 | 885 | image->columns, image->rows, |
257 | 885 | image->x_resolution,image->y_resolution); |
258 | 885 | if (image_info->ping) |
259 | 0 | { |
260 | 0 | jbg_dec_free(&jbig_info); |
261 | 0 | MagickFreeMemory(buffer); |
262 | 0 | CloseBlob(image); |
263 | 0 | return(image); |
264 | 0 | } |
265 | 885 | if (CheckImagePixelLimits(image, exception) != MagickPass) |
266 | 110 | { |
267 | 110 | jbg_dec_free(&jbig_info); |
268 | 110 | MagickFreeMemory(buffer); |
269 | 110 | ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); |
270 | 0 | } |
271 | | /* |
272 | | Convert bitmap image to pixel packets. |
273 | | */ |
274 | 775 | { |
275 | 775 | ImportPixelAreaOptions |
276 | 775 | import_options; |
277 | | |
278 | 775 | ImportPixelAreaInfo |
279 | 775 | import_info; |
280 | | |
281 | 775 | ImportPixelAreaOptionsInit(&import_options); |
282 | 775 | import_options.grayscale_miniswhite=MagickTrue; |
283 | 775 | p=jbg_dec_getimage(&jbig_info,0); |
284 | 857k | for (y=0; y < image->rows; y++) |
285 | 856k | { |
286 | 856k | q=SetImagePixels(image,0,y,image->columns,1); |
287 | 856k | if (q == (PixelPacket *) NULL) |
288 | 0 | break; |
289 | 856k | if (!ImportImagePixelArea(image,GrayQuantum,1,p,&import_options,&import_info)) |
290 | 0 | break; |
291 | 856k | p+=import_info.bytes_imported; |
292 | 856k | if (!SyncImagePixels(image)) |
293 | 0 | break; |
294 | 856k | if (QuantumTick(y,image->rows)) |
295 | 73.2k | if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText, |
296 | 73.2k | image->filename, |
297 | 73.2k | image->columns,image->rows)) |
298 | 0 | break; |
299 | 856k | } |
300 | 775 | } |
301 | | /* |
302 | | Free scale resource. |
303 | | */ |
304 | 775 | jbg_dec_free(&jbig_info); |
305 | 775 | MagickFreeMemory(buffer); |
306 | 775 | CloseBlob(image); |
307 | 775 | image->is_grayscale=MagickTrue; |
308 | 775 | image->is_monochrome=MagickTrue; |
309 | 775 | StopTimer(&image->timer); |
310 | 775 | return(image); |
311 | 885 | } |
312 | | #endif |
313 | | |
314 | | /* |
315 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
316 | | % % |
317 | | % % |
318 | | % % |
319 | | % R e g i s t e r J B I G I m a g e % |
320 | | % % |
321 | | % % |
322 | | % % |
323 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
324 | | % |
325 | | % Method RegisterJBIGImage adds attributes for the JBIG image format to |
326 | | % the list of supported formats. The attributes include the image format |
327 | | % tag, a method to read and/or write the format, whether the format |
328 | | % supports the saving of more than one frame to the same file or blob, |
329 | | % whether the format supports native in-memory I/O, and a brief |
330 | | % description of the format. |
331 | | % |
332 | | % The format of the RegisterJBIGImage method is: |
333 | | % |
334 | | % RegisterJBIGImage(void) |
335 | | % |
336 | | */ |
337 | | ModuleExport void RegisterJBIGImage(void) |
338 | 2 | { |
339 | 2 | static const char |
340 | 2 | description[]="Joint Bi-level Image experts Group interchange format"; |
341 | | |
342 | 2 | static const char |
343 | 2 | version[]="JBIG-Kit " JBG_VERSION " (" JBG_LICENCE " license)"; |
344 | | |
345 | 2 | MagickInfo |
346 | 2 | *entry; |
347 | | |
348 | 2 | entry=SetMagickInfo("BIE"); |
349 | 2 | #if defined(HasJBIG) |
350 | 2 | entry->decoder=(DecoderHandler) ReadJBIGImage; |
351 | 2 | entry->encoder=(EncoderHandler) WriteJBIGImage; |
352 | 2 | #endif |
353 | 2 | entry->adjoin=False; |
354 | 2 | entry->description=description; |
355 | 2 | entry->version=version; |
356 | 2 | entry->module="JBIG"; |
357 | 2 | entry->coder_class=StableCoderClass; |
358 | 2 | (void) RegisterMagickInfo(entry); |
359 | | |
360 | 2 | entry=SetMagickInfo("JBG"); |
361 | 2 | #if defined(HasJBIG) |
362 | 2 | entry->decoder=(DecoderHandler) ReadJBIGImage; |
363 | 2 | entry->encoder=(EncoderHandler) WriteJBIGImage; |
364 | 2 | #endif |
365 | 2 | entry->description=description; |
366 | 2 | entry->version=version; |
367 | 2 | entry->module="JBIG"; |
368 | 2 | entry->coder_class=StableCoderClass; |
369 | 2 | (void) RegisterMagickInfo(entry); |
370 | | |
371 | 2 | entry=SetMagickInfo("JBIG"); |
372 | 2 | #if defined(HasJBIG) |
373 | 2 | entry->decoder=(DecoderHandler) ReadJBIGImage; |
374 | 2 | entry->encoder=(EncoderHandler) WriteJBIGImage; |
375 | 2 | #endif |
376 | 2 | entry->description=description; |
377 | 2 | entry->version=version; |
378 | 2 | entry->module="JBIG"; |
379 | 2 | entry->coder_class=UnstableCoderClass; |
380 | 2 | (void) RegisterMagickInfo(entry); |
381 | 2 | } |
382 | | |
383 | | /* |
384 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
385 | | % % |
386 | | % % |
387 | | % % |
388 | | % U n r e g i s t e r J B I G I m a g e % |
389 | | % % |
390 | | % % |
391 | | % % |
392 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
393 | | % |
394 | | % Method UnregisterJBIGImage removes format registrations made by the |
395 | | % JBIG module from the list of supported formats. |
396 | | % |
397 | | % The format of the UnregisterJBIGImage method is: |
398 | | % |
399 | | % UnregisterJBIGImage(void) |
400 | | % |
401 | | */ |
402 | | ModuleExport void UnregisterJBIGImage(void) |
403 | 0 | { |
404 | 0 | (void) UnregisterMagickInfo("BIE"); |
405 | 0 | (void) UnregisterMagickInfo("JBG"); |
406 | 0 | (void) UnregisterMagickInfo("JBIG"); |
407 | 0 | } |
408 | | |
409 | | #if defined(HasJBIG) |
410 | | /* |
411 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
412 | | % % |
413 | | % % |
414 | | % % |
415 | | % W r i t e J B I G I m a g e % |
416 | | % % |
417 | | % % |
418 | | % % |
419 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
420 | | % |
421 | | % Method WriteJBIGImage writes an image in the JBIG encoded image format. |
422 | | % |
423 | | % The format of the WriteJBIGImage method is: |
424 | | % |
425 | | % unsigned int WriteJBIGImage(const ImageInfo *image_info,Image *image) |
426 | | % |
427 | | % A description of each parameter follows. |
428 | | % |
429 | | % o status: Method WriteJBIGImage return True if the image is written. |
430 | | % False is returned is there is a memory shortage or if the image file |
431 | | % fails to write. |
432 | | % |
433 | | % o image_info: Specifies a pointer to a ImageInfo structure. |
434 | | % |
435 | | % o image: A pointer to an Image structure. |
436 | | % |
437 | | % |
438 | | */ |
439 | | |
440 | | static void JBIGEncode(unsigned char *pixels,size_t length,void *data) |
441 | 76.8k | { |
442 | 76.8k | Image |
443 | 76.8k | *image; |
444 | | |
445 | 76.8k | image=(Image *) data; |
446 | 76.8k | (void) WriteBlob(image,length,pixels); |
447 | 76.8k | } |
448 | | |
449 | | static unsigned int WriteJBIGImage(const ImageInfo *image_info,Image *image) |
450 | 775 | { |
451 | 775 | double |
452 | 775 | jbig_lib_version; |
453 | | |
454 | 775 | unsigned long |
455 | 775 | y; |
456 | | |
457 | 775 | register const PixelPacket |
458 | 775 | *p; |
459 | | |
460 | 775 | register unsigned char |
461 | 775 | *q; |
462 | | |
463 | 775 | struct jbg_enc_state |
464 | 775 | jbig_info; |
465 | | |
466 | 775 | unsigned char |
467 | 775 | *pixels; |
468 | | |
469 | 775 | size_t |
470 | 775 | bytes_per_row; |
471 | | |
472 | 775 | unsigned int |
473 | 775 | status; |
474 | | |
475 | 775 | unsigned long |
476 | 775 | scene; |
477 | | |
478 | 775 | size_t |
479 | 775 | image_list_length; |
480 | | |
481 | | /* |
482 | | Open image file. |
483 | | */ |
484 | 775 | assert(image_info != (const ImageInfo *) NULL); |
485 | 775 | assert(image_info->signature == MagickSignature); |
486 | 775 | assert(image != (Image *) NULL); |
487 | 775 | assert(image->signature == MagickSignature); |
488 | 775 | image_list_length=GetImageListLength(image); |
489 | 775 | status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); |
490 | 775 | if (status == False) |
491 | 775 | ThrowWriterException(FileOpenError,UnableToOpenFile,image); |
492 | 775 | jbig_lib_version=strtod(JBG_VERSION, (char **)NULL); |
493 | 775 | scene=0; |
494 | 775 | do |
495 | 775 | { |
496 | | /* |
497 | | Ensure that image is in an RGB space. |
498 | | */ |
499 | 775 | if (TransformColorspace(image,RGBColorspace) == MagickFail) |
500 | 775 | ThrowWriterException(CoderError,UnableToTransformColorspace,image); |
501 | | /* |
502 | | Allocate pixel data. |
503 | | */ |
504 | 775 | bytes_per_row=((image->columns+7) >> 3); |
505 | 775 | pixels=MagickAllocateResourceLimitedArray(unsigned char *,bytes_per_row,image->rows); |
506 | 775 | if (pixels == (unsigned char *) NULL) |
507 | 775 | ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); |
508 | | /* |
509 | | Convert pixels to a bitmap. |
510 | | */ |
511 | 775 | { |
512 | 775 | ExportPixelAreaOptions |
513 | 775 | export_options; |
514 | | |
515 | 775 | ExportPixelAreaInfo |
516 | 775 | export_info; |
517 | | |
518 | 775 | ExportPixelAreaOptionsInit(&export_options); |
519 | 775 | export_options.grayscale_miniswhite=MagickTrue; |
520 | 775 | q=pixels; |
521 | 857k | for (y=0; y < image->rows; y++) |
522 | 856k | { |
523 | 856k | p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); |
524 | 856k | if (p == (const PixelPacket *) NULL) |
525 | 0 | break; |
526 | 856k | if (ExportImagePixelArea(image,GrayQuantum,1,q, |
527 | 856k | &export_options,&export_info) == MagickFail) |
528 | 0 | break; |
529 | 856k | q+=export_info.bytes_exported; |
530 | 856k | if (image->previous == (Image *) NULL) |
531 | 856k | if (QuantumTick(y,image->rows)) |
532 | 73.2k | if (!MagickMonitorFormatted(y,image->rows,&image->exception, |
533 | 73.2k | SaveImageText,image->filename, |
534 | 73.2k | image->columns,image->rows)) |
535 | 0 | break; |
536 | 856k | } |
537 | 775 | } |
538 | | /* |
539 | | Initialize JBIG info structure. |
540 | | */ |
541 | 775 | jbg_enc_init(&jbig_info,image->columns,image->rows,1,&pixels, |
542 | 775 | (void (*)(unsigned char *,size_t,void *)) JBIGEncode,image); |
543 | 775 | if (image_info->subimage != 0) |
544 | 0 | { |
545 | 0 | jbg_enc_layers(&jbig_info,(int) image_info->subimage); |
546 | 0 | } |
547 | 775 | else |
548 | 775 | { |
549 | 775 | long |
550 | 775 | sans_offset; |
551 | | |
552 | 775 | unsigned long |
553 | 775 | x_resolution, |
554 | 775 | y_resolution; |
555 | | |
556 | 775 | x_resolution=640; |
557 | 775 | y_resolution=480; |
558 | 775 | sans_offset=0; |
559 | 775 | if (image_info->density != (char *) NULL) |
560 | 0 | (void) GetGeometry(image_info->density,&sans_offset,&sans_offset, |
561 | 0 | &x_resolution,&y_resolution); |
562 | 775 | (void) jbg_enc_lrlmax(&jbig_info,x_resolution,y_resolution); |
563 | 775 | } |
564 | 775 | (void) jbg_enc_lrange(&jbig_info,-1,-1); |
565 | 775 | jbg_enc_options(&jbig_info, /* Encoder state */ |
566 | 775 | JBG_ILEAVE| JBG_SMID, /* Order */ |
567 | 775 | JBG_TPDON | JBG_TPBON | JBG_DPON, /* Options */ |
568 | | /* Lines per stripe in resolution layer 0. (was -1)*/ |
569 | 775 | (jbig_lib_version < 1.6 ? -1 : 0), |
570 | 775 | -1, /* mx */ |
571 | 775 | -1); /* my */ |
572 | | /* |
573 | | Write JBIG image. |
574 | | */ |
575 | 775 | jbg_enc_out(&jbig_info); |
576 | 775 | jbg_enc_free(&jbig_info); |
577 | 775 | MagickFreeResourceLimitedMemory(unsigned char *,pixels); |
578 | 775 | if (image->next == (Image *) NULL) |
579 | 775 | break; |
580 | 0 | image=SyncNextImageInList(image); |
581 | 0 | if (!MagickMonitorFormatted(scene++,image_list_length, |
582 | 0 | &image->exception,SaveImagesText, |
583 | 0 | image->filename)) |
584 | 0 | break; |
585 | 0 | } while (image_info->adjoin); |
586 | 775 | if (image_info->adjoin) |
587 | 775 | while (image->previous != (Image *) NULL) |
588 | 0 | image=image->previous; |
589 | 775 | status &= CloseBlob(image); |
590 | 775 | return(status); |
591 | 775 | } |
592 | | #endif |