//========================================================================
//
// ImageOutputDev.h
//
// Copyright 1998-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2006 Rainer Keller <class321@gmx.de>
// Copyright (C) 2008 Timothy Lee <timothy.lee@siriushk.com>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2010 Jakob Voss <jakob.voss@gbv.de>
// Copyright (C) 2012, 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2018 Albert Astals Cid <aacid@kde.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef IMAGEOUTPUTDEV_H
#define IMAGEOUTPUTDEV_H

#include "poppler/poppler-config.h"

#include <stdio.h>
#include "goo/ImgWriter.h"
#include "OutputDev.h"

class GfxState;

//------------------------------------------------------------------------
// ImageOutputDev
//------------------------------------------------------------------------

class ImageOutputDev: public OutputDev {
public:
  enum ImageType {
    imgImage,
    imgStencil,
    imgMask,
    imgSmask
  };
  enum ImageFormat {
    imgRGB,
    imgRGB48,
    imgGray,
    imgMonochrome,
    imgCMYK
  };

  // Create an OutputDev which will write images to files named
  // <fileRoot>-NNN.<type> or <fileRoot>-PPP-NNN.<type>, if 
  // <pageNames> is set. Normally, all images are written as PBM
  // (.pbm) or PPM (.ppm) files unless PNG or Tiff output is enabled
  // (PNG is used if both are enabled).  If Jpeg is enabled, JPEG images
  // are written as JPEG (.jpg) files.
  ImageOutputDev(char *fileRootA, bool pageNamesA, bool listImagesA);

  // Destructor.
  virtual ~ImageOutputDev();

  // Use PNG format for output
  void enablePNG(bool png) { outputPNG = png; }

  // Use TIFF format for output
  void enableTiff(bool tiff) { outputTiff = tiff; }

  // Use Jpeg format for Jpeg files
  void enableJpeg(bool jpeg) { dumpJPEG = jpeg; }

  // Use Jpeg2000 format for Jpeg2000 files
  void enableJpeg2000(bool jp2) { dumpJP2 = jp2; }

  // Use JBIG2 format for JBIG2 files
  void enableJBig2(bool jbig2) { dumpJBIG2 = jbig2; }

  // Use CCITT format for CCITT files
  void enableCCITT(bool ccitt) { dumpCCITT = ccitt; }

  // Check if file was successfully created.
  virtual bool isOk() { return ok; }

  // Does this device use tilingPatternFill()?  If this returns false,
  // tiling pattern fills will be reduced to a series of other drawing
  // operations.
  bool useTilingPatternFill() override { return true; }

  // Does this device use beginType3Char/endType3Char?  Otherwise,
  // text in Type 3 fonts will be drawn with drawChar/drawString.
  bool interpretType3Chars() override { return false; }

  // Does this device need non-text content?
  bool needNonText() override { return true; }

  // Start a page
  void startPage(int pageNumA, GfxState *state, XRef *xref)  override
			{ pageNum = pageNumA; }
 
  //---- get info about output device

  // Does this device use upside-down coordinates?
  // (Upside-down means (0,0) is the top left corner of the page.)
  bool upsideDown() override { return true; }

  // Does this device use drawChar() or drawString()?
  bool useDrawChar() override { return false; }

  //----- path painting
  bool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, Object *str,
			  const double *pmat, int paintType, int tilingType, Dict *resDict,
			  const double *mat, const double *bbox,
			  int x0, int y0, int x1, int y1,
			  double xStep, double yStep) override;

  //----- image drawing
  void drawImageMask(GfxState *state, Object *ref, Stream *str,
		     int width, int height, bool invert,
		     bool interpolate, bool inlineImg) override;
  void drawImage(GfxState *state, Object *ref, Stream *str,
		 int width, int height, GfxImageColorMap *colorMap,
		 bool interpolate, int *maskColors, bool inlineImg) override;
  void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
		       int width, int height,
		       GfxImageColorMap *colorMap,
		       bool interpolate,
		       Stream *maskStr, int maskWidth, int maskHeight,
		       bool maskInvert, bool maskInterpolate) override;
  void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
			   int width, int height,
			   GfxImageColorMap *colorMap,
			   bool interpolate,
			   Stream *maskStr,
			   int maskWidth, int maskHeight,
			   GfxImageColorMap *maskColorMap,
			   bool maskInterpolate) override;

private:
  // Sets the output filename with a given file extension
  void setFilename(const char *fileExt);
  void listImage(GfxState *state, Object *ref, Stream *str,
		 int width, int height,
		 GfxImageColorMap *colorMap,
		 bool interpolate, bool inlineImg,
		 ImageType imageType);
  void writeImage(GfxState *state, Object *ref, Stream *str,
                  int width, int height, GfxImageColorMap *colorMap, bool inlineImg);
  void writeRawImage(Stream *str, const char *ext);
  void writeImageFile(ImgWriter *writer, ImageFormat format, const char *ext,
                      Stream *str, int width, int height, GfxImageColorMap *colorMap);
  long getInlineImageLength(Stream *str, int width, int height, GfxImageColorMap *colorMap);

  char *fileRoot;		// root of output file names
  char *fileName;		// buffer for output file names
  bool listImages;		// list images instead of dumping
  bool dumpJPEG;		// set to dump native JPEG files
  bool dumpJP2;		// set to dump native JPEG2000 files
  bool dumpJBIG2;		// set to dump native JBIG2 files
  bool dumpCCITT;		// set to dump native CCITT files
  bool outputPNG;		// set to output in PNG format
  bool outputTiff;		// set to output in TIFF format
  bool pageNames;		// set to include page number in file names
  int pageNum;			// current page number
  int imgNum;			// current image number
  bool ok;			// set up ok?
};

#endif
