Powered by Pair ImageMagick logo
Image Magick
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

ImageMagick-6.1.1/magick/compress.c

Go to the documentation of this file.
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % CCCC OOO M M PPPP RRRR EEEEE SSSSS SSSSS % 00007 % C O O MM MM P P R R E SS SS % 00008 % C O O M M M PPPP RRRR EEE SSS SSS % 00009 % C O O M M P R R E SS SS % 00010 % CCCC OOO M M P R R EEEEE SSSSS SSSSS % 00011 % % 00012 % % 00013 % Image Compression/Decompression Methods % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % May 1993 % 00018 % % 00019 % % 00020 % Copyright 1999-2004 ImageMagick Studio LLC, a non-profit organization % 00021 % dedicated to making software imaging solutions freely available. % 00022 % % 00023 % You may not use this file except in compliance with the License. You may % 00024 % obtain a copy of the License at % 00025 % % 00026 % http://www.imagemagick.org/www/Copyright.html % 00027 % % 00028 % Unless required by applicable law or agreed to in writing, software % 00029 % distributed under the License is distributed on an "AS IS" BASIS, % 00030 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00031 % See the License for the specific language governing permissions and % 00032 % limitations under the License. % 00033 % % 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 % 00036 % 00037 % 00038 */ 00039 00040 /* 00041 Include declarations. 00042 */ 00043 #include "magick/studio.h" 00044 #include "magick/blob.h" 00045 #include "magick/blob_private.h" 00046 #include "magick/compress.h" 00047 #include "magick/constitute.h" 00048 #include "magick/error.h" 00049 #include "magick/error_private.h" 00050 #include "magick/image_private.h" 00051 #include "magick/memory_.h" 00052 #include "magick/monitor.h" 00053 #include "magick/resource_.h" 00054 #include "magick/string_.h" 00055 #if defined(HasTIFF) 00056 #if defined(HAVE_TIFFCONF_H) 00057 #include "tiffconf.h" 00058 #endif 00059 #include "tiffio.h" 00060 #define CCITTParam "-1" 00061 #else 00062 #define CCITTParam "0" 00063 #endif 00064 #if defined(HasZLIB) 00065 #include "zlib.h" 00066 #endif 00067 00068 /* 00069 Typedef declarations. 00070 */ 00071 typedef struct _Ascii85Info 00072 { 00073 long 00074 offset, 00075 line_break; 00076 00077 unsigned char 00078 buffer[10]; 00079 } Ascii85Info; 00080 00081 typedef struct HuffmanTable 00082 { 00083 unsigned long 00084 id, 00085 code, 00086 length, 00087 count; 00088 } HuffmanTable; 00089 00090 /* 00091 Huffman coding declarations. 00092 */ 00093 #define TWId 23 00094 #define MWId 24 00095 #define TBId 25 00096 #define MBId 26 00097 #define EXId 27 00098 00099 static const HuffmanTable 00100 MBTable[]= 00101 { 00102 { MBId, 0x0f, 10, 64 }, { MBId, 0xc8, 12, 128 }, 00103 { MBId, 0xc9, 12, 192 }, { MBId, 0x5b, 12, 256 }, 00104 { MBId, 0x33, 12, 320 }, { MBId, 0x34, 12, 384 }, 00105 { MBId, 0x35, 12, 448 }, { MBId, 0x6c, 13, 512 }, 00106 { MBId, 0x6d, 13, 576 }, { MBId, 0x4a, 13, 640 }, 00107 { MBId, 0x4b, 13, 704 }, { MBId, 0x4c, 13, 768 }, 00108 { MBId, 0x4d, 13, 832 }, { MBId, 0x72, 13, 896 }, 00109 { MBId, 0x73, 13, 960 }, { MBId, 0x74, 13, 1024 }, 00110 { MBId, 0x75, 13, 1088 }, { MBId, 0x76, 13, 1152 }, 00111 { MBId, 0x77, 13, 1216 }, { MBId, 0x52, 13, 1280 }, 00112 { MBId, 0x53, 13, 1344 }, { MBId, 0x54, 13, 1408 }, 00113 { MBId, 0x55, 13, 1472 }, { MBId, 0x5a, 13, 1536 }, 00114 { MBId, 0x5b, 13, 1600 }, { MBId, 0x64, 13, 1664 }, 00115 { MBId, 0x65, 13, 1728 }, { MBId, 0x00, 0, 0 } 00116 }; 00117 00118 static const HuffmanTable 00119 EXTable[]= 00120 { 00121 { EXId, 0x08, 11, 1792 }, { EXId, 0x0c, 11, 1856 }, 00122 { EXId, 0x0d, 11, 1920 }, { EXId, 0x12, 12, 1984 }, 00123 { EXId, 0x13, 12, 2048 }, { EXId, 0x14, 12, 2112 }, 00124 { EXId, 0x15, 12, 2176 }, { EXId, 0x16, 12, 2240 }, 00125 { EXId, 0x17, 12, 2304 }, { EXId, 0x1c, 12, 2368 }, 00126 { EXId, 0x1d, 12, 2432 }, { EXId, 0x1e, 12, 2496 }, 00127 { EXId, 0x1f, 12, 2560 }, { EXId, 0x00, 0, 0 } 00128 }; 00129 00130 static const HuffmanTable 00131 MWTable[]= 00132 { 00133 { MWId, 0x1b, 5, 64 }, { MWId, 0x12, 5, 128 }, 00134 { MWId, 0x17, 6, 192 }, { MWId, 0x37, 7, 256 }, 00135 { MWId, 0x36, 8, 320 }, { MWId, 0x37, 8, 384 }, 00136 { MWId, 0x64, 8, 448 }, { MWId, 0x65, 8, 512 }, 00137 { MWId, 0x68, 8, 576 }, { MWId, 0x67, 8, 640 }, 00138 { MWId, 0xcc, 9, 704 }, { MWId, 0xcd, 9, 768 }, 00139 { MWId, 0xd2, 9, 832 }, { MWId, 0xd3, 9, 896 }, 00140 { MWId, 0xd4, 9, 960 }, { MWId, 0xd5, 9, 1024 }, 00141 { MWId, 0xd6, 9, 1088 }, { MWId, 0xd7, 9, 1152 }, 00142 { MWId, 0xd8, 9, 1216 }, { MWId, 0xd9, 9, 1280 }, 00143 { MWId, 0xda, 9, 1344 }, { MWId, 0xdb, 9, 1408 }, 00144 { MWId, 0x98, 9, 1472 }, { MWId, 0x99, 9, 1536 }, 00145 { MWId, 0x9a, 9, 1600 }, { MWId, 0x18, 6, 1664 }, 00146 { MWId, 0x9b, 9, 1728 }, { MWId, 0x00, 0, 0 } 00147 }; 00148 00149 static const HuffmanTable 00150 TBTable[]= 00151 { 00152 { TBId, 0x37, 10, 0 }, { TBId, 0x02, 3, 1 }, { TBId, 0x03, 2, 2 }, 00153 { TBId, 0x02, 2, 3 }, { TBId, 0x03, 3, 4 }, { TBId, 0x03, 4, 5 }, 00154 { TBId, 0x02, 4, 6 }, { TBId, 0x03, 5, 7 }, { TBId, 0x05, 6, 8 }, 00155 { TBId, 0x04, 6, 9 }, { TBId, 0x04, 7, 10 }, { TBId, 0x05, 7, 11 }, 00156 { TBId, 0x07, 7, 12 }, { TBId, 0x04, 8, 13 }, { TBId, 0x07, 8, 14 }, 00157 { TBId, 0x18, 9, 15 }, { TBId, 0x17, 10, 16 }, { TBId, 0x18, 10, 17 }, 00158 { TBId, 0x08, 10, 18 }, { TBId, 0x67, 11, 19 }, { TBId, 0x68, 11, 20 }, 00159 { TBId, 0x6c, 11, 21 }, { TBId, 0x37, 11, 22 }, { TBId, 0x28, 11, 23 }, 00160 { TBId, 0x17, 11, 24 }, { TBId, 0x18, 11, 25 }, { TBId, 0xca, 12, 26 }, 00161 { TBId, 0xcb, 12, 27 }, { TBId, 0xcc, 12, 28 }, { TBId, 0xcd, 12, 29 }, 00162 { TBId, 0x68, 12, 30 }, { TBId, 0x69, 12, 31 }, { TBId, 0x6a, 12, 32 }, 00163 { TBId, 0x6b, 12, 33 }, { TBId, 0xd2, 12, 34 }, { TBId, 0xd3, 12, 35 }, 00164 { TBId, 0xd4, 12, 36 }, { TBId, 0xd5, 12, 37 }, { TBId, 0xd6, 12, 38 }, 00165 { TBId, 0xd7, 12, 39 }, { TBId, 0x6c, 12, 40 }, { TBId, 0x6d, 12, 41 }, 00166 { TBId, 0xda, 12, 42 }, { TBId, 0xdb, 12, 43 }, { TBId, 0x54, 12, 44 }, 00167 { TBId, 0x55, 12, 45 }, { TBId, 0x56, 12, 46 }, { TBId, 0x57, 12, 47 }, 00168 { TBId, 0x64, 12, 48 }, { TBId, 0x65, 12, 49 }, { TBId, 0x52, 12, 50 }, 00169 { TBId, 0x53, 12, 51 }, { TBId, 0x24, 12, 52 }, { TBId, 0x37, 12, 53 }, 00170 { TBId, 0x38, 12, 54 }, { TBId, 0x27, 12, 55 }, { TBId, 0x28, 12, 56 }, 00171 { TBId, 0x58, 12, 57 }, { TBId, 0x59, 12, 58 }, { TBId, 0x2b, 12, 59 }, 00172 { TBId, 0x2c, 12, 60 }, { TBId, 0x5a, 12, 61 }, { TBId, 0x66, 12, 62 }, 00173 { TBId, 0x67, 12, 63 }, { TBId, 0x00, 0, 0 } 00174 }; 00175 00176 static const HuffmanTable 00177 TWTable[]= 00178 { 00179 { TWId, 0x35, 8, 0 }, { TWId, 0x07, 6, 1 }, { TWId, 0x07, 4, 2 }, 00180 { TWId, 0x08, 4, 3 }, { TWId, 0x0b, 4, 4 }, { TWId, 0x0c, 4, 5 }, 00181 { TWId, 0x0e, 4, 6 }, { TWId, 0x0f, 4, 7 }, { TWId, 0x13, 5, 8 }, 00182 { TWId, 0x14, 5, 9 }, { TWId, 0x07, 5, 10 }, { TWId, 0x08, 5, 11 }, 00183 { TWId, 0x08, 6, 12 }, { TWId, 0x03, 6, 13 }, { TWId, 0x34, 6, 14 }, 00184 { TWId, 0x35, 6, 15 }, { TWId, 0x2a, 6, 16 }, { TWId, 0x2b, 6, 17 }, 00185 { TWId, 0x27, 7, 18 }, { TWId, 0x0c, 7, 19 }, { TWId, 0x08, 7, 20 }, 00186 { TWId, 0x17, 7, 21 }, { TWId, 0x03, 7, 22 }, { TWId, 0x04, 7, 23 }, 00187 { TWId, 0x28, 7, 24 }, { TWId, 0x2b, 7, 25 }, { TWId, 0x13, 7, 26 }, 00188 { TWId, 0x24, 7, 27 }, { TWId, 0x18, 7, 28 }, { TWId, 0x02, 8, 29 }, 00189 { TWId, 0x03, 8, 30 }, { TWId, 0x1a, 8, 31 }, { TWId, 0x1b, 8, 32 }, 00190 { TWId, 0x12, 8, 33 }, { TWId, 0x13, 8, 34 }, { TWId, 0x14, 8, 35 }, 00191 { TWId, 0x15, 8, 36 }, { TWId, 0x16, 8, 37 }, { TWId, 0x17, 8, 38 }, 00192 { TWId, 0x28, 8, 39 }, { TWId, 0x29, 8, 40 }, { TWId, 0x2a, 8, 41 }, 00193 { TWId, 0x2b, 8, 42 }, { TWId, 0x2c, 8, 43 }, { TWId, 0x2d, 8, 44 }, 00194 { TWId, 0x04, 8, 45 }, { TWId, 0x05, 8, 46 }, { TWId, 0x0a, 8, 47 }, 00195 { TWId, 0x0b, 8, 48 }, { TWId, 0x52, 8, 49 }, { TWId, 0x53, 8, 50 }, 00196 { TWId, 0x54, 8, 51 }, { TWId, 0x55, 8, 52 }, { TWId, 0x24, 8, 53 }, 00197 { TWId, 0x25, 8, 54 }, { TWId, 0x58, 8, 55 }, { TWId, 0x59, 8, 56 }, 00198 { TWId, 0x5a, 8, 57 }, { TWId, 0x5b, 8, 58 }, { TWId, 0x4a, 8, 59 }, 00199 { TWId, 0x4b, 8, 60 }, { TWId, 0x32, 8, 61 }, { TWId, 0x33, 8, 62 }, 00200 { TWId, 0x34, 8, 63 }, { TWId, 0x00, 0, 0 } 00201 }; 00202 00203 /* 00204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00205 % % 00206 % % 00207 % % 00208 % A S C I I 8 5 E n c o d e % 00209 % % 00210 % % 00211 % % 00212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00213 % 00214 % ASCII85Encode() encodes data in ASCII base-85 format. ASCII base-85 00215 % encoding produces five ASCII printing characters from every four bytes of 00216 % binary data. 00217 % 00218 % The format of the ASCII85Encode method is: 00219 % 00220 % void Ascii85Encode(Image *image,const unsigned long code) 00221 % 00222 % A description of each parameter follows: 00223 % 00224 % o code: a binary unsigned char to encode to ASCII 85. 00225 % 00226 % o file: write the encoded ASCII character to this file. 00227 % 00228 % 00229 */ 00230 #define MaxLineExtent 36 00231 00232 static char *Ascii85Tuple(unsigned char *data) 00233 { 00234 static char 00235 tuple[6]; 00236 00237 register long 00238 i, 00239 x; 00240 00241 unsigned long 00242 code, 00243 quantum; 00244 00245 code=((((unsigned long) data[0] << 8) | (unsigned long) data[1]) << 16) | 00246 ((unsigned long) data[2] << 8) | (unsigned long) data[3]; 00247 if (code == 0L) 00248 { 00249 tuple[0]='z'; 00250 tuple[1]='\0'; 00251 return(tuple); 00252 } 00253 quantum=85UL*85UL*85UL*85UL; 00254 for (i=0; i < 4; i++) 00255 { 00256 x=(long) (code/quantum); 00257 code-=quantum*x; 00258 tuple[i]=(char) (x+(int) '!'); 00259 quantum/=85L; 00260 } 00261 tuple[4]=(char) ((code % 85L)+(int) '!'); 00262 tuple[5]='\0'; 00263 return(tuple); 00264 } 00265 00266 MagickExport void Ascii85Initialize(Image *image) 00267 { 00268 /* 00269 Allocate image structure. 00270 */ 00271 if (image->ascii85 == (Ascii85Info *) NULL) 00272 image->ascii85=(Ascii85Info *) AcquireMagickMemory(sizeof(*image->ascii85)); 00273 if (image->ascii85 == (Ascii85Info *) NULL) 00274 ThrowMagickFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 00275 image->filename); 00276 (void) ResetMagickMemory(image->ascii85,0,sizeof(*image->ascii85)); 00277 image->ascii85->line_break=MaxLineExtent << 1; 00278 image->ascii85->offset=0; 00279 } 00280 00281 MagickExport void Ascii85Flush(Image *image) 00282 { 00283 register char 00284 *tuple; 00285 00286 assert(image != (Image *) NULL); 00287 assert(image->signature == MagickSignature); 00288 if (image->debug != MagickFalse) 00289 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00290 assert(image->ascii85 != (Ascii85Info *) NULL); 00291 if (image->ascii85->offset > 0) 00292 { 00293 image->ascii85->buffer[image->ascii85->offset]='\0'; 00294 image->ascii85->buffer[image->ascii85->offset+1]='\0'; 00295 image->ascii85->buffer[image->ascii85->offset+2]='\0'; 00296 tuple=Ascii85Tuple(image->ascii85->buffer); 00297 (void) WriteBlob(image,(size_t) image->ascii85->offset+1, 00298 (unsigned char *) (*tuple == 'z' ? "!!!!" : tuple)); 00299 } 00300 (void) WriteBlobByte(image,'~'); 00301 (void) WriteBlobByte(image,'>'); 00302 (void) WriteBlobByte(image,'\n'); 00303 } 00304 00305 MagickExport void Ascii85Encode(Image *image,const unsigned char code) 00306 { 00307 long 00308 n; 00309 00310 register char 00311 *q; 00312 00313 register unsigned char 00314 *p; 00315 00316 assert(image != (Image *) NULL); 00317 assert(image->signature == MagickSignature); 00318 assert(image->ascii85 != (Ascii85Info *) NULL); 00319 image->ascii85->buffer[image->ascii85->offset]=code; 00320 image->ascii85->offset++; 00321 if (image->ascii85->offset < 4) 00322 return; 00323 p=image->ascii85->buffer; 00324 for (n=image->ascii85->offset; n >= 4; n-=4) 00325 { 00326 for (q=Ascii85Tuple(p); *q != '\0'; q++) 00327 { 00328 image->ascii85->line_break--; 00329 if ((image->ascii85->line_break < 0) && (*q != '%')) 00330 { 00331 (void) WriteBlobByte(image,'\n'); 00332 image->ascii85->line_break=2*MaxLineExtent; 00333 } 00334 (void) WriteBlobByte(image,(unsigned char) *q); 00335 } 00336 p+=8; 00337 } 00338 image->ascii85->offset=n; 00339 p-=4; 00340 for (n=0; n < 4; n++) 00341 image->ascii85->buffer[n]=(*p++); 00342 } 00343 00344 /* 00345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00346 % % 00347 % % 00348 % % 00349 % H u f f m a n D e c o d e I m a g e % 00350 % % 00351 % % 00352 % % 00353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00354 % 00355 % HuffmanDecodeImage() uncompresses an image via Huffman-coding. 00356 % 00357 % The format of the HuffmanDecodeImage method is: 00358 % 00359 % MagickBooleanType HuffmanDecodeImage(Image *image) 00360 % 00361 % A description of each parameter follows: 00362 % 00363 % o image: The image. 00364 % 00365 % 00366 */ 00367 MagickExport MagickBooleanType HuffmanDecodeImage(Image *image) 00368 { 00369 #define HashSize 1021 00370 #define MBHashA 293 00371 #define MBHashB 2695 00372 #define MWHashA 3510 00373 #define MWHashB 1178 00374 00375 #define InitializeHashTable(hash,table,a,b) \ 00376 { \ 00377 entry=table; \ 00378 while (entry->code != 0) \ 00379 { \ 00380 hash[((entry->length+a)*(entry->code+b)) % HashSize]=(HuffmanTable *) entry; \ 00381 entry++; \ 00382 } \ 00383 } 00384 00385 #define InputBit(bit) \ 00386 { \ 00387 if ((mask & 0xff) == 0) \ 00388 { \ 00389 byte=ReadBlobByte(image); \ 00390 if (byte == EOF) \ 00391 break; \ 00392 mask=0x80; \ 00393 } \ 00394 runlength++; \ 00395 bit=(unsigned long) ((byte & mask) != 0 ? 0x01 : 0x00); \ 00396 mask>>=1; \ 00397 if (bit != 0) \ 00398 runlength=0; \ 00399 } 00400 00401 const HuffmanTable 00402 *entry; 00403 00404 HuffmanTable 00405 **mb_hash, 00406 **mw_hash; 00407 00408 IndexPacket 00409 index; 00410 00411 int 00412 byte; 00413 00414 long 00415 count, 00416 y; 00417 00418 MagickBooleanType 00419 status; 00420 00421 register IndexPacket 00422 *indexes; 00423 00424 register long 00425 i, 00426 x; 00427 00428 register PixelPacket 00429 *q; 00430 00431 register unsigned char 00432 *p; 00433 00434 unsigned char 00435 *scanline; 00436 00437 unsigned int 00438 bail, 00439 color; 00440 00441 unsigned long 00442 bit, 00443 code, 00444 mask, 00445 length, 00446 null_lines, 00447 runlength; 00448 00449 /* 00450 Allocate buffers. 00451 */ 00452 assert(image != (Image *) NULL); 00453 assert(image->signature == MagickSignature); 00454 if (image->debug != MagickFalse) 00455 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00456 mb_hash=(HuffmanTable **) AcquireMagickMemory(HashSize*sizeof(*mb_hash)); 00457 mw_hash=(HuffmanTable **) AcquireMagickMemory(HashSize*sizeof(*mw_hash)); 00458 scanline=(unsigned char *) AcquireMagickMemory((size_t) image->columns); 00459 if ((mb_hash == (HuffmanTable **) NULL) || 00460 (mw_hash == (HuffmanTable **) NULL) || 00461 (scanline == (unsigned char *) NULL)) 00462 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 00463 image->filename); 00464 /* 00465 Initialize Huffman tables. 00466 */ 00467 for (i=0; i < HashSize; i++) 00468 { 00469 mb_hash[i]=(HuffmanTable *) NULL; 00470 mw_hash[i]=(HuffmanTable *) NULL; 00471 } 00472 InitializeHashTable(mw_hash,TWTable,MWHashA,MWHashB); 00473 InitializeHashTable(mw_hash,MWTable,MWHashA,MWHashB); 00474 InitializeHashTable(mw_hash,EXTable,MWHashA,MWHashB); 00475 InitializeHashTable(mb_hash,TBTable,MBHashA,MBHashB); 00476 InitializeHashTable(mb_hash,MBTable,MBHashA,MBHashB); 00477 InitializeHashTable(mb_hash,EXTable,MBHashA,MBHashB); 00478 /* 00479 Uncompress 1D Huffman to runlength encoded pixels. 00480 */ 00481 byte=0; 00482 mask=0; 00483 null_lines=0; 00484 runlength=0; 00485 while (runlength < 11) 00486 InputBit(bit); 00487 do { InputBit(bit); } while ((int) bit == 0); 00488 image->x_resolution=204.0; 00489 image->y_resolution=196.0; 00490 image->units=PixelsPerInchResolution; 00491 for (y=0; ((y < (long) image->rows) && (null_lines < 3)); ) 00492 { 00493 /* 00494 Initialize scanline to white. 00495 */ 00496 p=scanline; 00497 for (x=0; x < (long) image->columns; x++) 00498 *p++=(unsigned char) 0; 00499 /* 00500 Decode Huffman encoded scanline. 00501 */ 00502 color=MagickTrue; 00503 code=0; 00504 count=0; 00505 length=0; 00506 runlength=0; 00507 x=0; 00508 for ( ; ; ) 00509 { 00510 if (byte == EOF) 00511 break; 00512 if (x >= (long) image->columns) 00513 { 00514 while (runlength < 11) 00515 InputBit(bit); 00516 do { InputBit(bit); } while ((int) bit == 0); 00517 break; 00518 } 00519 bail=MagickFalse; 00520 do 00521 { 00522 if (runlength < 11) 00523 InputBit(bit) 00524 else 00525 { 00526 InputBit(bit); 00527 if ((int) bit != 0) 00528 { 00529 null_lines++; 00530 if (x != 0) 00531 null_lines=0; 00532 bail=MagickTrue; 00533 break; 00534 } 00535 } 00536 code=(code << 1)+(unsigned long) bit; 00537 length++; 00538 } while (code == 0); 00539 if (bail != MagickFalse) 00540 break; 00541 if (length > 13) 00542 { 00543 while (runlength < 11) 00544 InputBit(bit); 00545 do { InputBit(bit); } while ((int) bit == 0); 00546 break; 00547 } 00548 if (color != MagickFalse) 00549 { 00550 if (length < 4) 00551 continue; 00552 entry=mw_hash[((length+MWHashA)*(code+MWHashB)) % HashSize]; 00553 } 00554 else 00555 { 00556 if (length < 2) 00557 continue; 00558 entry=mb_hash[((length+MBHashA)*(code+MBHashB)) % HashSize]; 00559 } 00560 if (entry == (const HuffmanTable *) NULL) 00561 continue; 00562 if ((entry->length != length) || (entry->code != code)) 00563 continue; 00564 switch (entry->id) 00565 { 00566 case TWId: 00567 case TBId: 00568 { 00569 count+=entry->count; 00570 if ((x+count) > (long) image->columns) 00571 count=(long) image->columns-x; 00572 if (count > 0) 00573 { 00574 if (color != MagickFalse) 00575 { 00576 x+=count; 00577 count=0; 00578 } 00579 else 00580 for ( ; count > 0; count--) 00581 scanline[x++]=(unsigned char) 1; 00582 } 00583 color=(unsigned int) 00584 ((color == MagickFalse) ? MagickTrue : MagickFalse); 00585 break; 00586 } 00587 case MWId: 00588 case MBId: 00589 case EXId: 00590 { 00591 count+=entry->count; 00592 break; 00593 } 00594 default: 00595 break; 00596 } 00597 code=0; 00598 length=0; 00599 } 00600 /* 00601 Transfer scanline to image pixels. 00602 */ 00603 p=scanline; 00604 q=SetImagePixels(image,0,y,image->columns,1); 00605 if (q == (PixelPacket *) NULL) 00606 break; 00607 indexes=GetIndexes(image); 00608 for (x=0; x < (long) image->columns; x++) 00609 { 00610 index=(IndexPacket) (*p++); 00611 indexes[x]=index; 00612 *q++=image->colormap[index]; 00613 } 00614 if (SyncImagePixels(image) == MagickFalse) 00615 break; 00616 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 00617 (QuantumTick(y,image->rows) != MagickFalse)) 00618 { 00619 status=image->progress_monitor(LoadImageTag,y,image->rows, 00620 image->client_data); 00621 if (status == MagickFalse) 00622 break; 00623 } 00624 y++; 00625 } 00626 image->rows=(unsigned long) Max(y-3,1); 00627 image->compression=FaxCompression; 00628 /* 00629 Free decoder memory. 00630 */ 00631 mw_hash=(HuffmanTable **) RelinquishMagickMemory(mw_hash); 00632 mb_hash=(HuffmanTable **) RelinquishMagickMemory(mb_hash); 00633 scanline=(unsigned char *) RelinquishMagickMemory(scanline); 00634 return(MagickTrue); 00635 } 00636 00637 /* 00638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00639 % % 00640 % % 00641 % % 00642 % H u f f m a n E n c o d e I m a g e % 00643 % % 00644 % % 00645 % % 00646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00647 % 00648 % HuffmanEncodeImage() compresses an image via Huffman-coding. 00649 % 00650 % The format of the HuffmanEncodeImage method is: 00651 % 00652 % MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info, 00653 % Image *image) 00654 % 00655 % A description of each parameter follows: 00656 % 00657 % o image_info: The image info.. 00658 % 00659 % o image: The image. 00660 % 00661 */ 00662 MagickExport MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info, 00663 Image *image) 00664 { 00665 #define HuffmanOutputCode(entry) \ 00666 { \ 00667 mask=1 << (entry->length-1); \ 00668 while (mask != 0) \ 00669 { \ 00670 OutputBit(((entry->code & mask) != 0 ? 1 : 0)); \ 00671 mask>>=1; \ 00672 } \ 00673 } 00674 00675 #define OutputBit(count) \ 00676 { \ 00677 if (count > 0) \ 00678 byte=byte | bit; \ 00679 bit>>=1; \ 00680 if ((int) (bit & 0xff) == 0) \ 00681 { \ 00682 if (LocaleCompare(image_info->magick,"FAX") == 0) \ 00683 (void) WriteBlobByte(image,(unsigned char) byte); \ 00684 else \ 00685 Ascii85Encode(image,byte); \ 00686 byte='\0'; \ 00687 bit=(unsigned char) 0x80; \ 00688 } \ 00689 } 00690 00691 const HuffmanTable 00692 *entry; 00693 00694 int 00695 k, 00696 runlength; 00697 00698 long 00699 n, 00700 y; 00701 00702 Image 00703 *huffman_image; 00704 00705 IndexPacket 00706 polarity; 00707 00708 MagickBooleanType 00709 status; 00710 00711 register IndexPacket 00712 *indexes; 00713 00714 register long 00715 i, 00716 x; 00717 00718 register const PixelPacket 00719 *p; 00720 00721 register unsigned char 00722 *q; 00723 00724 unsigned char 00725 byte, 00726 bit, 00727 *scanline; 00728 00729 unsigned long 00730 mask, 00731 width; 00732 00733 /* 00734 Allocate scanline buffer. 00735 */ 00736 assert(image != (Image *) NULL); 00737 assert(image->signature == MagickSignature); 00738 if (image->debug != MagickFalse) 00739 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00740 width=image->columns; 00741 if (LocaleCompare(image_info->magick,"FAX") == 0) 00742 width=Max(image->columns,1728); 00743 scanline=(unsigned char *) AcquireMagickMemory((size_t) width+1); 00744 if (scanline == (unsigned char *) NULL) 00745 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 00746 image->filename); 00747 huffman_image=CloneImage(image,0,0,MagickTrue,&image->exception); 00748 if (huffman_image == (Image *) NULL) 00749 return(MagickFalse); 00750 (void) SetImageType(huffman_image,BilevelType); 00751 byte='\0'; 00752 bit=(unsigned char) 0x80; 00753 if (LocaleCompare(image_info->magick,"FAX") != 0) 00754 Ascii85Initialize(image); 00755 else 00756 { 00757 /* 00758 End of line. 00759 */ 00760 for (k=0; k < 11; k++) 00761 OutputBit(0); 00762 OutputBit(1); 00763 } 00764 /* 00765 Compress runlength encoded to 1D Huffman pixels. 00766 */ 00767 polarity=(IndexPacket) (PixelIntensityToQuantum( 00768 &huffman_image->colormap[0]) >= (MaxRGB/2) ? 0x00 : 0x01); 00769 if (huffman_image->colors == 2) 00770 polarity=(IndexPacket) 00771 (PixelIntensityToQuantum(&huffman_image->colormap[0]) < 00772 PixelIntensityToQuantum(&huffman_image->colormap[1]) ? 0x00 : 0x01); 00773 q=scanline; 00774 for (i=0; i < (long) width; i++) 00775 *q++=(unsigned char) polarity; 00776 q=scanline; 00777 for (y=0; y < (long) huffman_image->rows; y++) 00778 { 00779 p=AcquireImagePixels(huffman_image,0,y,huffman_image->columns,1, 00780 &huffman_image->exception); 00781 if (p == (const PixelPacket *) NULL) 00782 break; 00783 indexes=GetIndexes(huffman_image); 00784 for (x=0; x < (long) huffman_image->columns; x++) 00785 { 00786 *q=(unsigned char) 00787 (indexes[x] == polarity ? polarity == 0 : polarity != 0); 00788 q++; 00789 } 00790 /* 00791 Huffman encode scanline. 00792 */ 00793 q=scanline; 00794 for (n=(long) width; n > 0; ) 00795 { 00796 /* 00797 Output white run. 00798 */ 00799 for (runlength=0; ((n > 0) && ((Quantum) *q == polarity)); n--) 00800 { 00801 q++; 00802 runlength++; 00803 } 00804 if (runlength >= 64) 00805 { 00806 if (runlength < 1792) 00807 entry=MWTable+((runlength/64)-1); 00808 else 00809 entry=EXTable+(Min(runlength,2560)-1792)/64; 00810 runlength-=entry->count; 00811 HuffmanOutputCode(entry); 00812 } 00813 entry=TWTable+Min(runlength,63); 00814 HuffmanOutputCode(entry); 00815 if (n != 0) 00816 { 00817 /* 00818 Output black run. 00819 */ 00820 for (runlength=0; (((Quantum) *q != polarity) && (n > 0)); n--) 00821 { 00822 q++; 00823 runlength++; 00824 } 00825 if (runlength >= 64) 00826 { 00827 entry=MBTable+((runlength/64)-1); 00828 if (runlength >= 1792) 00829 entry=EXTable+(Min(runlength,2560)-1792)/64; 00830 runlength-=entry->count; 00831 HuffmanOutputCode(entry); 00832 } 00833 entry=TBTable+Min(runlength,63); 00834 HuffmanOutputCode(entry); 00835 } 00836 } 00837 /* 00838 End of line. 00839 */ 00840 for (k=0; k < 11; k++) 00841 OutputBit(0); 00842 OutputBit(1); 00843 q=scanline; 00844 if (huffman_image->previous == (Image *) NULL) 00845 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 00846 (QuantumTick(y,huffman_image->rows) != MagickFalse)) 00847 { 00848 status=image->progress_monitor(LoadImageTag,y,huffman_image->rows, 00849 image->client_data); 00850 if (status == MagickFalse) 00851 break; 00852 } 00853 } 00854 /* 00855 End of page. 00856 */ 00857 for (i=0; i < 6; i++) 00858 { 00859 for (k=0; k < 11; k++) 00860 OutputBit(0); 00861 OutputBit(1); 00862 } 00863 /* 00864 Flush bits. 00865 */ 00866 if (((int) bit != 0x80) != 0) 00867 { 00868 if (LocaleCompare(image_info->magick,"FAX") == 0) 00869 (void) WriteBlobByte(image,byte); 00870 else 00871 Ascii85Encode(image, byte); 00872 } 00873 if (LocaleCompare(image_info->magick,"FAX") != 0) 00874 Ascii85Flush(image); 00875 huffman_image=DestroyImage(huffman_image); 00876 scanline=(unsigned char *) RelinquishMagickMemory(scanline); 00877 return(MagickTrue); 00878 } 00879 00880 #if defined(HasTIFF) 00881 /* 00882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00883 % % 00884 % % 00885 % % 00886 % H u f f m a n 2 D E n c o d e I m a g e % 00887 % % 00888 % % 00889 % % 00890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00891 % 00892 % Huffman2DEncodeImage() compresses an image via two-dimensional 00893 % Huffman-coding. 00894 % 00895 % The format of the Huffman2DEncodeImage method is: 00896 % 00897 % MagickBooleanType Huffman2DEncodeImage(const ImageInfo *image_info, 00898 % Image *image) 00899 % 00900 % A description of each parameter follows: 00901 % 00902 % o image_info: The image info.. 00903 % 00904 % o image: The image. 00905 % 00906 */ 00907 MagickExport MagickBooleanType Huffman2DEncodeImage(const ImageInfo *image_info, 00908 Image *image) 00909 { 00910 char 00911 filename[MaxTextExtent]; 00912 00913 Image 00914 *huffman_image; 00915 00916 ImageInfo 00917 *write_info; 00918 00919 int 00920 unique_file; 00921 00922 long 00923 j; 00924 00925 MagickBooleanType 00926 status; 00927 00928 register long 00929 i; 00930 00931 ssize_t 00932 count; 00933 00934 TIFF 00935 *tiff; 00936 00937 uint16 00938 fillorder; 00939 00940 unsigned char 00941 *buffer; 00942 00943 unsigned long 00944 *byte_count, 00945 strip_size; 00946 00947 /* 00948 Write image as CCITTFax4 TIFF image to a temporary file. 00949 */ 00950 assert(image_info != (ImageInfo *) NULL); 00951 assert(image_info->signature == MagickSignature); 00952 if (image->debug != MagickFalse) 00953 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00954 assert(image != (Image *) NULL); 00955 assert(image->signature == MagickSignature); 00956 huffman_image=CloneImage(image,0,0,MagickTrue,&image->exception); 00957 if (huffman_image == (Image *) NULL) 00958 return(MagickFalse); 00959 DestroyBlob(huffman_image); 00960 huffman_image->blob=CloneBlobInfo((BlobInfo *) NULL); 00961 (void) SetImageType(huffman_image,BilevelType); 00962 unique_file=AcquireUniqueFileResource(filename); 00963 (void) FormatMagickString(huffman_image->filename,MaxTextExtent,"tiff:%s", 00964 filename); 00965 write_info=CloneImageInfo(image_info); 00966 write_info->compression=Group4Compression; 00967 status=WriteImage(write_info,huffman_image); 00968 write_info=DestroyImageInfo(write_info); 00969 huffman_image=DestroyImage(huffman_image); 00970 if (status == MagickFalse) 00971 return(MagickFalse); 00972 tiff=(TIFF *) NULL; 00973 if (unique_file != -1) 00974 tiff=TIFFFdOpen(unique_file,filename,"rb"); 00975 if ((unique_file == -1) || (tiff == (TIFF *) NULL)) 00976 { 00977 (void) RelinquishUniqueFileResource(filename); 00978 ThrowFileException(&image->exception,FileOpenError,"UnableToOpenFile", 00979 image_info->filename); 00980 return(MagickFalse); 00981 } 00982 /* 00983 Allocate raw strip buffer. 00984 */ 00985 byte_count=0; 00986 (void) TIFFGetField(tiff,TIFFTAG_STRIPBYTECOUNTS,&byte_count); 00987 strip_size=byte_count[0]; 00988 for (i=1; i < (long) TIFFNumberOfStrips(tiff); i++) 00989 if (byte_count[i] > strip_size) 00990 strip_size=byte_count[i]; 00991 buffer=(unsigned char *) AcquireMagickMemory((size_t) strip_size); 00992 if (buffer == (unsigned char *) NULL) 00993 { 00994 TIFFClose(tiff); 00995 (void) RelinquishUniqueFileResource(filename); 00996 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 00997 image_info->filename); 00998 } 00999 /* 01000 Compress runlength encoded to 2D Huffman pixels. 01001 */ 01002 fillorder=FILLORDER_LSB2MSB; 01003 (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_FILLORDER,&fillorder); 01004 for (i=0; i < (long) TIFFNumberOfStrips(tiff); i++) 01005 { 01006 count=(ssize_t) TIFFReadRawStrip(tiff,(uint32) i,buffer,(long) 01007 byte_count[i]); 01008 if (fillorder == FILLORDER_LSB2MSB) 01009 TIFFReverseBits(buffer,(unsigned long) count); 01010 for (j=0; j < (long) count; j++) 01011 (void) WriteBlobByte(image,(unsigned char) buffer[j]); 01012 } 01013 buffer=(unsigned char *) RelinquishMagickMemory(buffer); 01014 TIFFClose(tiff); 01015 (void) RelinquishUniqueFileResource(filename); 01016 return(MagickTrue); 01017 } 01018 #else 01019 MagickExport MagickBooleanType Huffman2DEncodeImage(const ImageInfo *image_info, 01020 Image *image) 01021 { 01022 assert(image != (Image *) NULL); 01023 assert(image->signature == MagickSignature); 01024 if (image->debug != MagickFalse) 01025 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 01026 ThrowBinaryException(MissingDelegateError,"TIFFLibraryIsNotAvailable", 01027 image->filename); 01028 } 01029 #endif 01030 01031 #if defined(HasJPEG) 01032 /* 01033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01034 % % 01035 % % 01036 % % 01037 % J P E G E n c o d e I m a g e % 01038 % % 01039 % % 01040 % % 01041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01042 % 01043 % JPEGEncodeImage() compresses an image via JPEG compression. 01044 % 01045 % The format of the JPEGEncodeImage method is: 01046 % 01047 % MagickBooleanType JPEGEncodeImage(const ImageInfo *image_info, 01048 % Image *image) 01049 % 01050 % A description of each parameter follows: 01051 % 01052 % o image_info: The image info.. 01053 % 01054 % o image: The image. 01055 % 01056 */ 01057 MagickExport MagickBooleanType JPEGEncodeImage(const ImageInfo *image_info, 01058 Image *image) 01059 { 01060 Image 01061 *jpeg_image; 01062 01063 size_t 01064 length; 01065 01066 unsigned char 01067 *blob; 01068 01069 /* 01070 Write image as JPEG image to a temporary file. 01071 */ 01072 jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception); 01073 if (jpeg_image == (Image *) NULL) 01074 ThrowWriterException(CoderError,image->exception.reason); 01075 DestroyBlob(jpeg_image); 01076 jpeg_image->blob=CloneBlobInfo((BlobInfo *) NULL); 01077 (void) strcpy(jpeg_image->magick,"JPEG"); 01078 length=0; 01079 blob=ImageToBlob(image_info,jpeg_image,&length,&image->exception); 01080 if (blob == (void *) NULL) 01081 ThrowWriterException(CoderError,image->exception.reason); 01082 (void) WriteBlob(image,length,blob); 01083 jpeg_image=DestroyImage(jpeg_image); 01084 blob=(unsigned char *) RelinquishMagickMemory(blob); 01085 return(MagickTrue); 01086 } 01087 #else 01088 MagickExport MagickBooleanType JPEGEncodeImage(const ImageInfo *image_info, 01089 Image *image) 01090 { 01091 assert(image != (Image *) NULL); 01092 assert(image->signature == MagickSignature); 01093 if (image->debug != MagickFalse) 01094 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 01095 ThrowBinaryException(MissingDelegateError,"JPEGLibraryIsNotAvailable", 01096 image->filename); 01097 } 01098 #endif 01099 01100 /* 01101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01102 % % 01103 % % 01104 % % 01105 % L Z W E n c o d e I m a g e % 01106 % % 01107 % % 01108 % % 01109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01110 % 01111 % LZWEncodeImage() compresses an image via LZW-coding specific to Postscript 01112 % Level II or Portable Document Format. 01113 % 01114 % The format of the LZWEncodeImage method is: 01115 % 01116 % MagickBooleanType LZWEncodeImage(Image *image,const size_t length, 01117 % unsigned char *pixels) 01118 % 01119 % A description of each parameter follows: 01120 % 01121 % o image: The image. 01122 % 01123 % o length: A value that specifies the number of pixels to compress. 01124 % 01125 % o pixels: The address of an unsigned array of characters containing the 01126 % pixels to compress. 01127 % 01128 % 01129 */ 01130 MagickExport MagickBooleanType LZWEncodeImage(Image *image,const size_t length, 01131 unsigned char *pixels) 01132 { 01133 #define LZWClr 256UL /* Clear Table Marker */ 01134 #define LZWEod 257UL /* End of Data marker */ 01135 #define OutputCode(code) \ 01136 { \ 01137 accumulator+=code << (32-code_width-number_bits); \ 01138 number_bits+=code_width; \ 01139 while (number_bits >= 8) \ 01140 { \ 01141 (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); \ 01142 accumulator=accumulator << 8; \ 01143 number_bits-=8; \ 01144 } \ 01145 } 01146 01147 typedef struct _TableType 01148 { 01149 long 01150 prefix, 01151 suffix, 01152 next; 01153 } TableType; 01154 01155 long 01156 index; 01157 01158 register long 01159 i; 01160 01161 TableType 01162 *table; 01163 01164 unsigned long 01165 accumulator, 01166 number_bits, 01167 code_width, 01168 last_code, 01169 next_index; 01170 01171 /* 01172 Allocate string table. 01173 */ 01174 assert(image != (Image *) NULL); 01175 assert(image->signature == MagickSignature); 01176 if (image->debug != MagickFalse) 01177 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 01178 assert(pixels != (unsigned char *) NULL); 01179 table=(TableType *) AcquireMagickMemory((1 << 12)*sizeof(*table)); 01180 if (table == (TableType *) NULL) 01181 return(MagickFalse); 01182 /* 01183 Initialize variables. 01184 */ 01185 accumulator=0; 01186 code_width=9; 01187 number_bits=0; 01188 last_code=0; 01189 OutputCode(LZWClr); 01190 for (index=0; index < 256; index++) 01191 { 01192 table[index].prefix=(-1); 01193 table[index].suffix=(short) index; 01194 table[index].next=(-1); 01195 } 01196 next_index=LZWEod+1; 01197 code_width=9; 01198 last_code=(unsigned long) pixels[0]; 01199 for (i=1; i < (long) length; i++) 01200 { 01201 /* 01202 Find string. 01203 */ 01204 index=(long) last_code; 01205 while (index != -1) 01206 if ((table[index].prefix != (long) last_code) || 01207 (table[index].suffix != (long) pixels[i])) 01208 index=table[index].next; 01209 else 01210 { 01211 last_code=(unsigned long) index; 01212 break; 01213 } 01214 if (last_code != (unsigned long) index) 01215 { 01216 /* 01217 Add string. 01218 */ 01219 OutputCode(last_code); 01220 table[next_index].prefix=(long) last_code; 01221 table[next_index].suffix=(short) pixels[i]; 01222 table[next_index].next=table[last_code].next; 01223 table[last_code].next=(long) next_index; 01224 next_index++; 01225 /* 01226 Did we just move up to next bit width? 01227 */ 01228 if ((next_index >> code_width) != 0) 01229 { 01230 code_width++; 01231 if (code_width > 12) 01232 { 01233 /* 01234 Did we overflow the max bit width? 01235 */ 01236 code_width--; 01237 OutputCode(LZWClr); 01238 for (index=0; index < 256; index++) 01239 { 01240 table[index].prefix=(-1); 01241 table[index].suffix=index; 01242 table[index].next=(-1); 01243 } 01244 next_index=LZWEod+1; 01245 code_width=9; 01246 } 01247 } 01248 last_code=(unsigned long) pixels[i]; 01249 } 01250 } 01251 /* 01252 Flush tables. 01253 */ 01254 OutputCode(last_code); 01255 OutputCode(LZWEod); 01256 if (number_bits != 0) 01257 (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); 01258 table=(TableType *) RelinquishMagickMemory(table); 01259 return(MagickTrue); 01260 } 01261 01262 /* 01263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01264 % % 01265 % % 01266 % % 01267 % P a c k b i t s E n c o d e I m a g e % 01268 % % 01269 % % 01270 % % 01271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01272 % 01273 % PackbitsEncodeImage() compresses an image via Macintosh Packbits encoding 01274 % specific to Postscript Level II or Portable Document Format. To ensure 01275 % portability, the binary Packbits bytes are encoded as ASCII Base-85. 01276 % 01277 % The format of the PackbitsEncodeImage method is: 01278 % 01279 % MagickBooleanType PackbitsEncodeImage(Image *image,const size_t length, 01280 % unsigned char *pixels) 01281 % 01282 % A description of each parameter follows: 01283 % 01284 % o image: The image. 01285 % 01286 % o length: A value that specifies the number of pixels to compress. 01287 % 01288 % o pixels: The address of an unsigned array of characters containing the 01289 % pixels to compress. 01290 % 01291 % 01292 */ 01293 MagickExport MagickBooleanType PackbitsEncodeImage(Image *image, 01294 const size_t length,unsigned char *pixels) 01295 { 01296 int 01297 count; 01298 01299 register long 01300 i, 01301 j; 01302 01303 unsigned char 01304 *packbits; 01305 01306 /* 01307 Compress pixels with Packbits encoding. 01308 */ 01309 assert(image != (Image *) NULL); 01310 assert(image->signature == MagickSignature); 01311 if (image->debug != MagickFalse) 01312 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 01313 assert(pixels != (unsigned char *) NULL); 01314 packbits=(unsigned char *) AcquireMagickMemory(128); 01315 if (packbits == (unsigned char *) NULL) 01316 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 01317 image->filename); 01318 i=(long) length; 01319 while (i != 0) 01320 { 01321 switch (i) 01322 { 01323 case 1: 01324 { 01325 i--; 01326 (void) WriteBlobByte(image,(unsigned char) 0); 01327 (void) WriteBlobByte(image,*pixels); 01328 break; 01329 } 01330 case 2: 01331 { 01332 i-=2; 01333 (void) WriteBlobByte(image,(unsigned char) 1); 01334 (void) WriteBlobByte(image,*pixels); 01335 (void) WriteBlobByte(image,pixels[1]); 01336 break; 01337 } 01338 case 3: 01339 { 01340 i-=3; 01341 if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 01342 { 01343 (void) WriteBlobByte(image,(unsigned char) ((256-3)+1)); 01344 (void) WriteBlobByte(image,*pixels); 01345 break; 01346 } 01347 (void) WriteBlobByte(image,(unsigned char) 2); 01348 (void) WriteBlobByte(image,*pixels); 01349 (void) WriteBlobByte(image,pixels[1]); 01350 (void) WriteBlobByte(image,pixels[2]); 01351 break; 01352 } 01353 default: 01354 { 01355 if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 01356 { 01357 /* 01358 Packed run. 01359 */ 01360 count=3; 01361 while (((long) count < i) && (*pixels == *(pixels+count))) 01362 { 01363 count++; 01364 if (count >= 127) 01365 break; 01366 } 01367 i-=count; 01368 (void) WriteBlobByte(image,(unsigned char) ((256-count)+1)); 01369 (void) WriteBlobByte(image,*pixels); 01370 pixels+=count; 01371 break; 01372 } 01373 /* 01374 Literal run. 01375 */ 01376 count=0; 01377 while ((*(pixels+count) != *(pixels+count+1)) || 01378 (*(pixels+count+1) != *(pixels+count+2))) 01379 { 01380 packbits[count+1]=pixels[count]; 01381 count++; 01382 if (((long) count >= (i-3)) || (count >= 127)) 01383 break; 01384 } 01385 i-=count; 01386 *packbits=(unsigned char) (count-1); 01387 for (j=0; j <= (long) count; j++) 01388 (void) WriteBlobByte(image,packbits[j]); 01389 pixels+=count; 01390 break; 01391 } 01392 } 01393 } 01394 (void) WriteBlobByte(image,(unsigned char) 128); /* EOD marker */ 01395 packbits=(unsigned char *) RelinquishMagickMemory(packbits); 01396 return(MagickTrue); 01397 } 01398 01399 #if defined(HasZLIB) 01400 /* 01401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01402 % % 01403 % % 01404 % % 01405 % Z L I B E n c o d e I m a g e % 01406 % % 01407 % % 01408 % % 01409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01410 % 01411 % ZLIBEncodeImage compresses an image via ZLIB-coding specific to 01412 % Postscript Level II or Portable Document Format. 01413 % 01414 % The format of the ZLIBEncodeImage method is: 01415 % 01416 % MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length, 01417 % const unsigned long quality,unsigned char *pixels) 01418 % 01419 % A description of each parameter follows: 01420 % 01421 % o file: The address of a structure of type FILE. ZLIB encoded pixels 01422 % are written to this file. 01423 % 01424 % o length: A value that specifies the number of pixels to compress. 01425 % 01426 % o quality: the compression level (0-100). 01427 % 01428 % o pixels: The address of an unsigned array of characters containing the 01429 % pixels to compress. 01430 % 01431 % 01432 */ 01433 MagickExport MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length, 01434 const unsigned long quality,unsigned char *pixels) 01435 { 01436 int 01437 status; 01438 01439 register long 01440 i; 01441 01442 size_t 01443 compressed_packets; 01444 01445 unsigned char 01446 *compressed_pixels; 01447 01448 z_stream 01449 stream; 01450 01451 assert(image != (Image *) NULL); 01452 assert(image->signature == MagickSignature); 01453 if (image->debug != MagickFalse) 01454 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 01455 compressed_packets=(size_t) (1.001*length+12); 01456 compressed_pixels=(unsigned char *) AcquireMagickMemory(compressed_packets); 01457 if (compressed_pixels == (unsigned char *) NULL) 01458 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 0