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