compress.c revision c5c6f66d8eed62757aeda7f05848d8a8ddc7975a
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% CCCC OOO M M PPPP RRRR EEEEE SSSSS SSSSS % 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% C O O MM MM P P R R E SS SS % 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% C O O M M M PPPP RRRR EEE SSS SSS % 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% C O O M M P R R E SS SS % 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% CCCC OOO M M P R R EEEEE SSSSS SSSSS % 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickCore Image Compression/Decompression Methods % 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Software Design % 163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% John Cristy % 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% May 1993 % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2016af1cbdffcc02e7239d432e5fb51734fcf9f9ffcristy% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization % 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% dedicated to making software imaging solutions freely available. % 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% You may not use this file except in compliance with the License. You may % 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% obtain a copy of the License at % 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.imagemagick.org/script/license.php % 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Unless required by applicable law or agreed to in writing, software % 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% distributed under the License is distributed on an "AS IS" BASIS, % 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% See the License for the specific language governing permissions and % 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% limitations under the License. % 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Include declarations. 423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/studio.h" 443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob.h" 453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob-private.h" 463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color-private.h" 473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/cache.h" 483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/compress.h" 493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/constitute.h" 503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h" 513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h" 523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h" 533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h" 543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h" 553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h" 563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h" 573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/option.h" 583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/resource_.h" 593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/string_.h" 603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_TIFF_DELEGATE) 613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_HAVE_TIFFCONF_H) 623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "tiffconf.h" 633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "tiffio.h" 653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define CCITTParam "-1" 663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define CCITTParam "0" 683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_ZLIB_DELEGATE) 703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h" 713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Typedef declarations. 753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystruct _Ascii85Info 773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 78bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset, 803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy line_break; 813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer[10]; 843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}; 853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct HuffmanTable 873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 88bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy id, 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code, 913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length, 923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count; 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} HuffmanTable; 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Huffman coding declarations. 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TWId 23 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWId 24 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TBId 25 1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBId 26 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define EXId 27 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MBTable[]= 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x0f, 10, 64 }, { MBId, 0xc8, 12, 128 }, 1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0xc9, 12, 192 }, { MBId, 0x5b, 12, 256 }, 1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x33, 12, 320 }, { MBId, 0x34, 12, 384 }, 1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x35, 12, 448 }, { MBId, 0x6c, 13, 512 }, 1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x6d, 13, 576 }, { MBId, 0x4a, 13, 640 }, 1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x4b, 13, 704 }, { MBId, 0x4c, 13, 768 }, 1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x4d, 13, 832 }, { MBId, 0x72, 13, 896 }, 1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x73, 13, 960 }, { MBId, 0x74, 13, 1024 }, 1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x75, 13, 1088 }, { MBId, 0x76, 13, 1152 }, 1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x77, 13, 1216 }, { MBId, 0x52, 13, 1280 }, 1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x53, 13, 1344 }, { MBId, 0x54, 13, 1408 }, 1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x55, 13, 1472 }, { MBId, 0x5a, 13, 1536 }, 1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x5b, 13, 1600 }, { MBId, 0x64, 13, 1664 }, 1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x65, 13, 1728 }, { MBId, 0x00, 0, 0 } 1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy EXTable[]= 1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x08, 11, 1792 }, { EXId, 0x0c, 11, 1856 }, 1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x0d, 11, 1920 }, { EXId, 0x12, 12, 1984 }, 1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x13, 12, 2048 }, { EXId, 0x14, 12, 2112 }, 1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x15, 12, 2176 }, { EXId, 0x16, 12, 2240 }, 1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x17, 12, 2304 }, { EXId, 0x1c, 12, 2368 }, 1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x1d, 12, 2432 }, { EXId, 0x1e, 12, 2496 }, 1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x1f, 12, 2560 }, { EXId, 0x00, 0, 0 } 1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MWTable[]= 1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x1b, 5, 64 }, { MWId, 0x12, 5, 128 }, 1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x17, 6, 192 }, { MWId, 0x37, 7, 256 }, 1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x36, 8, 320 }, { MWId, 0x37, 8, 384 }, 1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x64, 8, 448 }, { MWId, 0x65, 8, 512 }, 1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x68, 8, 576 }, { MWId, 0x67, 8, 640 }, 1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xcc, 9, 704 }, { MWId, 0xcd, 9, 768 }, 1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd2, 9, 832 }, { MWId, 0xd3, 9, 896 }, 1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd4, 9, 960 }, { MWId, 0xd5, 9, 1024 }, 1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd6, 9, 1088 }, { MWId, 0xd7, 9, 1152 }, 1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd8, 9, 1216 }, { MWId, 0xd9, 9, 1280 }, 1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xda, 9, 1344 }, { MWId, 0xdb, 9, 1408 }, 1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x98, 9, 1472 }, { MWId, 0x99, 9, 1536 }, 1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x9a, 9, 1600 }, { MWId, 0x18, 6, 1664 }, 1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x9b, 9, 1728 }, { MWId, 0x00, 0, 0 } 1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TBTable[]= 1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x37, 10, 0 }, { TBId, 0x02, 3, 1 }, { TBId, 0x03, 2, 2 }, 1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x02, 2, 3 }, { TBId, 0x03, 3, 4 }, { TBId, 0x03, 4, 5 }, 1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x02, 4, 6 }, { TBId, 0x03, 5, 7 }, { TBId, 0x05, 6, 8 }, 1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x04, 6, 9 }, { TBId, 0x04, 7, 10 }, { TBId, 0x05, 7, 11 }, 1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x07, 7, 12 }, { TBId, 0x04, 8, 13 }, { TBId, 0x07, 8, 14 }, 1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x18, 9, 15 }, { TBId, 0x17, 10, 16 }, { TBId, 0x18, 10, 17 }, 1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x08, 10, 18 }, { TBId, 0x67, 11, 19 }, { TBId, 0x68, 11, 20 }, 1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x6c, 11, 21 }, { TBId, 0x37, 11, 22 }, { TBId, 0x28, 11, 23 }, 1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x17, 11, 24 }, { TBId, 0x18, 11, 25 }, { TBId, 0xca, 12, 26 }, 1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xcb, 12, 27 }, { TBId, 0xcc, 12, 28 }, { TBId, 0xcd, 12, 29 }, 1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x68, 12, 30 }, { TBId, 0x69, 12, 31 }, { TBId, 0x6a, 12, 32 }, 1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x6b, 12, 33 }, { TBId, 0xd2, 12, 34 }, { TBId, 0xd3, 12, 35 }, 1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xd4, 12, 36 }, { TBId, 0xd5, 12, 37 }, { TBId, 0xd6, 12, 38 }, 1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xd7, 12, 39 }, { TBId, 0x6c, 12, 40 }, { TBId, 0x6d, 12, 41 }, 1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xda, 12, 42 }, { TBId, 0xdb, 12, 43 }, { TBId, 0x54, 12, 44 }, 1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x55, 12, 45 }, { TBId, 0x56, 12, 46 }, { TBId, 0x57, 12, 47 }, 1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x64, 12, 48 }, { TBId, 0x65, 12, 49 }, { TBId, 0x52, 12, 50 }, 1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x53, 12, 51 }, { TBId, 0x24, 12, 52 }, { TBId, 0x37, 12, 53 }, 1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x38, 12, 54 }, { TBId, 0x27, 12, 55 }, { TBId, 0x28, 12, 56 }, 1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x58, 12, 57 }, { TBId, 0x59, 12, 58 }, { TBId, 0x2b, 12, 59 }, 1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x2c, 12, 60 }, { TBId, 0x5a, 12, 61 }, { TBId, 0x66, 12, 62 }, 1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x67, 12, 63 }, { TBId, 0x00, 0, 0 } 1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TWTable[]= 1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x35, 8, 0 }, { TWId, 0x07, 6, 1 }, { TWId, 0x07, 4, 2 }, 1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x08, 4, 3 }, { TWId, 0x0b, 4, 4 }, { TWId, 0x0c, 4, 5 }, 1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x0e, 4, 6 }, { TWId, 0x0f, 4, 7 }, { TWId, 0x13, 5, 8 }, 1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x14, 5, 9 }, { TWId, 0x07, 5, 10 }, { TWId, 0x08, 5, 11 }, 1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x08, 6, 12 }, { TWId, 0x03, 6, 13 }, { TWId, 0x34, 6, 14 }, 1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x35, 6, 15 }, { TWId, 0x2a, 6, 16 }, { TWId, 0x2b, 6, 17 }, 1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x27, 7, 18 }, { TWId, 0x0c, 7, 19 }, { TWId, 0x08, 7, 20 }, 1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x17, 7, 21 }, { TWId, 0x03, 7, 22 }, { TWId, 0x04, 7, 23 }, 1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x28, 7, 24 }, { TWId, 0x2b, 7, 25 }, { TWId, 0x13, 7, 26 }, 1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x24, 7, 27 }, { TWId, 0x18, 7, 28 }, { TWId, 0x02, 8, 29 }, 1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x03, 8, 30 }, { TWId, 0x1a, 8, 31 }, { TWId, 0x1b, 8, 32 }, 1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x12, 8, 33 }, { TWId, 0x13, 8, 34 }, { TWId, 0x14, 8, 35 }, 1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x15, 8, 36 }, { TWId, 0x16, 8, 37 }, { TWId, 0x17, 8, 38 }, 1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x28, 8, 39 }, { TWId, 0x29, 8, 40 }, { TWId, 0x2a, 8, 41 }, 1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x2b, 8, 42 }, { TWId, 0x2c, 8, 43 }, { TWId, 0x2d, 8, 44 }, 1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x04, 8, 45 }, { TWId, 0x05, 8, 46 }, { TWId, 0x0a, 8, 47 }, 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x0b, 8, 48 }, { TWId, 0x52, 8, 49 }, { TWId, 0x53, 8, 50 }, 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x54, 8, 51 }, { TWId, 0x55, 8, 52 }, { TWId, 0x24, 8, 53 }, 2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x25, 8, 54 }, { TWId, 0x58, 8, 55 }, { TWId, 0x59, 8, 56 }, 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x5a, 8, 57 }, { TWId, 0x5b, 8, 58 }, { TWId, 0x4a, 8, 59 }, 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x4b, 8, 60 }, { TWId, 0x32, 8, 61 }, { TWId, 0x33, 8, 62 }, 2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x34, 8, 63 }, { TWId, 0x00, 0, 0 } 2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A S C I I 8 5 E n c o d e % 2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ASCII85Encode() encodes data in ASCII base-85 format. ASCII base-85 2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% encoding produces five ASCII printing characters from every four bytes of 2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% binary data. 2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the ASCII85Encode method is: 2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% void Ascii85Encode(Image *image,const size_t code) 2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o code: a binary unsigned char to encode to ASCII 85. 2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o file: write the encoded ASCII character to this file. 2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MaxLineExtent 36 2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic char *Ascii85Tuple(unsigned char *data) 2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy static char 2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[6]; 2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 242bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i, 2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 246bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code, 2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum; 2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 250bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy code=((((size_t) data[0] << 8) | (size_t) data[1]) << 16) | 251bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ((size_t) data[2] << 8) | (size_t) data[3]; 2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (code == 0L) 2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[0]='z'; 2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[1]='\0'; 2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(tuple); 2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum=85UL*85UL*85UL*85UL; 2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; i < 4; i++) 2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy x=(ssize_t) (code/quantum); 2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code-=quantum*x; 2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[i]=(char) (x+(int) '!'); 2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum/=85L; 2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[4]=(char) ((code % 85L)+(int) '!'); 2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[5]='\0'; 2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(tuple); 2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Initialize(Image *image) 2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate image structure. 2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85 == (Ascii85Info *) NULL) 27790823213d62b0ba18557e61f1e6892c6fffd6cd4cristy image->ascii85=(Ascii85Info *) AcquireAlignedMemory(1,sizeof(*image->ascii85)); 2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85 == (Ascii85Info *) NULL) 2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(image->ascii85,0,sizeof(*image->ascii85)); 2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->line_break=MaxLineExtent << 1; 2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->offset=0; 2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Flush(Image *image) 2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *tuple; 2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->ascii85 != (Ascii85Info *) NULL); 2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85->offset > 0) 2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset]='\0'; 2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset+1]='\0'; 2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset+2]='\0'; 3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple=Ascii85Tuple(image->ascii85->buffer); 3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlob(image,(size_t) image->ascii85->offset+1, 3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (const unsigned char *) (*tuple == 'z' ? "!!!!" : tuple)); 3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'~'); 3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'>'); 3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'\n'); 3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Encode(Image *image,const unsigned char code) 3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 311bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy n; 3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q; 3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register unsigned char 3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->ascii85 != (Ascii85Info *) NULL); 3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset]=code; 3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->offset++; 3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85->offset < 4) 3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=image->ascii85->buffer; 3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (n=image->ascii85->offset; n >= 4; n-=4) 3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (q=Ascii85Tuple(p); *q != '\0'; q++) 3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->line_break--; 3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((image->ascii85->line_break < 0) && (*q != '%')) 3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'\n'); 3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->line_break=2*MaxLineExtent; 3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) *q); 3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p+=8; 3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->offset=n; 3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p-=4; 3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (n=0; n < 4; n++) 3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[n]=(*p++); 3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% H u f f m a n D e c o d e I m a g e % 3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% HuffmanDecodeImage() uncompresses an image via Huffman-coding. 3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the HuffmanDecodeImage method is: 3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType HuffmanDecodeImage(Image *image) 3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline size_t MagickMax(const size_t x,const size_t y) 3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (x > y) 3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(x); 3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(y); 3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline size_t MagickMin(const size_t x,const size_t y) 3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (x < y) 3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(x); 3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(y); 3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType HuffmanDecodeImage(Image *image) 3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HashSize 1021 3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBHashA 293 3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBHashB 2695 3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWHashA 3510 3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWHashB 1178 3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define InitializeHashTable(hash,table,a,b) \ 3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=table; \ 3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (entry->code != 0) \ 3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hash[((entry->length+a)*(entry->code+b)) % HashSize]=(HuffmanTable *) entry; \ 3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry++; \ 4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define InputBit(bit) \ 4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((mask & 0xff) == 0) \ 4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte=ReadBlobByte(image); \ 4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (byte == EOF) \ 4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; \ 4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask=0x80; \ 4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength++; \ 413bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy bit=(size_t) ((byte & mask) != 0 ? 0x01 : 0x00); \ 4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask>>=1; \ 4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bit != 0) \ 4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength=0; \ 4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 419c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy CacheView 420c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy *image_view; 421c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy 4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const HuffmanTable 4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *entry; 4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExceptionInfo 4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *exception; 4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanTable 4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **mb_hash, 4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **mw_hash; 4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy IndexPacket 4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy index; 4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte; 4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed; 4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register IndexPacket 4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *indexes; 4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 444bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register unsigned char 4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ssize_t 451c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy count, 452c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy y; 4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *scanline; 4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int 4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bail, 4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy color; 4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 461bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit, 4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code, 4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask, 4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length, 4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy null_lines, 4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength; 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate buffers. 4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mb_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mb_hash)); 4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mw_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mw_hash)); 4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) AcquireQuantumMemory((size_t) image->columns, 4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sizeof(*scanline)); 4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((mb_hash == (HuffmanTable **) NULL) || 4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (mw_hash == (HuffmanTable **) NULL) || 4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (scanline == (unsigned char *) NULL)) 4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize Huffman tables. 4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; i < HashSize; i++) 4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mb_hash[i]=(HuffmanTable *) NULL; 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mw_hash[i]=(HuffmanTable *) NULL; 4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mw_hash,TWTable,MWHashA,MWHashB); 4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mw_hash,MWTable,MWHashA,MWHashB); 4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mw_hash,EXTable,MWHashA,MWHashB); 4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mb_hash,TBTable,MBHashA,MBHashB); 4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mb_hash,MBTable,MBHashA,MBHashB); 4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mb_hash,EXTable,MBHashA,MBHashB); 4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Uncompress 1D Huffman to runlength encoded pixels. 5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte=0; 5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask=0; 5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy null_lines=0; 5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength=0; 5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (runlength < 11) 5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { InputBit(bit); } while ((int) bit == 0); 5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->x_resolution=204.0; 5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->y_resolution=196.0; 5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->units=PixelsPerInchResolution; 5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy exception=(&image->exception); 513c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy image_view=AcquireCacheView(image); 514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; ((y < (ssize_t) image->rows) && (null_lines < 3)); ) 5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register PixelPacket 517c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy *restrict q; 5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 519c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy register ssize_t 520c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy x; 521c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy 5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize scanline to white. 5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=scanline; 526bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p++=(unsigned char) 0; 5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Decode Huffman encoded scanline. 5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy color=MagickTrue; 5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code=0; 5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=0; 5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=0; 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength=0; 5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x=0; 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; ; ) 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (byte == EOF) 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 541bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (x >= (ssize_t) image->columns) 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (runlength < 11) 5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { InputBit(bit); } while ((int) bit == 0); 5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bail=MagickFalse; 5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do 5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength < 11) 5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit) 5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((int) bit != 0) 5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy null_lines++; 5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (x != 0) 5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy null_lines=0; 5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bail=MagickTrue; 5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 565bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy code=(code << 1)+(size_t) bit; 5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length++; 5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } while (code == 0); 5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bail != MagickFalse) 5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length > 13) 5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (runlength < 11) 5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { InputBit(bit); } while ((int) bit == 0); 5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (color != MagickFalse) 5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length < 4) 5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=mw_hash[((length+MWHashA)*(code+MWHashB)) % HashSize]; 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length < 2) 5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=mb_hash[((length+MBHashA)*(code+MBHashB)) % HashSize]; 5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (entry == (const HuffmanTable *) NULL) 5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((entry->length != length) || (entry->code != code)) 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (entry->id) 5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case TWId: 5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case TBId: 5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 598eaedf06777741da32408da72c1e512975c600c48cristy count+=(ssize_t) entry->count; 599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((x+count) > (ssize_t) image->columns) 6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=(ssize_t) image->columns-x; 6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count > 0) 6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (color != MagickFalse) 6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x+=count; 6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=0; 6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; count > 0; count--) 6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline[x++]=(unsigned char) 1; 6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy color=(unsigned int) 6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ((color == MagickFalse) ? MagickTrue : MagickFalse); 6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case MWId: 6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case MBId: 6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case EXId: 6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 620eaedf06777741da32408da72c1e512975c600c48cristy count+=(ssize_t) entry->count; 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code=0; 6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=0; 6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Transfer scanline to image pixels. 6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=scanline; 633c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (q == (PixelPacket *) NULL) 6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 636c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy indexes=GetCacheViewAuthenticIndexQueue(image_view); 637bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy index=(IndexPacket) (*p++); 6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy indexes[x]=index; 641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy *q++=image->colormap[(ssize_t) index]; 6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 643c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed=SetImageProgress(image,LoadImageTag,y,image->rows); 6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (proceed == MagickFalse) 6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy y++; 6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 650c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy image_view=DestroyCacheView(image_view); 651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy image->rows=(size_t) MagickMax((size_t) y-3,1); 6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->compression=FaxCompression; 6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Free decoder memory. 6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mw_hash=(HuffmanTable **) RelinquishMagickMemory(mw_hash); 6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mb_hash=(HuffmanTable **) RelinquishMagickMemory(mb_hash); 6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) RelinquishMagickMemory(scanline); 6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% H u f f m a n E n c o d e I m a g e % 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% HuffmanEncodeImage() compresses an image via Huffman-coding. 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the HuffmanEncodeImage method is: 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info, 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Image *image,Image *inject_image) 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image_info: the image info.. 6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o inject_image: inject into the image stream. 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info, 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image *image,Image *inject_image) 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HuffmanOutputCode(entry) \ 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 694eaedf06777741da32408da72c1e512975c600c48cristy mask=one << (entry->length-1); \ 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (mask != 0) \ 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(((entry->code & mask) != 0 ? 1 : 0)); \ 6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask>>=1; \ 6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputBit(count) \ 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count > 0) \ 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte=byte | bit; \ 7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit>>=1; \ 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((int) (bit & 0xff) == 0) \ 7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") == 0) \ 7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) byte); \ 7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else \ 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Encode(image,byte); \ 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte='\0'; \ 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit=(unsigned char) 0x80; \ 7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const HuffmanTable 7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *entry; 7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExceptionInfo 7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *exception; 7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy k, 7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength; 7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 728bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy n, 7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy y; 7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image 7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *huffman_image; 7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed; 7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i, 7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register const PixelPacket 7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register unsigned char 7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q; 7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte, 7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit, 7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *scanline; 7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask, 755eaedf06777741da32408da72c1e512975c600c48cristy one, 7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width; 7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate scanline buffer. 7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image_info != (ImageInfo *) NULL); 7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image_info->signature == MagickSignature); 7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(inject_image != (Image *) NULL); 7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(inject_image->signature == MagickSignature); 769eaedf06777741da32408da72c1e512975c600c48cristy one=1; 7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width=inject_image->columns; 7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") == 0) 772bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy width=(size_t) MagickMax(inject_image->columns,1728); 7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) AcquireQuantumMemory((size_t) width+1UL, 7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sizeof(*scanline)); 7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (scanline == (unsigned char *) NULL) 7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy inject_image->filename); 7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(scanline,0,width*sizeof(*scanline)); 7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy huffman_image=CloneImage(inject_image,0,0,MagickTrue,&image->exception); 7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (huffman_image == (Image *) NULL) 7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) RelinquishMagickMemory(scanline); 7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) SetImageType(huffman_image,BilevelType); 7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte='\0'; 7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit=(unsigned char) 0x80; 7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") != 0) 7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Initialize(image); 7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy End of line. 7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (k=0; k < 11; k++) 7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(0); 7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(1); 7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Compress to 1D Huffman pixels. 8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy exception=(&huffman_image->exception); 8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=scanline; 804bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) huffman_image->rows; y++) 8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=GetVirtualPixels(huffman_image,0,y,huffman_image->columns,1,exception); 8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (p == (const PixelPacket *) NULL) 8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) huffman_image->columns; x++) 8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q++=(unsigned char) (PixelIntensity(p) >= ((MagickRealType) 8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy QuantumRange/2.0) ? 0 : 1); 8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p++; 8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Huffman encode scanline. 8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=scanline; 819bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (n=(ssize_t) width; n > 0; ) 8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Output white run. 8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (runlength=0; ((n > 0) && (*q == 0)); n--) 8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q++; 8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength++; 8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength >= 64) 8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength < 1792) 8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=MWTable+((runlength/64)-1); 8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64; 8358891f9ce489d3e61399b60436ea6c62f5ed9b887cristy runlength-=(long) entry->count; 8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=TWTable+MagickMin((size_t) runlength,63); 8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (n != 0) 8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Output black run. 8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (runlength=0; ((*q != 0) && (n > 0)); n--) 8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q++; 8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength++; 8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength >= 64) 8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=MBTable+((runlength/64)-1); 8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength >= 1792) 8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64; 8558891f9ce489d3e61399b60436ea6c62f5ed9b887cristy runlength-=(long) entry->count; 8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=TBTable+MagickMin((size_t) runlength,63); 8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy End of line. 8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (k=0; k < 11; k++) 8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(0); 8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(1); 8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=scanline; 8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (GetPreviousImageInList(huffman_image) == (Image *) NULL) 8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed=SetImageProgress(huffman_image,LoadImageTag,y, 8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy huffman_image->rows); 8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (proceed == MagickFalse) 8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy End of page. 8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; i < 6; i++) 8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (k=0; k < 11; k++) 8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(0); 8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(1); 8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Flush bits. 8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (((int) bit != 0x80) != 0) 8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") == 0) 8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,byte); 8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Encode(image,byte); 8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") != 0) 8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Flush(image); 8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy huffman_image=DestroyImage(huffman_image); 8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) RelinquishMagickMemory(scanline); 9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% L Z W E n c o d e I m a g e % 9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% LZWEncodeImage() compresses an image via LZW-coding specific to Postscript 9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Level II or Portable Document Format. 9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the LZWEncodeImage method is: 9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType LZWEncodeImage(Image *image,const size_t length, 9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% unsigned char *pixels) 9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: A value that specifies the number of pixels to compress. 9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o pixels: the address of an unsigned array of characters containing the 9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pixels to compress. 9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType LZWEncodeImage(Image *image,const size_t length, 9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char *pixels) 9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWClr 256UL /* Clear Table Marker */ 9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWEod 257UL /* End of Data marker */ 9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputCode(code) \ 9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator+=code << (32-code_width-number_bits); \ 9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits+=code_width; \ 9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (number_bits >= 8) \ 9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); \ 9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator=accumulator << 8; \ 9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits-=8; \ 9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy typedef struct _TableType 9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 951bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy prefix, 9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy suffix, 9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next; 9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } TableType; 9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy index; 9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 960bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TableType 9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *table; 9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 966bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator, 9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits, 9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width, 9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_code, 9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index; 9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate string table. 9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(pixels != (unsigned char *) NULL); 9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table=(TableType *) AcquireQuantumMemory(1UL << 12,sizeof(*table)); 9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (table == (TableType *) NULL) 9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize variables. 9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator=0; 9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width=9; 9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits=0; 9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_code=0; 9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(LZWClr); 9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (index=0; index < 256; index++) 9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].prefix=(-1); 9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].suffix=(short) index; 9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].next=(-1); 9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index=LZWEod+1; 9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width=9; 1000bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy last_code=(size_t) pixels[0]; 1001bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=1; i < (ssize_t) length; i++) 10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Find string. 10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1006bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy index=(ssize_t) last_code; 10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (index != -1) 1008bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((table[index].prefix != (ssize_t) last_code) || 1009bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy (table[index].suffix != (ssize_t) pixels[i])) 10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy index=table[index].next; 10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1013bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy last_code=(size_t) index; 10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1016bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (last_code != (size_t) index) 10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Add string. 10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(last_code); 1022bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy table[next_index].prefix=(ssize_t) last_code; 10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[next_index].suffix=(short) pixels[i]; 10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[next_index].next=table[last_code].next; 1025bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy table[last_code].next=(ssize_t) next_index; 10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index++; 10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Did we just move up to next bit width? 10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((next_index >> code_width) != 0) 10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width++; 10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (code_width > 12) 10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Did we overflow the max bit width? 10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width--; 10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(LZWClr); 10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (index=0; index < 256; index++) 10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].prefix=(-1); 10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].suffix=index; 10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].next=(-1); 10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index=LZWEod+1; 10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width=9; 10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1050bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy last_code=(size_t) pixels[i]; 10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Flush tables. 10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(last_code); 10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(LZWEod); 10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (number_bits != 0) 10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); 10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table=(TableType *) RelinquishMagickMemory(table); 10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% P a c k b i t s E n c o d e I m a g e % 10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% PackbitsEncodeImage() compresses an image via Macintosh Packbits encoding 10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% specific to Postscript Level II or Portable Document Format. To ensure 10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% portability, the binary Packbits bytes are encoded as ASCII Base-85. 10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the PackbitsEncodeImage method is: 10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType PackbitsEncodeImage(Image *image,const size_t length, 10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% unsigned char *pixels) 10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: A value that specifies the number of pixels to compress. 10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o pixels: the address of an unsigned array of characters containing the 10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pixels to compress. 10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType PackbitsEncodeImage(Image *image, 10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const size_t length,unsigned char *pixels) 10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count; 10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1100bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i, 11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy j; 11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *packbits; 11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Compress pixels with Packbits encoding. 11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(pixels != (unsigned char *) NULL); 11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packbits=(unsigned char *) AcquireQuantumMemory(128UL,sizeof(*packbits)); 11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (packbits == (unsigned char *) NULL) 11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 1119bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=(ssize_t) length; i != 0; ) 11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (i) 11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 1: 11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i--; 11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 0); 11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 2: 11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=2; 11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 1); 11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,pixels[1]); 11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 3: 11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=3; 11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) ((256-3)+1)); 11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 2); 11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,pixels[1]); 11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,pixels[2]); 11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Packed run. 11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=3; 1161bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy while (((ssize_t) count < i) && (*pixels == *(pixels+count))) 11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count++; 11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count >= 127) 11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=count; 11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) ((256-count)+1)); 11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixels+=count; 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Literal run. 11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=0; 11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while ((*(pixels+count) != *(pixels+count+1)) || 11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (*(pixels+count+1) != *(pixels+count+2))) 11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packbits[count+1]=pixels[count]; 11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count++; 1182bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (((ssize_t) count >= (i-3)) || (count >= 127)) 11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=count; 11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *packbits=(unsigned char) (count-1); 1187bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (j=0; j <= (ssize_t) count; j++) 11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,packbits[j]); 11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixels+=count; 11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 128); /* EOD marker */ 11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packbits=(unsigned char *) RelinquishMagickMemory(packbits); 11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_ZLIB_DELEGATE) 12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Z L I B E n c o d e I m a g e % 12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ZLIBEncodeImage compresses an image via ZLIB-coding specific to 12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Postscript Level II or Portable Document Format. 12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the ZLIBEncodeImage method is: 12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length, 12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% unsigned char *pixels) 12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o file: the address of a structure of type FILE. ZLIB encoded pixels 12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% are written to this file. 12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: A value that specifies the number of pixels to compress. 12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o pixels: the address of an unsigned array of characters containing the 12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pixels to compress. 12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic voidpf AcquireZIPMemory(voidpf context,unsigned int items, 12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int size) 12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) context; 12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((voidpf) AcquireQuantumMemory(items,size)); 12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void RelinquishZIPMemory(voidpf context,voidpf memory) 12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) context; 12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy memory=RelinquishMagickMemory(memory); 12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length, 12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char *pixels) 12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1250bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_packets; 12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *compress_pixels; 12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy z_stream 12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream; 12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_packets=(size_t) (1.001*length+12); 12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_packets, 12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sizeof(*compress_pixels)); 12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (compress_pixels == (unsigned char *) NULL) 12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.next_in=pixels; 12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.avail_in=(unsigned int) length; 12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.next_out=compress_pixels; 12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.avail_out=(unsigned int) compress_packets; 12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.zalloc=AcquireZIPMemory; 12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.zfree=RelinquishZIPMemory; 12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.opaque=(voidpf) NULL; 12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=deflateInit(&stream,(int) (image->quality == 12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9))); 12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == Z_OK) 12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=deflate(&stream,Z_FINISH); 12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == Z_STREAM_END) 12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=deflateEnd(&stream); 12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) deflateEnd(&stream); 12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_packets=(size_t) stream.total_out; 12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status != Z_OK) 12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(CoderError,"UnableToZipCompressImage",image->filename) 12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1293bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) compress_packets; i++) 12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,compress_pixels[i]); 12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels); 12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status == Z_OK ? MagickTrue : MagickFalse); 12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image, 13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const size_t magick_unused(length),unsigned char *magick_unused(pixels)) 13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ThrowMagickException(&image->exception,GetMagickModule(), 13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (ZIP)", 13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 1312