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%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 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);
284e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
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);
314e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
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);
449e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
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
49205d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
494c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    register ssize_t
495c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy      x;
496c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Initialize scanline to white.
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
5002338d15770f9b565abd557063724d92264fbf450dirk    ResetMagickMemory(scanline,0,sizeof(*scanline)*image->columns);
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Decode Huffman encoded scanline.
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color=MagickTrue;
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    code=0;
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=0;
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=0;
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    runlength=0;
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x=0;
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for ( ; ; )
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (byte == EOF)
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if (x >= (ssize_t) image->columns)
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while (runlength < 11)
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            InputBit(bit);
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          do { InputBit(bit); } while ((int) bit == 0);
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bail=MagickFalse;
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      do
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (runlength < 11)
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          InputBit(bit)
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            InputBit(bit);
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) bit != 0)
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                null_lines++;
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (x != 0)
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  null_lines=0;
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                bail=MagickTrue;
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
538bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        code=(code << 1)+(size_t) bit;
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length++;
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      } while (code == 0);
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bail != MagickFalse)
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length > 13)
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while (runlength < 11)
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           InputBit(bit);
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          do { InputBit(bit); } while ((int) bit == 0);
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (color != MagickFalse)
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (length < 4)
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          entry=mw_hash[((length+MWHashA)*(code+MWHashB)) % HashSize];
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (length < 2)
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          entry=mb_hash[((length+MBHashA)*(code+MBHashB)) % HashSize];
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (entry == (const HuffmanTable *) NULL)
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((entry->length != length) || (entry->code != code))
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      switch (entry->id)
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case TWId:
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case TBId:
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
571eaedf06777741da32408da72c1e512975c600c48cristy          count+=(ssize_t) entry->count;
572bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          if ((x+count) > (ssize_t) image->columns)
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            count=(ssize_t) image->columns-x;
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (count > 0)
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (color != MagickFalse)
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x+=count;
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  count=0;
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for ( ; count > 0; count--)
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  scanline[x++]=(unsigned char) 1;
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          color=(unsigned int)
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((color == MagickFalse) ? MagickTrue : MagickFalse);
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case MWId:
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case MBId:
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        case EXId:
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
593eaedf06777741da32408da72c1e512975c600c48cristy          count+=(ssize_t) entry->count;
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        default:
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      code=0;
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      length=0;
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Transfer scanline to image pixels.
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=scanline;
606c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
607acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy    if (q == (Quantum *) NULL)
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
609bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6114c08aed51c5899665ade97263692328eea4af106cristy      index=(Quantum) (*p++);
6124c08aed51c5899665ade97263692328eea4af106cristy      SetPixelIndex(image,index,q);
61311a06d3f2cac0f17af7963e83bc6e9ebd2a377c0cristy      SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
614ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(image);
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
616c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (proceed == MagickFalse)
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y++;
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
623c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy  image_view=DestroyCacheView(image_view);
624bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->rows=(size_t) MagickMax((size_t) y-3,1);
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=FaxCompression;
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free decoder memory.
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mw_hash=(HuffmanTable **) RelinquishMagickMemory(mw_hash);
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mb_hash=(HuffmanTable **) RelinquishMagickMemory(mb_hash);
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   H u f f m a n E n c o d e I m a g e                                       %
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  HuffmanEncodeImage() compresses an image via Huffman-coding.
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the HuffmanEncodeImage method is:
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info,
651018f07f7333b25743d0afff892450cebdb905c1acristy%        Image *image,Image *inject_image,ExceptionInfo *exception)
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info..
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o inject_image: inject into the image stream.
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
661018f07f7333b25743d0afff892450cebdb905c1acristy%    o exception: return any errors or warnings in this structure.
662018f07f7333b25743d0afff892450cebdb905c1acristy%
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType HuffmanEncodeImage(const ImageInfo *image_info,
665018f07f7333b25743d0afff892450cebdb905c1acristy  Image *image,Image *inject_image,ExceptionInfo *exception)
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define HuffmanOutputCode(entry)  \
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{  \
669eaedf06777741da32408da72c1e512975c600c48cristy  mask=one << (entry->length-1);  \
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mask != 0)  \
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {  \
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    OutputBit(((entry->code & mask) != 0 ? 1 : 0));  \
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mask>>=1;  \
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }  \
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputBit(count)  \
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{  \
67993b02b797c4127ce2b06dbd3b2d75ecc33fca759dirkDisableMSCWarning(4127) \
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (count > 0)  \
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte=byte | bit;  \
68293b02b797c4127ce2b06dbd3b2d75ecc33fca759dirkRestoreMSCWarning \
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bit>>=1;  \
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((int) (bit & 0xff) == 0)   \
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {  \
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(image_info->magick,"FAX") == 0) \
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) byte);  \
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else \
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Ascii85Encode(image,byte); \
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      byte='\0';  \
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bit=(unsigned char) 0x80;  \
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }  \
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const HuffmanTable
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    k,
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    runlength;
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *huffman_image;
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    proceed;
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7124c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mask,
720eaedf06777741da32408da72c1e512975c600c48cristy    one,
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7239d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
7249d314ff2c17a77996c05413c2013880387e50f0ecristy    n,
7259d314ff2c17a77996c05413c2013880387e50f0ecristy    y;
7269d314ff2c17a77996c05413c2013880387e50f0ecristy
7279d314ff2c17a77996c05413c2013880387e50f0ecristy  unsigned char
7289d314ff2c17a77996c05413c2013880387e50f0ecristy    byte,
7299d314ff2c17a77996c05413c2013880387e50f0ecristy    bit,
7309d314ff2c17a77996c05413c2013880387e50f0ecristy    *scanline;
7319d314ff2c17a77996c05413c2013880387e50f0ecristy
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate scanline buffer.
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (ImageInfo *) NULL);
736e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
738e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(inject_image != (Image *) NULL);
742e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(inject_image->signature == MagickCoreSignature);
743eaedf06777741da32408da72c1e512975c600c48cristy  one=1;
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  width=inject_image->columns;
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"FAX") == 0)
746bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    width=(size_t) MagickMax(inject_image->columns,1728);
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) AcquireQuantumMemory((size_t) width+1UL,
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*scanline));
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (scanline == (unsigned char *) NULL)
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      inject_image->filename);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(scanline,0,width*sizeof(*scanline));
753c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy  huffman_image=CloneImage(inject_image,0,0,MagickTrue,exception);
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (huffman_image == (Image *) NULL)
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scanline=(unsigned char *) RelinquishMagickMemory(scanline);
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
759018f07f7333b25743d0afff892450cebdb905c1acristy  (void) SetImageType(huffman_image,BilevelType,exception);
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  byte='\0';
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bit=(unsigned char) 0x80;
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"FAX") != 0)
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Ascii85Initialize(image);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        End of line.
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (k=0; k < 11; k++)
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        OutputBit(0);
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      OutputBit(1);
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress to 1D Huffman pixels.
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=scanline;
777bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) huffman_image->rows; y++)
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(huffman_image,0,y,huffman_image->columns,1,exception);
7804c08aed51c5899665ade97263692328eea4af106cristy    if (p == (const Quantum *) NULL)
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
782bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) huffman_image->columns; x++)
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7844c08aed51c5899665ade97263692328eea4af106cristy      *q++=(unsigned char) (GetPixelIntensity(huffman_image,p) >=
785a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy        ((double) QuantumRange/2.0) ? 0 : 1);
786ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(huffman_image);
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Huffman encode scanline.
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=scanline;
792bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (n=(ssize_t) width; n > 0; )
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Output white run.
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (runlength=0; ((n > 0) && (*q == 0)); n--)
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q++;
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        runlength++;
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (runlength >= 64)
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (runlength < 1792)
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            entry=MWTable+((runlength/64)-1);
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64;
8088891f9ce489d3e61399b60436ea6c62f5ed9b887cristy          runlength-=(long) entry->count;
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          HuffmanOutputCode(entry);
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      entry=TWTable+MagickMin((size_t) runlength,63);
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      HuffmanOutputCode(entry);
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (n != 0)
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Output black run.
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (runlength=0; ((*q != 0) && (n > 0)); n--)
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            runlength++;
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (runlength >= 64)
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              entry=MBTable+((runlength/64)-1);
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (runlength >= 1792)
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                entry=EXTable+(MagickMin((size_t) runlength,2560)-1792)/64;
8288891f9ce489d3e61399b60436ea6c62f5ed9b887cristy              runlength-=(long) entry->count;
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              HuffmanOutputCode(entry);
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          entry=TBTable+MagickMin((size_t) runlength,63);
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          HuffmanOutputCode(entry);
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      End of line.
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (k=0; k < 11; k++)
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      OutputBit(0);
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    OutputBit(1);
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=scanline;
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetPreviousImageInList(huffman_image) == (Image *) NULL)
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(huffman_image,LoadImageTag,y,
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          huffman_image->rows);
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    End of page.
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < 6; i++)
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (k=0; k < 11; k++)
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      OutputBit(0);
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    OutputBit(1);
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flush bits.
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (((int) bit != 0x80) != 0)
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(image_info->magick,"FAX") == 0)
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,byte);
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Ascii85Encode(image,byte);
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"FAX") != 0)
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Ascii85Flush(image);
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  huffman_image=DestroyImage(huffman_image);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   L Z W E n c o d e I m a g e                                               %
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  LZWEncodeImage() compresses an image via LZW-coding specific to Postscript
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Level II or Portable Document Format.
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the LZWEncodeImage method is:
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType LZWEncodeImage(Image *image,const size_t length,
89305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk%        unsigned char *magick_restrict pixels,ExceptionInfo *exception)
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  A value that specifies the number of pixels to compress.
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels: the address of an unsigned array of characters containing the
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixels to compress.
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
904018f07f7333b25743d0afff892450cebdb905c1acristy%    o exception: return any errors or warnings in this structure.
905018f07f7333b25743d0afff892450cebdb905c1acristy%
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType LZWEncodeImage(Image *image,const size_t length,
90805d2ff7ebf21f659f5b11e45afb294e152f4330cdirk  unsigned char *magick_restrict pixels,ExceptionInfo *exception)
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWClr  256UL  /* Clear Table Marker */
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LZWEod  257UL  /* End of Data marker */
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define OutputCode(code) \
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ \
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    accumulator+=code << (32-code_width-number_bits); \
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_bits+=code_width; \
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (number_bits >= 8) \
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    { \
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24)); \
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        accumulator=accumulator << 8; \
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_bits-=8; \
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } \
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  typedef struct _TableType
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
926bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      prefix,
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      suffix,
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next;
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } TableType;
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    accumulator,
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_bits,
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    code_width,
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    last_code,
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    next_index;
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9429d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
9439d314ff2c17a77996c05413c2013880387e50f0ecristy    index;
9449d314ff2c17a77996c05413c2013880387e50f0ecristy
9459d314ff2c17a77996c05413c2013880387e50f0ecristy  TableType
9469d314ff2c17a77996c05413c2013880387e50f0ecristy    *table;
9479d314ff2c17a77996c05413c2013880387e50f0ecristy
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate string table.
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
952e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pixels != (unsigned char *) NULL);
956b0de93fdedaac769cb08e15b3ec176d4c9078907cristy  assert(exception != (ExceptionInfo *) NULL);
957e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  table=(TableType *) AcquireQuantumMemory(1UL << 12,sizeof(*table));
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (table == (TableType *) NULL)
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize variables.
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  accumulator=0;
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  code_width=9;
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  number_bits=0;
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  last_code=0;
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  OutputCode(LZWClr);
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (index=0; index < 256; index++)
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    table[index].prefix=(-1);
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    table[index].suffix=(short) index;
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    table[index].next=(-1);
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  next_index=LZWEod+1;
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  code_width=9;
977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  last_code=(size_t) pixels[0];
978bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=1; i < (ssize_t) length; i++)
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Find string.
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
983bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    index=(ssize_t) last_code;
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (index != -1)
985bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((table[index].prefix != (ssize_t) last_code) ||
986bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (table[index].suffix != (ssize_t) pixels[i]))
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        index=table[index].next;
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
990bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          last_code=(size_t) index;
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
993bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    if (last_code != (size_t) index)
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Add string.
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        OutputCode(last_code);
999bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        table[next_index].prefix=(ssize_t) last_code;
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        table[next_index].suffix=(short) pixels[i];
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        table[next_index].next=table[last_code].next;
1002bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        table[last_code].next=(ssize_t) next_index;
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_index++;
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Did we just move up to next bit width?
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((next_index >> code_width) != 0)
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            code_width++;
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (code_width > 12)
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Did we overflow the max bit width?
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                code_width--;
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                OutputCode(LZWClr);
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (index=0; index < 256; index++)
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  table[index].prefix=(-1);
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  table[index].suffix=index;
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  table[index].next=(-1);
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_index=LZWEod+1;
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                code_width=9;
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
1027bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          last_code=(size_t) pixels[i];
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flush tables.
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  OutputCode(last_code);
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  OutputCode(LZWEod);
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (number_bits != 0)
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,(unsigned char) (accumulator >> 24));
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  table=(TableType *) RelinquishMagickMemory(table);
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   P a c k b i t s E n c o d e I m a g e                                     %
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PackbitsEncodeImage() compresses an image via Macintosh Packbits encoding
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  specific to Postscript Level II or Portable Document Format.  To ensure
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  portability, the binary Packbits bytes are encoded as ASCII Base-85.
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the PackbitsEncodeImage method is:
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType PackbitsEncodeImage(Image *image,const size_t length,
105905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk%        unsigned char *magick_restrict pixels)
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  A value that specifies the number of pixels to compress.
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels: the address of an unsigned array of characters containing the
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixels to compress.
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType PackbitsEncodeImage(Image *image,
107205d2ff7ebf21f659f5b11e45afb294e152f4330cdirk  const size_t length,unsigned char *magick_restrict pixels,
107305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk  ExceptionInfo *exception)
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1078bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j;
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *packbits;
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress pixels with Packbits encoding.
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
1089e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pixels != (unsigned char *) NULL);
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packbits=(unsigned char *) AcquireQuantumMemory(128UL,sizeof(*packbits));
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (packbits == (unsigned char *) NULL)
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
1097bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=(ssize_t) length; i != 0; )
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    switch (i)
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 1:
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i--;
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) 0);
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,*pixels);
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 2:
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i-=2;
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) 1);
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,*pixels);
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,pixels[1]);
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case 3:
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i-=3;
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,(unsigned char) ((256-3)+1));
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,*pixels);
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,(unsigned char) 2);
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,*pixels);
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,pixels[1]);
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobByte(image,pixels[2]);
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      default:
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Packed run.
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            count=3;
1139bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            while (((ssize_t) count < i) && (*pixels == *(pixels+count)))
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              count++;
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (count >= 127)
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i-=count;
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,(unsigned char) ((256-count)+1));
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,*pixels);
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            pixels+=count;
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Literal run.
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=0;
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((*(pixels+count) != *(pixels+count+1)) ||
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (*(pixels+count+1) != *(pixels+count+2)))
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          packbits[count+1]=pixels[count];
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          count++;
1160bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          if (((ssize_t) count >= (i-3)) || (count >= 127))
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i-=count;
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *packbits=(unsigned char) (count-1);
1165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (j=0; j <= (ssize_t) count; j++)
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobByte(image,packbits[j]);
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels+=count;
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,(unsigned char) 128);  /* EOD marker */
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packbits=(unsigned char *) RelinquishMagickMemory(packbits);
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_ZLIB_DELEGATE)
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Z L I B E n c o d e I m a g e                                             %
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ZLIBEncodeImage compresses an image via ZLIB-coding specific to
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Postscript Level II or Portable Document Format.
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ZLIBEncodeImage method is:
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length,
119505d2ff7ebf21f659f5b11e45afb294e152f4330cdirk%        unsigned char *magick_restrict pixels,ExceptionInfo *exception)
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o file: the address of a structure of type FILE.  ZLIB encoded pixels
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      are written to this file.
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  A value that specifies the number of pixels to compress.
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels: the address of an unsigned array of characters containing the
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixels to compress.
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1207018f07f7333b25743d0afff892450cebdb905c1acristy%    o exception: return any errors or warnings in this structure.
1208018f07f7333b25743d0afff892450cebdb905c1acristy%
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic voidpf AcquireZIPMemory(voidpf context,unsigned int items,
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int size)
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) context;
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((voidpf) AcquireQuantumMemory(items,size));
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void RelinquishZIPMemory(voidpf context,voidpf memory)
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) context;
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  memory=RelinquishMagickMemory(memory);
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image,const size_t length,
122505d2ff7ebf21f659f5b11e45afb294e152f4330cdirk  unsigned char *magick_restrict pixels,ExceptionInfo *exception)
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1230bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compress_packets;
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *compress_pixels;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  z_stream
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    stream;
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
1243e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  compress_packets=(size_t) (1.001*length+12);
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_packets,
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*compress_pixels));
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (compress_pixels == (unsigned char *) NULL)
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.next_in=pixels;
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.avail_in=(unsigned int) length;
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.next_out=compress_pixels;
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.avail_out=(unsigned int) compress_packets;
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.zalloc=AcquireZIPMemory;
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.zfree=RelinquishZIPMemory;
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  stream.opaque=(voidpf) NULL;
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=deflateInit(&stream,(int) (image->quality ==
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9)));
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == Z_OK)
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=deflate(&stream,Z_FINISH);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (status == Z_STREAM_END)
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=deflateEnd(&stream);
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) deflateEnd(&stream);
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      compress_packets=(size_t) stream.total_out;
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status != Z_OK)
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(CoderError,"UnableToZipCompressImage",image->filename)
12724d0ca34912f861b25e5ed95e3f624048cb180358cristy  for (i=0; i < (ssize_t) compress_packets; i++)
12734d0ca34912f861b25e5ed95e3f624048cb180358cristy    (void) WriteBlobByte(image,compress_pixels[i]);
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels);
12754d0ca34912f861b25e5ed95e3f624048cb180358cristy  return(MagickTrue);
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ZLIBEncodeImage(Image *image,
12795451932d79a42e7a0882b61c361ee18dd2abf012cristy  const size_t magick_unused(length),unsigned char *magick_unused(pixels),
12805451932d79a42e7a0882b61c361ee18dd2abf012cristy  ExceptionInfo *exception)
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
1283e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12865451932d79a42e7a0882b61c361ee18dd2abf012cristy  (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
1287e5b39652d8d21bc3940d83b8d6088d4070a8a34aanthony    "DelegateLibrarySupportNotBuiltIn","'%s' (ZIP)",image->filename);
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1291