]> granicus.if.org Git - imagemagick/blob - magick/compress.c
minor note
[imagemagick] / magick / compress.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %           CCCC   OOO   M   M  PPPP   RRRR   EEEEE   SSSSS  SSSSS            %
7 %          C      O   O  MM MM  P   P  R   R  E       SS     SS               %
8 %          C      O   O  M M M  PPPP   RRRR   EEE      SSS    SSS             %
9 %          C      O   O  M   M  P      R R    E          SS     SS            %
10 %           CCCC   OOO   M   M  P      R  R   EEEEE   SSSSS  SSSSS            %
11 %                                                                             %
12 %                                                                             %
13 %             MagickCore Image Compression/Decompression Methods              %
14 %                                                                             %
15 %                           Software Design                                   %
16 %                             John Cristy                                     %
17 %                              May  1993                                      %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    http://www.imagemagick.org/script/license.php                            %
27 %                                                                             %
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.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 \f
40 /*
41   Include declarations.
42 */
43 #include "magick/studio.h"
44 #include "magick/blob.h"
45 #include "magick/blob-private.h"
46 #include "magick/color-private.h"
47 #include "magick/cache.h"
48 #include "magick/compress.h"
49 #include "magick/constitute.h"
50 #include "magick/exception.h"
51 #include "magick/exception-private.h"
52 #include "magick/image-private.h"
53 #include "magick/list.h"
54 #include "magick/memory_.h"
55 #include "magick/monitor.h"
56 #include "magick/monitor-private.h"
57 #include "magick/option.h"
58 #include "magick/resource_.h"
59 #include "magick/string_.h"
60 #if defined(MAGICKCORE_TIFF_DELEGATE)
61 #if defined(MAGICKCORE_HAVE_TIFFCONF_H)
62 #include "tiffconf.h"
63 #endif
64 #include "tiffio.h"
65 #define CCITTParam  "-1"
66 #else
67 #define CCITTParam  "0"
68 #endif
69 #if defined(MAGICKCORE_ZLIB_DELEGATE)
70 #include "zlib.h"
71 #endif
72 \f
73 /*
74   Typedef declarations.
75 */
76 struct _Ascii85Info
77 {
78   ssize_t
79     offset,
80     line_break;
81
82   unsigned char
83     buffer[10];
84 };
85
86 typedef struct HuffmanTable
87 {
88   size_t
89     id,
90     code,
91     length,
92     count;
93 } HuffmanTable;
94 \f
95 /*
96   Huffman coding declarations.
97 */
98 #define TWId  23
99 #define MWId  24
100 #define TBId  25
101 #define MBId  26
102 #define EXId  27
103
104 static const HuffmanTable
105   MBTable[]=
106   {
107     { MBId, 0x0f, 10, 64 }, { MBId, 0xc8, 12, 128 },
108     { MBId, 0xc9, 12, 192 }, { MBId, 0x5b, 12, 256 },
109     { MBId, 0x33, 12, 320 }, { MBId, 0x34, 12, 384 },
110     { MBId, 0x35, 12, 448 }, { MBId, 0x6c, 13, 512 },
111     { MBId, 0x6d, 13, 576 }, { MBId, 0x4a, 13, 640 },
112     { MBId, 0x4b, 13, 704 }, { MBId, 0x4c, 13, 768 },
113     { MBId, 0x4d, 13, 832 }, { MBId, 0x72, 13, 896 },
114     { MBId, 0x73, 13, 960 }, { MBId, 0x74, 13, 1024 },
115     { MBId, 0x75, 13, 1088 }, { MBId, 0x76, 13, 1152 },
116     { MBId, 0x77, 13, 1216 }, { MBId, 0x52, 13, 1280 },
117     { MBId, 0x53, 13, 1344 }, { MBId, 0x54, 13, 1408 },
118     { MBId, 0x55, 13, 1472 }, { MBId, 0x5a, 13, 1536 },
119     { MBId, 0x5b, 13, 1600 }, { MBId, 0x64, 13, 1664 },
120     { MBId, 0x65, 13, 1728 }, { MBId, 0x00, 0, 0 }
121   };
122
123 static const HuffmanTable
124   EXTable[]=
125   {
126     { EXId, 0x08, 11, 1792 }, { EXId, 0x0c, 11, 1856 },
127     { EXId, 0x0d, 11, 1920 }, { EXId, 0x12, 12, 1984 },
128     { EXId, 0x13, 12, 2048 }, { EXId, 0x14, 12, 2112 },
129     { EXId, 0x15, 12, 2176 }, { EXId, 0x16, 12, 2240 },
130     { EXId, 0x17, 12, 2304 }, { EXId, 0x1c, 12, 2368 },
131     { EXId, 0x1d, 12, 2432 }, { EXId, 0x1e, 12, 2496 },
132     { EXId, 0x1f, 12, 2560 }, { EXId, 0x00, 0, 0 }
133   };
134
135 static const HuffmanTable
136   MWTable[]=
137   {
138     { MWId, 0x1b, 5, 64 }, { MWId, 0x12, 5, 128 },
139     { MWId, 0x17, 6, 192 }, { MWId, 0x37, 7, 256 },
140     { MWId, 0x36, 8, 320 }, { MWId, 0x37, 8, 384 },
141     { MWId, 0x64, 8, 448 }, { MWId, 0x65, 8, 512 },
142     { MWId, 0x68, 8, 576 }, { MWId, 0x67, 8, 640 },
143     { MWId, 0xcc, 9, 704 }, { MWId, 0xcd, 9, 768 },
144     { MWId, 0xd2, 9, 832 }, { MWId, 0xd3, 9, 896 },
145     { MWId, 0xd4, 9, 960 }, { MWId, 0xd5, 9, 1024 },
146     { MWId, 0xd6, 9, 1088 }, { MWId, 0xd7, 9, 1152 },
147     { MWId, 0xd8, 9, 1216 }, { MWId, 0xd9, 9, 1280 },
148     { MWId, 0xda, 9, 1344 }, { MWId, 0xdb, 9, 1408 },
149     { MWId, 0x98, 9, 1472 }, { MWId, 0x99, 9, 1536 },
150     { MWId, 0x9a, 9, 1600 }, { MWId, 0x18, 6, 1664 },
151     { MWId, 0x9b, 9, 1728 }, { MWId, 0x00, 0, 0 }
152   };
153
154 static const HuffmanTable
155   TBTable[]=
156   {
157     { TBId, 0x37, 10, 0 }, { TBId, 0x02, 3, 1 }, { TBId, 0x03, 2, 2 },
158     { TBId, 0x02, 2, 3 }, { TBId, 0x03, 3, 4 }, { TBId, 0x03, 4, 5 },
159     { TBId, 0x02, 4, 6 }, { TBId, 0x03, 5, 7 }, { TBId, 0x05, 6, 8 },
160     { TBId, 0x04, 6, 9 }, { TBId, 0x04, 7, 10 }, { TBId, 0x05, 7, 11 },
161     { TBId, 0x07, 7, 12 }, { TBId, 0x04, 8, 13 }, { TBId, 0x07, 8, 14 },
162     { TBId, 0x18, 9, 15 }, { TBId, 0x17, 10, 16 }, { TBId, 0x18, 10, 17 },
163     { TBId, 0x08, 10, 18 }, { TBId, 0x67, 11, 19 }, { TBId, 0x68, 11, 20 },
164     { TBId, 0x6c, 11, 21 }, { TBId, 0x37, 11, 22 }, { TBId, 0x28, 11, 23 },
165     { TBId, 0x17, 11, 24 }, { TBId, 0x18, 11, 25 }, { TBId, 0xca, 12, 26 },
166     { TBId, 0xcb, 12, 27 }, { TBId, 0xcc, 12, 28 }, { TBId, 0xcd, 12, 29 },
167     { TBId, 0x68, 12, 30 }, { TBId, 0x69, 12, 31 }, { TBId, 0x6a, 12, 32 },
168     { TBId, 0x6b, 12, 33 }, { TBId, 0xd2, 12, 34 }, { TBId, 0xd3, 12, 35 },
169     { TBId, 0xd4, 12, 36 }, { TBId, 0xd5, 12, 37 }, { TBId, 0xd6, 12, 38 },
170     { TBId, 0xd7, 12, 39 }, { TBId, 0x6c, 12, 40 }, { TBId, 0x6d, 12, 41 },
171     { TBId, 0xda, 12, 42 }, { TBId, 0xdb, 12, 43 }, { TBId, 0x54, 12, 44 },
172     { TBId, 0x55, 12, 45 }, { TBId, 0x56, 12, 46 }, { TBId, 0x57, 12, 47 },
173     { TBId, 0x64, 12, 48 }, { TBId, 0x65, 12, 49 }, { TBId, 0x52, 12, 50 },
174     { TBId, 0x53, 12, 51 }, { TBId, 0x24, 12, 52 }, { TBId, 0x37, 12, 53 },
175     { TBId, 0x38, 12, 54 }, { TBId, 0x27, 12, 55 }, { TBId, 0x28, 12, 56 },
176     { TBId, 0x58, 12, 57 }, { TBId, 0x59, 12, 58 }, { TBId, 0x2b, 12, 59 },
177     { TBId, 0x2c, 12, 60 }, { TBId, 0x5a, 12, 61 }, { TBId, 0x66, 12, 62 },
178     { TBId, 0x67, 12, 63 }, { TBId, 0x00, 0, 0 }
179   };
180
181 static const HuffmanTable
182   TWTable[]=
183   {
184     { TWId, 0x35, 8, 0 }, { TWId, 0x07, 6, 1 }, { TWId, 0x07, 4, 2 },
185     { TWId, 0x08, 4, 3 }, { TWId, 0x0b, 4, 4 }, { TWId, 0x0c, 4, 5 },
186     { TWId, 0x0e, 4, 6 }, { TWId, 0x0f, 4, 7 }, { TWId, 0x13, 5, 8 },
187     { TWId, 0x14, 5, 9 }, { TWId, 0x07, 5, 10 }, { TWId, 0x08, 5, 11 },
188     { TWId, 0x08, 6, 12 }, { TWId, 0x03, 6, 13 }, { TWId, 0x34, 6, 14 },
189     { TWId, 0x35, 6, 15 }, { TWId, 0x2a, 6, 16 }, { TWId, 0x2b, 6, 17 },
190     { TWId, 0x27, 7, 18 }, { TWId, 0x0c, 7, 19 }, { TWId, 0x08, 7, 20 },
191     { TWId, 0x17, 7, 21 }, { TWId, 0x03, 7, 22 }, { TWId, 0x04, 7, 23 },
192     { TWId, 0x28, 7, 24 }, { TWId, 0x2b, 7, 25 }, { TWId, 0x13, 7, 26 },
193     { TWId, 0x24, 7, 27 }, { TWId, 0x18, 7, 28 }, { TWId, 0x02, 8, 29 },
194     { TWId, 0x03, 8, 30 }, { TWId, 0x1a, 8, 31 }, { TWId, 0x1b, 8, 32 },
195     { TWId, 0x12, 8, 33 }, { TWId, 0x13, 8, 34 }, { TWId, 0x14, 8, 35 },
196     { TWId, 0x15, 8, 36 }, { TWId, 0x16, 8, 37 }, { TWId, 0x17, 8, 38 },
197     { TWId, 0x28, 8, 39 }, { TWId, 0x29, 8, 40 }, { TWId, 0x2a, 8, 41 },
198     { TWId, 0x2b, 8, 42 }, { TWId, 0x2c, 8, 43 }, { TWId, 0x2d, 8, 44 },
199     { TWId, 0x04, 8, 45 }, { TWId, 0x05, 8, 46 }, { TWId, 0x0a, 8, 47 },
200     { TWId, 0x0b, 8, 48 }, { TWId, 0x52, 8, 49 }, { TWId, 0x53, 8, 50 },
201     { TWId, 0x54, 8, 51 }, { TWId, 0x55, 8, 52 }, { TWId, 0x24, 8, 53 },
202     { TWId, 0x25, 8, 54 }, { TWId, 0x58, 8, 55 }, { TWId, 0x59, 8, 56 },
203     { TWId, 0x5a, 8, 57 }, { TWId, 0x5b, 8, 58 }, { TWId, 0x4a, 8, 59 },
204     { TWId, 0x4b, 8, 60 }, { TWId, 0x32, 8, 61 }, { TWId, 0x33, 8, 62 },
205     { TWId, 0x34, 8, 63 }, { TWId, 0x00, 0, 0 }
206   };
207 \f
208 /*
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 %                                                                             %
211 %                                                                             %
212 %                                                                             %
213 %   A S C I I 8 5 E n c o d e                                                 %
214 %                                                                             %
215 %                                                                             %
216 %                                                                             %
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218 %
219 %  ASCII85Encode() encodes data in ASCII base-85 format.  ASCII base-85
220 %  encoding produces five ASCII printing characters from every four bytes of
221 %  binary data.
222 %
223 %  The format of the ASCII85Encode method is:
224 %
225 %      void Ascii85Encode(Image *image,const size_t code)
226 %
227 %  A description of each parameter follows:
228 %
229 %    o code: a binary unsigned char to encode to ASCII 85.
230 %
231 %    o file: write the encoded ASCII character to this file.
232 %
233 %
234 */
235 #define MaxLineExtent  36
236
237 static char *Ascii85Tuple(unsigned char *data)
238 {
239   static char
240     tuple[6];
241
242   register ssize_t
243     i,
244     x;
245
246   size_t
247     code,
248     quantum;
249
250   code=((((size_t) data[0] << 8) | (size_t) data[1]) << 16) |
251     ((size_t) data[2] << 8) | (size_t) data[3];
252   if (code == 0L)
253     {
254       tuple[0]='z';
255       tuple[1]='\0';
256       return(tuple);
257     }
258   quantum=85UL*85UL*85UL*85UL;
259   for (i=0; i < 4; i++)
260   {
261     x=(ssize_t) (code/quantum);
262     code-=quantum*x;
263     tuple[i]=(char) (x+(int) '!');
264     quantum/=85L;
265   }
266   tuple[4]=(char) ((code % 85L)+(int) '!');
267   tuple[5]='\0';
268   return(tuple);
269 }
270
271 MagickExport void Ascii85Initialize(Image *image)
272 {
273   /*
274     Allocate image structure.
275   */
276   if (image->ascii85 == (Ascii85Info *) NULL)
277     image->ascii85=(Ascii85Info *) AcquireMagickMemory(sizeof(*image->ascii85));
278   if (image->ascii85 == (Ascii85Info *) NULL)
279     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
280   (void) ResetMagickMemory(image->ascii85,0,sizeof(*image->ascii85));
281   image->ascii85->line_break=MaxLineExtent << 1;
282   image->ascii85->offset=0;
283 }
284
285 MagickExport void Ascii85Flush(Image *image)
286 {
287   register char
288     *tuple;
289
290   assert(image != (Image *) NULL);
291   assert(image->signature == MagickSignature);
292   if (image->debug != MagickFalse)
293     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
294   assert(image->ascii85 != (Ascii85Info *) NULL);
295   if (image->ascii85->offset > 0)
296     {
297       image->ascii85->buffer[image->ascii85->offset]='\0';
298       image->ascii85->buffer[image->ascii85->offset+1]='\0';
299       image->ascii85->buffer[image->ascii85->offset+2]='\0';
300       tuple=Ascii85Tuple(image->ascii85->buffer);
301       (void) WriteBlob(image,(size_t) image->ascii85->offset+1,
302         (const unsigned char *) (*tuple == 'z' ? "!!!!" : tuple));
303     }
304   (void) WriteBlobByte(image,'~');
305   (void) WriteBlobByte(image,'>');
306   (void) WriteBlobByte(image,'\n');
307 }
308
309 MagickExport void Ascii85Encode(Image *image,const unsigned char code)
310 {
311   register char
312     *q;
313
314   register unsigned char
315     *p;
316
317   ssize_t
318     n;
319
320   assert(image != (Image *) NULL);
321   assert(image->signature == MagickSignature);
322   assert(image->ascii85 != (Ascii85Info *) NULL);
323   image->ascii85->buffer[image->ascii85->offset]=code;
324   image->ascii85->offset++;
325   if (image->ascii85->offset < 4)
326     return;
327   p=image->ascii85->buffer;
328   for (n=image->ascii85->offset; n >= 4; n-=4)
329   {
330     for (q=Ascii85Tuple(p); *q != '\0'; q++)
331     {
332       image->ascii85->line_break--;
333       if ((image->ascii85->line_break < 0) && (*q != '%'))
334         {
335           (void) WriteBlobByte(image,'\n');
336           image->ascii85->line_break=2*MaxLineExtent;
337         }
338       (void) WriteBlobByte(image,(unsigned char) *q);
339     }
340     p+=8;
341   }
342   image->ascii85->offset=n;
343   p-=4;
344   for (n=0; n < 4; n++)
345     image->ascii85->buffer[n]=(*p++);
346 }
347 \f
348 /*
349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 %                                                                             %
351 %                                                                             %
352 %                                                                             %
353 %   H u f f m a n D e c o d e I m a g e                                       %
354 %                                                                             %
355 %                                                                             %
356 %                                                                             %
357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
358 %
359 %  HuffmanDecodeImage() uncompresses an image via Huffman-coding.
360 %
361 %  The format of the HuffmanDecodeImage method is:
362 %
363 %      MagickBooleanType HuffmanDecodeImage(Image *image)
364 %
365 %  A description of each parameter follows:
366 %
367 %    o image: the image.
368 %
369 */
370
371 static inline size_t MagickMax(const size_t x,const size_t y)
372 {
373   if (x > y)
374     return(x);
375   return(y);
376 }
377
378 static inline size_t MagickMin(const size_t x,const size_t y)
379 {
380   if (x < y)
381     return(x);
382   return(y);
383 }
384
385 MagickExport MagickBooleanType HuffmanDecodeImage(Image *image)
386 {
387 #define HashSize  1021
388 #define MBHashA  293
389 #define MBHashB  2695
390 #define MWHashA  3510
391 #define MWHashB  1178
392
393 #define InitializeHashTable(hash,table,a,b) \
394 { \
395   entry=table; \
396   while (entry->code != 0) \
397   {  \
398     hash[((entry->length+a)*(entry->code+b)) % HashSize]=(HuffmanTable *) entry; \
399     entry++; \
400   } \
401 }
402
403 #define InputBit(bit)  \
404 {  \
405   if ((mask & 0xff) == 0)  \
406     {  \
407       byte=ReadBlobByte(image);  \
408       if (byte == EOF)  \
409         break;  \
410       mask=0x80;  \
411     }  \
412   runlength++;  \
413   bit=(size_t) ((byte & mask) != 0 ? 0x01 : 0x00); \
414   mask>>=1;  \
415   if (bit != 0)  \
416     runlength=0;  \
417 }
418
419   CacheView
420     *image_view;
421
422   const HuffmanTable
423     *entry;
424
425   ExceptionInfo
426     *exception;
427
428   HuffmanTable
429     **mb_hash,
430     **mw_hash;
431
432   IndexPacket
433     index;
434
435   int
436     byte;
437
438   MagickBooleanType
439     proceed;
440
441   register IndexPacket
442     *indexes;
443
444   register ssize_t
445     i;
446
447   register unsigned char
448     *p;
449
450   size_t
451     bit,
452     code,
453     mask,
454     length,
455     null_lines,
456     runlength;
457
458   ssize_t
459     count,
460     y;
461
462   unsigned char
463     *scanline;
464
465   unsigned int
466     bail,
467     color;
468
469   /*
470     Allocate buffers.
471   */
472   assert(image != (Image *) NULL);
473   assert(image->signature == MagickSignature);
474   if (image->debug != MagickFalse)
475     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
476   mb_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mb_hash));
477   mw_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mw_hash));
478   scanline=(unsigned char *) AcquireQuantumMemory((size_t) image->columns,
479     sizeof(*scanline));
480   if ((mb_hash == (HuffmanTable **) NULL) ||
481       (mw_hash == (HuffmanTable **) NULL) ||
482       (scanline == (unsigned char *) NULL))
483     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
484       image->filename);
485   /*
486     Initialize Huffman tables.
487   */
488   for (i=0; i < HashSize; i++)
489   {
490     mb_hash[i]=(HuffmanTable *) NULL;
491     mw_hash[i]=(HuffmanTable *) NULL;
492   }
493   InitializeHashTable(mw_hash,TWTable,MWHashA,MWHashB);
494   InitializeHashTable(mw_hash,MWTable,MWHashA,MWHashB);
495   InitializeHashTable(mw_hash,EXTable,MWHashA,MWHashB);
496   InitializeHashTable(mb_hash,TBTable,MBHashA,MBHashB);
497   InitializeHashTable(mb_hash,MBTable,MBHashA,MBHashB);
498   InitializeHashTable(mb_hash,EXTable,MBHashA,MBHashB);
499   /*
500     Uncompress 1D Huffman to runlength encoded pixels.
501   */
502   byte=0;
503   mask=0;
504   null_lines=0;
505   runlength=0;
506   while (runlength < 11)
507    InputBit(bit);
508   do { InputBit(bit); } while ((int) bit == 0);
509   image->x_resolution=204.0;
510   image->y_resolution=196.0;
511   image->units=PixelsPerInchResolution;
512   exception=(&image->exception);
513   image_view=AcquireCacheView(image);
514   for (y=0; ((y < (ssize_t) image->rows) && (null_lines < 3)); )
515   {
516     register PixelPacket
517       *restrict q;
518
519     register ssize_t
520       x;
521
522     /*
523       Initialize scanline to white.
524     */
525     p=scanline;
526     for (x=0; x < (ssize_t) image->columns; x++)
527       *p++=(unsigned char) 0;
528     /*
529       Decode Huffman encoded scanline.
530     */
531     color=MagickTrue;
532     code=0;
533     count=0;
534     length=0;
535     runlength=0;
536     x=0;
537     for ( ; ; )
538     {
539       if (byte == EOF)
540         break;
541       if (x >= (ssize_t) image->columns)
542         {
543           while (runlength < 11)
544             InputBit(bit);
545           do { InputBit(bit); } while ((int) bit == 0);
546           break;
547         }
548       bail=MagickFalse;
549       do
550       {
551         if (runlength < 11)
552           InputBit(bit)
553         else
554           {
555             InputBit(bit);
556             if ((int) bit != 0)
557               {
558                 null_lines++;
559                 if (x != 0)
560                   null_lines=0;
561                 bail=MagickTrue;
562                 break;
563               }
564           }
565         code=(code << 1)+(size_t) bit;
566         length++;
567       } while (code == 0);
568       if (bail != MagickFalse)
569         break;
570       if (length > 13)
571         {
572           while (runlength < 11)
573            InputBit(bit);
574           do { InputBit(bit); } while ((int) bit == 0);
575           break;
576         }
577       if (color != MagickFalse)
578         {
579           if (length < 4)
580             continue;
581           entry=mw_hash[((length+MWHashA)*(code+MWHashB)) % HashSize];
582         }
583       else
584         {
585           if (length < 2)
586             continue;
587           entry=mb_hash[((length+MBHashA)*(code+MBHashB)) % HashSize];
588         }
589       if (entry == (const HuffmanTable *) NULL)
590         continue;
591       if ((entry->length != length) || (entry->code != code))
592         continue;
593       switch (entry->id)
594       {
595         case TWId:
596         case TBId:
597         {
598           count+=(ssize_t) entry->count;
599           if ((x+count) > (ssize_t) image->columns)
600             count=(ssize_t) image->columns-x;
601           if (count > 0)
602             {
603               if (color != MagickFalse)
604                 {
605                   x+=count;
606                   count=0;
607                 }
608               else
609                 for ( ; count > 0; count--)
610                   scanline[x++]=(unsigned char) 1;
611             }
612           color=(unsigned int)
613             ((color == MagickFalse) ? MagickTrue : MagickFalse);
614           break;
615         }
616         case MWId:
617         case MBId:
618         case EXId:
619         {
620           count+=(ssize_t) entry->count;
621           break;
622         }
623         default:
624           break;
625       }
626       code=0;
627       length=0;
628     }
629     /*
630       Transfer scanline to image pixels.
631     */
632     p=scanline;
633     q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
634     if (q == (PixelPacket *) NULL)
635       break;
636     indexes=GetCacheViewAuthenticIndexQueue(image_view);
637     for (x=0; x < (ssize_t) image->columns; x++)
638     {
639       index=(IndexPacket) (*p++);
640       indexes[x]=index;
641       *q++=image->colormap[(ssize_t) index];
642     }
643     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
644       break;
645     proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
646     if (proceed == MagickFalse)
647       break;
648     y++;
649   }
650   image_view=DestroyCacheView(image_view);
651   image->rows=(size_t) MagickMax((size_t) y-3,1);
652   image->compression=FaxCompression;
653   /*
654     Free decoder memory.
655   */
656   mw_hash=(HuffmanTable **) RelinquishMagickMemory(mw_hash);
657   mb_hash=(HuffmanTable **) RelinquishMagickMemory(mb_hash);
658   scanline=(unsigned char *) RelinquishMagickMemory(scanline);
659   return(MagickTrue);
660 }
661 \f
662 /*
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664 %                                                                             %
665 %                                                                             %
666 %                                                                             %
667 %   H u f f m a n E n c o d e I m a g e                                       %
668 %                                                                             %
669 %                                                                             %
670 %                                                                             %
671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 %
673 %  HuffmanEncodeImage() compresses an image via Huffman-coding.
674 %
675 %  The format of the HuffmanEncodeImage method is:
676 %
677 %      MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info,
678 %        Image *image,Image *inject_image)
679 %
680 %  A description of each parameter follows:
681 %
682 %    o image_info: the image info..
683 %
684 %    o image: the image.
685 %
686 %    o inject_image: inject into the image stream.
687 %
688 */
689 MagickExport MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info,
690   Image *image,Image *inject_image)
691 {
692 #define HuffmanOutputCode(entry)  \
693 {  \
694   mask=one << (entry->length-1);  \
695   while (mask != 0)  \
696   {  \
697     OutputBit(((entry->code & mask) != 0 ? 1 : 0));  \
698     mask>>=1;  \
699   }  \
700 }
701
702 #define OutputBit(count)  \
703 {  \
704   if (count > 0)  \
705     byte=byte | bit;  \
706   bit>>=1;  \
707   if ((int) (bit & 0xff) == 0)   \
708     {  \
709       if (LocaleCompare(image_info->magick,"FAX") == 0) \
710         (void) WriteBlobByte(image,(unsigned char) byte);  \
711       else \
712         Ascii85Encode(image,byte); \
713       byte='\0';  \
714       bit=(unsigned char) 0x80;  \
715     }  \
716 }
717
718   const HuffmanTable
719     *entry;
720
721   ExceptionInfo
722     *exception;
723
724   int
725     k,
726     runlength;
727
728   Image
729     *huffman_image;
730
731   MagickBooleanType
732     proceed;
733
734   register ssize_t
735     i,
736     x;
737
738   register const PixelPacket
739     *p;
740
741   register unsigned char
742     *q;
743
744   size_t
745     mask,
746     one,
747     width;
748
749   ssize_t
750     n,
751     y;
752
753   unsigned char
754     byte,
755     bit,
756     *scanline;
757
758   /*
759     Allocate scanline buffer.
760   */
761   assert(image_info != (ImageInfo *) NULL);
762   assert(image_info->signature == MagickSignature);
763   assert(image != (Image *) NULL);
764   assert(image->signature == MagickSignature);
765   if (image->debug != MagickFalse)
766     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
767   assert(inject_image != (Image *) NULL);
768   assert(inject_image->signature == MagickSignature);
769   one=1;
770   width=inject_image->columns;
771   if (LocaleCompare(image_info->magick,"FAX") == 0)
772     width=(size_t) MagickMax(inject_image->columns,1728);
773   scanline=(unsigned char *) AcquireQuantumMemory((size_t) width+1UL,
774     sizeof(*scanline));
775   if (scanline == (unsigned char *) NULL)
776     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
777       inject_image->filename);
778   (void) ResetMagickMemory(scanline,0,width*sizeof(*scanline));
779   huffman_image=CloneImage(inject_image,0,0,MagickTrue,&image->exception);
780   if (huffman_image == (Image *) NULL)
781     {
782       scanline=(unsigned char *) RelinquishMagickMemory(scanline);
783       return(MagickFalse);
784     }
785   (void) SetImageType(huffman_image,BilevelType);
786   byte='\0';
787   bit=(unsigned char) 0x80;
788   if (LocaleCompare(image_info->magick,"FAX") != 0)
789     Ascii85Initialize(image);
790   else
791     {
792       /*
793         End of line.
794       */
795       for (k=0; k < 11; k++)
796         OutputBit(0);
797       OutputBit(1);
798     }
799   /*
800     Compress to 1D Huffman pixels.
801   */
802   exception=(&huffman_image->exception);
803   q=scanline;
804   for (y=0; y < (ssize_t) huffman_image->rows; y++)
805   {
806     p=GetVirtualPixels(huffman_image,0,y,huffman_image->columns,1,exception);
807     if (p == (const PixelPacket *) NULL)
808       break;
809     for (x=0; x < (ssize_t) huffman_image->columns; x++)
810     {
811       *q++=(unsigned char) (PixelIntensity(p) >= ((MagickRealType)
812         QuantumRange/2.0) ? 0 : 1);
813       p++;
814     }
815     /*
816       Huffman encode scanline.
817     */
818     q=scanline;
819     for (n=(ssize_t) width; n > 0; )
820     {
821       /*
822         Output white run.
823       */
824       for (runlength=0; ((n > 0) && (*q == 0)); n--)
825       {
826         q++;
827         runlength++;
828       }
829       if (runlength >= 64)
830         {
831           if (runlength < 1792)
832             entry=MWTable+((runlength/64)-1);
833           else
834             entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64;
835           runlength-=(long) entry->count;
836           HuffmanOutputCode(entry);
837         }
838       entry=TWTable+MagickMin((size_t) runlength,63);
839       HuffmanOutputCode(entry);
840       if (n != 0)
841         {
842           /*
843             Output black run.
844           */
845           for (runlength=0; ((*q != 0) && (n > 0)); n--)
846           {
847             q++;
848             runlength++;
849           }
850           if (runlength >= 64)
851             {
852               entry=MBTable+((runlength/64)-1);
853               if (runlength >= 1792)
854                 entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64;
855               runlength-=(long) entry->count;
856               HuffmanOutputCode(entry);
857             }
858           entry=TBTable+MagickMin((size_t) runlength,63);
859           HuffmanOutputCode(entry);
860         }
861     }
862     /*
863       End of line.
864     */
865     for (k=0; k < 11; k++)
866       OutputBit(0);
867     OutputBit(1);
868     q=scanline;
869     if (GetPreviousImageInList(huffman_image) == (Image *) NULL)
870       {
871         proceed=SetImageProgress(huffman_image,LoadImageTag,y,
872           huffman_image->rows);
873         if (proceed == MagickFalse)
874           break;
875       }
876   }
877   /*
878     End of page.
879   */
880   for (i=0; i < 6; i++)
881   {
882     for (k=0; k < 11; k++)
883       OutputBit(0);
884     OutputBit(1);
885   }
886   /*
887     Flush bits.
888   */
889   if (((int) bit != 0x80) != 0)
890     {
891       if (LocaleCompare(image_info->magick,"FAX") == 0)
892         (void) WriteBlobByte(image,byte);
893       else
894         Ascii85Encode(image,byte);
895     }
896   if (LocaleCompare(image_info->magick,"FAX") != 0)
897     Ascii85Flush(image);
898   huffman_image=DestroyImage(huffman_image);
899   scanline=(unsigned char *) RelinquishMagickMemory(scanline);
900   return(MagickTrue);
901 }
902 \f
903 /*
904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
905 %                                                                             %
906 %                                                                             %
907 %                                                                             %
908 %   L Z W E n c o d e I m a g e                                               %
909 %                                                                             %
910 %                                                                             %
911 %                                                                             %
912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913 %
914 %  LZWEncodeImage() compresses an image via LZW-coding specific to Postscript
915 %  Level II or Portable Document Format.
916 %
917 %  The format of the LZWEncodeImage method is:
918 %
919 %      MagickBooleanType LZWEncodeImage(Image *image,const size_t length,
920 %        unsigned char *pixels)
921 %
922 %  A description of each parameter follows:
923 %
924 %    o image: the image.
925 %
926 %    o length:  A value that specifies the number of pixels to compress.
927 %
928 %    o pixels: the address of an unsigned array of characters containing the
929 %      pixels to compress.
930 %
931 */
932 MagickExport MagickBooleanType LZWEncodeImage(Image *image,const size_t length,
933   unsigned char *pixels)
934 {
935 #define LZWClr  256UL  /* Clear Table Marker */
936 #define LZWEod  257UL  /* End of Data marker */
937 #define OutputCode(code) \
938 { \
939     accumulator+=code << (32-code_width-number_bits); \
940     number_bits+=code_width; \
941     while (number_bits >= 8) \
942     { \
943         (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); \
944         accumulator=accumulator << 8; \
945         number_bits-=8; \
946     } \
947 }
948
949   typedef struct _TableType
950   {
951     ssize_t
952       prefix,
953       suffix,
954       next;
955   } TableType;
956
957   register ssize_t
958     i;
959
960   size_t
961     accumulator,
962     number_bits,
963     code_width,
964     last_code,
965     next_index;
966
967   ssize_t
968     index;
969
970   TableType
971     *table;
972
973   /*
974     Allocate string table.
975   */
976   assert(image != (Image *) NULL);
977   assert(image->signature == MagickSignature);
978   if (image->debug != MagickFalse)
979     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
980   assert(pixels != (unsigned char *) NULL);
981   table=(TableType *) AcquireQuantumMemory(1UL << 12,sizeof(*table));
982   if (table == (TableType *) NULL)
983     return(MagickFalse);
984   /*
985     Initialize variables.
986   */
987   accumulator=0;
988   code_width=9;
989   number_bits=0;
990   last_code=0;
991   OutputCode(LZWClr);
992   for (index=0; index < 256; index++)
993   {
994     table[index].prefix=(-1);
995     table[index].suffix=(short) index;
996     table[index].next=(-1);
997   }
998   next_index=LZWEod+1;
999   code_width=9;
1000   last_code=(size_t) pixels[0];
1001   for (i=1; i < (ssize_t) length; i++)
1002   {
1003     /*
1004       Find string.
1005     */
1006     index=(ssize_t) last_code;
1007     while (index != -1)
1008       if ((table[index].prefix != (ssize_t) last_code) ||
1009           (table[index].suffix != (ssize_t) pixels[i]))
1010         index=table[index].next;
1011       else
1012         {
1013           last_code=(size_t) index;
1014           break;
1015         }
1016     if (last_code != (size_t) index)
1017       {
1018         /*
1019           Add string.
1020         */
1021         OutputCode(last_code);
1022         table[next_index].prefix=(ssize_t) last_code;
1023         table[next_index].suffix=(short) pixels[i];
1024         table[next_index].next=table[last_code].next;
1025         table[last_code].next=(ssize_t) next_index;
1026         next_index++;
1027         /*
1028           Did we just move up to next bit width?
1029         */
1030         if ((next_index >> code_width) != 0)
1031           {
1032             code_width++;
1033             if (code_width > 12)
1034               {
1035                 /*
1036                   Did we overflow the max bit width?
1037                 */
1038                 code_width--;
1039                 OutputCode(LZWClr);
1040                 for (index=0; index < 256; index++)
1041                 {
1042                   table[index].prefix=(-1);
1043                   table[index].suffix=index;
1044                   table[index].next=(-1);
1045                 }
1046                 next_index=LZWEod+1;
1047                 code_width=9;
1048               }
1049             }
1050           last_code=(size_t) pixels[i];
1051       }
1052   }
1053   /*
1054     Flush tables.
1055   */
1056   OutputCode(last_code);
1057   OutputCode(LZWEod);
1058   if (number_bits != 0)
1059     (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24));
1060   table=(TableType *) RelinquishMagickMemory(table);
1061   return(MagickTrue);
1062 }
1063 \f
1064 /*
1065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1066 %                                                                             %
1067 %                                                                             %
1068 %                                                                             %
1069 %   P a c k b i t s E n c o d e I m a g e                                     %
1070 %                                                                             %
1071 %                                                                             %
1072 %                                                                             %
1073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1074 %
1075 %  PackbitsEncodeImage() compresses an image via Macintosh Packbits encoding
1076 %  specific to Postscript Level II or Portable Document Format.  To ensure
1077 %  portability, the binary Packbits bytes are encoded as ASCII Base-85.
1078 %
1079 %  The format of the PackbitsEncodeImage method is:
1080 %
1081 %      MagickBooleanType PackbitsEncodeImage(Image *image,const size_t length,
1082 %        unsigned char *pixels)
1083 %
1084 %  A description of each parameter follows:
1085 %
1086 %    o image: the image.
1087 %
1088 %    o length:  A value that specifies the number of pixels to compress.
1089 %
1090 %    o pixels: the address of an unsigned array of characters containing the
1091 %      pixels to compress.
1092 %
1093 */
1094 MagickExport MagickBooleanType PackbitsEncodeImage(Image *image,
1095   const size_t length,unsigned char *pixels)
1096 {
1097   int
1098     count;
1099
1100   register ssize_t
1101     i,
1102     j;
1103
1104   unsigned char
1105     *packbits;
1106
1107   /*
1108     Compress pixels with Packbits encoding.
1109   */
1110   assert(image != (Image *) NULL);
1111   assert(image->signature == MagickSignature);
1112   if (image->debug != MagickFalse)
1113     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1114   assert(pixels != (unsigned char *) NULL);
1115   packbits=(unsigned char *) AcquireQuantumMemory(128UL,sizeof(*packbits));
1116   if (packbits == (unsigned char *) NULL)
1117     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1118       image->filename);
1119   for (i=(ssize_t) length; i != 0; )
1120   {
1121     switch (i)
1122     {
1123       case 1:
1124       {
1125         i--;
1126         (void) WriteBlobByte(image,(unsigned char) 0);
1127         (void) WriteBlobByte(image,*pixels);
1128         break;
1129       }
1130       case 2:
1131       {
1132         i-=2;
1133         (void) WriteBlobByte(image,(unsigned char) 1);
1134         (void) WriteBlobByte(image,*pixels);
1135         (void) WriteBlobByte(image,pixels[1]);
1136         break;
1137       }
1138       case 3:
1139       {
1140         i-=3;
1141         if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
1142           {
1143             (void) WriteBlobByte(image,(unsigned char) ((256-3)+1));
1144             (void) WriteBlobByte(image,*pixels);
1145             break;
1146           }
1147         (void) WriteBlobByte(image,(unsigned char) 2);
1148         (void) WriteBlobByte(image,*pixels);
1149         (void) WriteBlobByte(image,pixels[1]);
1150         (void) WriteBlobByte(image,pixels[2]);
1151         break;
1152       }
1153       default:
1154       {
1155         if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
1156           {
1157             /*
1158               Packed run.
1159             */
1160             count=3;
1161             while (((ssize_t) count < i) && (*pixels == *(pixels+count)))
1162             {
1163               count++;
1164               if (count >= 127)
1165                 break;
1166             }
1167             i-=count;
1168             (void) WriteBlobByte(image,(unsigned char) ((256-count)+1));
1169             (void) WriteBlobByte(image,*pixels);
1170             pixels+=count;
1171             break;
1172           }
1173         /*
1174           Literal run.
1175         */
1176         count=0;
1177         while ((*(pixels+count) != *(pixels+count+1)) ||
1178                (*(pixels+count+1) != *(pixels+count+2)))
1179         {
1180           packbits[count+1]=pixels[count];
1181           count++;
1182           if (((ssize_t) count >= (i-3)) || (count >= 127))
1183             break;
1184         }
1185         i-=count;
1186         *packbits=(unsigned char) (count-1);
1187         for (j=0; j <= (ssize_t) count; j++)
1188           (void) WriteBlobByte(image,packbits[j]);
1189         pixels+=count;
1190         break;
1191       }
1192     }
1193   }
1194   (void) WriteBlobByte(image,(unsigned char) 128);  /* EOD marker */
1195   packbits=(unsigned char *) RelinquishMagickMemory(packbits);
1196   return(MagickTrue);
1197 }
1198 \f
1199 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1200 /*
1201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1202 %                                                                             %
1203 %                                                                             %
1204 %                                                                             %
1205 %   Z L I B E n c o d e I m a g e                                             %
1206 %                                                                             %
1207 %                                                                             %
1208 %                                                                             %
1209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1210 %
1211 %  ZLIBEncodeImage compresses an image via ZLIB-coding specific to
1212 %  Postscript Level II or Portable Document Format.
1213 %
1214 %  The format of the ZLIBEncodeImage method is:
1215 %
1216 %      MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length,
1217 %        unsigned char *pixels)
1218 %
1219 %  A description of each parameter follows:
1220 %
1221 %    o file: the address of a structure of type FILE.  ZLIB encoded pixels
1222 %      are written to this file.
1223 %
1224 %    o length:  A value that specifies the number of pixels to compress.
1225 %
1226 %    o pixels: the address of an unsigned array of characters containing the
1227 %      pixels to compress.
1228 %
1229 */
1230
1231 static voidpf AcquireZIPMemory(voidpf context,unsigned int items,
1232   unsigned int size)
1233 {
1234   (void) context;
1235   return((voidpf) AcquireQuantumMemory(items,size));
1236 }
1237
1238 static void RelinquishZIPMemory(voidpf context,voidpf memory)
1239 {
1240   (void) context;
1241   memory=RelinquishMagickMemory(memory);
1242 }
1243
1244 MagickExport MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length,
1245   unsigned char *pixels)
1246 {
1247   int
1248     status;
1249
1250   register ssize_t
1251     i;
1252
1253   size_t
1254     compress_packets;
1255
1256   unsigned char
1257     *compress_pixels;
1258
1259   z_stream
1260     stream;
1261
1262   assert(image != (Image *) NULL);
1263   assert(image->signature == MagickSignature);
1264   if (image->debug != MagickFalse)
1265     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1266   compress_packets=(size_t) (1.001*length+12);
1267   compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_packets,
1268     sizeof(*compress_pixels));
1269   if (compress_pixels == (unsigned char *) NULL)
1270     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1271       image->filename);
1272   stream.next_in=pixels;
1273   stream.avail_in=(unsigned int) length;
1274   stream.next_out=compress_pixels;
1275   stream.avail_out=(unsigned int) compress_packets;
1276   stream.zalloc=AcquireZIPMemory;
1277   stream.zfree=RelinquishZIPMemory;
1278   stream.opaque=(voidpf) NULL;
1279   status=deflateInit(&stream,(int) (image->quality ==
1280     UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9)));
1281   if (status == Z_OK)
1282     {
1283       status=deflate(&stream,Z_FINISH);
1284       if (status == Z_STREAM_END)
1285         status=deflateEnd(&stream);
1286       else
1287         (void) deflateEnd(&stream);
1288       compress_packets=(size_t) stream.total_out;
1289     }
1290   if (status != Z_OK)
1291     ThrowBinaryException(CoderError,"UnableToZipCompressImage",image->filename)
1292   else
1293     for (i=0; i < (ssize_t) compress_packets; i++)
1294       (void) WriteBlobByte(image,compress_pixels[i]);
1295   compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels);
1296   return(status == Z_OK ? MagickTrue : MagickFalse);
1297 }
1298 #else
1299 MagickExport MagickBooleanType ZLIBEncodeImage(Image *image,
1300   const size_t magick_unused(length),unsigned char *magick_unused(pixels))
1301 {
1302   assert(image != (Image *) NULL);
1303   assert(image->signature == MagickSignature);
1304   if (image->debug != MagickFalse)
1305     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1306   (void) ThrowMagickException(&image->exception,GetMagickModule(),
1307     MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (ZIP)",
1308     image->filename);
1309   return(MagickFalse);
1310 }
1311 #endif