/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%                            EEEEE  PPPP   TTTTT                              %
%                            E      P   P    T                                %
%                            EEE    PPPP     T                                %
%                            E      P        T                                %
%                            EEEEE  P        T                                %
%                                                                             %
%                                                                             %
%           Read/Write Encapsulated Postscript Format (with preview).         %
%                                                                             %
%                              Software Design                                %
%                                   Cristy                                    %
%                                 July 1992                                   %
%                                                                             %
%                                                                             %
%  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
%  dedicated to making software imaging solutions freely available.           %
%                                                                             %
%  You may not use this file except in compliance with the License.  You may  %
%  obtain a copy of the License at                                            %
%                                                                             %
%    https://imagemagick.org/script/license.php                               %
%                                                                             %
%  Unless required by applicable law or agreed to in writing, software        %
%  distributed under the License is distributed on an "AS IS" BASIS,          %
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
%  See the License for the specific language governing permissions and        %
%  limitations under the License.                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/

/*
  Include declarations.
*/
#include "MagickCore/studio.h"
#include "MagickCore/blob.h"
#include "MagickCore/blob-private.h"
#include "MagickCore/color.h"
#include "MagickCore/constitute.h"
#include "MagickCore/draw.h"
#include "MagickCore/exception.h"
#include "MagickCore/exception-private.h"
#include "MagickCore/delegate.h"
#include "MagickCore/geometry.h"
#include "MagickCore/histogram.h"
#include "MagickCore/image.h"
#include "MagickCore/image-private.h"
#include "MagickCore/list.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
#include "MagickCore/monitor.h"
#include "MagickCore/monitor-private.h"
#include "MagickCore/quantize.h"
#include "MagickCore/resource_.h"
#include "MagickCore/resize.h"
#include "MagickCore/quantum-private.h"
#include "MagickCore/static.h"
#include "MagickCore/string_.h"
#include "MagickCore/module.h"
#include "MagickCore/utility.h"

/*
  Typedef declarations.
*/
typedef struct _EPTInfo
{
  size_t
    magick;

  MagickOffsetType
    postscript_offset,
    tiff_offset;

  size_t
    postscript_length,
    tiff_length;

  unsigned char
    *postscript,
    *tiff;
} EPTInfo;

/*
  Forward declarations.
*/
static MagickBooleanType
  WriteEPTImage(const ImageInfo *,Image *,ExceptionInfo *);

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   I s E P T                                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  IsEPT() returns MagickTrue if the image format type, identified by the
%  magick string, is EPT.
%
%  The format of the IsEPT method is:
%
%      MagickBooleanType IsEPT(const unsigned char *magick,const size_t length)
%
%  A description of each parameter follows:
%
%    o magick: compare image format pattern against these bytes.
%
%    o length: Specifies the length of the magick string.
%
*/
static MagickBooleanType IsEPT(const unsigned char *magick,const size_t length)
{
  if (length < 4)
    return(MagickFalse);
  if (memcmp(magick,"\305\320\323\306",4) == 0)
    return(MagickTrue);
  return(MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d E P T I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadEPTImage() reads a binary Postscript image file and returns it.  It
%  allocates the memory necessary for the new Image structure and returns a
%  pointer to the new image.
%
%  The format of the ReadEPTImage method is:
%
%      Image *ReadEPTImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadEPTImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  EPTInfo
    ept_info;

  Image
    *image;

  ImageInfo
    *read_info;

  MagickBooleanType
    status;

  MagickOffsetType
    offset;

  ssize_t
    count;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  image=AcquireImage(image_info,exception);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  ept_info.magick=ReadBlobLSBLong(image);
  if (ept_info.magick != 0xc6d3d0c5ul)
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  ept_info.postscript_offset=(MagickOffsetType) ReadBlobLSBLong(image);
  ept_info.postscript_length=ReadBlobLSBLong(image);
  if (ept_info.postscript_length > GetBlobSize(image))
    ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
  (void) ReadBlobLSBLong(image);
  (void) ReadBlobLSBLong(image);
  ept_info.tiff_offset=(MagickOffsetType) ReadBlobLSBLong(image);
  ept_info.tiff_length=ReadBlobLSBLong(image);
  if (ept_info.tiff_length > GetBlobSize(image))
    ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
  (void) ReadBlobLSBShort(image);
  ept_info.postscript=(unsigned char *) AcquireQuantumMemory(
    ept_info.postscript_length+1,sizeof(*ept_info.postscript));
  if (ept_info.postscript == (unsigned char *) NULL)
    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  (void) memset(ept_info.postscript,0,(ept_info.postscript_length+1)*
    sizeof(*ept_info.postscript));
  ept_info.tiff=(unsigned char *) AcquireQuantumMemory(ept_info.tiff_length+1,
    sizeof(*ept_info.tiff));
  if (ept_info.tiff == (unsigned char *) NULL)
    {
      ept_info.postscript=(unsigned char *) RelinquishMagickMemory(
        ept_info.postscript);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  (void) memset(ept_info.tiff,0,(ept_info.tiff_length+1)*
    sizeof(*ept_info.tiff));
  offset=SeekBlob(image,ept_info.tiff_offset,SEEK_SET);
  if ((ept_info.tiff_length != 0) && (offset < 30))
    {
      ept_info.tiff=(unsigned char *) RelinquishMagickMemory(ept_info.tiff);
      ept_info.postscript=(unsigned char *) RelinquishMagickMemory(
        ept_info.postscript);
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    }
  count=ReadBlob(image,ept_info.tiff_length,ept_info.tiff);
  if (count != (ssize_t) (ept_info.tiff_length))
    (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageWarning,
      "InsufficientImageDataInFile","`%s'",image->filename);
  offset=SeekBlob(image,ept_info.postscript_offset,SEEK_SET);
  if ((ept_info.postscript_length != 0) && (offset < 30))
    {
      ept_info.tiff=(unsigned char *) RelinquishMagickMemory(ept_info.tiff);
      ept_info.postscript=(unsigned char *) RelinquishMagickMemory(
        ept_info.postscript);
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    }
  count=ReadBlob(image,ept_info.postscript_length,ept_info.postscript);
  if (count != (ssize_t) (ept_info.postscript_length))
    (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageWarning,
      "InsufficientImageDataInFile","`%s'",image->filename);
  (void) CloseBlob(image);
  image=DestroyImage(image);
  read_info=CloneImageInfo(image_info);
  (void) CopyMagickString(read_info->magick,"EPS",MagickPathExtent);
  image=BlobToImage(read_info,ept_info.postscript,ept_info.postscript_length,
    exception);
  if (image == (Image *) NULL)
    {
      (void) CopyMagickString(read_info->magick,"TIFF",MagickPathExtent);
      image=BlobToImage(read_info,ept_info.tiff,ept_info.tiff_length,exception);
    }
  read_info=DestroyImageInfo(read_info);
  if (image != (Image *) NULL)
    {
      (void) CopyMagickString(image->filename,image_info->filename,
        MagickPathExtent);
      (void) CopyMagickString(image->magick,"EPT",MagickPathExtent);
    }
  ept_info.tiff=(unsigned char *) RelinquishMagickMemory(ept_info.tiff);
  ept_info.postscript=(unsigned char *) RelinquishMagickMemory(
    ept_info.postscript);
  return(image);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e g i s t e r E P T I m a g e                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RegisterEPTImage() adds attributes for the EPT image format to
%  the list of supported formats.  The attributes include the image format
%  tag, a method to read and/or write the format, whether the format
%  supports the saving of more than one frame to the same file or blob,
%  whether the format supports native in-memory I/O, and a brief
%  description of the format.
%
%  The format of the RegisterEPTImage method is:
%
%      size_t RegisterEPTImage(void)
%
*/
ModuleExport size_t RegisterEPTImage(void)
{
  MagickInfo
    *entry;

  entry=AcquireMagickInfo("EPT","EPT",
    "Encapsulated PostScript with TIFF preview");
  entry->decoder=(DecodeImageHandler *) ReadEPTImage;
  entry->encoder=(EncodeImageHandler *) WriteEPTImage;
  entry->magick=(IsImageFormatHandler *) IsEPT;
  entry->flags|=CoderDecoderSeekableStreamFlag;
  entry->flags^=CoderAdjoinFlag;
  entry->flags^=CoderBlobSupportFlag;
  (void) RegisterMagickInfo(entry);
  entry=AcquireMagickInfo("EPT","EPT2",
    "Encapsulated PostScript Level II with TIFF preview");
  entry->decoder=(DecodeImageHandler *) ReadEPTImage;
  entry->encoder=(EncodeImageHandler *) WriteEPTImage;
  entry->magick=(IsImageFormatHandler *) IsEPT;
  entry->flags^=CoderAdjoinFlag;
  entry->flags|=CoderDecoderSeekableStreamFlag;
  entry->flags^=CoderBlobSupportFlag;
  (void) RegisterMagickInfo(entry);
  entry=AcquireMagickInfo("EPT","EPT3",
    "Encapsulated PostScript Level III with TIFF preview");
  entry->decoder=(DecodeImageHandler *) ReadEPTImage;
  entry->encoder=(EncodeImageHandler *) WriteEPTImage;
  entry->magick=(IsImageFormatHandler *) IsEPT;
  entry->flags|=CoderDecoderSeekableStreamFlag;
  entry->flags^=CoderBlobSupportFlag;
  (void) RegisterMagickInfo(entry);
  return(MagickImageCoderSignature);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   U n r e g i s t e r E P T I m a g e                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  UnregisterEPTImage() removes format registrations made by the
%  EPT module from the list of supported formats.
%
%  The format of the UnregisterEPTImage method is:
%
%      UnregisterEPTImage(void)
%
*/
ModuleExport void UnregisterEPTImage(void)
{
  (void) UnregisterMagickInfo("EPT");
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e E P T I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  WriteEPTImage() writes an image in the Encapsulated Postscript format
%  with a TIFF preview.
%
%  The format of the WriteEPTImage method is:
%
%      MagickBooleanType WriteEPTImage(const ImageInfo *image_info,
%        Image *image,ExceptionInfo *exception)
%
%  A description of each parameter follows.
%
%    o image_info: the image info.
%
%    o image:  The image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType WriteEPTImage(const ImageInfo *image_info,Image *image,
  ExceptionInfo *exception)
{
  char
    filename[MagickPathExtent];

  EPTInfo
    ept_info;

  Image
    *write_image;

  ImageInfo
    *write_info;

  MagickBooleanType
    status;

  /*
    Write EPT image.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickCoreSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
  if (status == MagickFalse)
    return(status);
  write_image=CloneImage(image,0,0,MagickTrue,exception);
  if (write_image == (Image *) NULL)
    return(MagickFalse);
  write_info=CloneImageInfo(image_info);
  (void) CopyMagickString(write_info->filename,"EPS:",MagickPathExtent);
  (void) CopyMagickString(write_info->magick,"EPS",MagickPathExtent);
  if (LocaleCompare(image_info->magick,"EPT2") == 0)
    {
      (void) CopyMagickString(write_info->filename,"EPS2:",MagickPathExtent);
      (void) CopyMagickString(write_info->magick,"EPS2",MagickPathExtent);
    }
  if (LocaleCompare(image_info->magick,"EPT3") == 0)
    {
      (void) CopyMagickString(write_info->filename,"EPS3:",MagickPathExtent);
      (void) CopyMagickString(write_info->magick,"EPS3",MagickPathExtent);
    }
  (void) memset(&ept_info,0,sizeof(ept_info));
  ept_info.magick=0xc6d3d0c5ul;
  ept_info.postscript=(unsigned char *) ImageToBlob(write_info,write_image,
    &ept_info.postscript_length,exception);
  write_image=DestroyImage(write_image);
  write_info=DestroyImageInfo(write_info);
  if (ept_info.postscript == (void *) NULL)
    return(MagickFalse);
  write_image=CloneImage(image,0,0,MagickTrue,exception);
  if (write_image == (Image *) NULL)
    return(MagickFalse);
  write_info=CloneImageInfo(image_info);
  (void) CopyMagickString(write_info->magick,"TIFF",MagickPathExtent);
  (void) FormatLocaleString(filename,MagickPathExtent,"tiff:%s",
    write_info->filename); 
  (void) CopyMagickString(write_info->filename,filename,MagickPathExtent);
  if ((write_image->columns > 512) || (write_image->rows > 512))
    {
      Image
        *resize_image;

      resize_image=ResizeImage(write_image,512,512,write_image->filter,
        exception);
      if (resize_image != (Image *) NULL)
        {
          write_image=DestroyImage(write_image);
          write_image=resize_image;
        }
    }
  if ((write_image->storage_class == DirectClass) ||
      (write_image->colors > 256))
    {
      QuantizeInfo
        quantize_info;

      /*
        EPT preview requires that the image is colormapped.
      */
      GetQuantizeInfo(&quantize_info);
      quantize_info.dither_method=IdentifyPaletteImage(write_image,
        exception) == MagickFalse ? RiemersmaDitherMethod : NoDitherMethod;
      (void) QuantizeImage(&quantize_info,write_image,exception);
    }
  write_info->compression=NoCompression;
  ept_info.tiff=(unsigned char *) ImageToBlob(write_info,write_image,
    &ept_info.tiff_length,exception);
  write_image=DestroyImage(write_image);
  write_info=DestroyImageInfo(write_info);
  if (ept_info.tiff == (void *) NULL)
    {
      ept_info.postscript=(unsigned char *) RelinquishMagickMemory(
        ept_info.postscript);
      return(MagickFalse);
    }
  /*
    Write EPT image.
  */
  (void) WriteBlobLSBLong(image,(unsigned int) ept_info.magick);
  (void) WriteBlobLSBLong(image,30);
  (void) WriteBlobLSBLong(image,(unsigned int) ept_info.postscript_length);
  (void) WriteBlobLSBLong(image,0);
  (void) WriteBlobLSBLong(image,0);
  (void) WriteBlobLSBLong(image,(unsigned int) ept_info.postscript_length+30);
  (void) WriteBlobLSBLong(image,(unsigned int) ept_info.tiff_length);
  (void) WriteBlobLSBShort(image,0xffff);
  (void) WriteBlob(image,ept_info.postscript_length,ept_info.postscript);
  (void) WriteBlob(image,ept_info.tiff_length,ept_info.tiff);
  /*
    Relinquish resources.
  */
  ept_info.postscript=(unsigned char *) RelinquishMagickMemory(
    ept_info.postscript);
  ept_info.tiff=(unsigned char *) RelinquishMagickMemory(ept_info.tiff);
  (void) CloseBlob(image);
  return(MagickTrue);
}
