compress.c revision 11a06d3f2cac0f17af7963e83bc6e9ebd2a377c0
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                                   %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                Cristy                                       %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              May  1993                                      %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20b56bb24a985ca4366713bcd8ffdfacbb48a98a2fcristy%  Copyright 1999-2015 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"
448941c70abb86cb5841cc745b991002d87eb09339cristy#include "MagickCore/attribute.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h"
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/compress.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_ZLIB_DELEGATE)
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Typedef declarations.
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystruct _Ascii85Info
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
71bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset,
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    line_break;
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[10];
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy};
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct HuffmanTable
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
81bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    id,
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    code,
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} HuffmanTable;
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Huffman coding declarations.
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TWId  23
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWId  24
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TBId  25
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBId  26
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define EXId  27
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MBTable[]=
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x0f, 10, 64 }, { MBId, 0xc8, 12, 128 },
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0xc9, 12, 192 }, { MBId, 0x5b, 12, 256 },
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x33, 12, 320 }, { MBId, 0x34, 12, 384 },
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x35, 12, 448 }, { MBId, 0x6c, 13, 512 },
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x6d, 13, 576 }, { MBId, 0x4a, 13, 640 },
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x4b, 13, 704 }, { MBId, 0x4c, 13, 768 },
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x4d, 13, 832 }, { MBId, 0x72, 13, 896 },
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x73, 13, 960 }, { MBId, 0x74, 13, 1024 },
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x75, 13, 1088 }, { MBId, 0x76, 13, 1152 },
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x77, 13, 1216 }, { MBId, 0x52, 13, 1280 },
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x53, 13, 1344 }, { MBId, 0x54, 13, 1408 },
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x55, 13, 1472 }, { MBId, 0x5a, 13, 1536 },
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x5b, 13, 1600 }, { MBId, 0x64, 13, 1664 },
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MBId, 0x65, 13, 1728 }, { MBId, 0x00, 0, 0 }
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  EXTable[]=
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { EXId, 0x08, 11, 1792 }, { EXId, 0x0c, 11, 1856 },
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { EXId, 0x0d, 11, 1920 }, { EXId, 0x12, 12, 1984 },
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { EXId, 0x13, 12, 2048 }, { EXId, 0x14, 12, 2112 },
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { EXId, 0x15, 12, 2176 }, { EXId, 0x16, 12, 2240 },
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { EXId, 0x17, 12, 2304 }, { EXId, 0x1c, 12, 2368 },
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { EXId, 0x1d, 12, 2432 }, { EXId, 0x1e, 12, 2496 },
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { EXId, 0x1f, 12, 2560 }, { EXId, 0x00, 0, 0 }
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MWTable[]=
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x1b, 5, 64 }, { MWId, 0x12, 5, 128 },
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x17, 6, 192 }, { MWId, 0x37, 7, 256 },
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x36, 8, 320 }, { MWId, 0x37, 8, 384 },
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x64, 8, 448 }, { MWId, 0x65, 8, 512 },
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x68, 8, 576 }, { MWId, 0x67, 8, 640 },
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0xcc, 9, 704 }, { MWId, 0xcd, 9, 768 },
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0xd2, 9, 832 }, { MWId, 0xd3, 9, 896 },
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0xd4, 9, 960 }, { MWId, 0xd5, 9, 1024 },
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0xd6, 9, 1088 }, { MWId, 0xd7, 9, 1152 },
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0xd8, 9, 1216 }, { MWId, 0xd9, 9, 1280 },
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0xda, 9, 1344 }, { MWId, 0xdb, 9, 1408 },
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x98, 9, 1472 }, { MWId, 0x99, 9, 1536 },
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x9a, 9, 1600 }, { MWId, 0x18, 6, 1664 },
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { MWId, 0x9b, 9, 1728 }, { MWId, 0x00, 0, 0 }
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  TBTable[]=
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x37, 10, 0 }, { TBId, 0x02, 3, 1 }, { TBId, 0x03, 2, 2 },
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x02, 2, 3 }, { TBId, 0x03, 3, 4 }, { TBId, 0x03, 4, 5 },
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x02, 4, 6 }, { TBId, 0x03, 5, 7 }, { TBId, 0x05, 6, 8 },
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x04, 6, 9 }, { TBId, 0x04, 7, 10 }, { TBId, 0x05, 7, 11 },
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x07, 7, 12 }, { TBId, 0x04, 8, 13 }, { TBId, 0x07, 8, 14 },
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x18, 9, 15 }, { TBId, 0x17, 10, 16 }, { TBId, 0x18, 10, 17 },
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x08, 10, 18 }, { TBId, 0x67, 11, 19 }, { TBId, 0x68, 11, 20 },
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x6c, 11, 21 }, { TBId, 0x37, 11, 22 }, { TBId, 0x28, 11, 23 },
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x17, 11, 24 }, { TBId, 0x18, 11, 25 }, { TBId, 0xca, 12, 26 },
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0xcb, 12, 27 }, { TBId, 0xcc, 12, 28 }, { TBId, 0xcd, 12, 29 },
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x68, 12, 30 }, { TBId, 0x69, 12, 31 }, { TBId, 0x6a, 12, 32 },
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x6b, 12, 33 }, { TBId, 0xd2, 12, 34 }, { TBId, 0xd3, 12, 35 },
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0xd4, 12, 36 }, { TBId, 0xd5, 12, 37 }, { TBId, 0xd6, 12, 38 },
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0xd7, 12, 39 }, { TBId, 0x6c, 12, 40 }, { TBId, 0x6d, 12, 41 },
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0xda, 12, 42 }, { TBId, 0xdb, 12, 43 }, { TBId, 0x54, 12, 44 },
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x55, 12, 45 }, { TBId, 0x56, 12, 46 }, { TBId, 0x57, 12, 47 },
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x64, 12, 48 }, { TBId, 0x65, 12, 49 }, { TBId, 0x52, 12, 50 },
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x53, 12, 51 }, { TBId, 0x24, 12, 52 }, { TBId, 0x37, 12, 53 },
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x38, 12, 54 }, { TBId, 0x27, 12, 55 }, { TBId, 0x28, 12, 56 },
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x58, 12, 57 }, { TBId, 0x59, 12, 58 }, { TBId, 0x2b, 12, 59 },
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x2c, 12, 60 }, { TBId, 0x5a, 12, 61 }, { TBId, 0x66, 12, 62 },
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TBId, 0x67, 12, 63 }, { TBId, 0x00, 0, 0 }
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const HuffmanTable
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  TWTable[]=
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x35, 8, 0 }, { TWId, 0x07, 6, 1 }, { TWId, 0x07, 4, 2 },
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x08, 4, 3 }, { TWId, 0x0b, 4, 4 }, { TWId, 0x0c, 4, 5 },
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x0e, 4, 6 }, { TWId, 0x0f, 4, 7 }, { TWId, 0x13, 5, 8 },
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x14, 5, 9 }, { TWId, 0x07, 5, 10 }, { TWId, 0x08, 5, 11 },
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x08, 6, 12 }, { TWId, 0x03, 6, 13 }, { TWId, 0x34, 6, 14 },
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x35, 6, 15 }, { TWId, 0x2a, 6, 16 }, { TWId, 0x2b, 6, 17 },
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x27, 7, 18 }, { TWId, 0x0c, 7, 19 }, { TWId, 0x08, 7, 20 },
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x17, 7, 21 }, { TWId, 0x03, 7, 22 }, { TWId, 0x04, 7, 23 },
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x28, 7, 24 }, { TWId, 0x2b, 7, 25 }, { TWId, 0x13, 7, 26 },
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x24, 7, 27 }, { TWId, 0x18, 7, 28 }, { TWId, 0x02, 8, 29 },
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x03, 8, 30 }, { TWId, 0x1a, 8, 31 }, { TWId, 0x1b, 8, 32 },
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x12, 8, 33 }, { TWId, 0x13, 8, 34 }, { TWId, 0x14, 8, 35 },
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x15, 8, 36 }, { TWId, 0x16, 8, 37 }, { TWId, 0x17, 8, 38 },
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x28, 8, 39 }, { TWId, 0x29, 8, 40 }, { TWId, 0x2a, 8, 41 },
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x2b, 8, 42 }, { TWId, 0x2c, 8, 43 }, { TWId, 0x2d, 8, 44 },
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x04, 8, 45 }, { TWId, 0x05, 8, 46 }, { TWId, 0x0a, 8, 47 },
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x0b, 8, 48 }, { TWId, 0x52, 8, 49 }, { TWId, 0x53, 8, 50 },
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x54, 8, 51 }, { TWId, 0x55, 8, 52 }, { TWId, 0x24, 8, 53 },
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x25, 8, 54 }, { TWId, 0x58, 8, 55 }, { TWId, 0x59, 8, 56 },
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x5a, 8, 57 }, { TWId, 0x5b, 8, 58 }, { TWId, 0x4a, 8, 59 },
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x4b, 8, 60 }, { TWId, 0x32, 8, 61 }, { TWId, 0x33, 8, 62 },
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { TWId, 0x34, 8, 63 }, { TWId, 0x00, 0, 0 }
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   A S C I I 8 5 E n c o d e                                                 %
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ASCII85Encode() encodes data in ASCII base-85 format.  ASCII base-85
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  encoding produces five ASCII printing characters from every four bytes of
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  binary data.
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ASCII85Encode method is:
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
218bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      void Ascii85Encode(Image *image,const size_t code)
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o code: a binary unsigned char to encode to ASCII 85.
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o file: write the encoded ASCII character to this file.
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MaxLineExtent  36
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic char *Ascii85Tuple(unsigned char *data)
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static char
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tuple[6];
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
235bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
239bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    code,
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quantum;
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
243bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  code=((((size_t) data[0] << 8) | (size_t) data[1]) << 16) |
244bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ((size_t) data[2] << 8) | (size_t) data[3];
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (code == 0L)
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      tuple[0]='z';
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      tuple[1]='\0';
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(tuple);
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum=85UL*85UL*85UL*85UL;
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < 4; i++)
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
254bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    x=(ssize_t) (code/quantum);
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    code-=quantum*x;
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tuple[i]=(char) (x+(int) '!');
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quantum/=85L;
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  tuple[4]=(char) ((code % 85L)+(int) '!');
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  tuple[5]='\0';
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(tuple);
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Initialize(Image *image)
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate image structure.
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->ascii85 == (Ascii85Info *) NULL)
27073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy    image->ascii85=(Ascii85Info *) AcquireMagickMemory(sizeof(*image->ascii85));
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->ascii85 == (Ascii85Info *) NULL)
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(image->ascii85,0,sizeof(*image->ascii85));
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->ascii85->line_break=MaxLineExtent << 1;
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->ascii85->offset=0;
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Flush(Image *image)
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register char
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *tuple;
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->ascii85 != (Ascii85Info *) NULL);
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->ascii85->offset > 0)
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->ascii85->buffer[image->ascii85->offset]='\0';
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->ascii85->buffer[image->ascii85->offset+1]='\0';
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->ascii85->buffer[image->ascii85->offset+2]='\0';
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      tuple=Ascii85Tuple(image->ascii85->buffer);
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,(size_t) image->ascii85->offset+1,
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (const unsigned char *) (*tuple == 'z' ? "!!!!" : tuple));
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,'~');
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,'>');
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,'\n');
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport void Ascii85Encode(Image *image,const unsigned char code)
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register char
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3109d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
3119d314ff2c17a77996c05413c2013880387e50f0ecristy    n;
3129d314ff2c17a77996c05413c2013880387e50f0ecristy
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->ascii85 != (Ascii85Info *) NULL);
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->ascii85->buffer[image->ascii85->offset]=code;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->ascii85->offset++;
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->ascii85->offset < 4)
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=image->ascii85->buffer;
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (n=image->ascii85->offset; n >= 4; n-=4)
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (q=Ascii85Tuple(p); *q != '\0'; q++)
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->ascii85->line_break--;
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((image->ascii85->line_break < 0) && (*q != '%'))
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobByte(image,'\n');
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->ascii85->line_break=2*MaxLineExtent;
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,(unsigned char) *q);
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p+=8;
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->ascii85->offset=n;
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p-=4;
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (n=0; n < 4; n++)
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->ascii85->buffer[n]=(*p++);
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   H u f f m a n D e c o d e I m a g e                                       %
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  HuffmanDecodeImage() uncompresses an image via Huffman-coding.
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the HuffmanDecodeImage method is:
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
356018f07f7333b25743d0afff892450cebdb905c1acristy%      MagickBooleanType HuffmanDecodeImage(Image *image,
357018f07f7333b25743d0afff892450cebdb905c1acristy%        ExceptionInfo *exception)
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363018f07f7333b25743d0afff892450cebdb905c1acristy%    o exception: return any errors or warnings in this structure.
364018f07f7333b25743d0afff892450cebdb905c1acristy%
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
366018f07f7333b25743d0afff892450cebdb905c1acristyMagickExport MagickBooleanType HuffmanDecodeImage(Image *image,
367018f07f7333b25743d0afff892450cebdb905c1acristy  ExceptionInfo *exception)
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HashSize  1021
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBHashA  293
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MBHashB  2695
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWHashA  3510
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MWHashB  1178
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define InitializeHashTable(hash,table,a,b) \
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=table; \
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (entry->code != 0) \
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {  \
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    hash[((entry->length+a)*(entry->code+b)) % HashSize]=(HuffmanTable *) entry; \
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry++; \
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } \
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define InputBit(bit)  \
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{  \
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mask & 0xff) == 0)  \
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {  \
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      byte=ReadBlobByte(image);  \
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (byte == EOF)  \
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;  \
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mask=0x80;  \
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }  \
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength++;  \
395bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  bit=(size_t) ((byte & mask) != 0 ? 0x01 : 0x00); \
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mask>>=1;  \
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (bit != 0)  \
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    runlength=0;  \
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
401c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy  CacheView
402c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    *image_view;
403c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const HuffmanTable
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  HuffmanTable
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **mb_hash,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **mw_hash;
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte;
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    proceed;
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4174c08aed51c5899665ade97263692328eea4af106cristy  Quantum
4184c08aed51c5899665ade97263692328eea4af106cristy    index;
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
420bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4269d314ff2c17a77996c05413c2013880387e50f0ecristy  size_t
4279d314ff2c17a77996c05413c2013880387e50f0ecristy    bit,
4289d314ff2c17a77996c05413c2013880387e50f0ecristy    code,
4299d314ff2c17a77996c05413c2013880387e50f0ecristy    mask,
4309d314ff2c17a77996c05413c2013880387e50f0ecristy    length,
4319d314ff2c17a77996c05413c2013880387e50f0ecristy    null_lines,
4329d314ff2c17a77996c05413c2013880387e50f0ecristy    runlength;
4339d314ff2c17a77996c05413c2013880387e50f0ecristy
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
435c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    count,
436c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    y;
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *scanline;
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bail,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color;
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate buffers.
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mb_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mb_hash));
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mw_hash=(HuffmanTable **) AcquireQuantumMemory(HashSize,sizeof(*mw_hash));
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) AcquireQuantumMemory((size_t) image->columns,
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*scanline));
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mb_hash == (HuffmanTable **) NULL) ||
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (mw_hash == (HuffmanTable **) NULL) ||
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (scanline == (unsigned char *) NULL))
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize Huffman tables.
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < HashSize; i++)
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mb_hash[i]=(HuffmanTable *) NULL;
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mw_hash[i]=(HuffmanTable *) NULL;
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  InitializeHashTable(mw_hash,TWTable,MWHashA,MWHashB);
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  InitializeHashTable(mw_hash,MWTable,MWHashA,MWHashB);
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  InitializeHashTable(mw_hash,EXTable,MWHashA,MWHashB);
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  InitializeHashTable(mb_hash,TBTable,MBHashA,MBHashB);
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  InitializeHashTable(mb_hash,MBTable,MBHashA,MBHashB);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  InitializeHashTable(mb_hash,EXTable,MBHashA,MBHashB);
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Uncompress 1D Huffman to runlength encoded pixels.
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  byte=0;
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mask=0;
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  null_lines=0;
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength=0;
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (runlength < 11)
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   InputBit(bit);
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do { InputBit(bit); } while ((int) bit == 0);
4852a11befa48257796843468409d77bb8cfb129cdccristy  image->resolution.x=204.0;
4862a11befa48257796843468409d77bb8cfb129cdccristy  image->resolution.y=196.0;
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->units=PixelsPerInchResolution;
48846ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireAuthenticCacheView(image,exception);
489bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; ((y < (ssize_t) image->rows) && (null_lines < 3)); )
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4914c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
492c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
494c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    register ssize_t
495c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy      x;
496c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Initialize scanline to white.
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=scanline;
501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p++=(unsigned char) 0;
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Decode Huffman encoded scanline.
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color=MagickTrue;
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    code=0;
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=0;
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=0;
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    runlength=0;
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x=0;
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for ( ; ; )
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (byte == EOF)
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
516bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if (x >= (ssize_t) image->columns)
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while (runlength < 11)
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            InputBit(bit);
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          do { InputBit(bit); } while ((int) bit == 0);
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bail=MagickFalse;
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      do
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (runlength < 11)
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          InputBit(bit)
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            InputBit(bit);
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) bit != 0)
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                null_lines++;
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (x != 0)
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  null_lines=0;
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                bail=MagickTrue;
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
540bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        code=(code << 1)+(size_t) bit;
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length++;
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      } while (code == 0);
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bail != MagickFalse)
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length > 13)
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while (runlength < 11)
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           InputBit(bit);
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          do { InputBit(bit); } while ((int) bit == 0);
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (color != MagickFalse)
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (length < 4)
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          entry=mw_hash[((length+MWHashA)*(code+MWHashB)) % HashSize];
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (length < 2)
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          entry=mb_hash[((length+MBHashA)*(code+MBHashB)) % HashSize];
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (entry == (const HuffmanTable *) NULL)
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((entry->length != length) || (entry->code != code))
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      switch (entry->id)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case TWId:
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case TBId:
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
573eaedf06777741da32408da72c1e512975c600c48cristy          count+=(ssize_t) entry->count;
574bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          if ((x+count) > (ssize_t) image->columns)
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            count=(ssize_t) image->columns-x;
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (count > 0)
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (color != MagickFalse)
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x+=count;
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  count=0;
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for ( ; count > 0; count--)
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  scanline[x++]=(unsigned char) 1;
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          color=(unsigned int)
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((color == MagickFalse) ? MagickTrue : MagickFalse);
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case MWId:
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case MBId:
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case EXId:
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
595eaedf06777741da32408da72c1e512975c600c48cristy          count+=(ssize_t) entry->count;
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        default:
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      code=0;
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      length=0;
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Transfer scanline to image pixels.
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=scanline;
608c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
609acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy    if (q == (Quantum *) NULL)
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6134c08aed51c5899665ade97263692328eea4af106cristy      index=(Quantum) (*p++);
6144c08aed51c5899665ade97263692328eea4af106cristy      SetPixelIndex(image,index,q);
61511a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy      SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
616ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(image);
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
618c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (proceed == MagickFalse)
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y++;
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
625c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy  image_view=DestroyCacheView(image_view);
626bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->rows=(size_t) MagickMax((size_t) y-3,1);
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=FaxCompression;
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free decoder memory.
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mw_hash=(HuffmanTable **) RelinquishMagickMemory(mw_hash);
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mb_hash=(HuffmanTable **) RelinquishMagickMemory(mb_hash);
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   H u f f m a n E n c o d e I m a g e                                       %
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  HuffmanEncodeImage() compresses an image via Huffman-coding.
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the HuffmanEncodeImage method is:
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info,
653018f07f7333b25743d0afff892450cebdb905c1acristy%        Image *image,Image *inject_image,ExceptionInfo *exception)
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info..
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o inject_image: inject into the image stream.
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
663018f07f7333b25743d0afff892450cebdb905c1acristy%    o exception: return any errors or warnings in this structure.
664018f07f7333b25743d0afff892450cebdb905c1acristy%
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info,
667018f07f7333b25743d0afff892450cebdb905c1acristy  Image *image,Image *inject_image,ExceptionInfo *exception)
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HuffmanOutputCode(entry)  \
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{  \
671eaedf06777741da32408da72c1e512975c600c48cristy  mask=one << (entry->length-1);  \
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mask != 0)  \
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {  \
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    OutputBit(((entry->code & mask) != 0 ? 1 : 0));  \
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mask>>=1;  \
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }  \
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputBit(count)  \
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{  \
68193b02b797c4127ce2b06dbd3b2d75ecc33fca759dirkDisableMSCWarning(4127) \
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (count > 0)  \
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte=byte | bit;  \
68493b02b797c4127ce2b06dbd3b2d75ecc33fca759dirkRestoreMSCWarning \
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bit>>=1;  \
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((int) (bit & 0xff) == 0)   \
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {  \
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(image_info->magick,"FAX") == 0) \
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) byte);  \
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else \
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Ascii85Encode(image,byte); \
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      byte='\0';  \
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bit=(unsigned char) 0x80;  \
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }  \
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const HuffmanTable
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    k,
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    runlength;
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *huffman_image;
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    proceed;
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
710bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7144c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
720bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mask,
722eaedf06777741da32408da72c1e512975c600c48cristy    one,
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7259d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
7269d314ff2c17a77996c05413c2013880387e50f0ecristy    n,
7279d314ff2c17a77996c05413c2013880387e50f0ecristy    y;
7289d314ff2c17a77996c05413c2013880387e50f0ecristy
7299d314ff2c17a77996c05413c2013880387e50f0ecristy  unsigned char
7309d314ff2c17a77996c05413c2013880387e50f0ecristy    byte,
7319d314ff2c17a77996c05413c2013880387e50f0ecristy    bit,
7329d314ff2c17a77996c05413c2013880387e50f0ecristy    *scanline;
7339d314ff2c17a77996c05413c2013880387e50f0ecristy
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate scanline buffer.
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (ImageInfo *) NULL);
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(inject_image != (Image *) NULL);
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(inject_image->signature == MagickSignature);
745eaedf06777741da32408da72c1e512975c600c48cristy  one=1;
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  width=inject_image->columns;
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"FAX") == 0)
748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    width=(size_t) MagickMax(inject_image->columns,1728);
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) AcquireQuantumMemory((size_t) width+1UL,
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*scanline));
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (scanline == (unsigned char *) NULL)
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      inject_image->filename);
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(scanline,0,width*sizeof(*scanline));
755c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy  huffman_image=CloneImage(inject_image,0,0,MagickTrue,exception);
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (huffman_image == (Image *) NULL)
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scanline=(unsigned char *) RelinquishMagickMemory(scanline);
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
761018f07f7333b25743d0afff892450cebdb905c1acristy  (void) SetImageType(huffman_image,BilevelType,exception);
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  byte='\0';
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bit=(unsigned char) 0x80;
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"FAX") != 0)
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Ascii85Initialize(image);
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        End of line.
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (k=0; k < 11; k++)
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        OutputBit(0);
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      OutputBit(1);
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress to 1D Huffman pixels.
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=scanline;
779bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) huffman_image->rows; y++)
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(huffman_image,0,y,huffman_image->columns,1,exception);
7824c08aed51c5899665ade97263692328eea4af106cristy    if (p == (const Quantum *) NULL)
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) huffman_image->columns; x++)
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7864c08aed51c5899665ade97263692328eea4af106cristy      *q++=(unsigned char) (GetPixelIntensity(huffman_image,p) >=
787a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy        ((double) QuantumRange/2.0) ? 0 : 1);
788ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(huffman_image);
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Huffman encode scanline.
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=scanline;
794bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (n=(ssize_t) width; n > 0; )
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Output white run.
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (runlength=0; ((n > 0) && (*q == 0)); n--)
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q++;
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        runlength++;
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (runlength >= 64)
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (runlength < 1792)
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            entry=MWTable+((runlength/64)-1);
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64;
8108891f9ce489d3e61399b60436ea6c62f5ed9b887cristy          runlength-=(long) entry->count;
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          HuffmanOutputCode(entry);
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      entry=TWTable+MagickMin((size_t) runlength,63);
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      HuffmanOutputCode(entry);
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (n != 0)
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Output black run.
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (runlength=0; ((*q != 0) && (n > 0)); n--)
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            runlength++;
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (runlength >= 64)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              entry=MBTable+((runlength/64)-1);
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (runlength >= 1792)
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64;
8308891f9ce489d3e61399b60436ea6c62f5ed9b887cristy              runlength-=(long) entry->count;
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              HuffmanOutputCode(entry);
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          entry=TBTable+MagickMin((size_t) runlength,63);
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          HuffmanOutputCode(entry);
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      End of line.
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (k=0; k < 11; k++)
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      OutputBit(0);
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    OutputBit(1);
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=scanline;
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetPreviousImageInList(huffman_image) == (Image *) NULL)
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(huffman_image,LoadImageTag,y,
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          huffman_image->rows);
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    End of page.
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < 6; i++)
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (k=0; k < 11; k++)
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      OutputBit(0);
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    OutputBit(1);
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flush bits.
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (((int) bit != 0x80) != 0)
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(image_info->magick,"FAX") == 0)
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,byte);
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Ascii85Encode(image,byte);
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"FAX") != 0)
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Ascii85Flush(image);
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  huffman_image=DestroyImage(huffman_image);
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   L Z W E n c o d e I m a g e                                               %
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  LZWEncodeImage() compresses an image via LZW-coding specific to Postscript
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Level II or Portable Document Format.
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the LZWEncodeImage method is:
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType LZWEncodeImage(Image *image,const size_t length,
8951d1254d929614c9b0cd5b3d7f8bbe051eb3e99d6cristy%        unsigned char *restrict pixels,ExceptionInfo *exception)
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  A value that specifies the number of pixels to compress.
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels: the address of an unsigned array of characters containing the
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixels to compress.
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
906018f07f7333b25743d0afff892450cebdb905c1acristy%    o exception: return any errors or warnings in this structure.
907018f07f7333b25743d0afff892450cebdb905c1acristy%
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType LZWEncodeImage(Image *image,const size_t length,
9101d1254d929614c9b0cd5b3d7f8bbe051eb3e99d6cristy  unsigned char *restrict pixels,ExceptionInfo *exception)
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWClr  256UL  /* Clear Table Marker */
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWEod  257UL  /* End of Data marker */
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputCode(code) \
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    accumulator+=code << (32-code_width-number_bits); \
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_bits+=code_width; \
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (number_bits >= 8) \
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { \
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); \
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        accumulator=accumulator << 8; \
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_bits-=8; \
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } \
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  typedef struct _TableType
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
928bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      prefix,
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      suffix,
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next;
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } TableType;
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
934bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
937bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    accumulator,
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_bits,
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    code_width,
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    last_code,
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    next_index;
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9449d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
9459d314ff2c17a77996c05413c2013880387e50f0ecristy    index;
9469d314ff2c17a77996c05413c2013880387e50f0ecristy
9479d314ff2c17a77996c05413c2013880387e50f0ecristy  TableType
9489d314ff2c17a77996c05413c2013880387e50f0ecristy    *table;
9499d314ff2c17a77996c05413c2013880387e50f0ecristy
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate string table.
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pixels != (unsigned char *) NULL);
958b0de93fdedaac769cb08e15b3ec176d4c9078907cristy  assert(exception != (ExceptionInfo *) NULL);
959b0de93fdedaac769cb08e15b3ec176d4c9078907cristy  assert(exception->signature == MagickSignature);
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  table=(TableType *) AcquireQuantumMemory(1UL << 12,sizeof(*table));
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (table == (TableType *) NULL)
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize variables.
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  accumulator=0;
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  code_width=9;
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  number_bits=0;
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  last_code=0;
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  OutputCode(LZWClr);
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (index=0; index < 256; index++)
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    table[index].prefix=(-1);
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    table[index].suffix=(short) index;
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    table[index].next=(-1);
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  next_index=LZWEod+1;
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  code_width=9;
979bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  last_code=(size_t) pixels[0];
980bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=1; i < (ssize_t) length; i++)
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Find string.
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
985bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    index=(ssize_t) last_code;
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (index != -1)
987bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((table[index].prefix != (ssize_t) last_code) ||
988bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (table[index].suffix != (ssize_t) pixels[i]))
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        index=table[index].next;
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
992bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          last_code=(size_t) index;
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
995bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    if (last_code != (size_t) index)
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Add string.
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        OutputCode(last_code);
1001bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        table[next_index].prefix=(ssize_t) last_code;
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        table[next_index].suffix=(short) pixels[i];
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        table[next_index].next=table[last_code].next;
1004bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        table[last_code].next=(ssize_t) next_index;
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_index++;
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Did we just move up to next bit width?
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((next_index >> code_width) != 0)
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            code_width++;
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (code_width > 12)
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Did we overflow the max bit width?
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                code_width--;
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                OutputCode(LZWClr);
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (index=0; index < 256; index++)
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  table[index].prefix=(-1);
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  table[index].suffix=index;
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  table[index].next=(-1);
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_index=LZWEod+1;
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                code_width=9;
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
1029bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          last_code=(size_t) pixels[i];
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flush tables.
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  OutputCode(last_code);
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  OutputCode(LZWEod);
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (number_bits != 0)
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24));
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  table=(TableType *) RelinquishMagickMemory(table);
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   P a c k b i t s E n c o d e I m a g e                                     %
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PackbitsEncodeImage() compresses an image via Macintosh Packbits encoding
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  specific to Postscript Level II or Portable Document Format.  To ensure
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  portability, the binary Packbits bytes are encoded as ASCII Base-85.
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the PackbitsEncodeImage method is:
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType PackbitsEncodeImage(Image *image,const size_t length,
10611d1254d929614c9b0cd5b3d7f8bbe051eb3e99d6cristy%        unsigned char *restrict pixels)
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  A value that specifies the number of pixels to compress.
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels: the address of an unsigned array of characters containing the
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixels to compress.
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType PackbitsEncodeImage(Image *image,
10741d1254d929614c9b0cd5b3d7f8bbe051eb3e99d6cristy  const size_t length,unsigned char *restrict pixels,ExceptionInfo *exception)
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1079bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j;
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *packbits;
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress pixels with Packbits encoding.
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pixels != (unsigned char *) NULL);
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packbits=(unsigned char *) AcquireQuantumMemory(128UL,sizeof(*packbits));
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (packbits == (unsigned char *) NULL)
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
1098bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=(ssize_t) length; i != 0; )
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    switch (i)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 1:
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i--;
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) 0);
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,*pixels);
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 2:
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i-=2;
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) 1);
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,*pixels);
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,pixels[1]);
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 3:
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i-=3;
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,(unsigned char) ((256-3)+1));
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,*pixels);
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) 2);
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,*pixels);
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,pixels[1]);
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,pixels[2]);
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      default:
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Packed run.
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            count=3;
1140bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            while (((ssize_t) count < i) && (*pixels == *(pixels+count)))
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              count++;
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (count >= 127)
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i-=count;
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,(unsigned char) ((256-count)+1));
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,*pixels);
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            pixels+=count;
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Literal run.
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=0;
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((*(pixels+count) != *(pixels+count+1)) ||
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (*(pixels+count+1) != *(pixels+count+2)))
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          packbits[count+1]=pixels[count];
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          count++;
1161bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          if (((ssize_t) count >= (i-3)) || (count >= 127))
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i-=count;
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *packbits=(unsigned char) (count-1);
1166bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (j=0; j <= (ssize_t) count; j++)
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobByte(image,packbits[j]);
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels+=count;
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,(unsigned char) 128);  /* EOD marker */
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packbits=(unsigned char *) RelinquishMagickMemory(packbits);
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_ZLIB_DELEGATE)
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Z L I B E n c o d e I m a g e                                             %
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ZLIBEncodeImage compresses an image via ZLIB-coding specific to
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Postscript Level II or Portable Document Format.
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ZLIBEncodeImage method is:
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length,
11961d1254d929614c9b0cd5b3d7f8bbe051eb3e99d6cristy%        unsigned char *restrict pixels,ExceptionInfo *exception)
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o file: the address of a structure of type FILE.  ZLIB encoded pixels
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      are written to this file.
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  A value that specifies the number of pixels to compress.
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels: the address of an unsigned array of characters containing the
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixels to compress.
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1208018f07f7333b25743d0afff892450cebdb905c1acristy%    o exception: return any errors or warnings in this structure.
1209018f07f7333b25743d0afff892450cebdb905c1acristy%
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic voidpf AcquireZIPMemory(voidpf context,unsigned int items,
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int size)
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) context;
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((voidpf) AcquireQuantumMemory(items,size));
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void RelinquishZIPMemory(voidpf context,voidpf memory)
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) context;
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  memory=RelinquishMagickMemory(memory);
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length,
12261d1254d929614c9b0cd5b3d7f8bbe051eb3e99d6cristy  unsigned char *restrict pixels,ExceptionInfo *exception)
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compress_packets;
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *compress_pixels;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  z_stream
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    stream;
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  compress_packets=(size_t) (1.001*length+12);
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_packets,
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*compress_pixels));
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (compress_pixels == (unsigned char *) NULL)
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.next_in=pixels;
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.avail_in=(unsigned int) length;
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.next_out=compress_pixels;
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.avail_out=(unsigned int) compress_packets;
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.zalloc=AcquireZIPMemory;
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.zfree=RelinquishZIPMemory;
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.opaque=(voidpf) NULL;
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=deflateInit(&stream,(int) (image->quality ==
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9)));
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == Z_OK)
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=deflate(&stream,Z_FINISH);
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (status == Z_STREAM_END)
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=deflateEnd(&stream);
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) deflateEnd(&stream);
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      compress_packets=(size_t) stream.total_out;
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status != Z_OK)
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(CoderError,"UnableToZipCompressImage",image->filename)
12734d0ca34912f861b25e5ed95e3f624048cb180358cristy  for (i=0; i < (ssize_t) compress_packets; i++)
12744d0ca34912f861b25e5ed95e3f624048cb180358cristy    (void) WriteBlobByte(image,compress_pixels[i]);
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels);
12764d0ca34912f861b25e5ed95e3f624048cb180358cristy  return(MagickTrue);
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image,
12805451932d79a42e7a0882b61c361ee18dd2abf012cristy  const size_t magick_unused(length),unsigned char *magick_unused(pixels),
12815451932d79a42e7a0882b61c361ee18dd2abf012cristy  ExceptionInfo *exception)
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12875451932d79a42e7a0882b61c361ee18dd2abf012cristy  (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
1288e5b39652d8d21bc3940d83b8d6088d4070a8a34aanthony    "DelegateLibrarySupportNotBuiltIn","'%s' (ZIP)",image->filename);
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1292