13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            FFFFF   AAA   X   X                              %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            F      A   A   X X                               %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            FFF    AAAAA    X                                %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            F      A   A   X X                               %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            F      A   A  X   X                              %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                   Read/Write Group 3 Fax Image Format                       %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
43d9ecd04e9c567113b4b605cf76681cbb37c093cdcristy#include "MagickCore/attribute.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h"
48510d06a3f7063e91993e13d546d5685048248074cristy#include "MagickCore/colorspace-private.h"
4952456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk#include "MagickCore/constitute.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/compress.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
6152456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk#include "MagickCore/resource_.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
701e178e70fb3c956f9fc1e30c3ba863e882666465cristy  WriteFAXImage(const ImageInfo *,Image *,ExceptionInfo *);
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s F A X                                                                 %
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsFAX() returns MagickTrue if the image format type, identified by the
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is FAX.
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsFAX method is:
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsFAX(const unsigned char *magick,const size_t length)
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsFAX(const unsigned char *magick,const size_t length)
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 4)
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleNCompare((char *) magick,"DFAX",4) == 0)
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d F A X I m a g e                                                   %
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadFAXImage() reads a Group 3 FAX image file and returns it.  It
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadFAXImage method is:
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception)
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13352456ef5ab4b8c1e3f0229674f38765cdc074b2ddirkstatic Image* FaxReadG3(Image *image,ExceptionInfo *exception)
13452456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk{
13552456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  MagickBooleanType
13652456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    status;
13752456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk
13852456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  status=HuffmanDecodeImage(image,exception);
13952456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  if (status == MagickFalse)
14052456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    ThrowFileException(exception,CorruptImageError,"UnableToReadImageData",
14152456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk      image->filename);
14252456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  if (EOFBlob(image) != MagickFalse)
14352456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
14452456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk      image->filename);
14552456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  (void) CloseBlob(image);
14652456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  return(GetFirstImageInList(image));
14752456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk}
14852456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk
14952456ef5ab4b8c1e3f0229674f38765cdc074b2ddirkstatic Image* FaxReadG4(Image *image,const ImageInfo *image_info,
15052456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  ExceptionInfo *exception)
15152456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk{
15252456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  char
15352456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    filename[MagickPathExtent];
15452456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk
15552456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  ImageInfo
15652456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    *read_info;
15752456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk
15852456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  filename[0]='\0';
15952456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  if (ImageToFile(image,filename,exception) == MagickFalse)
16052456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    ThrowImageException(FileOpenError,"UnableToCreateTemporaryFile");
16152456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  (void) CloseBlob(image);
16252456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  image=DestroyImage(image);
16352456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  read_info=CloneImageInfo(image_info);
16452456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  SetImageInfoBlob(read_info,(void *) NULL,0);
16552456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  (void) FormatLocaleString(read_info->filename,MagickPathExtent,"group4:%s",
16652456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    filename);
16752456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  read_info->orientation=TopLeftOrientation;
16852456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  image=ReadImage(read_info,exception);
16952456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  if (image != (Image *) NULL)
17052456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    {
17152456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk      (void) CopyMagickString(image->filename,image_info->filename,
17252456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk        MagickPathExtent);
17352456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk      (void) CopyMagickString(image->magick_filename,image_info->filename,
17452456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk        MagickPathExtent);
17552456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk      (void) CopyMagickString(image->magick,"G4",MagickPathExtent);
17652456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    }
17752456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  read_info=DestroyImageInfo(read_info);
17852456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  (void) RelinquishUniqueFileResource(filename);
17952456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  return(GetFirstImageInList(image));
18052456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk}
18152456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception)
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
194e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
199e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
2009950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->storage_class=PseudoClass;
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0)
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->columns=2592;
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->rows == 0)
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->rows=3508;
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
216018f07f7333b25743d0afff892450cebdb905c1acristy  if (AcquireImageColormap(image,2,exception) == MagickFalse)
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Monochrome colormap.
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2216e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy  image->colormap[0].red=QuantumRange;
2226e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy  image->colormap[0].green=QuantumRange;
2236e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy  image->colormap[0].blue=QuantumRange;
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colormap[1].red=(Quantum) 0;
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colormap[1].green=(Quantum) 0;
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colormap[1].blue=(Quantum) 0;
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping != MagickFalse)
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CloseBlob(image);
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
232acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  status=SetImageExtent(image,image->columns,image->rows,exception);
233acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  if (status == MagickFalse)
234acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy    return(DestroyImageList(image));
23552456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  if (LocaleCompare(image_info->magick,"G4") == 0)
23652456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    return(FaxReadG4(image,image_info,exception));
23752456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  else
23852456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk    return(FaxReadG3(image,exception));
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r F A X I m a g e                                           %
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterFAXImage() adds attributes for the FAX image format to
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterFAXImage method is:
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterFAXImage(void)
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterFAXImage(void)
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *Note=
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
272c4a5dd23930e6969f01a7bdf250f8f1cdf7bcd5fcristy      "FAX machines use non-square pixels which are 1.5 times wider than\n"
273c4a5dd23930e6969f01a7bdf250f8f1cdf7bcd5fcristy      "they are tall but computer displays use square pixels, therefore\n"
274c4a5dd23930e6969f01a7bdf250f8f1cdf7bcd5fcristy      "FAX images may appear to be narrow unless they are explicitly\n"
275c4a5dd23930e6969f01a7bdf250f8f1cdf7bcd5fcristy      "resized using a geometry of \"150x100%\".\n"
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27806b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("FAX","FAX","Group 3 FAX");
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadFAXImage;
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteFAXImage;
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsFAX;
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(Note);
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
28406b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("FAX","G3","Group 3 FAX");
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadFAXImage;
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteFAXImage;
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsFAX;
28808e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
29052456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  entry=AcquireMagickInfo("FAX","G4","Group 4 FAX");
29152456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  entry->decoder=(DecodeImageHandler *) ReadFAXImage;
29252456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  entry->encoder=(EncodeImageHandler *) WriteFAXImage;
29352456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  entry->magick=(IsImageFormatHandler *) IsFAX;
29452456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  entry->flags^=CoderAdjoinFlag;
29552456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  (void) RegisterMagickInfo(entry);
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r F A X I m a g e                                       %
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterFAXImage() removes format registrations made by the
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  FAX module from the list of supported formats.
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterFAXImage method is:
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterFAXImage(void)
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterFAXImage(void)
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("FAX");
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("G3");
32252456ef5ab4b8c1e3f0229674f38765cdc074b2ddirk  (void) UnregisterMagickInfo("G4");
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e F A X I m a g e                                                 %
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteFAXImage() writes an image to a file in 1 dimensional Huffman encoded
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  format.
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteFAXImage method is:
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3411e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WriteFAXImage(const ImageInfo *image_info,
3421e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3501e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
3511e178e70fb3c956f9fc1e30c3ba863e882666465cristy%
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
3531e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WriteFAXImage(const ImageInfo *image_info,Image *image,
3541e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *write_info;
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
369e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
371e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3743a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception != (ExceptionInfo *) NULL);
375e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
3761e178e70fb3c956f9fc1e30c3ba863e882666465cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_info=CloneImageInfo(image_info);
380151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(write_info->magick,"FAX",MagickPathExtent);
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Convert MIFF to monochrome.
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
387af8d391906d11f0a1f2bbf4e2adbc4995c852d33cristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
388018f07f7333b25743d0afff892450cebdb905c1acristy    status=HuffmanEncodeImage(write_info,image,image,exception);
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (write_info->adjoin != MagickFalse);
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_info=DestroyImageInfo(write_info);
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
401