compress.c revision 4c08aed51c5899665ade97263692328eea4af106
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% % 207e41fe84a841d7b9d7b36b245b65e9dcb3314943cristy% Copyright 1999-2011 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*/ 434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h" 444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h" 454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h" 464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h" 474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h" 484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/compress.h" 494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h" 514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h" 544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h" 554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h" 604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_TIFF_DELEGATE) 623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_HAVE_TIFFCONF_H) 633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "tiffconf.h" 643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "tiffio.h" 663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define CCITTParam "-1" 673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define CCITTParam "0" 693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_ZLIB_DELEGATE) 713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h" 723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Typedef declarations. 763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystruct _Ascii85Info 783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 79bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset, 813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy line_break; 823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer[10]; 853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}; 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 873ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct HuffmanTable 883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 89bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy id, 913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code, 923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length, 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count; 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} HuffmanTable; 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Huffman coding declarations. 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TWId 23 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWId 24 1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TBId 25 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBId 26 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define EXId 27 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MBTable[]= 1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x0f, 10, 64 }, { MBId, 0xc8, 12, 128 }, 1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0xc9, 12, 192 }, { MBId, 0x5b, 12, 256 }, 1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x33, 12, 320 }, { MBId, 0x34, 12, 384 }, 1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x35, 12, 448 }, { MBId, 0x6c, 13, 512 }, 1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x6d, 13, 576 }, { MBId, 0x4a, 13, 640 }, 1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x4b, 13, 704 }, { MBId, 0x4c, 13, 768 }, 1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x4d, 13, 832 }, { MBId, 0x72, 13, 896 }, 1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x73, 13, 960 }, { MBId, 0x74, 13, 1024 }, 1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x75, 13, 1088 }, { MBId, 0x76, 13, 1152 }, 1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x77, 13, 1216 }, { MBId, 0x52, 13, 1280 }, 1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x53, 13, 1344 }, { MBId, 0x54, 13, 1408 }, 1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x55, 13, 1472 }, { MBId, 0x5a, 13, 1536 }, 1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x5b, 13, 1600 }, { MBId, 0x64, 13, 1664 }, 1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MBId, 0x65, 13, 1728 }, { MBId, 0x00, 0, 0 } 1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy EXTable[]= 1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x08, 11, 1792 }, { EXId, 0x0c, 11, 1856 }, 1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x0d, 11, 1920 }, { EXId, 0x12, 12, 1984 }, 1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x13, 12, 2048 }, { EXId, 0x14, 12, 2112 }, 1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x15, 12, 2176 }, { EXId, 0x16, 12, 2240 }, 1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x17, 12, 2304 }, { EXId, 0x1c, 12, 2368 }, 1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x1d, 12, 2432 }, { EXId, 0x1e, 12, 2496 }, 1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { EXId, 0x1f, 12, 2560 }, { EXId, 0x00, 0, 0 } 1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MWTable[]= 1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x1b, 5, 64 }, { MWId, 0x12, 5, 128 }, 1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x17, 6, 192 }, { MWId, 0x37, 7, 256 }, 1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x36, 8, 320 }, { MWId, 0x37, 8, 384 }, 1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x64, 8, 448 }, { MWId, 0x65, 8, 512 }, 1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x68, 8, 576 }, { MWId, 0x67, 8, 640 }, 1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xcc, 9, 704 }, { MWId, 0xcd, 9, 768 }, 1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd2, 9, 832 }, { MWId, 0xd3, 9, 896 }, 1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd4, 9, 960 }, { MWId, 0xd5, 9, 1024 }, 1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd6, 9, 1088 }, { MWId, 0xd7, 9, 1152 }, 1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xd8, 9, 1216 }, { MWId, 0xd9, 9, 1280 }, 1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0xda, 9, 1344 }, { MWId, 0xdb, 9, 1408 }, 1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x98, 9, 1472 }, { MWId, 0x99, 9, 1536 }, 1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x9a, 9, 1600 }, { MWId, 0x18, 6, 1664 }, 1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { MWId, 0x9b, 9, 1728 }, { MWId, 0x00, 0, 0 } 1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TBTable[]= 1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x37, 10, 0 }, { TBId, 0x02, 3, 1 }, { TBId, 0x03, 2, 2 }, 1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x02, 2, 3 }, { TBId, 0x03, 3, 4 }, { TBId, 0x03, 4, 5 }, 1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x02, 4, 6 }, { TBId, 0x03, 5, 7 }, { TBId, 0x05, 6, 8 }, 1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x04, 6, 9 }, { TBId, 0x04, 7, 10 }, { TBId, 0x05, 7, 11 }, 1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x07, 7, 12 }, { TBId, 0x04, 8, 13 }, { TBId, 0x07, 8, 14 }, 1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x18, 9, 15 }, { TBId, 0x17, 10, 16 }, { TBId, 0x18, 10, 17 }, 1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x08, 10, 18 }, { TBId, 0x67, 11, 19 }, { TBId, 0x68, 11, 20 }, 1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x6c, 11, 21 }, { TBId, 0x37, 11, 22 }, { TBId, 0x28, 11, 23 }, 1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x17, 11, 24 }, { TBId, 0x18, 11, 25 }, { TBId, 0xca, 12, 26 }, 1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xcb, 12, 27 }, { TBId, 0xcc, 12, 28 }, { TBId, 0xcd, 12, 29 }, 1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x68, 12, 30 }, { TBId, 0x69, 12, 31 }, { TBId, 0x6a, 12, 32 }, 1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x6b, 12, 33 }, { TBId, 0xd2, 12, 34 }, { TBId, 0xd3, 12, 35 }, 1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xd4, 12, 36 }, { TBId, 0xd5, 12, 37 }, { TBId, 0xd6, 12, 38 }, 1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xd7, 12, 39 }, { TBId, 0x6c, 12, 40 }, { TBId, 0x6d, 12, 41 }, 1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0xda, 12, 42 }, { TBId, 0xdb, 12, 43 }, { TBId, 0x54, 12, 44 }, 1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x55, 12, 45 }, { TBId, 0x56, 12, 46 }, { TBId, 0x57, 12, 47 }, 1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x64, 12, 48 }, { TBId, 0x65, 12, 49 }, { TBId, 0x52, 12, 50 }, 1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x53, 12, 51 }, { TBId, 0x24, 12, 52 }, { TBId, 0x37, 12, 53 }, 1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x38, 12, 54 }, { TBId, 0x27, 12, 55 }, { TBId, 0x28, 12, 56 }, 1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x58, 12, 57 }, { TBId, 0x59, 12, 58 }, { TBId, 0x2b, 12, 59 }, 1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x2c, 12, 60 }, { TBId, 0x5a, 12, 61 }, { TBId, 0x66, 12, 62 }, 1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TBId, 0x67, 12, 63 }, { TBId, 0x00, 0, 0 } 1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable 1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TWTable[]= 1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x35, 8, 0 }, { TWId, 0x07, 6, 1 }, { TWId, 0x07, 4, 2 }, 1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x08, 4, 3 }, { TWId, 0x0b, 4, 4 }, { TWId, 0x0c, 4, 5 }, 1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x0e, 4, 6 }, { TWId, 0x0f, 4, 7 }, { TWId, 0x13, 5, 8 }, 1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x14, 5, 9 }, { TWId, 0x07, 5, 10 }, { TWId, 0x08, 5, 11 }, 1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x08, 6, 12 }, { TWId, 0x03, 6, 13 }, { TWId, 0x34, 6, 14 }, 1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x35, 6, 15 }, { TWId, 0x2a, 6, 16 }, { TWId, 0x2b, 6, 17 }, 1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x27, 7, 18 }, { TWId, 0x0c, 7, 19 }, { TWId, 0x08, 7, 20 }, 1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x17, 7, 21 }, { TWId, 0x03, 7, 22 }, { TWId, 0x04, 7, 23 }, 1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x28, 7, 24 }, { TWId, 0x2b, 7, 25 }, { TWId, 0x13, 7, 26 }, 1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x24, 7, 27 }, { TWId, 0x18, 7, 28 }, { TWId, 0x02, 8, 29 }, 1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x03, 8, 30 }, { TWId, 0x1a, 8, 31 }, { TWId, 0x1b, 8, 32 }, 1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x12, 8, 33 }, { TWId, 0x13, 8, 34 }, { TWId, 0x14, 8, 35 }, 1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x15, 8, 36 }, { TWId, 0x16, 8, 37 }, { TWId, 0x17, 8, 38 }, 1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x28, 8, 39 }, { TWId, 0x29, 8, 40 }, { TWId, 0x2a, 8, 41 }, 1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x2b, 8, 42 }, { TWId, 0x2c, 8, 43 }, { TWId, 0x2d, 8, 44 }, 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x04, 8, 45 }, { TWId, 0x05, 8, 46 }, { TWId, 0x0a, 8, 47 }, 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x0b, 8, 48 }, { TWId, 0x52, 8, 49 }, { TWId, 0x53, 8, 50 }, 2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x54, 8, 51 }, { TWId, 0x55, 8, 52 }, { TWId, 0x24, 8, 53 }, 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x25, 8, 54 }, { TWId, 0x58, 8, 55 }, { TWId, 0x59, 8, 56 }, 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x5a, 8, 57 }, { TWId, 0x5b, 8, 58 }, { TWId, 0x4a, 8, 59 }, 2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x4b, 8, 60 }, { TWId, 0x32, 8, 61 }, { TWId, 0x33, 8, 62 }, 2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { TWId, 0x34, 8, 63 }, { TWId, 0x00, 0, 0 } 2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A S C I I 8 5 E n c o d e % 2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ASCII85Encode() encodes data in ASCII base-85 format. ASCII base-85 2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% encoding produces five ASCII printing characters from every four bytes of 2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% binary data. 2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the ASCII85Encode method is: 2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 226bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% void Ascii85Encode(Image *image,const size_t code) 2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o code: a binary unsigned char to encode to ASCII 85. 2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o file: write the encoded ASCII character to this file. 2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MaxLineExtent 36 2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic char *Ascii85Tuple(unsigned char *data) 2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy static char 2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[6]; 2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 243bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i, 2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 247bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code, 2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum; 2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 251bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy code=((((size_t) data[0] << 8) | (size_t) data[1]) << 16) | 252bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ((size_t) data[2] << 8) | (size_t) data[3]; 2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (code == 0L) 2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[0]='z'; 2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[1]='\0'; 2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(tuple); 2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum=85UL*85UL*85UL*85UL; 2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; i < 4; i++) 2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 262bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy x=(ssize_t) (code/quantum); 2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code-=quantum*x; 2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[i]=(char) (x+(int) '!'); 2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum/=85L; 2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[4]=(char) ((code % 85L)+(int) '!'); 2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple[5]='\0'; 2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(tuple); 2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Initialize(Image *image) 2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate image structure. 2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85 == (Ascii85Info *) NULL) 27873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy image->ascii85=(Ascii85Info *) AcquireMagickMemory(sizeof(*image->ascii85)); 2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85 == (Ascii85Info *) NULL) 2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(image->ascii85,0,sizeof(*image->ascii85)); 2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->line_break=MaxLineExtent << 1; 2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->offset=0; 2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Flush(Image *image) 2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *tuple; 2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->ascii85 != (Ascii85Info *) NULL); 2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85->offset > 0) 2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset]='\0'; 2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset+1]='\0'; 3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset+2]='\0'; 3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy tuple=Ascii85Tuple(image->ascii85->buffer); 3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlob(image,(size_t) image->ascii85->offset+1, 3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (const unsigned char *) (*tuple == 'z' ? "!!!!" : tuple)); 3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'~'); 3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'>'); 3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'\n'); 3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Encode(Image *image,const unsigned char code) 3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q; 3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register unsigned char 3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3189d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 3199d314ff2c17a77996c05413c2013880387e50f0ecristy n; 3209d314ff2c17a77996c05413c2013880387e50f0ecristy 3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->ascii85 != (Ascii85Info *) NULL); 3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[image->ascii85->offset]=code; 3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->offset++; 3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->ascii85->offset < 4) 3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=image->ascii85->buffer; 3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (n=image->ascii85->offset; n >= 4; n-=4) 3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (q=Ascii85Tuple(p); *q != '\0'; q++) 3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->line_break--; 3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((image->ascii85->line_break < 0) && (*q != '%')) 3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,'\n'); 3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->line_break=2*MaxLineExtent; 3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) *q); 3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p+=8; 3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->offset=n; 3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p-=4; 3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (n=0; n < 4; n++) 3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->ascii85->buffer[n]=(*p++); 3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% H u f f m a n D e c o d e I m a g e % 3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% HuffmanDecodeImage() uncompresses an image via Huffman-coding. 3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the HuffmanDecodeImage method is: 3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType HuffmanDecodeImage(Image *image) 3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline size_t MagickMax(const size_t x,const size_t y) 3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (x > y) 3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(x); 3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(y); 3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline size_t MagickMin(const size_t x,const size_t y) 3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (x < y) 3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(x); 3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(y); 3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType HuffmanDecodeImage(Image *image) 3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HashSize 1021 3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBHashA 293 3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBHashB 2695 3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWHashA 3510 3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWHashB 1178 3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define InitializeHashTable(hash,table,a,b) \ 3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=table; \ 3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (entry->code != 0) \ 3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy hash[((entry->length+a)*(entry->code+b)) % HashSize]=(HuffmanTable *) entry; \ 4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry++; \ 4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define InputBit(bit) \ 4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((mask & 0xff) == 0) \ 4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte=ReadBlobByte(image); \ 4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (byte == EOF) \ 4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; \ 4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask=0x80; \ 4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength++; \ 414bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy bit=(size_t) ((byte & mask) != 0 ? 0x01 : 0x00); \ 4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask>>=1; \ 4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bit != 0) \ 4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength=0; \ 4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 420c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy CacheView 421c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy *image_view; 422c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy 4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const HuffmanTable 4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *entry; 4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExceptionInfo 4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *exception; 4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanTable 4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **mb_hash, 4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **mw_hash; 4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte; 4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed; 4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4394c08aed51c5899665ade97263692328eea4af106cristy Quantum 4404c08aed51c5899665ade97263692328eea4af106cristy index; 4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 442bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register unsigned char 4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4489d314ff2c17a77996c05413c2013880387e50f0ecristy size_t 4499d314ff2c17a77996c05413c2013880387e50f0ecristy bit, 4509d314ff2c17a77996c05413c2013880387e50f0ecristy code, 4519d314ff2c17a77996c05413c2013880387e50f0ecristy mask, 4529d314ff2c17a77996c05413c2013880387e50f0ecristy length, 4539d314ff2c17a77996c05413c2013880387e50f0ecristy null_lines, 4549d314ff2c17a77996c05413c2013880387e50f0ecristy runlength; 4559d314ff2c17a77996c05413c2013880387e50f0ecristy 4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ssize_t 457c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy count, 458c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy y; 4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *scanline; 4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int 4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bail, 4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy color; 4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate buffers. 4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mb_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mb_hash)); 4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mw_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mw_hash)); 4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) AcquireQuantumMemory((size_t) image->columns, 4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sizeof(*scanline)); 4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((mb_hash == (HuffmanTable **) NULL) || 4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (mw_hash == (HuffmanTable **) NULL) || 4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (scanline == (unsigned char *) NULL)) 4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize Huffman tables. 4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; i < HashSize; i++) 4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mb_hash[i]=(HuffmanTable *) NULL; 4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mw_hash[i]=(HuffmanTable *) NULL; 4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mw_hash,TWTable,MWHashA,MWHashB); 4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mw_hash,MWTable,MWHashA,MWHashB); 4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mw_hash,EXTable,MWHashA,MWHashB); 4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mb_hash,TBTable,MBHashA,MBHashB); 4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mb_hash,MBTable,MBHashA,MBHashB); 4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InitializeHashTable(mb_hash,EXTable,MBHashA,MBHashB); 4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Uncompress 1D Huffman to runlength encoded pixels. 4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte=0; 5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask=0; 5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy null_lines=0; 5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength=0; 5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (runlength < 11) 5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { InputBit(bit); } while ((int) bit == 0); 5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->x_resolution=204.0; 5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->y_resolution=196.0; 5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->units=PixelsPerInchResolution; 5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy exception=(&image->exception); 511c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy image_view=AcquireCacheView(image); 512bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; ((y < (ssize_t) image->rows) && (null_lines < 3)); ) 5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5144c08aed51c5899665ade97263692328eea4af106cristy register Quantum 515c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy *restrict q; 5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 517c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy register ssize_t 518c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy x; 519c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy 5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize scanline to white. 5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=scanline; 524bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p++=(unsigned char) 0; 5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Decode Huffman encoded scanline. 5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy color=MagickTrue; 5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code=0; 5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=0; 5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=0; 5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength=0; 5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x=0; 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; ; ) 5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (byte == EOF) 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 539bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (x >= (ssize_t) image->columns) 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (runlength < 11) 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { InputBit(bit); } while ((int) bit == 0); 5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bail=MagickFalse; 5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do 5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength < 11) 5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit) 5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((int) bit != 0) 5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy null_lines++; 5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (x != 0) 5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy null_lines=0; 5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bail=MagickTrue; 5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 563bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy code=(code << 1)+(size_t) bit; 5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length++; 5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } while (code == 0); 5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bail != MagickFalse) 5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length > 13) 5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (runlength < 11) 5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy InputBit(bit); 5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy do { InputBit(bit); } while ((int) bit == 0); 5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (color != MagickFalse) 5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length < 4) 5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=mw_hash[((length+MWHashA)*(code+MWHashB)) % HashSize]; 5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length < 2) 5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=mb_hash[((length+MBHashA)*(code+MBHashB)) % HashSize]; 5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (entry == (const HuffmanTable *) NULL) 5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((entry->length != length) || (entry->code != code)) 5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (entry->id) 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case TWId: 5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case TBId: 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 596eaedf06777741da32408da72c1e512975c600c48cristy count+=(ssize_t) entry->count; 597bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((x+count) > (ssize_t) image->columns) 5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=(ssize_t) image->columns-x; 5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count > 0) 6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (color != MagickFalse) 6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x+=count; 6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=0; 6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; count > 0; count--) 6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline[x++]=(unsigned char) 1; 6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy color=(unsigned int) 6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ((color == MagickFalse) ? MagickTrue : MagickFalse); 6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case MWId: 6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case MBId: 6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case EXId: 6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 618eaedf06777741da32408da72c1e512975c600c48cristy count+=(ssize_t) entry->count; 6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code=0; 6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=0; 6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Transfer scanline to image pixels. 6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=scanline; 631c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 6324c08aed51c5899665ade97263692328eea4af106cristy if (q == (const Quantum *) NULL) 6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 634bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6364c08aed51c5899665ade97263692328eea4af106cristy index=(Quantum) (*p++); 6374c08aed51c5899665ade97263692328eea4af106cristy SetPixelIndex(image,index,q); 6384c08aed51c5899665ade97263692328eea4af106cristy SetPixelPacket(image,image->colormap+(ssize_t) index,q); 6394c08aed51c5899665ade97263692328eea4af106cristy q+=GetPixelChannels(image); 6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 641c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed=SetImageProgress(image,LoadImageTag,y,image->rows); 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (proceed == MagickFalse) 6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy y++; 6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 648c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy image_view=DestroyCacheView(image_view); 649bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy image->rows=(size_t) MagickMax((size_t) y-3,1); 6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->compression=FaxCompression; 6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Free decoder memory. 6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mw_hash=(HuffmanTable **) RelinquishMagickMemory(mw_hash); 6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mb_hash=(HuffmanTable **) RelinquishMagickMemory(mb_hash); 6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) RelinquishMagickMemory(scanline); 6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% H u f f m a n E n c o d e I m a g e % 6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% HuffmanEncodeImage() compresses an image via Huffman-coding. 6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the HuffmanEncodeImage method is: 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info, 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Image *image,Image *inject_image) 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image_info: the image info.. 6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o inject_image: inject into the image stream. 6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info, 6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image *image,Image *inject_image) 6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HuffmanOutputCode(entry) \ 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 692eaedf06777741da32408da72c1e512975c600c48cristy mask=one << (entry->length-1); \ 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (mask != 0) \ 6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(((entry->code & mask) != 0 ? 1 : 0)); \ 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask>>=1; \ 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputBit(count) \ 7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count > 0) \ 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte=byte | bit; \ 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit>>=1; \ 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((int) (bit & 0xff) == 0) \ 7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") == 0) \ 7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) byte); \ 7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else \ 7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Encode(image,byte); \ 7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte='\0'; \ 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit=(unsigned char) 0x80; \ 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const HuffmanTable 7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *entry; 7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExceptionInfo 7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *exception; 7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy k, 7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength; 7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image 7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *huffman_image; 7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed; 7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 732bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i, 7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7364c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register unsigned char 7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q; 7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 742bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy mask, 744eaedf06777741da32408da72c1e512975c600c48cristy one, 7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width; 7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7479d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 7489d314ff2c17a77996c05413c2013880387e50f0ecristy n, 7499d314ff2c17a77996c05413c2013880387e50f0ecristy y; 7509d314ff2c17a77996c05413c2013880387e50f0ecristy 7519d314ff2c17a77996c05413c2013880387e50f0ecristy unsigned char 7529d314ff2c17a77996c05413c2013880387e50f0ecristy byte, 7539d314ff2c17a77996c05413c2013880387e50f0ecristy bit, 7549d314ff2c17a77996c05413c2013880387e50f0ecristy *scanline; 7559d314ff2c17a77996c05413c2013880387e50f0ecristy 7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate scanline buffer. 7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image_info != (ImageInfo *) NULL); 7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image_info->signature == MagickSignature); 7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(inject_image != (Image *) NULL); 7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(inject_image->signature == MagickSignature); 767eaedf06777741da32408da72c1e512975c600c48cristy one=1; 7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width=inject_image->columns; 7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") == 0) 770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy width=(size_t) MagickMax(inject_image->columns,1728); 7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) AcquireQuantumMemory((size_t) width+1UL, 7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sizeof(*scanline)); 7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (scanline == (unsigned char *) NULL) 7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy inject_image->filename); 7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(scanline,0,width*sizeof(*scanline)); 7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy huffman_image=CloneImage(inject_image,0,0,MagickTrue,&image->exception); 7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (huffman_image == (Image *) NULL) 7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) RelinquishMagickMemory(scanline); 7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) SetImageType(huffman_image,BilevelType); 7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy byte='\0'; 7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bit=(unsigned char) 0x80; 7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") != 0) 7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Initialize(image); 7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy End of line. 7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (k=0; k < 11; k++) 7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(0); 7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(1); 7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Compress to 1D Huffman pixels. 7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy exception=(&huffman_image->exception); 8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=scanline; 802bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) huffman_image->rows; y++) 8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=GetVirtualPixels(huffman_image,0,y,huffman_image->columns,1,exception); 8054c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 807bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) huffman_image->columns; x++) 8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8094c08aed51c5899665ade97263692328eea4af106cristy *q++=(unsigned char) (GetPixelIntensity(huffman_image,p) >= 8104c08aed51c5899665ade97263692328eea4af106cristy ((MagickRealType) QuantumRange/2.0) ? 0 : 1); 8114c08aed51c5899665ade97263692328eea4af106cristy p+=GetPixelChannels(huffman_image); 8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Huffman encode scanline. 8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=scanline; 817bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (n=(ssize_t) width; n > 0; ) 8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Output white run. 8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (runlength=0; ((n > 0) && (*q == 0)); n--) 8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q++; 8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength++; 8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength >= 64) 8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength < 1792) 8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=MWTable+((runlength/64)-1); 8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64; 8338891f9ce489d3e61399b60436ea6c62f5ed9b887cristy runlength-=(long) entry->count; 8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=TWTable+MagickMin((size_t) runlength,63); 8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (n != 0) 8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Output black run. 8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (runlength=0; ((*q != 0) && (n > 0)); n--) 8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q++; 8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy runlength++; 8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength >= 64) 8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=MBTable+((runlength/64)-1); 8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (runlength >= 1792) 8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64; 8538891f9ce489d3e61399b60436ea6c62f5ed9b887cristy runlength-=(long) entry->count; 8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry=TBTable+MagickMin((size_t) runlength,63); 8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy HuffmanOutputCode(entry); 8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy End of line. 8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (k=0; k < 11; k++) 8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(0); 8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(1); 8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=scanline; 8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (GetPreviousImageInList(huffman_image) == (Image *) NULL) 8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed=SetImageProgress(huffman_image,LoadImageTag,y, 8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy huffman_image->rows); 8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (proceed == MagickFalse) 8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy End of page. 8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; i < 6; i++) 8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (k=0; k < 11; k++) 8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(0); 8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputBit(1); 8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Flush bits. 8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (((int) bit != 0x80) != 0) 8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") == 0) 8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,byte); 8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Encode(image,byte); 8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(image_info->magick,"FAX") != 0) 8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Ascii85Flush(image); 8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy huffman_image=DestroyImage(huffman_image); 8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scanline=(unsigned char *) RelinquishMagickMemory(scanline); 8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% L Z W E n c o d e I m a g e % 9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% LZWEncodeImage() compresses an image via LZW-coding specific to Postscript 9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Level II or Portable Document Format. 9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the LZWEncodeImage method is: 9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType LZWEncodeImage(Image *image,const size_t length, 9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% unsigned char *pixels) 9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: A value that specifies the number of pixels to compress. 9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o pixels: the address of an unsigned array of characters containing the 9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pixels to compress. 9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType LZWEncodeImage(Image *image,const size_t length, 9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char *pixels) 9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWClr 256UL /* Clear Table Marker */ 9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWEod 257UL /* End of Data marker */ 9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputCode(code) \ 9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \ 9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator+=code << (32-code_width-number_bits); \ 9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits+=code_width; \ 9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (number_bits >= 8) \ 9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { \ 9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); \ 9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator=accumulator << 8; \ 9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits-=8; \ 9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } \ 9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy typedef struct _TableType 9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 949bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy prefix, 9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy suffix, 9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next; 9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } TableType; 9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 955bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 958bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator, 9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits, 9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width, 9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_code, 9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index; 9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9659d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 9669d314ff2c17a77996c05413c2013880387e50f0ecristy index; 9679d314ff2c17a77996c05413c2013880387e50f0ecristy 9689d314ff2c17a77996c05413c2013880387e50f0ecristy TableType 9699d314ff2c17a77996c05413c2013880387e50f0ecristy *table; 9709d314ff2c17a77996c05413c2013880387e50f0ecristy 9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate string table. 9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(pixels != (unsigned char *) NULL); 9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table=(TableType *) AcquireQuantumMemory(1UL << 12,sizeof(*table)); 9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (table == (TableType *) NULL) 9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize variables. 9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy accumulator=0; 9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width=9; 9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_bits=0; 9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_code=0; 9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(LZWClr); 9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (index=0; index < 256; index++) 9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].prefix=(-1); 9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].suffix=(short) index; 9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].next=(-1); 9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index=LZWEod+1; 9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width=9; 998bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy last_code=(size_t) pixels[0]; 999bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=1; i < (ssize_t) length; i++) 10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Find string. 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1004bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy index=(ssize_t) last_code; 10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (index != -1) 1006bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((table[index].prefix != (ssize_t) last_code) || 1007bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy (table[index].suffix != (ssize_t) pixels[i])) 10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy index=table[index].next; 10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1011bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy last_code=(size_t) index; 10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1014bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (last_code != (size_t) index) 10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Add string. 10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(last_code); 1020bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy table[next_index].prefix=(ssize_t) last_code; 10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[next_index].suffix=(short) pixels[i]; 10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[next_index].next=table[last_code].next; 1023bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy table[last_code].next=(ssize_t) next_index; 10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index++; 10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Did we just move up to next bit width? 10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((next_index >> code_width) != 0) 10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width++; 10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (code_width > 12) 10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Did we overflow the max bit width? 10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width--; 10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(LZWClr); 10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (index=0; index < 256; index++) 10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].prefix=(-1); 10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].suffix=index; 10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table[index].next=(-1); 10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy next_index=LZWEod+1; 10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy code_width=9; 10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1048bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy last_code=(size_t) pixels[i]; 10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Flush tables. 10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(last_code); 10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutputCode(LZWEod); 10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (number_bits != 0) 10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); 10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy table=(TableType *) RelinquishMagickMemory(table); 10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% P a c k b i t s E n c o d e I m a g e % 10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% PackbitsEncodeImage() compresses an image via Macintosh Packbits encoding 10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% specific to Postscript Level II or Portable Document Format. To ensure 10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% portability, the binary Packbits bytes are encoded as ASCII Base-85. 10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the PackbitsEncodeImage method is: 10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType PackbitsEncodeImage(Image *image,const size_t length, 10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% unsigned char *pixels) 10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: A value that specifies the number of pixels to compress. 10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o pixels: the address of an unsigned array of characters containing the 10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pixels to compress. 10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType PackbitsEncodeImage(Image *image, 10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const size_t length,unsigned char *pixels) 10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count; 10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1098bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i, 11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy j; 11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *packbits; 11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Compress pixels with Packbits encoding. 11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(pixels != (unsigned char *) NULL); 11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packbits=(unsigned char *) AcquireQuantumMemory(128UL,sizeof(*packbits)); 11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (packbits == (unsigned char *) NULL) 11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 1117bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=(ssize_t) length; i != 0; ) 11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (i) 11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 1: 11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i--; 11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 0); 11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 2: 11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=2; 11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 1); 11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,pixels[1]); 11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 3: 11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=3; 11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) ((256-3)+1)); 11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 2); 11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,pixels[1]); 11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,pixels[2]); 11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Packed run. 11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=3; 1159bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy while (((ssize_t) count < i) && (*pixels == *(pixels+count))) 11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count++; 11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count >= 127) 11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=count; 11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) ((256-count)+1)); 11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,*pixels); 11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixels+=count; 11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Literal run. 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=0; 11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while ((*(pixels+count) != *(pixels+count+1)) || 11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (*(pixels+count+1) != *(pixels+count+2))) 11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packbits[count+1]=pixels[count]; 11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count++; 1180bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (((ssize_t) count >= (i-3)) || (count >= 127)) 11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i-=count; 11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *packbits=(unsigned char) (count-1); 1185bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (j=0; j <= (ssize_t) count; j++) 11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,packbits[j]); 11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixels+=count; 11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,(unsigned char) 128); /* EOD marker */ 11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packbits=(unsigned char *) RelinquishMagickMemory(packbits); 11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_ZLIB_DELEGATE) 11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Z L I B E n c o d e I m a g e % 12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ZLIBEncodeImage compresses an image via ZLIB-coding specific to 12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Postscript Level II or Portable Document Format. 12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the ZLIBEncodeImage method is: 12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length, 12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% unsigned char *pixels) 12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o file: the address of a structure of type FILE. ZLIB encoded pixels 12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% are written to this file. 12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: A value that specifies the number of pixels to compress. 12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o pixels: the address of an unsigned array of characters containing the 12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pixels to compress. 12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic voidpf AcquireZIPMemory(voidpf context,unsigned int items, 12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned int size) 12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) context; 12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((voidpf) AcquireQuantumMemory(items,size)); 12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void RelinquishZIPMemory(voidpf context,voidpf memory) 12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) context; 12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy memory=RelinquishMagickMemory(memory); 12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length, 12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char *pixels) 12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1248bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_packets; 12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *compress_pixels; 12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy z_stream 12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream; 12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_packets=(size_t) (1.001*length+12); 12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_packets, 12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sizeof(*compress_pixels)); 12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (compress_pixels == (unsigned char *) NULL) 12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.next_in=pixels; 12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.avail_in=(unsigned int) length; 12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.next_out=compress_pixels; 12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.avail_out=(unsigned int) compress_packets; 12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.zalloc=AcquireZIPMemory; 12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.zfree=RelinquishZIPMemory; 12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy stream.opaque=(voidpf) NULL; 12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=deflateInit(&stream,(int) (image->quality == 12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9))); 12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == Z_OK) 12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=deflate(&stream,Z_FINISH); 12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == Z_STREAM_END) 12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=deflateEnd(&stream); 12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) deflateEnd(&stream); 12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_packets=(size_t) stream.total_out; 12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status != Z_OK) 12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(CoderError,"UnableToZipCompressImage",image->filename) 12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) compress_packets; i++) 12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,compress_pixels[i]); 12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels); 12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status == Z_OK ? MagickTrue : MagickFalse); 12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image, 12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const size_t magick_unused(length),unsigned char *magick_unused(pixels)) 12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image->signature == MagickSignature); 13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ThrowMagickException(&image->exception,GetMagickModule(), 13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (ZIP)", 13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 1310