//========================================================================
//
// GfxState.cc
//
// Copyright 1996-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) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2006, 2010 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2006-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2009, 2012 Koji Otani <sho@bbr.jp>
// Copyright (C) 2009, 2011-2016 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2009, 2019 Christian Persch <chpe@gnome.org>
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
// Copyright (C) 2011 Andrea Canciani <ranma42@gmail.com>
// Copyright (C) 2012 William Bader <williambader@hotmail.com>
// Copyright (C) 2013 Lu Wang <coolwanglu@gmail.com>
// Copyright (C) 2013 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2013 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2015 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2016 Marek Kasik <mkasik@redhat.com>
// Copyright (C) 2017 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018 Volker Krause <vkrause@kde.org>
// Copyright (C) 2018, 2019 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
//
// 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
//
//========================================================================

#include <config.h>

#include <algorithm>
#include <memory>
#include <stddef.h>
#include <math.h>
#include <string.h>
#include "goo/gfile.h"
#include "goo/gmem.h"
#include "Error.h"
#include "Object.h"
#include "Array.h"
#include "Page.h"
#include "Gfx.h"
#include "GfxState.h"
#include "GfxState_helpers.h"
#include "GfxFont.h"
#include "GlobalParams.h"
#include "PopplerCache.h"
#include "OutputDev.h"
#include "splash/SplashTypes.h"

//------------------------------------------------------------------------

// Max depth of nested color spaces.  This is used to catch infinite
// loops in the color space object structure.
#define colorSpaceRecursionLimit 8

//------------------------------------------------------------------------

bool Matrix::invertTo(Matrix *other) const
{
  const double det_denominator = determinant();
  if (unlikely(det_denominator == 0)) {
      *other = {1, 0, 0, 1, 0, 0};
      return false;
  }

  const double det = 1 / det_denominator;
  other->m[0] = m[3] * det;
  other->m[1] = -m[1] * det;
  other->m[2] = -m[2] * det;
  other->m[3] = m[0] * det;
  other->m[4] = (m[2] * m[5] - m[3] * m[4]) * det;
  other->m[5] = (m[1] * m[4] - m[0] * m[5]) * det;

  return true;
}

void Matrix::translate(double tx, double ty)
{
  double x0 = tx*m[0] + ty*m[2] + m[4];
  double y0 = tx*m[1] + ty*m[3] + m[5];
  m[4] = x0;
  m[5] = y0;
}

void Matrix::scale(double sx, double sy)
{
  m[0] *= sx;
  m[1] *= sx;
  m[2] *= sy;
  m[3] *= sy;
}

void Matrix::transform(double x, double y, double *tx, double *ty) const
{
  double temp_x, temp_y;

  temp_x = m[0] * x + m[2] * y + m[4];
  temp_y = m[1] * x + m[3] * y + m[5];

  *tx = temp_x;
  *ty = temp_y;
}

// Matrix norm, taken from _cairo_matrix_transformed_circle_major_axis
double Matrix::norm() const
{
  double f, g, h, i, j;

  i = m[0]*m[0] + m[1]*m[1];
  j = m[2]*m[2] + m[3]*m[3];

  f = 0.5 * (i + j);
  g = 0.5 * (i - j);
  h = m[0]*m[2] + m[1]*m[3];

  return sqrt (f + hypot (g, h));
}

//------------------------------------------------------------------------

struct GfxBlendModeInfo {
  const char *name;
  GfxBlendMode mode;
};

static const GfxBlendModeInfo gfxBlendModeNames[] = {
  { "Normal",     gfxBlendNormal },
  { "Compatible", gfxBlendNormal },
  { "Multiply",   gfxBlendMultiply },
  { "Screen",     gfxBlendScreen },
  { "Overlay",    gfxBlendOverlay },
  { "Darken",     gfxBlendDarken },
  { "Lighten",    gfxBlendLighten },
  { "ColorDodge", gfxBlendColorDodge },
  { "ColorBurn",  gfxBlendColorBurn },
  { "HardLight",  gfxBlendHardLight },
  { "SoftLight",  gfxBlendSoftLight },
  { "Difference", gfxBlendDifference },
  { "Exclusion",  gfxBlendExclusion },
  { "Hue",        gfxBlendHue },
  { "Saturation", gfxBlendSaturation },
  { "Color",      gfxBlendColor },
  { "Luminosity", gfxBlendLuminosity }
};

#define nGfxBlendModeNames \
          ((int)((sizeof(gfxBlendModeNames) / sizeof(GfxBlendModeInfo))))
	 
//------------------------------------------------------------------------
// 
// NB: This must match the GfxColorSpaceMode enum defined in
// GfxState.h
static const char *gfxColorSpaceModeNames[] = {
  "DeviceGray",
  "CalGray",
  "DeviceRGB",
  "CalRGB",
  "DeviceCMYK",
  "Lab",
  "ICCBased",
  "Indexed",
  "Separation",
  "DeviceN",
  "Pattern"
};

#define nGfxColorSpaceModes ((sizeof(gfxColorSpaceModeNames) / sizeof(char *)))

#ifdef USE_CMS

static const std::map<unsigned int, unsigned int>::size_type CMSCACHE_LIMIT = 2048;

#include <lcms2.h>
#define LCMS_FLAGS cmsFLAGS_NOOPTIMIZE | cmsFLAGS_BLACKPOINTCOMPENSATION

#define COLOR_PROFILE_DIR "/ColorProfiles/"
#define GLOBAL_COLOR_PROFILE_DIR POPPLER_DATADIR COLOR_PROFILE_DIR

void GfxColorTransform::doTransform(void *in, void *out, unsigned int size) {
  cmsDoTransform(transform, in, out, size);
}

// transformA should be a cmsHTRANSFORM
GfxColorTransform::GfxColorTransform(void *transformA, int cmsIntentA, unsigned int inputPixelTypeA, unsigned int transformPixelTypeA) {
  transform = transformA;
  refCount = 1;
  cmsIntent = cmsIntentA;
  inputPixelType = inputPixelTypeA;
  transformPixelType = transformPixelTypeA;
}

GfxColorTransform::~GfxColorTransform() {
  cmsDeleteTransform(transform);
}

void GfxColorTransform::ref() {
  refCount++;
}

unsigned int GfxColorTransform::unref() {
  return --refCount;
}

static cmsHPROFILE RGBProfile = nullptr;
static GooString *displayProfileName = nullptr; // display profile file Name
static cmsHPROFILE displayProfile = nullptr; // display profile
static unsigned int displayPixelType = 0;
static GfxColorTransform *XYZ2DisplayTransform = nullptr;

// convert color space signature to cmsColor type 
static unsigned int getCMSColorSpaceType(cmsColorSpaceSignature cs);
static unsigned int getCMSNChannels(cmsColorSpaceSignature cs);
static cmsHPROFILE loadColorProfile(const char *fileName);

void GfxColorSpace::setDisplayProfile(void *displayProfileA) {
  if (displayProfile != nullptr) {
    error(errInternal, -1, "The display color profile can only be set once before any rendering is done.");
    return;
  }
  displayProfile = displayProfileA;
  if (displayProfile != nullptr) {
    cmsHTRANSFORM transform;
    unsigned int nChannels;

    displayPixelType = getCMSColorSpaceType(cmsGetColorSpace(displayProfile));
    nChannels = getCMSNChannels(cmsGetColorSpace(displayProfile));
    // create transform from XYZ
    cmsHPROFILE XYZProfile = cmsCreateXYZProfile();
    if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
	   displayProfile,
	   COLORSPACE_SH(displayPixelType) |
	     CHANNELS_SH(nChannels) | BYTES_SH(1),
	  INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
      error(errSyntaxWarning, -1, "Can't create Lab transform");
    } else {
      XYZ2DisplayTransform = new GfxColorTransform(transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
    }
    cmsCloseProfile(XYZProfile);
  }
}

void GfxColorSpace::setDisplayProfileName(GooString *name) {
  if (displayProfile != nullptr) {
    error(errInternal, -1, "The display color profile can only be set before any rendering is done.");
    return;
  }
  delete displayProfileName;
  displayProfileName = name->copy();
}

cmsHPROFILE GfxColorSpace::getRGBProfile() {
  return RGBProfile;
}

cmsHPROFILE GfxColorSpace::getDisplayProfile() {
  return displayProfile;
}

#endif

//------------------------------------------------------------------------
// GfxColorSpace
//------------------------------------------------------------------------

GfxColorSpace::GfxColorSpace() {
  overprintMask = 0x0f;
  mapping = nullptr;
}

GfxColorSpace::~GfxColorSpace() {
}

GfxColorSpace *GfxColorSpace::parse(GfxResources *res, Object *csObj, OutputDev *out, GfxState *state, int recursion) {
  GfxColorSpace *cs;
  Object obj1;

  if (recursion > colorSpaceRecursionLimit) {
    error(errSyntaxError, -1, "Loop detected in color space objects");
    return nullptr;
  }

  cs = nullptr;
  if (csObj->isName()) {
    if (csObj->isName("DeviceGray") || csObj->isName("G")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultGray");
        if (objCS.isNull()) {
          cs = new GfxDeviceGrayColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceGrayColorSpace();
      }
    } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultRGB");
        if (objCS.isNull()) {
          cs = new GfxDeviceRGBColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceRGBColorSpace();
      }
    } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultCMYK");
        if (objCS.isNull()) {
          cs = new GfxDeviceCMYKColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceCMYKColorSpace();
      }
    } else if (csObj->isName("Pattern")) {
      cs = new GfxPatternColorSpace(nullptr);
    } else {
      error(errSyntaxWarning, -1, "Bad color space '{0:s}'", csObj->getName());
    }
  } else if (csObj->isArray() && csObj->arrayGetLength() > 0) {
    obj1 = csObj->arrayGet(0);
    if (obj1.isName("DeviceGray") || obj1.isName("G")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultGray");
        if (objCS.isNull()) {
          cs = new GfxDeviceGrayColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceGrayColorSpace();
      }
    } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultRGB");
        if (objCS.isNull()) {
          cs = new GfxDeviceRGBColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceRGBColorSpace();
      }
    } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultCMYK");
        if (objCS.isNull()) {
          cs = new GfxDeviceCMYKColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceCMYKColorSpace();
      }
    } else if (obj1.isName("CalGray")) {
      cs = GfxCalGrayColorSpace::parse(csObj->getArray(), state);
    } else if (obj1.isName("CalRGB")) {
      cs = GfxCalRGBColorSpace::parse(csObj->getArray(), state);
    } else if (obj1.isName("Lab")) {
      cs = GfxLabColorSpace::parse(csObj->getArray(), state);
    } else if (obj1.isName("ICCBased")) {
      cs = GfxICCBasedColorSpace::parse(csObj->getArray(), out, state, recursion);
    } else if (obj1.isName("Indexed") || obj1.isName("I")) {
      cs = GfxIndexedColorSpace::parse(res, csObj->getArray(), out, state, recursion);
    } else if (obj1.isName("Separation")) {
      cs = GfxSeparationColorSpace::parse(res, csObj->getArray(), out, state, recursion);
    } else if (obj1.isName("DeviceN")) {
      cs = GfxDeviceNColorSpace::parse(res, csObj->getArray(), out, state, recursion);
    } else if (obj1.isName("Pattern")) {
      cs = GfxPatternColorSpace::parse(res, csObj->getArray(), out, state, recursion);
    } else {
      error(errSyntaxWarning, -1, "Bad color space");
    }
  } else if (csObj->isDict()) {
    obj1 = csObj->dictLookup("ColorSpace");
    if (obj1.isName("DeviceGray")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultGray");
        if (objCS.isNull()) {
          cs = new GfxDeviceGrayColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceGrayColorSpace();
      }
    } else if (obj1.isName("DeviceRGB")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultRGB");
        if (objCS.isNull()) {
          cs = new GfxDeviceRGBColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceRGBColorSpace();
      }
    } else if (obj1.isName("DeviceCMYK")) {
      if (res != nullptr) {
        Object objCS = res->lookupColorSpace("DefaultCMYK");
        if (objCS.isNull()) {
          cs = new GfxDeviceCMYKColorSpace();
        } else {
          cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
        }
      } else {
        cs = new GfxDeviceCMYKColorSpace();
      }
    } else {
      error(errSyntaxWarning, -1, "Bad color space dict'");
    }
  } else {
    error(errSyntaxWarning, -1, "Bad color space - expected name or array or dict");
  }
  return cs;
}

void GfxColorSpace::createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) {
  return;
}

void GfxColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
				     int maxImgPixel) {
  int i;

  for (i = 0; i < getNComps(); ++i) {
    decodeLow[i] = 0;
    decodeRange[i] = 1;
  }
}

int GfxColorSpace::getNumColorSpaceModes() {
  return nGfxColorSpaceModes;
}

const char *GfxColorSpace::getColorSpaceModeName(int idx) {
  return gfxColorSpaceModeNames[idx];
}

#ifdef USE_CMS
cmsHPROFILE loadColorProfile(const char *fileName)
{
  cmsHPROFILE hp = nullptr;
  FILE *fp;

  if (fileName[0] == '/') {
    // full path
    // check if open the file
    if ((fp = openFile(fileName,"r")) != nullptr) {
      fclose(fp);
      hp = cmsOpenProfileFromFile(fileName,"r");
    }
    return hp;
  }
  // try to load from global directory
  GooString *path = new GooString(GLOBAL_COLOR_PROFILE_DIR);
  path->append(fileName);
  // check if open the file
  if ((fp = openFile(path->c_str(),"r")) != nullptr) {
    fclose(fp);
    hp = cmsOpenProfileFromFile(path->c_str(),"r");
  }
  delete path;
  return hp;
}

static void CMSError(cmsContext /*contextId*/, cmsUInt32Number /*ecode*/, const char *text)
{
    error(errSyntaxWarning, -1, "{0:s}", text);
}

int GfxColorSpace::setupColorProfiles()
{
  static bool initialized = false;
  cmsHTRANSFORM transform;
  unsigned int nChannels;

  // do only once
  if (initialized) return 0;
  initialized = true;

  // set error handlor
  cmsSetLogErrorHandler(CMSError);

  if (displayProfile == nullptr) {
    // load display profile if it was not already loaded.
    if (displayProfileName == nullptr) {
      displayProfile = loadColorProfile("display.icc");
    } else if (displayProfileName->getLength() > 0) {
      displayProfile = loadColorProfile(displayProfileName->c_str());
    }
  }
  // load RGB profile
  RGBProfile = loadColorProfile("RGB.icc");
  if (RGBProfile == nullptr) {
    /* use built in sRGB profile */
    RGBProfile = cmsCreate_sRGBProfile();
  }
  // create transforms
  if (displayProfile != nullptr) {
    displayPixelType = getCMSColorSpaceType(cmsGetColorSpace(displayProfile));
    nChannels = getCMSNChannels(cmsGetColorSpace(displayProfile));
    // create transform from XYZ
    cmsHPROFILE XYZProfile = cmsCreateXYZProfile();
    if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
	   displayProfile,
	   COLORSPACE_SH(displayPixelType) |
	     CHANNELS_SH(nChannels) | BYTES_SH(1),
	  INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
      error(errSyntaxWarning, -1, "Can't create Lab transform");
    } else {
      XYZ2DisplayTransform = new GfxColorTransform(transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
    }
    cmsCloseProfile(XYZProfile);
  }
  return 0;
}

unsigned int getCMSColorSpaceType(cmsColorSpaceSignature cs)
{
    switch (cs) {
    case cmsSigXYZData:
      return PT_XYZ;
      break;
    case cmsSigLabData:
      return PT_Lab;
      break;
    case cmsSigLuvData:
      return PT_YUV;
      break;
    case cmsSigYCbCrData:
      return PT_YCbCr;
      break;
    case cmsSigYxyData:
      return PT_Yxy;
      break;
    case cmsSigRgbData:
      return PT_RGB;
      break;
    case cmsSigGrayData:
      return PT_GRAY;
      break;
    case cmsSigHsvData:
      return PT_HSV;
      break;
    case cmsSigHlsData:
      return PT_HLS;
      break;
    case cmsSigCmykData:
      return PT_CMYK;
      break;
    case cmsSigCmyData:
      return PT_CMY;
      break;
    case cmsSig2colorData:
    case cmsSig3colorData:
    case cmsSig4colorData:
    case cmsSig5colorData:
    case cmsSig6colorData:
    case cmsSig7colorData:
    case cmsSig8colorData:
    case cmsSig9colorData:
    case cmsSig10colorData:
    case cmsSig11colorData:
    case cmsSig12colorData:
    case cmsSig13colorData:
    case cmsSig14colorData:
    case cmsSig15colorData:
    default:
      break;
    }
    return PT_RGB;
}

unsigned int getCMSNChannels(cmsColorSpaceSignature cs)
{
    switch (cs) {
    case cmsSigXYZData:
    case cmsSigLuvData:
    case cmsSigLabData:
    case cmsSigYCbCrData:
    case cmsSigYxyData:
    case cmsSigRgbData:
    case cmsSigHsvData:
    case cmsSigHlsData:
    case cmsSigCmyData:
    case cmsSig3colorData:
      return 3;
      break;
    case cmsSigGrayData:
      return 1;
      break;
    case cmsSigCmykData:
    case cmsSig4colorData:
      return 4;
      break;
    case cmsSig2colorData:
      return 2;
      break;
    case cmsSig5colorData:
      return 5;
      break;
    case cmsSig6colorData:
      return 6;
      break;
    case cmsSig7colorData:
      return 7;
      break;
    case cmsSig8colorData:
      return 8;
      break;
    case cmsSig9colorData:
      return 9;
      break;
    case cmsSig10colorData:
      return 10;
      break;
    case cmsSig11colorData:
      return 11;
      break;
    case cmsSig12colorData:
      return 12;
      break;
    case cmsSig13colorData:
      return 13;
      break;
    case cmsSig14colorData:
      return 14;
      break;
    case cmsSig15colorData:
      return 15;
    default:
      break;
    }
    return 3;
}
#endif

//------------------------------------------------------------------------
// GfxDeviceGrayColorSpace
//------------------------------------------------------------------------

GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() {
}

GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() {
}

GfxColorSpace *GfxDeviceGrayColorSpace::copy() {
  return new GfxDeviceGrayColorSpace();
}

void GfxDeviceGrayColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  *gray = clip01(color->c[0]);
}

void GfxDeviceGrayColorSpace::getGrayLine(unsigned char *in, unsigned char *out, int length) {
  memcpy (out, in, length);
}

void GfxDeviceGrayColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
}

void GfxDeviceGrayColorSpace::getRGBLine(unsigned char *in, unsigned int *out,
					 int length) {
  int i;

  for (i = 0; i < length; i++)
    out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0);
}

void GfxDeviceGrayColorSpace::getRGBLine(unsigned char *in, unsigned char *out, int length) {
  for (int i = 0; i < length; i++) {
    *out++ = in[i];
    *out++ = in[i];
    *out++ = in[i];
  }
}

void GfxDeviceGrayColorSpace::getRGBXLine(unsigned char *in, unsigned char *out, int length) {
  for (int i = 0; i < length; i++) {
    *out++ = in[i];
    *out++ = in[i];
    *out++ = in[i];
    *out++ = 255;
  }
}

void GfxDeviceGrayColorSpace::getCMYKLine(unsigned char *in, unsigned char *out, int length) {
  for (int i = 0; i < length; i++) {
    *out++ = 0;
    *out++ = 0;
    *out++ = 0;
    *out++ = in[i];
  }
}

void GfxDeviceGrayColorSpace::getDeviceNLine(unsigned char *in, unsigned char *out, int length) {
  for (int i = 0; i < length; i++) {
    for (int j = 0; j < SPOT_NCOMPS+4; j++)
      out[j] = 0;
    out[4] = in[i];
    out += (SPOT_NCOMPS+4);
  }
}

void GfxDeviceGrayColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  cmyk->c = cmyk->m = cmyk->y = 0;
  cmyk->k = clip01(gfxColorComp1 - color->c[0]);
}

void GfxDeviceGrayColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  deviceN->c[3] = clip01(gfxColorComp1 - color->c[0]);
}

void GfxDeviceGrayColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
}

//------------------------------------------------------------------------
// GfxCalGrayColorSpace
//------------------------------------------------------------------------

GfxCalGrayColorSpace::GfxCalGrayColorSpace() {
  whiteX = whiteY = whiteZ = 1;
  blackX = blackY = blackZ = 0;
  gamma = 1;
}

GfxCalGrayColorSpace::~GfxCalGrayColorSpace() {
#ifdef USE_CMS
  if (transform != nullptr) {
    if (transform->unref() == 0) delete transform;
  }
#endif
}

GfxColorSpace *GfxCalGrayColorSpace::copy() {
  GfxCalGrayColorSpace *cs;

  cs = new GfxCalGrayColorSpace();
  cs->whiteX = whiteX;
  cs->whiteY = whiteY;
  cs->whiteZ = whiteZ;
  cs->blackX = blackX;
  cs->blackY = blackY;
  cs->blackZ = blackZ;
  cs->gamma = gamma;
  cs->kr = kr;
  cs->kg = kg;
  cs->kb = kb;
#ifdef USE_CMS
  cs->transform = transform;
  if (transform != nullptr) transform->ref();
#endif
  return cs;
}

// This is the inverse of MatrixLMN in Example 4.10 from the PostScript
// Language Reference, Third Edition.
static const double xyzrgb[3][3] = {
  {  3.240449, -1.537136, -0.498531 },
  { -0.969265,  1.876011,  0.041556 },
  {  0.055643, -0.204026,  1.057229 }
};

GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr, GfxState *state) {
  GfxCalGrayColorSpace *cs;
  Object obj1, obj2;

  obj1 = arr->get(1);
  if (!obj1.isDict()) {
    error(errSyntaxWarning, -1, "Bad CalGray color space");
    return nullptr;
  }
  cs = new GfxCalGrayColorSpace();
  obj2 = obj1.dictLookup("WhitePoint");
  if (obj2.isArray() && obj2.arrayGetLength() == 3) {
    Object obj3 = obj2.arrayGet(0);
    if (likely(obj3.isNum()))
      cs->whiteX = obj3.getNum();
    obj3 = obj2.arrayGet(1);
    if (likely(obj3.isNum()))
      cs->whiteY = obj3.getNum();
    obj3 = obj2.arrayGet(2);
    if (likely(obj3.isNum()))
      cs->whiteZ = obj3.getNum();
  }
  obj2 = obj1.dictLookup("BlackPoint");
  if (obj2.isArray() && obj2.arrayGetLength() == 3) {
    Object obj3 = obj2.arrayGet(0);
    if (likely(obj3.isNum()))
      cs->blackX = obj3.getNum();
    obj3 = obj2.arrayGet(1);
    if (likely(obj3.isNum()))
      cs->blackY = obj3.getNum();
    obj3 = obj2.arrayGet(2);
    if (likely(obj3.isNum()))
      cs->blackZ = obj3.getNum();
  }
  obj2 = obj1.dictLookup("Gamma");
  if (obj2.isNum()) {
    cs->gamma = obj2.getNum();
  }

  cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
		xyzrgb[0][1] * cs->whiteY +
		xyzrgb[0][2] * cs->whiteZ);
  cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
		xyzrgb[1][1] * cs->whiteY +
		xyzrgb[1][2] * cs->whiteZ);
  cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
		xyzrgb[2][1] * cs->whiteY +
		xyzrgb[2][2] * cs->whiteZ);
#ifdef USE_CMS
  cs->transform = (state != nullptr) ? state->getXYZ2DisplayTransform() : XYZ2DisplayTransform;
  if (cs->transform != nullptr) cs->transform->ref();
#endif
  return cs;
}

// convert CalGray to media XYZ color space
// (not multiply by the white point)
void GfxCalGrayColorSpace::getXYZ(const GfxColor *color,
  double *pX, double *pY, double *pZ) const {
  const double A = colToDbl(color->c[0]);
  const double xyzColor = pow(A,gamma);
  *pX = xyzColor;
  *pY = xyzColor;
  *pZ = xyzColor;
}

void GfxCalGrayColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  GfxRGB rgb;

#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_GRAY) {
    unsigned char out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    double X, Y, Z;
    
    getXYZ(color,&X,&Y,&Z);
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    transform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
    return;
  }
#endif
  getRGB(color, &rgb);
  *gray = clip01((GfxColorComp)(0.299 * rgb.r +
				0.587 * rgb.g +
				0.114 * rgb.b + 0.5));
}

void GfxCalGrayColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  double X, Y, Z;
  double r, g, b;

  getXYZ(color,&X,&Y,&Z);
#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_RGB) {
    unsigned char out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    transform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
    return;
  }
#endif
  X *= whiteX;
  Y *= whiteY;
  Z *= whiteZ;
  // convert XYZ to RGB, including gamut mapping and gamma correction
  r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
  g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
  b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
  rgb->r = dblToCol(sqrt(clip01(r * kr)));
  rgb->g = dblToCol(sqrt(clip01(g * kg)));
  rgb->b = dblToCol(sqrt(clip01(b * kb)));
}

void GfxCalGrayColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  GfxRGB rgb;
  GfxColorComp c, m, y, k;

#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_CMYK) {
    double in[gfxColorMaxComps];
    unsigned char out[gfxColorMaxComps];
    double X, Y, Z;
    
    getXYZ(color,&X,&Y,&Z);
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    
    transform->doTransform(in,out,1);
    cmyk->c = byteToCol(out[0]);
    cmyk->m = byteToCol(out[1]);
    cmyk->y = byteToCol(out[2]);
    cmyk->k = byteToCol(out[3]);
    return;
  }
#endif
  getRGB(color, &rgb);
  c = clip01(gfxColorComp1 - rgb.r);
  m = clip01(gfxColorComp1 - rgb.g);
  y = clip01(gfxColorComp1 - rgb.b);
  k = c;
  if (m < k) {
    k = m;
  }
  if (y < k) {
    k = y;
  }
  cmyk->c = c - k;
  cmyk->m = m - k;
  cmyk->y = y - k;
  cmyk->k = k;
}

void GfxCalGrayColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  GfxCMYK cmyk;
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  getCMYK(color, &cmyk);
  deviceN->c[0] = cmyk.c;
  deviceN->c[1] = cmyk.m;
  deviceN->c[2] = cmyk.y;
  deviceN->c[3] = cmyk.k;
}

void GfxCalGrayColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
}

//------------------------------------------------------------------------
// GfxDeviceRGBColorSpace
//------------------------------------------------------------------------

GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() {
}

GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() {
}

GfxColorSpace *GfxDeviceRGBColorSpace::copy() {
  return new GfxDeviceRGBColorSpace();
}

void GfxDeviceRGBColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  *gray = clip01((GfxColorComp)(0.3 * color->c[0] +
		 0.59 * color->c[1] +
		 0.11 * color->c[2] + 0.5));
}

void GfxDeviceRGBColorSpace::getGrayLine(unsigned char *in, unsigned char *out, int length) {
  int i;

  for (i = 0; i < length; i++) {
    out[i] = 
      (in[i * 3 + 0] * 19595 + 
       in[i * 3 + 1] * 38469 + 
       in[i * 3 + 2] * 7472) / 65536;
  }
}

void GfxDeviceRGBColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  rgb->r = clip01(color->c[0]);
  rgb->g = clip01(color->c[1]);
  rgb->b = clip01(color->c[2]);
}

void GfxDeviceRGBColorSpace::getRGBLine(unsigned char *in, unsigned int *out,
					int length) {
  unsigned char *p;
  int i;

  for (i = 0, p = in; i < length; i++, p += 3)
    out[i] = (p[0] << 16) | (p[1] << 8) | (p[2] << 0);
}

void GfxDeviceRGBColorSpace::getRGBLine(unsigned char *in, unsigned char *out, int length) {
  for (int i = 0; i < length; i++) {
    *out++ = *in++;
    *out++ = *in++;
    *out++ = *in++;
  }
}

void GfxDeviceRGBColorSpace::getRGBXLine(unsigned char *in, unsigned char *out, int length) {
  for (int i = 0; i < length; i++) {
    *out++ = *in++;
    *out++ = *in++;
    *out++ = *in++;
    *out++ = 255;
  }
}

void GfxDeviceRGBColorSpace::getCMYKLine(unsigned char *in, unsigned char *out, int length) {
  GfxColorComp c, m, y, k;

  for (int i = 0; i < length; i++) {
    c = byteToCol(255 - *in++);
    m = byteToCol(255 - *in++);
    y = byteToCol(255 - *in++);
    k = c;
    if (m < k) {
      k = m;
    }
    if (y < k) {
      k = y;
    }
    *out++ = colToByte(c - k);
    *out++ = colToByte(m - k);
    *out++ = colToByte(y - k);
    *out++ = colToByte(k);
  }
}

void GfxDeviceRGBColorSpace::getDeviceNLine(unsigned char *in, unsigned char *out, int length) {
  GfxColorComp c, m, y, k;

  for (int i = 0; i < length; i++) {
    for (int j = 0; j < SPOT_NCOMPS+4; j++) 
      out[j] = 0;
    c = byteToCol(255 - *in++);
    m = byteToCol(255 - *in++);
    y = byteToCol(255 - *in++);
    k = c;
    if (m < k) {
      k = m;
    }
    if (y < k) {
      k = y;
    }
    out[0] = colToByte(c - k);
    out[1] = colToByte(m - k);
    out[2] = colToByte(y - k);
    out[3] = colToByte(k);
    out += (SPOT_NCOMPS+4);
  }
}

void GfxDeviceRGBColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  GfxColorComp c, m, y, k;

  c = clip01(gfxColorComp1 - color->c[0]);
  m = clip01(gfxColorComp1 - color->c[1]);
  y = clip01(gfxColorComp1 - color->c[2]);
  k = c;
  if (m < k) {
    k = m;
  }
  if (y < k) {
    k = y;
  }
  cmyk->c = c - k;
  cmyk->m = m - k;
  cmyk->y = y - k;
  cmyk->k = k;
}

void GfxDeviceRGBColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  GfxCMYK cmyk;
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  getCMYK(color, &cmyk);
  deviceN->c[0] = cmyk.c;
  deviceN->c[1] = cmyk.m;
  deviceN->c[2] = cmyk.y;
  deviceN->c[3] = cmyk.k;
}

void GfxDeviceRGBColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
  color->c[1] = 0;
  color->c[2] = 0;
}

//------------------------------------------------------------------------
// GfxCalRGBColorSpace
//------------------------------------------------------------------------

GfxCalRGBColorSpace::GfxCalRGBColorSpace() {
  whiteX = whiteY = whiteZ = 1;
  blackX = blackY = blackZ = 0;
  gammaR = gammaG = gammaB = 1;
  mat[0] = 1; mat[1] = 0; mat[2] = 0;
  mat[3] = 0; mat[4] = 1; mat[5] = 0;
  mat[6] = 0; mat[7] = 0; mat[8] = 1;
}

GfxCalRGBColorSpace::~GfxCalRGBColorSpace() {
#ifdef USE_CMS
  if (transform != nullptr) {
    if (transform->unref() == 0) delete transform;
  }
#endif
}

GfxColorSpace *GfxCalRGBColorSpace::copy() {
  GfxCalRGBColorSpace *cs;
  int i;

  cs = new GfxCalRGBColorSpace();
  cs->whiteX = whiteX;
  cs->whiteY = whiteY;
  cs->whiteZ = whiteZ;
  cs->blackX = blackX;
  cs->blackY = blackY;
  cs->blackZ = blackZ;
  cs->gammaR = gammaR;
  cs->gammaG = gammaG;
  cs->gammaB = gammaB;
  cs->kr = kr;
  cs->kg = kg;
  cs->kb = kb;
  for (i = 0; i < 9; ++i) {
    cs->mat[i] = mat[i];
  }
#ifdef USE_CMS
  cs->transform = transform;
  if (transform != nullptr) transform->ref();
#endif
  return cs;
}

GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr, GfxState *state) {
  GfxCalRGBColorSpace *cs;
  Object obj1, obj2;
  int i;

  obj1 = arr->get(1);
  if (!obj1.isDict()) {
    error(errSyntaxWarning, -1, "Bad CalRGB color space");
    return nullptr;
  }
  cs = new GfxCalRGBColorSpace();
  obj2 = obj1.dictLookup("WhitePoint");
  if (obj2.isArray() && obj2.arrayGetLength() == 3) {
    Object obj3 = obj2.arrayGet(0);
    if (likely(obj3.isNum()))
      cs->whiteX = obj3.getNum();
    obj3 = obj2.arrayGet(1);
    if (likely(obj3.isNum()))
      cs->whiteY = obj3.getNum();
    obj3 = obj2.arrayGet(2);
    if (likely(obj3.isNum()))
      cs->whiteZ = obj3.getNum();
  }
  obj2 = obj1.dictLookup("BlackPoint");
  if (obj2.isArray() && obj2.arrayGetLength() == 3) {
    Object obj3 = obj2.arrayGet(0);
    if (likely(obj3.isNum()))
      cs->blackX = obj3.getNum();
    obj3 = obj2.arrayGet(1);
    if (likely(obj3.isNum()))
      cs->blackY = obj3.getNum();
    obj3 = obj2.arrayGet(2);
    if (likely(obj3.isNum()))
      cs->blackZ = obj3.getNum();
  }
  obj2 = obj1.dictLookup("Gamma");
  if (obj2.isArray() && obj2.arrayGetLength() == 3) {
    Object obj3 = obj2.arrayGet(0);
    if (likely(obj3.isNum()))
      cs->gammaR = obj3.getNum();
    obj3 = obj2.arrayGet(1);
    if (likely(obj3.isNum()))
      cs->gammaG = obj3.getNum();
    obj3 = obj2.arrayGet(2);
    if (likely(obj3.isNum()))
      cs->gammaB = obj3.getNum();
  }
  obj2 = obj1.dictLookup("Matrix");
  if (obj2.isArray() && obj2.arrayGetLength() == 9) {
    for (i = 0; i < 9; ++i) {
      Object obj3 = obj2.arrayGet(i);
      if (likely(obj3.isNum()))
        cs->mat[i] = obj3.getNum();
    }
  }

  cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
		xyzrgb[0][1] * cs->whiteY +
		xyzrgb[0][2] * cs->whiteZ);
  cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
		xyzrgb[1][1] * cs->whiteY +
		xyzrgb[1][2] * cs->whiteZ);
  cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
		xyzrgb[2][1] * cs->whiteY +
		xyzrgb[2][2] * cs->whiteZ);

#ifdef USE_CMS
  cs->transform = (state != nullptr) ? state->getXYZ2DisplayTransform() : XYZ2DisplayTransform;
  if (cs->transform != nullptr) cs->transform->ref();
#endif
  return cs;
}

// convert CalRGB to XYZ color space
void GfxCalRGBColorSpace::getXYZ(const GfxColor *color,
  double *pX, double *pY, double *pZ) const {
  double A, B, C;

  A = pow(colToDbl(color->c[0]), gammaR);
  B = pow(colToDbl(color->c[1]), gammaG);
  C = pow(colToDbl(color->c[2]), gammaB);
  *pX = mat[0] * A + mat[3] * B + mat[6] * C;
  *pY = mat[1] * A + mat[4] * B + mat[7] * C;
  *pZ = mat[2] * A + mat[5] * B + mat[8] * C;
}

void GfxCalRGBColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  GfxRGB rgb;

#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_GRAY) {
    unsigned char out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    double X, Y, Z;
    
    getXYZ(color,&X,&Y,&Z);
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    transform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
    return;
  }
#endif
  getRGB(color, &rgb);
  *gray = clip01((GfxColorComp)(0.299 * rgb.r +
				0.587 * rgb.g +
				0.114 * rgb.b + 0.5));
}

void GfxCalRGBColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  double X, Y, Z;
  double r, g, b;

  getXYZ(color,&X,&Y,&Z);
#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_RGB) {
    unsigned char out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    in[0] = clip01(X/whiteX);
    in[1] = clip01(Y/whiteY);
    in[2] = clip01(Z/whiteZ);
    transform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
    return;
  }
#endif
  // convert XYZ to RGB, including gamut mapping and gamma correction
  r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
  g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
  b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
  rgb->r = dblToCol(sqrt(clip01(r)));
  rgb->g = dblToCol(sqrt(clip01(g)));
  rgb->b = dblToCol(sqrt(clip01(b)));
}

void GfxCalRGBColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  GfxRGB rgb;
  GfxColorComp c, m, y, k;

#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_CMYK) {
    double in[gfxColorMaxComps];
    unsigned char out[gfxColorMaxComps];
    double X, Y, Z;
    
    getXYZ(color,&X,&Y,&Z);
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    transform->doTransform(in,out,1);
    cmyk->c = byteToCol(out[0]);
    cmyk->m = byteToCol(out[1]);
    cmyk->y = byteToCol(out[2]);
    cmyk->k = byteToCol(out[3]);
    return;
  }
#endif
  getRGB(color, &rgb);
  c = clip01(gfxColorComp1 - rgb.r);
  m = clip01(gfxColorComp1 - rgb.g);
  y = clip01(gfxColorComp1 - rgb.b);
  k = c;
  if (m < k) {
    k = m;
  }
  if (y < k) {
    k = y;
  }
  cmyk->c = c - k;
  cmyk->m = m - k;
  cmyk->y = y - k;
  cmyk->k = k;
}

void GfxCalRGBColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  GfxCMYK cmyk;
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  getCMYK(color, &cmyk);
  deviceN->c[0] = cmyk.c;
  deviceN->c[1] = cmyk.m;
  deviceN->c[2] = cmyk.y;
  deviceN->c[3] = cmyk.k;
}

void GfxCalRGBColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
  color->c[1] = 0;
  color->c[2] = 0;
}

//------------------------------------------------------------------------
// GfxDeviceCMYKColorSpace
//------------------------------------------------------------------------

GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() {
}

GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() {
}

GfxColorSpace *GfxDeviceCMYKColorSpace::copy() {
  return new GfxDeviceCMYKColorSpace();
}

void GfxDeviceCMYKColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  *gray = clip01((GfxColorComp)(gfxColorComp1 - color->c[3]
				- 0.3  * color->c[0]
				- 0.59 * color->c[1]
				- 0.11 * color->c[2] + 0.5));
}

void GfxDeviceCMYKColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  double c, m, y, k, c1, m1, y1, k1, r, g, b;
    
  c = colToDbl(color->c[0]);
  m = colToDbl(color->c[1]);
  y = colToDbl(color->c[2]);
  k = colToDbl(color->c[3]);
  c1 = 1 - c;
  m1 = 1 - m;
  y1 = 1 - y;
  k1 = 1 - k;
  cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
  rgb->r = clip01(dblToCol(r));
  rgb->g = clip01(dblToCol(g));
  rgb->b = clip01(dblToCol(b));
}

static inline void GfxDeviceCMYKColorSpacegetRGBLineHelper(unsigned char *&in, double &r, double &g, double &b)
{
  double c, m, y, k, c1, m1, y1, k1;
  
  c = byteToDbl(*in++);
  m = byteToDbl(*in++);
  y = byteToDbl(*in++);
  k = byteToDbl(*in++);
  c1 = 1 - c;
  m1 = 1 - m;
  y1 = 1 - y;
  k1 = 1 - k;
  cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
}

void GfxDeviceCMYKColorSpace::getRGBLine(unsigned char *in, unsigned int *out, int length)
{
  double r, g, b;
  for (int i = 0; i < length; i++) {
    GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
    *out++ = (dblToByte(clip01(r)) << 16) | (dblToByte(clip01(g)) << 8) | dblToByte(clip01(b));
  }
}

void GfxDeviceCMYKColorSpace::getRGBLine(unsigned char *in, unsigned char *out, int length)
{
  double r, g, b;
  
  for (int i = 0; i < length; i++) {
    GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
    *out++ = dblToByte(clip01(r));
    *out++ = dblToByte(clip01(g));
    *out++ = dblToByte(clip01(b));
  }
}

void GfxDeviceCMYKColorSpace::getRGBXLine(unsigned char *in, unsigned char *out, int length)
{
  double r, g, b;
  
  for (int i = 0; i < length; i++) {
    GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
    *out++ = dblToByte(clip01(r));
    *out++ = dblToByte(clip01(g));
    *out++ = dblToByte(clip01(b));
    *out++ = 255;
  }
}

void GfxDeviceCMYKColorSpace::getCMYKLine(unsigned char *in, unsigned char *out, int length)
{
  for (int i = 0; i < length; i++) {
    *out++ = *in++;
    *out++ = *in++;
    *out++ = *in++;
    *out++ = *in++;
  }
}

void GfxDeviceCMYKColorSpace::getDeviceNLine(unsigned char *in, unsigned char *out, int length)
{
  for (int i = 0; i < length; i++) {
    for (int j = 0; j < SPOT_NCOMPS+4; j++)
      out[j] = 0;
    out[0] = *in++;
    out[1] = *in++;
    out[2] = *in++;
    out[3] = *in++;
    out += (SPOT_NCOMPS+4);
  }
}

void GfxDeviceCMYKColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  cmyk->c = clip01(color->c[0]);
  cmyk->m = clip01(color->c[1]);
  cmyk->y = clip01(color->c[2]);
  cmyk->k = clip01(color->c[3]);
}

void GfxDeviceCMYKColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  deviceN->c[0] = clip01(color->c[0]);
  deviceN->c[1] = clip01(color->c[1]);
  deviceN->c[2] = clip01(color->c[2]);
  deviceN->c[3] = clip01(color->c[3]);
}

void GfxDeviceCMYKColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
  color->c[1] = 0;
  color->c[2] = 0;
  color->c[3] = gfxColorComp1;
}

//------------------------------------------------------------------------
// GfxLabColorSpace
//------------------------------------------------------------------------

GfxLabColorSpace::GfxLabColorSpace() {
  whiteX = whiteY = whiteZ = 1;
  blackX = blackY = blackZ = 0;
  aMin = bMin = -100;
  aMax = bMax = 100;
}

GfxLabColorSpace::~GfxLabColorSpace() {
#ifdef USE_CMS
  if (transform != nullptr) {
    if (transform->unref() == 0) delete transform;
  }
#endif
}

GfxColorSpace *GfxLabColorSpace::copy() {
  GfxLabColorSpace *cs;

  cs = new GfxLabColorSpace();
  cs->whiteX = whiteX;
  cs->whiteY = whiteY;
  cs->whiteZ = whiteZ;
  cs->blackX = blackX;
  cs->blackY = blackY;
  cs->blackZ = blackZ;
  cs->aMin = aMin;
  cs->aMax = aMax;
  cs->bMin = bMin;
  cs->bMax = bMax;
  cs->kr = kr;
  cs->kg = kg;
  cs->kb = kb;
#ifdef USE_CMS
  cs->transform = transform;
  if (transform != nullptr) transform->ref();
#endif
  return cs;
}

GfxColorSpace *GfxLabColorSpace::parse(Array *arr, GfxState *state) {
  GfxLabColorSpace *cs;
  Object obj1, obj2;

  obj1 = arr->get(1);
  if (!obj1.isDict()) {
    error(errSyntaxWarning, -1, "Bad Lab color space");
    return nullptr;
  }
  cs = new GfxLabColorSpace();
  bool ok = true;
  obj2 = obj1.dictLookup("WhitePoint");
  if (obj2.isArray() && obj2.arrayGetLength() == 3) {
    Object obj3 = obj2.arrayGet(0);
    cs->whiteX = obj3.getNum(&ok);
    obj3 = obj2.arrayGet(1);
    cs->whiteY = obj3.getNum(&ok);
    obj3 = obj2.arrayGet(2);
    cs->whiteZ = obj3.getNum(&ok);
  }
  obj2 = obj1.dictLookup("BlackPoint");
  if (obj2.isArray() && obj2.arrayGetLength() == 3) {
    Object obj3 = obj2.arrayGet(0);
    cs->blackX = obj3.getNum(&ok);
    obj3 = obj2.arrayGet(1);
    cs->blackY = obj3.getNum(&ok);
    obj3 = obj2.arrayGet(2);
    cs->blackZ = obj3.getNum(&ok);
  }
  obj2 = obj1.dictLookup("Range");
  if (obj2.isArray() && obj2.arrayGetLength() == 4) {
    Object obj3 = obj2.arrayGet(0);
    cs->aMin = obj3.getNum(&ok);
    obj3 = obj2.arrayGet(1);
    cs->aMax = obj3.getNum(&ok);
    obj3 = obj2.arrayGet(2);
    cs->bMin = obj3.getNum(&ok);
    obj3 = obj2.arrayGet(3);
    cs->bMax = obj3.getNum(&ok);
  }

  if (!ok) {
      error(errSyntaxWarning, -1, "Bad Lab color space");
#ifdef USE_CMS
      cs->transform = nullptr;
#endif
      delete cs;
      return nullptr;
  }

  cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
		xyzrgb[0][1] * cs->whiteY +
		xyzrgb[0][2] * cs->whiteZ);
  cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
		xyzrgb[1][1] * cs->whiteY +
		xyzrgb[1][2] * cs->whiteZ);
  cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
		xyzrgb[2][1] * cs->whiteY +
		xyzrgb[2][2] * cs->whiteZ);

#ifdef USE_CMS
  cs->transform = (state != nullptr) ? state->getXYZ2DisplayTransform() : XYZ2DisplayTransform;
  if (cs->transform != nullptr) cs->transform->ref();
#endif
  return cs;
}

void GfxLabColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  GfxRGB rgb;

#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_GRAY) {
    unsigned char out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    getXYZ(color, &in[0], &in[1], &in[2]);
    transform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
    return;
  }
#endif
  getRGB(color, &rgb);
  *gray = clip01((GfxColorComp)(0.299 * rgb.r +
				0.587 * rgb.g +
				0.114 * rgb.b + 0.5));
}

// convert L*a*b* to media XYZ color space
// (not multiply by the white point)
void GfxLabColorSpace::getXYZ(const GfxColor *color,
  double *pX, double *pY, double *pZ) const {
  double X, Y, Z;
  double t1, t2;

  t1 = (colToDbl(color->c[0]) + 16) / 116;
  t2 = t1 + colToDbl(color->c[1]) / 500;
  if (t2 >= (6.0 / 29.0)) {
    X = t2 * t2 * t2;
  } else {
    X = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
  }
  if (t1 >= (6.0 / 29.0)) {
    Y = t1 * t1 * t1;
  } else {
    Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0));
  }
  t2 = t1 - colToDbl(color->c[2]) / 200;
  if (t2 >= (6.0 / 29.0)) {
    Z = t2 * t2 * t2;
  } else {
    Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
  }
  *pX = X;
  *pY = Y;
  *pZ = Z;
}

void GfxLabColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  double X, Y, Z;

  getXYZ(color, &X, &Y, &Z);
#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_RGB) {
    unsigned char out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    
    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    transform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
    return;
  } else if (transform != nullptr && transform->getTransformPixelType() == PT_CMYK) {
    unsigned char out[gfxColorMaxComps];
    double in[gfxColorMaxComps];
    double c, m, y, k, c1, m1, y1, k1, r, g, b;

    in[0] = clip01(X);
    in[1] = clip01(Y);
    in[2] = clip01(Z);
    transform->doTransform(in,out,1);
    c = byteToDbl(out[0]);
    m = byteToDbl(out[1]);
    y = byteToDbl(out[2]);
    k = byteToDbl(out[3]);
    c1 = 1 - c;
    m1 = 1 - m;
    y1 = 1 - y;
    k1 = 1 - k;
    cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
    rgb->r = clip01(dblToCol(r));
    rgb->g = clip01(dblToCol(g));
    rgb->b = clip01(dblToCol(b));
    return;
  }
#endif
  X *= whiteX;
  Y *= whiteY;
  Z *= whiteZ;
  // convert XYZ to RGB, including gamut mapping and gamma correction
  const double r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
  const double g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
  const double b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
  rgb->r = dblToCol(sqrt(clip01(r * kr)));
  rgb->g = dblToCol(sqrt(clip01(g * kg)));
  rgb->b = dblToCol(sqrt(clip01(b * kb)));
}

void GfxLabColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  GfxRGB rgb;
  GfxColorComp c, m, y, k;

#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_CMYK) {
    double in[gfxColorMaxComps];
    unsigned char out[gfxColorMaxComps];
    
    getXYZ(color, &in[0], &in[1], &in[2]);
    transform->doTransform(in,out,1);
    cmyk->c = byteToCol(out[0]);
    cmyk->m = byteToCol(out[1]);
    cmyk->y = byteToCol(out[2]);
    cmyk->k = byteToCol(out[3]);
    return;
  }
#endif
  getRGB(color, &rgb);
  c = clip01(gfxColorComp1 - rgb.r);
  m = clip01(gfxColorComp1 - rgb.g);
  y = clip01(gfxColorComp1 - rgb.b);
  k = c;
  if (m < k) {
    k = m;
  }
  if (y < k) {
    k = y;
  }
  cmyk->c = c - k;
  cmyk->m = m - k;
  cmyk->y = y - k;
  cmyk->k = k;
}

void GfxLabColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  GfxCMYK cmyk;
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  getCMYK(color, &cmyk);
  deviceN->c[0] = cmyk.c;
  deviceN->c[1] = cmyk.m;
  deviceN->c[2] = cmyk.y;
  deviceN->c[3] = cmyk.k;
}

void GfxLabColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
  if (aMin > 0) {
    color->c[1] = dblToCol(aMin);
  } else if (aMax < 0) {
    color->c[1] = dblToCol(aMax);
  } else {
    color->c[1] = 0;
  }
  if (bMin > 0) {
    color->c[2] = dblToCol(bMin);
  } else if (bMax < 0) {
    color->c[2] = dblToCol(bMax);
  } else {
    color->c[2] = 0;
  }
}

void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
					int maxImgPixel) {
  decodeLow[0] = 0;
  decodeRange[0] = 100;
  decodeLow[1] = aMin;
  decodeRange[1] = aMax - aMin;
  decodeLow[2] = bMin;
  decodeRange[2] = bMax - bMin;
}

//------------------------------------------------------------------------
// GfxICCBasedColorSpace
//------------------------------------------------------------------------

GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
					     Ref *iccProfileStreamA) {
  nComps = nCompsA;
  alt = altA;
  iccProfileStream = *iccProfileStreamA;
  rangeMin[0] = rangeMin[1] = rangeMin[2] = rangeMin[3] = 0;
  rangeMax[0] = rangeMax[1] = rangeMax[2] = rangeMax[3] = 1;
#ifdef USE_CMS
  transform = nullptr;
  lineTransform = nullptr;
#endif
}

GfxICCBasedColorSpace::~GfxICCBasedColorSpace() {
  delete alt;
#ifdef USE_CMS
  if (transform != nullptr) {
    if (transform->unref() == 0) delete transform;
  }
  if (lineTransform != nullptr) {
    if (lineTransform->unref() == 0) delete lineTransform;
  }
#endif
}

GfxColorSpace *GfxICCBasedColorSpace::copy() {
  GfxICCBasedColorSpace *cs;
  int i;

  cs = new GfxICCBasedColorSpace(nComps, alt->copy(), &iccProfileStream);
  for (i = 0; i < 4; ++i) {
    cs->rangeMin[i] = rangeMin[i];
    cs->rangeMax[i] = rangeMax[i];
  }
#ifdef USE_CMS
  cs->transform = transform;
  if (transform != nullptr) transform->ref();
  cs->lineTransform = lineTransform;
  if (lineTransform != nullptr) lineTransform->ref();
#endif
  return cs;
}

GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState *state, int recursion) {
  GfxICCBasedColorSpace *cs;
  Ref iccProfileStreamA;
  int nCompsA;
  GfxColorSpace *altA;
  Dict *dict;
  Object obj1, obj2, obj3;
  int i;

  if (arr->getLength() < 2) {
    error(errSyntaxError, -1, "Bad ICCBased color space");
    return nullptr;
  }
  const Object &obj1Ref = arr->getNF(1);
  if (obj1Ref.isRef()) {
    iccProfileStreamA = obj1Ref.getRef();
  } else {
    iccProfileStreamA.num = 0;
    iccProfileStreamA.gen = 0;
  }
#ifdef USE_CMS
  // check cache
  if (out && iccProfileStreamA.num > 0) {
    if (auto *item = out->getIccColorSpaceCache()->lookup(iccProfileStreamA)) {
      cs = static_cast<GfxICCBasedColorSpace*>(item->copy());
      int transformIntent = cs->getIntent();
      int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
      if (state != nullptr) {
        const char *intent = state->getRenderingIntent();
        if (intent != nullptr) {
          if (strcmp(intent, "AbsoluteColorimetric") == 0) {
            cmsIntent = INTENT_ABSOLUTE_COLORIMETRIC;
          } else if (strcmp(intent, "Saturation") == 0) {
            cmsIntent = INTENT_SATURATION;
          } else if (strcmp(intent, "Perceptual") == 0) {
            cmsIntent = INTENT_PERCEPTUAL;
          }
        }
      }
      if (transformIntent == cmsIntent) {
        return cs;
      }
      delete cs;
    }
  }
#endif
  obj1 = arr->get(1);
  if (!obj1.isStream()) {
    error(errSyntaxWarning, -1, "Bad ICCBased color space (stream)");
    return nullptr;
  }
  dict = obj1.streamGetDict();
  obj2 = dict->lookup("N");
  if (!obj2.isInt()) {
    error(errSyntaxWarning, -1, "Bad ICCBased color space (N)");
    return nullptr;
  }
  nCompsA = obj2.getInt();
  if (nCompsA > 4) {
    error(errSyntaxError, -1,
	  "ICCBased color space with too many ({0:d} > 4) components",
	  nCompsA);
    nCompsA = 4;
  }
  obj2 = dict->lookup("Alternate");
  if (obj2.isNull() ||
      !(altA = GfxColorSpace::parse(nullptr, &obj2, out, state, recursion + 1))) {
    switch (nCompsA) {
    case 1:
      altA = new GfxDeviceGrayColorSpace();
      break;
    case 3:
      altA = new GfxDeviceRGBColorSpace();
      break;
    case 4:
      altA = new GfxDeviceCMYKColorSpace();
      break;
    default:
      error(errSyntaxWarning, -1, "Bad ICCBased color space - invalid N");
      return nullptr;
    }
  }
  if (altA->getNComps() != nCompsA) {
      error(errSyntaxWarning, -1, "Bad ICCBased color space - N doesn't match alt color space");
      delete altA;
      return nullptr;
  }
  cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA);
  obj2 = dict->lookup("Range");
  if (obj2.isArray() && obj2.arrayGetLength() == 2 * nCompsA) {
    Object obj4;
    for (i = 0; i < nCompsA; ++i) {
      obj3 = obj2.arrayGet(2*i);
      obj4 = obj2.arrayGet(2*i+1);
      if (obj3.isNum() && obj4.isNum()) {
        cs->rangeMin[i] = obj3.getNum();
        cs->rangeMax[i] = obj4.getNum();
      }
    }
  }

#ifdef USE_CMS
  obj1 = arr->get(1);
  unsigned char *profBuf;
  Stream *iccStream = obj1.getStream();
  int length = 0;

  profBuf = iccStream->toUnsignedChars(&length, 65536, 65536);
  cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,length);
  gfree(profBuf);
  if (hp == nullptr) {
    error(errSyntaxWarning, -1, "read ICCBased color space profile error");
  } else {
    cmsHPROFILE dhp = (state != nullptr && state->getDisplayProfile() != nullptr) ? state->getDisplayProfile() : displayProfile;
    if (dhp == nullptr) {
      if (unlikely(RGBProfile == nullptr)) {
        GfxColorSpace::setupColorProfiles();
      }
      dhp = RGBProfile;
    }
    unsigned int cst = getCMSColorSpaceType(cmsGetColorSpace(hp));
    unsigned int dNChannels = getCMSNChannels(cmsGetColorSpace(dhp));
    unsigned int dcst = getCMSColorSpaceType(cmsGetColorSpace(dhp));
    cmsHTRANSFORM transform;

    int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
    if (state != nullptr) {
      const char *intent = state->getRenderingIntent();
      if (intent != nullptr) {
        if (strcmp(intent, "AbsoluteColorimetric") == 0) {
          cmsIntent = INTENT_ABSOLUTE_COLORIMETRIC;
        } else if (strcmp(intent, "Saturation") == 0) {
          cmsIntent = INTENT_SATURATION;
        } else if (strcmp(intent, "Perceptual") == 0) {
          cmsIntent = INTENT_PERCEPTUAL;
        }
      }
    }
    if ((transform = cmsCreateTransform(hp,
	   COLORSPACE_SH(cst) |CHANNELS_SH(nCompsA) | BYTES_SH(1),
	   dhp,
	   COLORSPACE_SH(dcst) |
	     CHANNELS_SH(dNChannels) | BYTES_SH(1),
	   cmsIntent, LCMS_FLAGS)) == nullptr) {
      error(errSyntaxWarning, -1, "Can't create transform");
      cs->transform = nullptr;
    } else {
      cs->transform = new GfxColorTransform(transform, cmsIntent, cst, dcst);
    }
    if (dcst == PT_RGB || dcst == PT_CMYK) {
       // create line transform only when the display is RGB type color space 
      if ((transform = cmsCreateTransform(hp,
	    CHANNELS_SH(nCompsA) | BYTES_SH(1),dhp,
	    (dcst == PT_RGB) ? TYPE_RGB_8 : TYPE_CMYK_8, cmsIntent, LCMS_FLAGS)) == nullptr) {
	error(errSyntaxWarning, -1, "Can't create transform");
	cs->lineTransform = nullptr;
      } else {
	cs->lineTransform = new GfxColorTransform(transform, cmsIntent, cst, dcst);
      }
    }
    cmsCloseProfile(hp);
  }
  // put this colorSpace into cache
  if (out && iccProfileStreamA.num > 0) {
    out->getIccColorSpaceCache()->put(iccProfileStreamA, static_cast<GfxICCBasedColorSpace*>(cs->copy()));
  }
#endif
  return cs;
}

void GfxICCBasedColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_GRAY) {
    unsigned char in[gfxColorMaxComps];
    unsigned char out[gfxColorMaxComps];
    
    if (nComps == 3 && transform->getInputPixelType() == PT_Lab) {
      in[0] = colToByte(dblToCol(colToDbl(color->c[0]) / 100.0));
      in[1] = colToByte(dblToCol((colToDbl(color->c[1]) + 128.0) / 255.0));
      in[2] = colToByte(dblToCol((colToDbl(color->c[2]) + 128.0) / 255.0));
    } else {
      for (int i = 0;i < nComps;i++) {
	in[i] = colToByte(color->c[i]);
      }
    }
    if (nComps <= 4) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
      if (it != cmsCache.end()) {
        unsigned int value = it->second;
        *gray = byteToCol(value & 0xff);
        return;
      }
    }    
    transform->doTransform(in,out,1);
    *gray = byteToCol(out[0]);
    if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      unsigned int value = out[0];
      cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
    }
  } else {
    GfxRGB rgb;
    getRGB(color,&rgb);
    *gray = clip01((GfxColorComp)(0.3 * rgb.r +
		   0.59 * rgb.g +
		   0.11 * rgb.b + 0.5));
  }
#else
  alt->getGray(color, gray);
#endif
}

void GfxICCBasedColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_RGB) {
    unsigned char in[gfxColorMaxComps];
    unsigned char out[gfxColorMaxComps];
    
    if (nComps == 3 && transform->getInputPixelType() == PT_Lab) {
      in[0] = colToByte(dblToCol(colToDbl(color->c[0]) / 100.0));
      in[1] = colToByte(dblToCol((colToDbl(color->c[1]) + 128.0) / 255.0));
      in[2] = colToByte(dblToCol((colToDbl(color->c[2]) + 128.0) / 255.0));
    } else {
      for (int i = 0;i < nComps;i++) {
	in[i] = colToByte(color->c[i]);
      }
    }
    if (nComps <= 4) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
      if (it != cmsCache.end()) {
        unsigned int value = it->second;
        rgb->r = byteToCol(value >> 16);
        rgb->g = byteToCol((value >> 8) & 0xff);
        rgb->b = byteToCol(value & 0xff);
        return;
      }
    }    
    transform->doTransform(in,out,1);
    rgb->r = byteToCol(out[0]);
    rgb->g = byteToCol(out[1]);
    rgb->b = byteToCol(out[2]);
    if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      unsigned int value = (out[0] << 16) + (out[1] << 8) + out[2];
      cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
    }
  } else if (transform != nullptr && transform->getTransformPixelType() == PT_CMYK) {
    unsigned char in[gfxColorMaxComps];
    unsigned char out[gfxColorMaxComps];
    double c, m, y, k, c1, m1, y1, k1, r, g, b;

    if (nComps == 3 && transform->getInputPixelType() == PT_Lab) {
      in[0] = colToByte(dblToCol(colToDbl(color->c[0]) / 100.0));
      in[1] = colToByte(dblToCol((colToDbl(color->c[1]) + 128.0) / 255.0));
      in[2] = colToByte(dblToCol((colToDbl(color->c[2]) + 128.0) / 255.0));
    } else {
      for (int i = 0;i < nComps;i++) {
	in[i] = colToByte(color->c[i]);
      }
    }
    if (nComps <= 4) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
      if (it != cmsCache.end()) {
        unsigned int value = it->second;
        rgb->r = byteToCol(value >> 16);
        rgb->g = byteToCol((value >> 8) & 0xff);
        rgb->b = byteToCol(value & 0xff);
        return;
      }
    }    
    transform->doTransform(in,out,1);
    c = byteToDbl(out[0]);
    m = byteToDbl(out[1]);
    y = byteToDbl(out[2]);
    k = byteToDbl(out[3]);
    c1 = 1 - c;
    m1 = 1 - m;
    y1 = 1 - y;
    k1 = 1 - k;
    cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
    rgb->r = clip01(dblToCol(r));
    rgb->g = clip01(dblToCol(g));
    rgb->b = clip01(dblToCol(b));
    if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      unsigned int value = (dblToByte(r) << 16) + (dblToByte(g) << 8) + dblToByte(b);
      cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
    }
  } else {
    alt->getRGB(color, rgb);
  }
#else
  alt->getRGB(color, rgb);
#endif
}

void GfxICCBasedColorSpace::getRGBLine(unsigned char *in, unsigned int *out,
				       int length) {
#ifdef USE_CMS
  if (lineTransform != nullptr && lineTransform->getTransformPixelType() == PT_RGB) {
    unsigned char* tmp = (unsigned char *)gmallocn(3 * length, sizeof(unsigned char));
    lineTransform->doTransform(in, tmp, length);
    for (int i = 0; i < length; ++i) {
        unsigned char *current = tmp + (i * 3);
        out[i] = (current[0] << 16) | (current[1] << 8) | current[2];
    }
    gfree(tmp);
  } else {
    alt->getRGBLine(in, out, length);
  }
#else
  alt->getRGBLine(in, out, length);
#endif
}

void GfxICCBasedColorSpace::getRGBLine(unsigned char *in, unsigned char *out, int length) {
#ifdef USE_CMS
  if (lineTransform != nullptr && lineTransform->getTransformPixelType() == PT_RGB) {
    unsigned char* tmp = (unsigned char *)gmallocn(3 * length, sizeof(unsigned char));
    lineTransform->doTransform(in, tmp, length);
    unsigned char *current = tmp;
    for (int i = 0; i < length; ++i) {
        *out++ = *current++;
        *out++ = *current++;
        *out++ = *current++;
    }
    gfree(tmp);
  } else if (lineTransform != nullptr && lineTransform->getTransformPixelType() == PT_CMYK) {
    unsigned char* tmp = (unsigned char *)gmallocn(4 * length, sizeof(unsigned char));
    lineTransform->doTransform(in, tmp, length);
    unsigned char *current = tmp;
    double c, m, y, k, c1, m1, y1, k1, r, g, b;
    for (int i = 0; i < length; ++i) {
      c = byteToDbl(*current++);
      m = byteToDbl(*current++);
      y = byteToDbl(*current++);
      k = byteToDbl(*current++);
      c1 = 1 - c;
      m1 = 1 - m;
      y1 = 1 - y;
      k1 = 1 - k;
      cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
      *out++ = dblToByte(r);
      *out++ = dblToByte(g);
      *out++ = dblToByte(b);
    }
    gfree(tmp);
  } else {
    alt->getRGBLine(in, out, length);
  }
#else
  alt->getRGBLine(in, out, length);
#endif
}

void GfxICCBasedColorSpace::getRGBXLine(unsigned char *in, unsigned char *out, int length) {
#ifdef USE_CMS
  if (lineTransform != nullptr && lineTransform->getTransformPixelType() == PT_RGB) {
    unsigned char* tmp = (unsigned char *)gmallocn(3 * length, sizeof(unsigned char));
    lineTransform->doTransform(in, tmp, length);
    unsigned char *current = tmp;
    for (int i = 0; i < length; ++i) {
        *out++ = *current++;
        *out++ = *current++;
        *out++ = *current++;
        *out++ = 255;
    }
    gfree(tmp);
  } else {
    alt->getRGBXLine(in, out, length);
  }
#else
  alt->getRGBXLine(in, out, length);
#endif
}

void GfxICCBasedColorSpace::getCMYKLine(unsigned char *in, unsigned char *out, int length) {
#ifdef USE_CMS
  if (lineTransform != nullptr && lineTransform->getTransformPixelType() == PT_CMYK) {
    transform->doTransform(in,out,length);
  } else if (lineTransform != nullptr && nComps != 4) {
    GfxColorComp c, m, y, k;
    unsigned char* tmp = (unsigned char *)gmallocn(3 * length, sizeof(unsigned char));
    getRGBLine(in, tmp, length);
    unsigned char *p = tmp;
    for (int i = 0; i < length; i++) {
      c = byteToCol(255 - *p++);
      m = byteToCol(255 - *p++);
      y = byteToCol(255 - *p++);
      k = c;
      if (m < k) {
        k = m;
      }
      if (y < k) {
        k = y;
      }
      *out++ = colToByte(c - k);
      *out++ = colToByte(m - k);
      *out++ = colToByte(y - k);
      *out++ = colToByte(k);
    }
    gfree(tmp);
  } else {
    alt->getCMYKLine(in, out, length);
  }
#else
  alt->getCMYKLine(in, out, length);
#endif
}

void GfxICCBasedColorSpace::getDeviceNLine(unsigned char *in, unsigned char *out, int length) {
#ifdef USE_CMS
  if (lineTransform != nullptr && lineTransform->getTransformPixelType() == PT_CMYK) {
    unsigned char* tmp = (unsigned char *)gmallocn(4 * length, sizeof(unsigned char));
    transform->doTransform(in,tmp,length);
    unsigned char *p = tmp;
    for (int i = 0; i < length; i++) {
      for (int j = 0; j < 4; j++)
        *out++ = *p++;
      for (int j = 4; j < SPOT_NCOMPS+4; j++)
        *out++ = 0;
    }
    gfree(tmp);
  } else if (lineTransform != nullptr && nComps != 4) {
    GfxColorComp c, m, y, k;
    unsigned char* tmp = (unsigned char *)gmallocn(3 * length, sizeof(unsigned char));
    getRGBLine(in, tmp, length);
    unsigned char *p = tmp;
    for (int i = 0; i < length; i++) {
      for (int j = 0; j < SPOT_NCOMPS+4; j++) 
        out[j] = 0;
      c = byteToCol(255 - *p++);
      m = byteToCol(255 - *p++);
      y = byteToCol(255 - *p++);
      k = c;
      if (m < k) {
        k = m;
      }
      if (y < k) {
        k = y;
      }
      out[0] = colToByte(c - k);
      out[1] = colToByte(m - k);
      out[2] = colToByte(y - k);
      out[3] = colToByte(k);
      out += (SPOT_NCOMPS+4);
    }
    gfree(tmp);
  } else {
    alt->getDeviceNLine(in, out, length);
  }
#else
  alt->getDeviceNLine(in, out, length);
#endif
}

void GfxICCBasedColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
#ifdef USE_CMS
  if (transform != nullptr && transform->getTransformPixelType() == PT_CMYK) {
    unsigned char in[gfxColorMaxComps];
    unsigned char out[gfxColorMaxComps];
    
    if (nComps == 3 && transform->getInputPixelType() == PT_Lab) {
      in[0] = colToByte(dblToCol(colToDbl(color->c[0]) / 100.0));
      in[1] = colToByte(dblToCol((colToDbl(color->c[1]) + 128.0) / 255.0));
      in[2] = colToByte(dblToCol((colToDbl(color->c[2]) + 128.0) / 255.0));
    } else {
      for (int i = 0;i < nComps;i++) {
	in[i] = colToByte(color->c[i]);
      }
    }
    if (nComps <= 4) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      std::map<unsigned int, unsigned int>::iterator it = cmsCache.find(key);
      if (it != cmsCache.end()) {
        unsigned int value = it->second;
        cmyk->c = byteToCol(value >> 24);
        cmyk->m = byteToCol((value >> 16) & 0xff);
        cmyk->y = byteToCol((value >> 8) & 0xff);
        cmyk->k = byteToCol(value & 0xff);
        return;
      }
    }    
    transform->doTransform(in,out,1);
    cmyk->c = byteToCol(out[0]);
    cmyk->m = byteToCol(out[1]);
    cmyk->y = byteToCol(out[2]);
    cmyk->k = byteToCol(out[3]);
    if (nComps <= 4 && cmsCache.size() <= CMSCACHE_LIMIT) {
      unsigned int key = 0;
      for (int j = 0; j < nComps; j++) {
        key = (key << 8) + in[j];
      }
      unsigned int value = (out[0] << 24) + (out[1] << 16) + (out[2] << 8) + out[3];
      cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
    }
  } else if (nComps != 4 && transform != nullptr && transform->getTransformPixelType() == PT_RGB) {
    GfxRGB rgb;
    GfxColorComp c, m, y, k;

    getRGB(color,&rgb);
    c = clip01(gfxColorComp1 - rgb.r);
    m = clip01(gfxColorComp1 - rgb.g);
    y = clip01(gfxColorComp1 - rgb.b);
    k = c;
    if (m < k) {
      k = m;
    }
    if (y < k) {
      k = y;
    }
    cmyk->c = c - k;
    cmyk->m = m - k;
    cmyk->y = y - k;
    cmyk->k = k;
  } else {
    alt->getCMYK(color, cmyk);
  }
#else
  alt->getCMYK(color, cmyk);
#endif
}

bool GfxICCBasedColorSpace::useGetRGBLine() const {
#ifdef USE_CMS
  return lineTransform != nullptr || alt->useGetRGBLine();
#else
  return alt->useGetRGBLine();
#endif
}

bool GfxICCBasedColorSpace::useGetCMYKLine() const {
#ifdef USE_CMS
  return lineTransform != nullptr || alt->useGetCMYKLine();
#else
  return alt->useGetCMYKLine();
#endif
}

bool GfxICCBasedColorSpace::useGetDeviceNLine() const {
#ifdef USE_CMS
  return lineTransform != nullptr || alt->useGetDeviceNLine();
#else
  return alt->useGetDeviceNLine();
#endif
}

void GfxICCBasedColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  GfxCMYK cmyk;
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  getCMYK(color, &cmyk);
  deviceN->c[0] = cmyk.c;
  deviceN->c[1] = cmyk.m;
  deviceN->c[2] = cmyk.y;
  deviceN->c[3] = cmyk.k;
}

void GfxICCBasedColorSpace::getDefaultColor(GfxColor *color) {
  int i;

  for (i = 0; i < nComps; ++i) {
    if (rangeMin[i] > 0) {
      color->c[i] = dblToCol(rangeMin[i]);
    } else if (rangeMax[i] < 0) {
      color->c[i] = dblToCol(rangeMax[i]);
    } else {
      color->c[i] = 0;
    }
  }
}

void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
					     double *decodeRange,
					     int maxImgPixel) {
  alt->getDefaultRanges(decodeLow, decodeRange, maxImgPixel);

#if 0
  // this is nominally correct, but some PDF files don't set the
  // correct ranges in the ICCBased dict
  int i;

  for (i = 0; i < nComps; ++i) {
    decodeLow[i] = rangeMin[i];
    decodeRange[i] = rangeMax[i] - rangeMin[i];
  }
#endif
}

//------------------------------------------------------------------------
// GfxIndexedColorSpace
//------------------------------------------------------------------------

GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA,
					   int indexHighA) {
  base = baseA;
  indexHigh = indexHighA;
  lookup = (unsigned char *)gmallocn((indexHigh + 1) * base->getNComps(),
			      sizeof(unsigned char));
  overprintMask = base->getOverprintMask();
}

GfxIndexedColorSpace::~GfxIndexedColorSpace() {
  delete base;
  gfree(lookup);
}

GfxColorSpace *GfxIndexedColorSpace::copy() {
  GfxIndexedColorSpace *cs;

  cs = new GfxIndexedColorSpace(base->copy(), indexHigh);
  memcpy(cs->lookup, lookup,
	 (indexHigh + 1) * base->getNComps() * sizeof(unsigned char));
  return cs;
}

GfxColorSpace *GfxIndexedColorSpace::parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion) {
  GfxColorSpace *baseA;
  int indexHighA;
  Object obj1;
  const char *s;
  int i, j;

  if (arr->getLength() != 4) {
    error(errSyntaxWarning, -1, "Bad Indexed color space");
    return nullptr;
  }
  obj1 = arr->get(1);
  if (!(baseA = GfxColorSpace::parse(res, &obj1, out, state, recursion + 1))) {
    error(errSyntaxWarning, -1, "Bad Indexed color space (base color space)");
    return nullptr;
  }
  obj1 = arr->get(2);
  if (!obj1.isInt()) {
    error(errSyntaxWarning, -1, "Bad Indexed color space (hival)");
    delete baseA;
    return nullptr;
  }
  indexHighA = obj1.getInt();
  if (indexHighA < 0 || indexHighA > 255) {
    // the PDF spec requires indexHigh to be in [0,255] -- allowing
    // values larger than 255 creates a security hole: if nComps *
    // indexHigh is greater than 2^31, the loop below may overwrite
    // past the end of the array
    int previousValue = indexHighA;
    if (indexHighA < 0) indexHighA = 0;
    else indexHighA = 255;
    error(errSyntaxWarning, -1, "Bad Indexed color space (invalid indexHigh value, was {0:d} using {1:d} to try to recover)", previousValue, indexHighA);
  }
  GfxIndexedColorSpace *cs = new GfxIndexedColorSpace(baseA, indexHighA);
  obj1 = arr->get(3);
  const int n = baseA->getNComps();
  if (obj1.isStream()) {
    obj1.streamReset();
    for (i = 0; i <= indexHighA; ++i) {
      const int readChars = obj1.streamGetChars(n, &cs->lookup[i*n]);
      for (j = readChars; j < n; ++j) {
        error(errSyntaxWarning, -1, "Bad Indexed color space (lookup table stream too short) padding with zeroes");
        cs->lookup[i*n + j] = 0;
      }
    }
    obj1.streamClose();
  } else if (obj1.isString()) {
    if (obj1.getString()->getLength() < (indexHighA + 1) * n) {
      error(errSyntaxWarning, -1, "Bad Indexed color space (lookup table string too short)");
      goto err3;
    }
    s = obj1.getString()->c_str();
    for (i = 0; i <= indexHighA; ++i) {
      for (j = 0; j < n; ++j) {
	cs->lookup[i*n + j] = (unsigned char)*s++;
      }
    }
  } else {
    error(errSyntaxWarning, -1, "Bad Indexed color space (lookup table)");
    goto err3;
  }
  return cs;

 err3:
  delete cs;
  return nullptr;
}

GfxColor *GfxIndexedColorSpace::mapColorToBase(const GfxColor *color,
					       GfxColor *baseColor) const {
  unsigned char *p;
  double low[gfxColorMaxComps], range[gfxColorMaxComps];
  int n, i;

  n = base->getNComps();
  base->getDefaultRanges(low, range, indexHigh);
  const int idx = (int)(colToDbl(color->c[0]) + 0.5) * n;
  if (likely((idx + n - 1 < (indexHigh + 1) * base->getNComps()) && idx >= 0)) {
    p = &lookup[idx];
    for (i = 0; i < n; ++i) {
      baseColor->c[i] = dblToCol(low[i] + (p[i] / 255.0) * range[i]);
    }
  } else {
    for (i = 0; i < n; ++i) {
      baseColor->c[i] = 0;
    }
  }
  return baseColor;
}

void GfxIndexedColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  GfxColor color2;

  base->getGray(mapColorToBase(color, &color2), gray);
}

void GfxIndexedColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  GfxColor color2;

  base->getRGB(mapColorToBase(color, &color2), rgb);
}

void GfxIndexedColorSpace::getRGBLine(unsigned char *in, unsigned int *out, int length) {
  unsigned char *line;
  int i, j, n;

  n = base->getNComps();
  line = (unsigned char *) gmallocn (length, n);
  for (i = 0; i < length; i++)
    for (j = 0; j < n; j++)
      line[i * n + j] = lookup[in[i] * n + j];

  base->getRGBLine(line, out, length);

  gfree (line);
}

void GfxIndexedColorSpace::getRGBLine(unsigned char *in, unsigned char *out, int length)
{
  unsigned char *line;
  int i, j, n;

  n = base->getNComps();
  line = (unsigned char *) gmallocn (length, n);
  for (i = 0; i < length; i++)
    for (j = 0; j < n; j++)
      line[i * n + j] = lookup[in[i] * n + j];

  base->getRGBLine(line, out, length);

  gfree (line);
}

void GfxIndexedColorSpace::getRGBXLine(unsigned char *in, unsigned char *out, int length)
{
  unsigned char *line;
  int i, j, n;

  n = base->getNComps();
  line = (unsigned char *) gmallocn (length, n);
  for (i = 0; i < length; i++)
    for (j = 0; j < n; j++)
      line[i * n + j] = lookup[in[i] * n + j];

  base->getRGBXLine(line, out, length);

  gfree (line);
}

void GfxIndexedColorSpace::getCMYKLine(unsigned char *in, unsigned char *out, int length) {
  unsigned char *line;
  int i, j, n;

  n = base->getNComps();
  line = (unsigned char *) gmallocn (length, n);
  for (i = 0; i < length; i++)
    for (j = 0; j < n; j++)
      line[i * n + j] = lookup[in[i] * n + j];

  base->getCMYKLine(line, out, length);

  gfree (line);
}

void GfxIndexedColorSpace::getDeviceNLine(unsigned char *in, unsigned char *out, int length) {
  unsigned char *line;
  int i, j, n;

  n = base->getNComps();
  line = (unsigned char *) gmallocn (length, n);
  for (i = 0; i < length; i++)
    for (j = 0; j < n; j++)
      line[i * n + j] = lookup[in[i] * n + j];

  base->getDeviceNLine(line, out, length);

  gfree (line);
}

void GfxIndexedColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  GfxColor color2;

  base->getCMYK(mapColorToBase(color, &color2), cmyk);
}

void GfxIndexedColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  GfxColor color2;

  base->getDeviceN(mapColorToBase(color, &color2), deviceN);
}

void GfxIndexedColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = 0;
}

void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow,
					    double *decodeRange,
					    int maxImgPixel) {
  decodeLow[0] = 0;
  decodeRange[0] = maxImgPixel;
}

//------------------------------------------------------------------------
// GfxSeparationColorSpace
//------------------------------------------------------------------------

GfxSeparationColorSpace::GfxSeparationColorSpace(GooString *nameA,
						 GfxColorSpace *altA,
						 Function *funcA) {
  name = nameA;
  alt = altA;
  func = funcA;
  nonMarking = !name->cmp("None");
  if (!name->cmp("Cyan")) {
    overprintMask = 0x01;
  } else if (!name->cmp("Magenta")) {
    overprintMask = 0x02;
  } else if (!name->cmp("Yellow")) {
    overprintMask = 0x04;
  } else if (!name->cmp("Black")) {
    overprintMask = 0x08;
  } else if (!name->cmp("All")) {
    overprintMask = 0xffffffff;
  }
}

GfxSeparationColorSpace::GfxSeparationColorSpace(GooString *nameA,
						 GfxColorSpace *altA,
						 Function *funcA,
						 bool nonMarkingA,
						 unsigned int overprintMaskA,
						 int *mappingA) {
  name = nameA;
  alt = altA;
  func = funcA;
  nonMarking = nonMarkingA;
  overprintMask = overprintMaskA;
  mapping = mappingA;
}

GfxSeparationColorSpace::~GfxSeparationColorSpace() {
  delete name;
  delete alt;
  delete func;
  if (mapping != nullptr)
    gfree(mapping);
}

GfxColorSpace *GfxSeparationColorSpace::copy() {
  int *mappingA = nullptr;
  if (mapping != nullptr) {
    mappingA = (int *) gmalloc(sizeof(int));
    *mappingA = *mapping;
  }
  return new GfxSeparationColorSpace(name->copy(), alt->copy(), func->copy(),
				     nonMarking, overprintMask, mappingA);
}

//~ handle the 'All' and 'None' colorants
GfxColorSpace *GfxSeparationColorSpace::parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion) {
  GfxSeparationColorSpace *cs;
  GooString *nameA;
  GfxColorSpace *altA;
  Function *funcA;
  Object obj1;

  if (arr->getLength() != 4) {
    error(errSyntaxWarning, -1, "Bad Separation color space");
    goto err1;
  }
  obj1 = arr->get(1);
  if (!obj1.isName()) {
    error(errSyntaxWarning, -1, "Bad Separation color space (name)");
    goto err1;
  }
  nameA = new GooString(obj1.getName());
  obj1 = arr->get(2);
  if (!(altA = GfxColorSpace::parse(res, &obj1, out, state, recursion + 1))) {
    error(errSyntaxWarning, -1, "Bad Separation color space (alternate color space)");
    goto err3;
  }
  obj1 = arr->get(3);
  if (!(funcA = Function::parse(&obj1))) {
    goto err4;
  }
  if (funcA->getInputSize() != 1) {
    error(errSyntaxWarning, -1, "Bad SeparationColorSpace function");
    goto err5;
  }
  cs = new GfxSeparationColorSpace(nameA, altA, funcA);
  return cs;

 err5:
  delete funcA;
 err4:
  delete altA;
 err3:
  delete nameA;
 err1:
  return nullptr;
}

void GfxSeparationColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  double x;
  double c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  if (alt->getMode() == csDeviceGray && name->cmp("Black") == 0) {
    *gray = clip01(gfxColorComp1 - color->c[0]);
  } else {
    x = colToDbl(color->c[0]);
    func->transform(&x, c);
    for (i = 0; i < alt->getNComps(); ++i) {
      color2.c[i] = dblToCol(c[i]);
    }
    alt->getGray(&color2, gray);
  }
}

void GfxSeparationColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  double x;
  double c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  if (alt->getMode() == csDeviceGray && name->cmp("Black") == 0) {
    rgb->r = clip01(gfxColorComp1 - color->c[0]);
    rgb->g = clip01(gfxColorComp1 - color->c[0]);
    rgb->b = clip01(gfxColorComp1 - color->c[0]);
  } else {
    x = colToDbl(color->c[0]);
    func->transform(&x, c);
    const int altNComps = alt->getNComps();
    for (i = 0; i < altNComps; ++i) {
      color2.c[i] = dblToCol(c[i]);
    }
    if (unlikely(altNComps > func->getOutputSize())) {
      for (i = func->getOutputSize(); i < altNComps; ++i) {
	color2.c[i] = 0;
      }
    }
    alt->getRGB(&color2, rgb);
  }
}

void GfxSeparationColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  double x;
  double c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  if (name->cmp("Black") == 0) {
    cmyk->c = 0;
    cmyk->m = 0;
    cmyk->y = 0;
    cmyk->k = color->c[0];
  } else if (name->cmp("Cyan") == 0) {
    cmyk->c = color->c[0];
    cmyk->m = 0;
    cmyk->y = 0;
    cmyk->k = 0;
  } else if (name->cmp("Magenta") == 0) {
    cmyk->c = 0;
    cmyk->m = color->c[0];
    cmyk->y = 0;
    cmyk->k = 0;
  } else if (name->cmp("Yellow") == 0) {
    cmyk->c = 0;
    cmyk->m = 0;
    cmyk->y = color->c[0];
    cmyk->k = 0;
  } else {
    x = colToDbl(color->c[0]);
    func->transform(&x, c);
    for (i = 0; i < alt->getNComps(); ++i) {
      color2.c[i] = dblToCol(c[i]);
    }
    alt->getCMYK(&color2, cmyk);
  }
}

void GfxSeparationColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  if (mapping == nullptr || mapping[0] == -1) {
    GfxCMYK cmyk;

    getCMYK(color, &cmyk);
    deviceN->c[0] = cmyk.c;
    deviceN->c[1] = cmyk.m;
    deviceN->c[2] = cmyk.y;
    deviceN->c[3] = cmyk.k;
  } else {
    deviceN->c[mapping[0]] = color->c[0];
  }
}

void GfxSeparationColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0] = gfxColorComp1;
}

void GfxSeparationColorSpace::createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) {
  if (nonMarking)
    return;
  mapping = (int *)gmalloc(sizeof(int));
  switch (overprintMask) {
    case 0x01:
      *mapping = 0;
      break;
    case 0x02:
      *mapping = 1;
      break;
    case 0x04:
      *mapping = 2;
      break;
    case 0x08:
      *mapping = 3;
      break;
    default:
      unsigned int newOverprintMask = 0x10;
      for (std::size_t i = 0; i < separationList->size(); i++) {
        GfxSeparationColorSpace *sepCS = (GfxSeparationColorSpace *)separationList->get(i);
        if (!sepCS->getName()->cmp(name)) {
          if (sepCS->getFunc()->hasDifferentResultSet(func)) {
            error(errSyntaxWarning, -1,
              "Different functions found for '{0:t}', convert immediately", name);
            gfree(mapping);
            mapping = nullptr;
            return;
          }
          *mapping = i+4;
          overprintMask = newOverprintMask;
          return;
        }
        newOverprintMask <<=1;
      }
      if ((int)separationList->size() == maxSepComps) {
        error(errSyntaxWarning, -1,
	        "Too many ({0:d}) spots, convert '{1:t}' immediately", maxSepComps, name);
        gfree(mapping);
        mapping = nullptr;
        return;
      }
      *mapping = separationList->size() + 4;
      separationList->push_back((GfxSeparationColorSpace*)copy());
      overprintMask = newOverprintMask;
      break;
  }
}

//------------------------------------------------------------------------
// GfxDeviceNColorSpace
//------------------------------------------------------------------------

GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
					   GooString **namesA,
					   GfxColorSpace *altA,
					   Function *funcA,
					   GooList<GfxSeparationColorSpace*> *sepsCSA) {
  int i;

  nComps = nCompsA;
  alt = altA;
  func = funcA;
  sepsCS = sepsCSA;
  nonMarking = true;
  overprintMask = 0;
  mapping = nullptr;
  for (i = 0; i < nComps; ++i) {
    names[i] = namesA[i];
    if (names[i]->cmp("None")) {
      nonMarking = false;
    }
    if (!names[i]->cmp("Cyan")) {
      overprintMask |= 0x01;
    } else if (!names[i]->cmp("Magenta")) {
      overprintMask |= 0x02;
    } else if (!names[i]->cmp("Yellow")) {
      overprintMask |= 0x04;
    } else if (!names[i]->cmp("Black")) {
      overprintMask |= 0x08;
    } else if (!names[i]->cmp("All")) {
      overprintMask = 0xffffffff;
    } else {
      overprintMask = 0x0f;
    }
  }
}

GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
					   GooString **namesA,
					   GfxColorSpace *altA,
					   Function *funcA,
					   GooList<GfxSeparationColorSpace*> *sepsCSA,
					   int *mappingA,
					   bool nonMarkingA,
					   unsigned int overprintMaskA) {
  int i;

  nComps = nCompsA;
  alt = altA;
  func = funcA;
  sepsCS = sepsCSA;
  mapping = mappingA;
  nonMarking = nonMarkingA;
  overprintMask = overprintMaskA;
  for (i = 0; i < nComps; ++i) {
    names[i] = namesA[i]->copy();
  }
}

GfxDeviceNColorSpace::~GfxDeviceNColorSpace() {
  int i;

  for (i = 0; i < nComps; ++i) {
    delete names[i];
  }
  delete alt;
  delete func;
  deleteGooList<GfxSeparationColorSpace*>(sepsCS);
  if (mapping != nullptr)
    gfree(mapping);
}

GfxColorSpace *GfxDeviceNColorSpace::copy() {
  int i;
  int *mappingA = nullptr;

  auto sepsCSA = new GooList<GfxSeparationColorSpace*>();
  sepsCSA->reserve(sepsCS->size());
  for (std::size_t i = 0; i < sepsCS->size(); i++) {
    GfxSeparationColorSpace *scs = (GfxSeparationColorSpace *) sepsCS->get(i);
    if (likely(scs != nullptr)) {
      sepsCSA->push_back((GfxSeparationColorSpace*)scs->copy());
    }
  }
  if (mapping != nullptr) {
    mappingA = (int *)gmalloc(sizeof(int) * nComps);
    for (i = 0; i < nComps; i++)
      mappingA[i] = mapping[i];
  }
  return new GfxDeviceNColorSpace(nComps, names, alt->copy(), func->copy(),
				  sepsCSA, mappingA, nonMarking, overprintMask);
}

//~ handle the 'None' colorant
GfxColorSpace *GfxDeviceNColorSpace::parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion) {
  int nCompsA;
  GooString *namesA[gfxColorMaxComps];
  GfxColorSpace *altA;
  Function *funcA;
  Object obj1;
  int i;
  auto separationList = new GooList<GfxSeparationColorSpace*>();

  if (arr->getLength() != 4 && arr->getLength() != 5) {
    error(errSyntaxWarning, -1, "Bad DeviceN color space");
    goto err1;
  }
  obj1 = arr->get(1);
  if (!obj1.isArray()) {
    error(errSyntaxWarning, -1, "Bad DeviceN color space (names)");
    goto err1;
  }
  nCompsA = obj1.arrayGetLength();
  if (nCompsA > gfxColorMaxComps) {
    error(errSyntaxWarning, -1, "DeviceN color space with too many ({0:d} > {1:d}) components",
	  nCompsA, gfxColorMaxComps);
    nCompsA = gfxColorMaxComps;
  }
  for (i = 0; i < nCompsA; ++i) {
    Object obj2 = obj1.arrayGet(i);
    if (!obj2.isName()) {
      error(errSyntaxWarning, -1, "Bad DeviceN color space (names)");
      nCompsA = i;
      goto err3;
    }
    namesA[i] = new GooString(obj2.getName());
  }
  obj1 = arr->get(2);
  if (!(altA = GfxColorSpace::parse(res, &obj1, out, state, recursion + 1))) {
    error(errSyntaxWarning, -1, "Bad DeviceN color space (alternate color space)");
    goto err3;
  }
  obj1 = arr->get(3);
  if (!(funcA = Function::parse(&obj1))) {
    goto err4;
  }
  if (arr->getLength() == 5) {
    obj1 = arr->get(4);
    if (!obj1.isDict()) {
      error(errSyntaxWarning, -1, "Bad DeviceN color space (attributes)");
      goto err5;
    }
    Dict *attribs = obj1.getDict();
    Object obj2 = attribs->lookup("Colorants");
    if (obj2.isDict()) {
      Dict *colorants = obj2.getDict();
      for (i = 0; i < colorants->getLength(); i++) {
        Object obj3 = colorants->getVal(i);
        if (obj3.isArray()) {
	  separationList->push_back((GfxSeparationColorSpace*)GfxSeparationColorSpace::parse(res, obj3.getArray(), out, state, recursion));
        } else {
          error(errSyntaxWarning, -1, "Bad DeviceN color space (colorant value entry is not an Array)");
          goto err5;
        }
      }
    }
  }
  return new GfxDeviceNColorSpace(nCompsA, namesA, altA, funcA, separationList);

 err5:
  delete funcA;
 err4:
  delete altA;
 err3:
  for (i = 0; i < nCompsA; ++i) {
    delete namesA[i];
  }
 err1:
  delete separationList;
  return nullptr;
}

void GfxDeviceNColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  double x[gfxColorMaxComps], c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  for (i = 0; i < nComps; ++i) {
    x[i] = colToDbl(color->c[i]);
  }
  func->transform(x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getGray(&color2, gray);
}

void GfxDeviceNColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  double x[gfxColorMaxComps], c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  for (i = 0; i < nComps; ++i) {
    x[i] = colToDbl(color->c[i]);
  }
  func->transform(x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getRGB(&color2, rgb);
}

void GfxDeviceNColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  double x[gfxColorMaxComps], c[gfxColorMaxComps];
  GfxColor color2;
  int i;

  for (i = 0; i < nComps; ++i) {
    x[i] = colToDbl(color->c[i]);
  }
  func->transform(x, c);
  for (i = 0; i < alt->getNComps(); ++i) {
    color2.c[i] = dblToCol(c[i]);
  }
  alt->getCMYK(&color2, cmyk);
}

void GfxDeviceNColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  if (mapping == nullptr) {
    GfxCMYK cmyk;

    getCMYK(color, &cmyk);
    deviceN->c[0] = cmyk.c;
    deviceN->c[1] = cmyk.m;
    deviceN->c[2] = cmyk.y;
    deviceN->c[3] = cmyk.k;
  } else {
    for (int j = 0; j < nComps; j++)
      if (mapping[j] != -1)
        deviceN->c[mapping[j]] = color->c[j];
  }
}

void GfxDeviceNColorSpace::getDefaultColor(GfxColor *color) {
  int i;

  for (i = 0; i < nComps; ++i) {
    color->c[i] = gfxColorComp1;
  }
}

void GfxDeviceNColorSpace::createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) {
  if (nonMarking)               // None
    return;
  mapping = (int *)gmalloc(sizeof(int) * nComps);
  unsigned int newOverprintMask = 0;
  for (int i = 0; i < nComps; i++) {
    if (!names[i]->cmp("None")) {
      mapping[i] = -1;
    } else if (!names[i]->cmp("Cyan")) {
      newOverprintMask |= 0x01;
      mapping[i] = 0;
    } else if (!names[i]->cmp("Magenta")) {
      newOverprintMask |= 0x02;
      mapping[i] = 1;
    } else if (!names[i]->cmp("Yellow")) {
      newOverprintMask |= 0x04;
      mapping[i] = 2;
    } else if (!names[i]->cmp("Black")) {
      newOverprintMask |= 0x08;
      mapping[i] = 3;
    } else {
      unsigned int startOverprintMask = 0x10;
      bool found = false;
      const Function *sepFunc = nullptr;
      if (nComps == 1)
        sepFunc = func;
      else {
        for (std::size_t k = 0; k < sepsCS->size(); k++) {
          GfxSeparationColorSpace *sepCS = (GfxSeparationColorSpace *)sepsCS->get(k);
          if (!sepCS->getName()->cmp(names[i])) {
            sepFunc = sepCS->getFunc();
            break;
          }
        }
      }
      for (std::size_t j = 0; j < separationList->size(); j++) {
        GfxSeparationColorSpace *sepCS = (GfxSeparationColorSpace *)separationList->get(j);
        if (!sepCS->getName()->cmp(names[i])) {
          if (sepFunc != nullptr && sepCS->getFunc()->hasDifferentResultSet(sepFunc)) {
            error(errSyntaxWarning, -1,
              "Different functions found for '{0:t}', convert immediately", names[i]);
            gfree(mapping);
            mapping = nullptr;
            overprintMask = 0xffffffff;
            return;
          }
          mapping[i] = j+4;
          newOverprintMask |= startOverprintMask;
          found = true;
          break;
        }
        startOverprintMask <<=1;
      }
      if (!found) {
        if ((int)separationList->size() == maxSepComps) {
          error(errSyntaxWarning, -1,
            "Too many ({0:d}) spots, convert '{1:t}' immediately", maxSepComps, names[i]);
          gfree(mapping);
          mapping = nullptr;
          overprintMask = 0xffffffff;
          return;
        }
        mapping[i] = separationList->size() + 4;
        newOverprintMask |= startOverprintMask;
        if (nComps == 1)
	  separationList->push_back(new GfxSeparationColorSpace(names[i]->copy(),alt->copy(), func->copy()));
        else {
          for (std::size_t k = 0; k < sepsCS->size(); k++) {
            GfxSeparationColorSpace *sepCS = (GfxSeparationColorSpace *)sepsCS->get(k);
            if (!sepCS->getName()->cmp(names[i])) {
              found = true;
	      separationList->push_back((GfxSeparationColorSpace*)sepCS->copy());
              break;
            }
          }
          if(!found) {
            error(errSyntaxWarning, -1, "DeviceN has no suitable colorant");
            gfree(mapping);
            mapping = nullptr;
            overprintMask = 0xffffffff;
            return;
          }
        }
      }
    }
  }
  overprintMask = newOverprintMask;
}

//------------------------------------------------------------------------
// GfxPatternColorSpace
//------------------------------------------------------------------------

GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *underA) {
  under = underA;
}

GfxPatternColorSpace::~GfxPatternColorSpace() {
  if (under) {
    delete under;
  }
}

GfxColorSpace *GfxPatternColorSpace::copy() {
  return new GfxPatternColorSpace(under ? under->copy() :
				          nullptr);
}

GfxColorSpace *GfxPatternColorSpace::parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion) {
  GfxPatternColorSpace *cs;
  GfxColorSpace *underA;
  Object obj1;

  if (arr->getLength() != 1 && arr->getLength() != 2) {
    error(errSyntaxWarning, -1, "Bad Pattern color space");
    return nullptr;
  }
  underA = nullptr;
  if (arr->getLength() == 2) {
    obj1 = arr->get(1);
    if (!(underA = GfxColorSpace::parse(res, &obj1, out, state, recursion + 1))) {
      error(errSyntaxWarning, -1, "Bad Pattern color space (underlying color space)");
      return nullptr;
    }
  }
  cs = new GfxPatternColorSpace(underA);
  return cs;
}

void GfxPatternColorSpace::getGray(const GfxColor *color, GfxGray *gray) const {
  *gray = 0;
}

void GfxPatternColorSpace::getRGB(const GfxColor *color, GfxRGB *rgb) const {
  rgb->r = rgb->g = rgb->b = 0;
}

void GfxPatternColorSpace::getCMYK(const GfxColor *color, GfxCMYK *cmyk) const {
  cmyk->c = cmyk->m = cmyk->y = 0;
  cmyk->k = 1;
}

void GfxPatternColorSpace::getDeviceN(const GfxColor *color, GfxColor *deviceN) const {
  for (int i = 0; i < gfxColorMaxComps; i++)
    deviceN->c[i] = 0;
  deviceN->c[3] = 1;
}

void GfxPatternColorSpace::getDefaultColor(GfxColor *color) {
  color->c[0]=0;
}

//------------------------------------------------------------------------
// Pattern
//------------------------------------------------------------------------

GfxPattern::GfxPattern(int typeA, int patternRefNumA)
 : type(typeA)
 , patternRefNum(patternRefNumA)
{

}

GfxPattern::~GfxPattern() {
}

GfxPattern *GfxPattern::parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state, int patternRefNum) {
  GfxPattern *pattern;
  Object obj1;

  if (obj->isDict()) {
    obj1 = obj->dictLookup("PatternType");
  } else if (obj->isStream()) {
    obj1 = obj->streamGetDict()->lookup("PatternType");
  } else {
    return nullptr;
  }
  pattern = nullptr;
  if (obj1.isInt() && obj1.getInt() == 1) {
    pattern = GfxTilingPattern::parse(obj, patternRefNum);
  } else if (obj1.isInt() && obj1.getInt() == 2) {
    pattern = GfxShadingPattern::parse(res, obj, out, state, patternRefNum);
  }
  return pattern;
}

//------------------------------------------------------------------------
// GfxTilingPattern
//------------------------------------------------------------------------

GfxTilingPattern *GfxTilingPattern::parse(Object *patObj, int patternRefNum) {
  Dict *dict;
  int paintTypeA, tilingTypeA;
  double bboxA[4], matrixA[6];
  double xStepA, yStepA;
  Object resDictA;
  Object obj1;
  int i;

  if (!patObj->isStream()) {
    return nullptr;
  }
  dict = patObj->streamGetDict();

  obj1 = dict->lookup("PaintType");
  if (obj1.isInt()) {
    paintTypeA = obj1.getInt();
  } else {
    paintTypeA = 1;
    error(errSyntaxWarning, -1, "Invalid or missing PaintType in pattern");
  }
  obj1 = dict->lookup("TilingType");
  if (obj1.isInt()) {
    tilingTypeA = obj1.getInt();
  } else {
    tilingTypeA = 1;
    error(errSyntaxWarning, -1, "Invalid or missing TilingType in pattern");
  }
  bboxA[0] = bboxA[1] = 0;
  bboxA[2] = bboxA[3] = 1;
  obj1 = dict->lookup("BBox");
  if (obj1.isArray() && obj1.arrayGetLength() == 4) {
    for (i = 0; i < 4; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (obj2.isNum()) {
	bboxA[i] = obj2.getNum();
      }
    }
  } else {
    error(errSyntaxWarning, -1, "Invalid or missing BBox in pattern");
  }
  obj1 = dict->lookup("XStep");
  if (obj1.isNum()) {
    xStepA = obj1.getNum();
  } else {
    xStepA = 1;
    error(errSyntaxWarning, -1, "Invalid or missing XStep in pattern");
  }
  obj1 = dict->lookup("YStep");
  if (obj1.isNum()) {
    yStepA = obj1.getNum();
  } else {
    yStepA = 1;
    error(errSyntaxWarning, -1, "Invalid or missing YStep in pattern");
  }
  resDictA = dict->lookup("Resources");
  if (!resDictA.isDict()) {
    error(errSyntaxWarning, -1, "Invalid or missing Resources in pattern");
  }
  matrixA[0] = 1; matrixA[1] = 0;
  matrixA[2] = 0; matrixA[3] = 1;
  matrixA[4] = 0; matrixA[5] = 0;
  obj1 = dict->lookup("Matrix");
  if (obj1.isArray() && obj1.arrayGetLength() == 6) {
    for (i = 0; i < 6; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (obj2.isNum()) {
	matrixA[i] = obj2.getNum();
      }
    }
  }

  return new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA,
			     &resDictA, matrixA, patObj, patternRefNum);
}

GfxTilingPattern::GfxTilingPattern(int paintTypeA, int tilingTypeA,
				   double *bboxA, double xStepA, double yStepA,
				   Object *resDictA, double *matrixA,
				   Object *contentStreamA, int patternRefNumA) :
  GfxPattern(1, patternRefNumA)
{
  int i;

  paintType = paintTypeA;
  tilingType = tilingTypeA;
  for (i = 0; i < 4; ++i) {
    bbox[i] = bboxA[i];
  }
  xStep = xStepA;
  yStep = yStepA;
  resDict = resDictA->copy();
  for (i = 0; i < 6; ++i) {
    matrix[i] = matrixA[i];
  }
  contentStream = contentStreamA->copy();
}

GfxTilingPattern::~GfxTilingPattern() {
}

GfxPattern *GfxTilingPattern::copy() {
  return new GfxTilingPattern(paintType, tilingType, bbox, xStep, yStep,
			      &resDict, matrix, &contentStream, getPatternRefNum());
}

//------------------------------------------------------------------------
// GfxShadingPattern
//------------------------------------------------------------------------

GfxShadingPattern *GfxShadingPattern::parse(GfxResources *res, Object *patObj, OutputDev *out, GfxState *state, int patternRefNum) {
  Dict *dict;
  GfxShading *shadingA;
  double matrixA[6];
  Object obj1;
  int i;

  if (!patObj->isDict()) {
    return nullptr;
  }
  dict = patObj->getDict();

  obj1 = dict->lookup("Shading");
  shadingA = GfxShading::parse(res, &obj1, out, state);
  if (!shadingA) {
    return nullptr;
  }

  matrixA[0] = 1; matrixA[1] = 0;
  matrixA[2] = 0; matrixA[3] = 1;
  matrixA[4] = 0; matrixA[5] = 0;
  obj1 = dict->lookup("Matrix");
  if (obj1.isArray() && obj1.arrayGetLength() == 6) {
    for (i = 0; i < 6; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (obj2.isNum()) {
	matrixA[i] = obj2.getNum();
      }
    }
  }

  return new GfxShadingPattern(shadingA, matrixA, patternRefNum);
}

GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA, int patternRefNumA):
  GfxPattern(2, patternRefNumA)
{
  int i;

  shading = shadingA;
  for (i = 0; i < 6; ++i) {
    matrix[i] = matrixA[i];
  }
}

GfxShadingPattern::~GfxShadingPattern() {
  delete shading;
}

GfxPattern *GfxShadingPattern::copy() {
  return new GfxShadingPattern(shading->copy(), matrix, getPatternRefNum());
}

//------------------------------------------------------------------------
// GfxShading
//------------------------------------------------------------------------

GfxShading::GfxShading(int typeA) {
  type = typeA;
  colorSpace = nullptr;
}

GfxShading::GfxShading(GfxShading *shading) {
  int i;

  type = shading->type;
  colorSpace = shading->colorSpace->copy();
  for (i = 0; i < gfxColorMaxComps; ++i) {
    background.c[i] = shading->background.c[i];
  }
  hasBackground = shading->hasBackground;
  xMin = shading->xMin;
  yMin = shading->yMin;
  xMax = shading->xMax;
  yMax = shading->yMax;
  hasBBox = shading->hasBBox;
}

GfxShading::~GfxShading() {
  if (colorSpace) {
    delete colorSpace;
  }
}

GfxShading *GfxShading::parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state) {
  GfxShading *shading;
  Dict *dict;
  int typeA;
  Object obj1;

  if (obj->isDict()) {
    dict = obj->getDict();
  } else if (obj->isStream()) {
    dict = obj->streamGetDict();
  } else {
    return nullptr;
  }

  obj1 = dict->lookup("ShadingType");
  if (!obj1.isInt()) {
    error(errSyntaxWarning, -1, "Invalid ShadingType in shading dictionary");
    return nullptr;
  }
  typeA = obj1.getInt();

  switch (typeA) {
  case 1:
    shading = GfxFunctionShading::parse(res, dict, out, state);
    break;
  case 2:
    shading = GfxAxialShading::parse(res, dict, out, state);
    break;
  case 3:
    shading = GfxRadialShading::parse(res, dict, out, state);
    break;
  case 4:
    if (obj->isStream()) {
      shading = GfxGouraudTriangleShading::parse(res, 4, dict, obj->getStream(), out, state);
    } else {
      error(errSyntaxWarning, -1, "Invalid Type 4 shading object");
      goto err1;
    }
    break;
  case 5:
    if (obj->isStream()) {
      shading = GfxGouraudTriangleShading::parse(res, 5, dict, obj->getStream(), out, state);
    } else {
      error(errSyntaxWarning, -1, "Invalid Type 5 shading object");
      goto err1;
    }
    break;
  case 6:
    if (obj->isStream()) {
      shading = GfxPatchMeshShading::parse(res, 6, dict, obj->getStream(), out, state);
    } else {
      error(errSyntaxWarning, -1, "Invalid Type 6 shading object");
      goto err1;
    }
    break;
  case 7:
    if (obj->isStream()) {
      shading = GfxPatchMeshShading::parse(res, 7, dict, obj->getStream(), out, state);
    } else {
      error(errSyntaxWarning, -1, "Invalid Type 7 shading object");
      goto err1;
    }
    break;
  default:
    error(errSyntaxWarning, -1, "Unimplemented shading type {0:d}", typeA);
    goto err1;
  }

  return shading;

 err1:
  return nullptr;
}

bool GfxShading::init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) {
  Object obj1;
  int i;

  obj1 = dict->lookup("ColorSpace");
  if (!(colorSpace = GfxColorSpace::parse(res, &obj1, out, state))) {
    error(errSyntaxWarning, -1, "Bad color space in shading dictionary");
    return false;
  }

  for (i = 0; i < gfxColorMaxComps; ++i) {
    background.c[i] = 0;
  }
  hasBackground = false;
  obj1 = dict->lookup("Background");
  if (obj1.isArray()) {
    if (obj1.arrayGetLength() == colorSpace->getNComps()) {
      hasBackground = true;
      for (i = 0; i < colorSpace->getNComps(); ++i) {
	Object obj2 = obj1.arrayGet(i);
	background.c[i] = dblToCol(obj2.getNum());
      }
    } else {
      error(errSyntaxWarning, -1, "Bad Background in shading dictionary");
    }
  }

  xMin = yMin = xMax = yMax = 0;
  hasBBox = false;
  obj1 = dict->lookup("BBox");
  if (obj1.isArray()) {
    if (obj1.arrayGetLength() == 4) {
      Object obj2 = obj1.arrayGet(0);
      Object obj3 = obj1.arrayGet(1);
      Object obj4 = obj1.arrayGet(2);
      Object obj5 = obj1.arrayGet(3);
      if (obj2.isNum() && obj3.isNum() && obj4.isNum() && obj5.isNum())
      {
        hasBBox = true;
        xMin = obj2.getNum();
        yMin = obj3.getNum();
        xMax = obj4.getNum();
        yMax = obj5.getNum();
      } else {
        error(errSyntaxWarning, -1, "Bad BBox in shading dictionary (Values not numbers)");
      }
    } else {
      error(errSyntaxWarning, -1, "Bad BBox in shading dictionary");
    }
  }

  return true;
}

//------------------------------------------------------------------------
// GfxFunctionShading
//------------------------------------------------------------------------

GfxFunctionShading::GfxFunctionShading(double x0A, double y0A,
				       double x1A, double y1A,
				       double *matrixA,
				       Function **funcsA, int nFuncsA):
  GfxShading(1)
{
  int i;

  x0 = x0A;
  y0 = y0A;
  x1 = x1A;
  y1 = y1A;
  for (i = 0; i < 6; ++i) {
    matrix[i] = matrixA[i];
  }
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
}

GfxFunctionShading::GfxFunctionShading(GfxFunctionShading *shading):
  GfxShading(shading)
{
  int i;

  x0 = shading->x0;
  y0 = shading->y0;
  x1 = shading->x1;
  y1 = shading->y1;
  for (i = 0; i < 6; ++i) {
    matrix[i] = shading->matrix[i];
  }
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
}

GfxFunctionShading::~GfxFunctionShading() {
  int i;

  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

GfxFunctionShading *GfxFunctionShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) {
  GfxFunctionShading *shading;
  double x0A, y0A, x1A, y1A;
  double matrixA[6];
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  Object obj1;
  int i;

  x0A = y0A = 0;
  x1A = y1A = 1;
  obj1 = dict->lookup("Domain");
  if (obj1.isArray() && obj1.arrayGetLength() == 4) {
    bool decodeOk = true;
    Object obj2;
    x0A = (obj2 = obj1.arrayGet(0), obj2.getNum(&decodeOk));
    x1A = (obj2 = obj1.arrayGet(1), obj2.getNum(&decodeOk));
    y0A = (obj2 = obj1.arrayGet(2), obj2.getNum(&decodeOk));
    y1A = (obj2 = obj1.arrayGet(3), obj2.getNum(&decodeOk));

    if (!decodeOk) {
      error(errSyntaxWarning, -1, "Invalid Domain array in function shading dictionary");
      return nullptr;
    }
  }

  matrixA[0] = 1; matrixA[1] = 0;
  matrixA[2] = 0; matrixA[3] = 1;
  matrixA[4] = 0; matrixA[5] = 0;
  obj1 = dict->lookup("Matrix");
  if (obj1.isArray() && obj1.arrayGetLength() == 6) {
    bool decodeOk = true;
    Object obj2;
    matrixA[0] = (obj2 = obj1.arrayGet(0), obj2.getNum(&decodeOk));
    matrixA[1] = (obj2 = obj1.arrayGet(1), obj2.getNum(&decodeOk));
    matrixA[2] = (obj2 = obj1.arrayGet(2), obj2.getNum(&decodeOk));
    matrixA[3] = (obj2 = obj1.arrayGet(3), obj2.getNum(&decodeOk));
    matrixA[4] = (obj2 = obj1.arrayGet(4), obj2.getNum(&decodeOk));
    matrixA[5] = (obj2 = obj1.arrayGet(5), obj2.getNum(&decodeOk));

    if (!decodeOk) {
      error(errSyntaxWarning, -1, "Invalid Matrix array in function shading dictionary");
      return nullptr;
    }
  }

  obj1 = dict->lookup("Function");
  if (obj1.isArray()) {
    nFuncsA = obj1.arrayGetLength();
    if (nFuncsA > gfxColorMaxComps || nFuncsA <= 0) {
      error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
      return nullptr;
    }
    for (i = 0; i < nFuncsA; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (!(funcsA[i] = Function::parse(&obj2))) {
	for (int j = 0; j < i; ++j) {
	  delete funcsA[j];
	}
	return nullptr;
      }
    }
  } else {
    nFuncsA = 1;
    if (!(funcsA[0] = Function::parse(&obj1))) {
      return nullptr;
    }
  }

  shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA,
				   funcsA, nFuncsA);
  if (!shading->init(res, dict, out, state)) {
    delete shading;
    return nullptr;
  }
  return shading;
}

GfxShading *GfxFunctionShading::copy() {
  return new GfxFunctionShading(this);
}

void GfxFunctionShading::getColor(double x, double y, GfxColor *color) const {
  double in[2], out[gfxColorMaxComps];
  int i;

  // NB: there can be one function with n outputs or n functions with
  // one output each (where n = number of color components)
  for (i = 0; i < gfxColorMaxComps; ++i) {
    out[i] = 0;
  }
  in[0] = x;
  in[1] = y;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i]->transform(in, &out[i]);
  }
  for (i = 0; i < gfxColorMaxComps; ++i) {
    color->c[i] = dblToCol(out[i]);
  }
}

//------------------------------------------------------------------------
// GfxUnivariateShading
//------------------------------------------------------------------------

GfxUnivariateShading::GfxUnivariateShading(int typeA,
					   double t0A, double t1A,
					   Function **funcsA, int nFuncsA,
					   bool extend0A, bool extend1A):
  GfxShading(typeA)
{
  int i;

  t0 = t0A;
  t1 = t1A;
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
  extend0 = extend0A;
  extend1 = extend1A;

  cacheSize = 0;
  lastMatch = 0;
  cacheBounds = nullptr;
  cacheCoeff = nullptr;
  cacheValues = nullptr;
}

GfxUnivariateShading::GfxUnivariateShading(GfxUnivariateShading *shading):
  GfxShading(shading)
{
  int i;

  t0 = shading->t0;
  t1 = shading->t1;
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
  extend0 = shading->extend0;
  extend1 = shading->extend1;

  cacheSize = 0;
  lastMatch = 0;
  cacheBounds = nullptr;
  cacheCoeff = nullptr;
  cacheValues = nullptr;
}

GfxUnivariateShading::~GfxUnivariateShading() {
  int i;

  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }

  gfree (cacheBounds);
}

int GfxUnivariateShading::getColor(double t, GfxColor *color) {
  double out[gfxColorMaxComps];
  int nComps;

  if (likely(nFuncs >= 1)) {
    // NB: there can be one function with n outputs or n functions with
    // one output each (where n = number of color components)
    nComps = nFuncs * funcs[0]->getOutputSize();
  }

  if (unlikely(nFuncs < 1 || nComps > gfxColorMaxComps)) {
    for (int i = 0; i < gfxColorMaxComps; i++)
        color->c[i] = 0;
    return gfxColorMaxComps;
  }

  if (cacheSize > 0) {
    double x, ix, *l, *u, *upper;

    if (cacheBounds[lastMatch - 1] >= t) {
      upper = std::lower_bound (cacheBounds, cacheBounds + lastMatch - 1, t);
      lastMatch = upper - cacheBounds;
      lastMatch = std::min<int>(std::max<int>(1, lastMatch), cacheSize - 1);
    } else if (cacheBounds[lastMatch] < t) {
      upper = std::lower_bound (cacheBounds + lastMatch + 1, cacheBounds + cacheSize, t);
      lastMatch = upper - cacheBounds;
      lastMatch = std::min<int>(std::max<int>(1, lastMatch), cacheSize - 1);
    }

    x = (t - cacheBounds[lastMatch-1]) * cacheCoeff[lastMatch];
    ix = 1.0 - x;
    u = cacheValues + lastMatch * nComps;
    l = u - nComps;

    for (int i = 0; i < nComps; ++i) {
      out[i] = ix * l[i] + x * u[i];
    }
  } else {
    for (int i = 0; i < nComps; ++i) {
      out[i] = 0;
    }
    for (int i = 0; i < nFuncs; ++i) {
      if (funcs[i]->getInputSize() != 1) {
        error(errSyntaxWarning, -1, "Invalid shading function (input != 1)");
        break;
      }
      funcs[i]->transform(&t, &out[i]);
    }
  }

  for (int i = 0; i < nComps; ++i) {
    color->c[i] = dblToCol(out[i]);
  }
  return nComps;
}

void GfxUnivariateShading::setupCache(const Matrix *ctm,
				      double xMin, double yMin,
				      double xMax, double yMax) {
  double sMin, sMax, tMin, tMax, upperBound;
  int i, j, nComps, maxSize;

  gfree (cacheBounds);
  cacheBounds = nullptr;
  cacheSize = 0;

  if (unlikely(nFuncs < 1))
    return;

  // NB: there can be one function with n outputs or n functions with
  // one output each (where n = number of color components)
  nComps = nFuncs * funcs[0]->getOutputSize();

  getParameterRange(&sMin, &sMax, xMin, yMin, xMax, yMax);
  upperBound = ctm->norm() * getDistance(sMin, sMax);
  maxSize = ceil(upperBound);
  maxSize = std::max<int>(maxSize, 2);

  {
    double x[4], y[4];

    ctm->transform(xMin, yMin, &x[0], &y[0]);
    ctm->transform(xMax, yMin, &x[1], &y[1]);
    ctm->transform(xMin, yMax, &x[2], &y[2]);
    ctm->transform(xMax, yMax, &x[3], &y[3]);

    xMin = xMax = x[0];
    yMin = yMax = y[0];
    for (i = 1; i < 4; i++) {
      xMin = std::min<double>(xMin, x[i]);
      yMin = std::min<double>(yMin, y[i]);
      xMax = std::max<double>(xMax, x[i]);
      yMax = std::max<double>(yMax, y[i]);
    }
  }

  if (maxSize > (xMax-xMin) * (yMax-yMin)) {
    return;
  }

  if (t0 < t1) {
    tMin = t0 + sMin * (t1 - t0);
    tMax = t0 + sMax * (t1 - t0);
  } else {
    tMin = t0 + sMax * (t1 - t0);
    tMax = t0 + sMin * (t1 - t0);
  }

  cacheBounds = (double *)gmallocn_checkoverflow(maxSize, sizeof(double) * (nComps + 2));
  if (unlikely(!cacheBounds))
    return;
  cacheCoeff = cacheBounds + maxSize;
  cacheValues = cacheCoeff + maxSize;

  if (cacheSize != 0) {
    for (j = 0; j < cacheSize; ++j) {
      cacheCoeff[j] = 1 / (cacheBounds[j+1] - cacheBounds[j]);
    }
  } else if (tMax != tMin) {
    double step = (tMax - tMin) / (maxSize - 1);
    double coeff = (maxSize - 1) / (tMax - tMin);

    cacheSize = maxSize;

    for (j = 0; j < cacheSize; ++j) {
      cacheBounds[j] = tMin + j * step;
      cacheCoeff[j] = coeff;

      for (i = 0; i < nComps; ++i) {
	cacheValues[j*nComps + i] = 0;
      }
      for (i = 0; i < nFuncs; ++i) {
	funcs[i]->transform(&cacheBounds[j], &cacheValues[j*nComps + i]);
      }
    }
  }

  lastMatch = 1;
}


//------------------------------------------------------------------------
// GfxAxialShading
//------------------------------------------------------------------------

GfxAxialShading::GfxAxialShading(double x0A, double y0A,
				 double x1A, double y1A,
				 double t0A, double t1A,
				 Function **funcsA, int nFuncsA,
				 bool extend0A, bool extend1A):
  GfxUnivariateShading(2, t0A, t1A, funcsA, nFuncsA, extend0A, extend1A)
{
  x0 = x0A;
  y0 = y0A;
  x1 = x1A;
  y1 = y1A;
}

GfxAxialShading::GfxAxialShading(GfxAxialShading *shading):
  GfxUnivariateShading(shading)
{
  x0 = shading->x0;
  y0 = shading->y0;
  x1 = shading->x1;
  y1 = shading->y1;
}

GfxAxialShading::~GfxAxialShading() {
}

GfxAxialShading *GfxAxialShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) {
  GfxAxialShading *shading;
  double x0A, y0A, x1A, y1A;
  double t0A, t1A;
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  bool extend0A, extend1A;
  Object obj1;

  x0A = y0A = x1A = y1A = 0;
  obj1 = dict->lookup("Coords");
  if (obj1.isArray() && obj1.arrayGetLength() == 4) {
    Object obj2 = obj1.arrayGet(0);
    Object obj3 = obj1.arrayGet(1);
    Object obj4 = obj1.arrayGet(2);
    Object obj5 = obj1.arrayGet(3);
    if (obj2.isNum() && obj3.isNum() && obj4.isNum() && obj5.isNum()) {
      x0A = obj2.getNum();
      y0A = obj3.getNum();
      x1A = obj4.getNum();
      y1A = obj5.getNum();
    }
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid Coords in shading dictionary");
    return nullptr;
  }

  t0A = 0;
  t1A = 1;
  obj1 = dict->lookup("Domain");
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
    Object obj2 = obj1.arrayGet(0);
    Object obj3 = obj1.arrayGet(1);
    if (obj2.isNum() && obj3.isNum()) {
      t0A = obj2.getNum();
      t1A = obj3.getNum();
    }
  }

  obj1 = dict->lookup("Function");
  if (obj1.isArray()) {
    nFuncsA = obj1.arrayGetLength();
    if (nFuncsA > gfxColorMaxComps || nFuncsA == 0) {
      error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
      return nullptr;
    }
    for (int i = 0; i < nFuncsA; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (!(funcsA[i] = Function::parse(&obj2))) {
	for (int j = 0; j < i; ++j)
	  delete funcsA[j];
	return nullptr;
      }
    }
  } else {
    nFuncsA = 1;
    if (!(funcsA[0] = Function::parse(&obj1))) {
      return nullptr;
    }
  }

  extend0A = extend1A = false;
  obj1 = dict->lookup("Extend");
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
    Object obj2 = obj1.arrayGet(0);
    if (obj2.isBool()) {
      extend0A = obj2.getBool();
    } else {
      error(errSyntaxWarning, -1, "Invalid axial shading extend (0)");
    }
    obj2 = obj1.arrayGet(1);
    if (obj2.isBool()) {
      extend1A = obj2.getBool();
    } else {
      error(errSyntaxWarning, -1, "Invalid axial shading extend (1)");
    }
  }

  shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
				funcsA, nFuncsA, extend0A, extend1A);
  if (!shading->init(res, dict, out, state)) {
    delete shading;
    shading = nullptr;
  }
  return shading;
}

GfxShading *GfxAxialShading::copy() {
  return new GfxAxialShading(this);
}

double GfxAxialShading::getDistance(double sMin, double sMax) {
  double xMin, yMin, xMax, yMax;

  xMin = x0 + sMin * (x1 - x0);
  yMin = y0 + sMin * (y1 - y0);
  xMax = x0 + sMax * (x1 - x0);
  yMax = y0 + sMax * (y1 - y0);

  return hypot(xMax-xMin, yMax-yMin);
}

void GfxAxialShading::getParameterRange(double *lower, double *upper,
					double xMin, double yMin,
					double xMax, double yMax) {
  double pdx, pdy, invsqnorm, tdx, tdy, t, range[2];

  // Linear gradients are orthogonal to the line passing through their
  // extremes. Because of convexity, the parameter range can be
  // computed as the convex hull (one the real line) of the parameter
  // values of the 4 corners of the box.
  //
  // The parameter value t for a point (x,y) can be computed as:
  //
  //   t = (p2 - p1) . (x,y) / |p2 - p1|^2
  //
  // t0  is the t value for the top left corner
  // tdx is the difference between left and right corners
  // tdy is the difference between top and bottom corners

  pdx = x1 - x0;
  pdy = y1 - y0;
  const double invsqnorm_denominator = (pdx * pdx + pdy * pdy);
  if (unlikely(invsqnorm_denominator == 0)) {
    *lower = 0;
    *upper = 0;
    return;
  }
  invsqnorm = 1.0 / invsqnorm_denominator;
  pdx *= invsqnorm;
  pdy *= invsqnorm;

  t = (xMin - x0) * pdx + (yMin - y0) * pdy;
  tdx = (xMax - xMin) * pdx;
  tdy = (yMax - yMin) * pdy;

  // Because of the linearity of the t value, tdx can simply be added
  // the t0 to move along the top edge. After this, *lower and *upper
  // represent the parameter range for the top edge, so extending it
  // to include the whole box simply requires adding tdy to the
  // correct extreme.

  range[0] = range[1] = t;
  if (tdx < 0)
    range[0] += tdx;
  else
    range[1] += tdx;

  if (tdy < 0)
    range[0] += tdy;
  else
    range[1] += tdy;

  *lower = std::max<double>(0., std::min<double>(1., range[0]));
  *upper = std::max<double>(0., std::min<double>(1., range[1]));
}					

//------------------------------------------------------------------------
// GfxRadialShading
//------------------------------------------------------------------------

#ifndef RADIAL_EPSILON
#define RADIAL_EPSILON	(1. / 1024 / 1024)
#endif

GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A,
				   double x1A, double y1A, double r1A,
				   double t0A, double t1A,
				   Function **funcsA, int nFuncsA,
				   bool extend0A, bool extend1A):
  GfxUnivariateShading(3, t0A, t1A, funcsA, nFuncsA, extend0A, extend1A)
{
  x0 = x0A;
  y0 = y0A;
  r0 = r0A;
  x1 = x1A;
  y1 = y1A;
  r1 = r1A;
}

GfxRadialShading::GfxRadialShading(GfxRadialShading *shading):
  GfxUnivariateShading(shading)
{
  x0 = shading->x0;
  y0 = shading->y0;
  r0 = shading->r0;
  x1 = shading->x1;
  y1 = shading->y1;
  r1 = shading->r1;
}

GfxRadialShading::~GfxRadialShading() {
}

GfxRadialShading *GfxRadialShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) {
  GfxRadialShading *shading;
  double x0A, y0A, r0A, x1A, y1A, r1A;
  double t0A, t1A;
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  bool extend0A, extend1A;
  Object obj1;
  int i;

  x0A = y0A = r0A = x1A = y1A = r1A = 0;
  obj1 = dict->lookup("Coords");
  if (obj1.isArray() && obj1.arrayGetLength() == 6) {
    Object obj2;
    bool dummy; // just so that we can use the getNum that returns 0 on obj2 not being a num instead of aborting
    x0A = (obj2 = obj1.arrayGet(0), obj2.getNum(&dummy));
    y0A = (obj2 = obj1.arrayGet(1), obj2.getNum(&dummy));
    r0A = (obj2 = obj1.arrayGet(2), obj2.getNum(&dummy));
    x1A = (obj2 = obj1.arrayGet(3), obj2.getNum(&dummy));
    y1A = (obj2 = obj1.arrayGet(4), obj2.getNum(&dummy));
    r1A = (obj2 = obj1.arrayGet(5), obj2.getNum(&dummy));
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid Coords in shading dictionary");
    return nullptr;
  }

  t0A = 0;
  t1A = 1;
  obj1 = dict->lookup("Domain");
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
    Object obj2;
    t0A = (obj2 = obj1.arrayGet(0), obj2.isNum() ? obj2.getNum() : 0);
    t1A = (obj2 = obj1.arrayGet(1), obj2.isNum() ? obj2.getNum() : 1);
  }

  obj1 = dict->lookup("Function");
  if (obj1.isArray()) {
    nFuncsA = obj1.arrayGetLength();
    if (nFuncsA > gfxColorMaxComps) {
      error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
      return nullptr;
    }
    for (i = 0; i < nFuncsA; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (!(funcsA[i] = Function::parse(&obj2))) {
	return nullptr;
      }
    }
  } else {
    nFuncsA = 1;
    if (!(funcsA[0] = Function::parse(&obj1))) {
      return nullptr;
    }
  }

  extend0A = extend1A = false;
  obj1 = dict->lookup("Extend");
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
    Object obj2;
    extend0A = (obj2 = obj1.arrayGet(0), obj2.isBool() ? obj2.getBool() : false);
    extend1A = (obj2 = obj1.arrayGet(1), obj2.isBool() ? obj2.getBool() : false);
  }

  shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
				 funcsA, nFuncsA, extend0A, extend1A);
  if (!shading->init(res, dict, out, state)) {
    delete shading;
    return nullptr;
  }
  return shading;
}

GfxShading *GfxRadialShading::copy() {
  return new GfxRadialShading(this);
}

double GfxRadialShading::getDistance(double sMin, double sMax) {
  double xMin, yMin, rMin, xMax, yMax, rMax;

  xMin = x0 + sMin * (x1 - x0);
  yMin = y0 + sMin * (y1 - y0);
  rMin = r0 + sMin * (r1 - r0);

  xMax = x0 + sMax * (x1 - x0);
  yMax = y0 + sMax * (y1 - y0);
  rMax = r0 + sMax * (r1 - r0);

  return hypot(xMax-xMin, yMax-yMin) + fabs(rMax-rMin);
}

// extend range, adapted from cairo, radialExtendRange
static bool
radialExtendRange (double range[2], double value, bool valid)
{
  if (!valid)
    range[0] = range[1] = value;
  else if (value < range[0])
    range[0] = value;
  else if (value > range[1])
    range[1] = value;

  return true;
}

inline void radialEdge(double num, double den, double delta, double lower, double upper,
					   double dr, double mindr, bool &valid, double *range)
{ 
  if (fabs (den) >= RADIAL_EPSILON) {					
    double t_edge, v;							    									
    t_edge = (num) / (den);						
    v = t_edge * (delta);						
    if (t_edge * dr >= mindr && (lower) <= v && v <= (upper))		
      valid = radialExtendRange (range, t_edge, valid);			
  }
}

inline void radialCorner1(double x, double y, double &b, double dx, double dy, double cr, 
					   double dr, double mindr, bool &valid, double *range)
{
    b = (x) * dx + (y) * dy + cr * dr;				
    if (fabs (b) >= RADIAL_EPSILON) {				
      double t_corner;						
      double x2 = (x) * (x);					
      double y2 = (y) * (y);					
      double cr2 = (cr) * (cr);					
      double c = x2 + y2 - cr2;					
								
      t_corner = 0.5 * c / b;					
      if (t_corner * dr >= mindr)				
	valid = radialExtendRange (range, t_corner, valid);	
    }
}

inline void radialCorner2(double x, double y, double a, double &b, double &c, double &d, double dx, double dy, double cr,
					   double inva, double dr, double mindr, bool &valid, double *range)
{
    b = (x) * dx + (y) * dy + cr * dr;				
    c = (x) * (x) + (y) * (y) - cr * cr;			
    d = b * b - a * c;						
    if (d >= 0) {						
      double t_corner;						
								
      d = sqrt (d);						
      t_corner = (b + d) * inva;				
      if (t_corner * dr >= mindr)				
	valid = radialExtendRange (range, t_corner, valid);	
      t_corner = (b - d) * inva;				
      if (t_corner * dr >= mindr)				
	valid = radialExtendRange (range, t_corner, valid);	
    }
}
void GfxRadialShading::getParameterRange(double *lower, double *upper,
					 double xMin, double yMin,
					 double xMax, double yMax) {
  double cx, cy, cr, dx, dy, dr;
  double a, x_focus, y_focus;
  double mindr, minx, miny, maxx, maxy;
  double range[2];
  bool valid;

  // A radial pattern is considered degenerate if it can be
  // represented as a solid or clear pattern.  This corresponds to one
  // of the two cases:
  //
  // 1) The radii are both very small:
  //      |dr| < FLT_EPSILON && min (r0, r1) < FLT_EPSILON
  //
  // 2) The two circles have about the same radius and are very
  //    close to each other (approximately a cylinder gradient that
  //    doesn't move with the parameter):
  //      |dr| < FLT_EPSILON && max (|dx|, |dy|) < 2 * FLT_EPSILON

  if (xMin >= xMax || yMin >=yMax || 
      (fabs (r0 - r1) < RADIAL_EPSILON &&
       (std::min<double>(r0, r1) < RADIAL_EPSILON ||
	std::max<double>(fabs (x0 - x1), fabs (y0 - y1)) < 2 * RADIAL_EPSILON))) {
    *lower = *upper = 0;
    return;
  }

  range[0] = range[1] = 0;
  valid = false;

  x_focus = y_focus = 0; // silence gcc

  cx = x0;
  cy = y0;
  cr = r0;
  dx = x1 - cx;
  dy = y1 - cy;
  dr = r1 - cr;

  // translate by -(cx, cy) to simplify computations
  xMin -= cx;
  yMin -= cy;
  xMax -= cx;
  yMax -= cy;

  // enlarge boundaries slightly to avoid rounding problems in the
  // parameter range computation
  xMin -= RADIAL_EPSILON;
  yMin -= RADIAL_EPSILON;
  xMax += RADIAL_EPSILON;
  yMax += RADIAL_EPSILON;

  // enlarge boundaries even more to avoid rounding problems when
  // testing if a point belongs to the box
  minx = xMin - RADIAL_EPSILON;
  miny = yMin - RADIAL_EPSILON;
  maxx = xMax + RADIAL_EPSILON;
  maxy = yMax + RADIAL_EPSILON;

  // we dont' allow negative radiuses, so we will be checking that
  // t*dr >= mindr to consider t valid
  mindr = -(cr + RADIAL_EPSILON);

  // After the previous transformations, the start circle is centered
  // in the origin and has radius cr. A 1-unit change in the t
  // parameter corresponds to dx,dy,dr changes in the x,y,r of the
  // circle (center coordinates, radius).
  //
  // To compute the minimum range needed to correctly draw the
  // pattern, we start with an empty range and extend it to include
  // the circles touching the bounding box or within it.
    
  // Focus, the point where the circle has radius == 0.
  //
  // r = cr + t * dr = 0
  // t = -cr / dr
  //
  // If the radius is constant (dr == 0) there is no focus (the
  // gradient represents a cylinder instead of a cone).
  if (fabs (dr) >= RADIAL_EPSILON) {
    double t_focus;

    t_focus = -cr / dr;
    x_focus = t_focus * dx;
    y_focus = t_focus * dy;
    if (minx <= x_focus && x_focus <= maxx &&
	miny <= y_focus && y_focus <= maxy)
    {
      valid = radialExtendRange (range, t_focus, valid);
    }
  }

  // Circles externally tangent to box edges.
  //
  // All circles have center in (dx, dy) * t
  //
  // If the circle is tangent to the line defined by the edge of the
  // box, then at least one of the following holds true:
  //
  //   (dx*t) + (cr + dr*t) == x0 (left   edge)
  //   (dx*t) - (cr + dr*t) == x1 (right  edge)
  //   (dy*t) + (cr + dr*t) == y0 (top    edge)
  //   (dy*t) - (cr + dr*t) == y1 (bottom edge)
  //
  // The solution is only valid if the tangent point is actually on
  // the edge, i.e. if its y coordinate is in [y0,y1] for left/right
  // edges and if its x coordinate is in [x0,x1] for top/bottom edges.
  //
  // For the first equation:
  //
  //   (dx + dr) * t = x0 - cr
  //   t = (x0 - cr) / (dx + dr)
  //   y = dy * t
  //
  // in the code this becomes:
  //
  //   t_edge = (num) / (den)
  //   v = (delta) * t_edge
  //
  // If the denominator in t is 0, the pattern is tangent to a line
  // parallel to the edge under examination. The corner-case where the
  // boundary line is the same as the edge is handled by the focus
  // point case and/or by the a==0 case.
  
  // circles tangent (externally) to left/right/top/bottom edge
  radialEdge(xMin - cr, dx + dr, dy, miny, maxy, dr, mindr, valid, range);
  radialEdge(xMax + cr, dx - dr, dy, miny, maxy, dr, mindr, valid, range);
  radialEdge(yMin - cr, dy + dr, dx, minx, maxx, dr, mindr, valid, range);
  radialEdge(yMax + cr, dy - dr, dx, minx, maxx, dr, mindr, valid, range);

  // Circles passing through a corner.
  //
  // A circle passing through the point (x,y) satisfies:
  //
  // (x-t*dx)^2 + (y-t*dy)^2 == (cr + t*dr)^2
  //
  // If we set:
  //   a = dx^2 + dy^2 - dr^2
  //   b = x*dx + y*dy + cr*dr
  //   c = x^2 + y^2 - cr^2
  // we have:
  //   a*t^2 - 2*b*t + c == 0
    
  a = dx * dx + dy * dy - dr * dr;
  if (fabs (a) < RADIAL_EPSILON * RADIAL_EPSILON) {
    double b;

    // Ensure that gradients with both a and dr small are
    // considered degenerate.
    // The floating point version of the degeneracy test implemented
    // in _radial_pattern_is_degenerate() is:
    //
    //  1) The circles are practically the same size:
    //     |dr| < RADIAL_EPSILON
    //  AND
    //  2a) The circles are both very small:
    //      min (r0, r1) < RADIAL_EPSILON
    //   OR
    //  2b) The circles are very close to each other:
    //      max (|dx|, |dy|) < 2 * RADIAL_EPSILON
    //
    // Assuming that the gradient is not degenerate, we want to
    // show that |a| < RADIAL_EPSILON^2 implies |dr| >= RADIAL_EPSILON.
    //
    // If the gradient is not degenerate yet it has |dr| <
    // RADIAL_EPSILON, (2b) is false, thus:
    //
    //   max (|dx|, |dy|) >= 2*RADIAL_EPSILON
    // which implies:
    //   4*RADIAL_EPSILON^2 <= max (|dx|, |dy|)^2 <= dx^2 + dy^2
    //
    // From the definition of a, we get:
    //   a = dx^2 + dy^2 - dr^2 < RADIAL_EPSILON^2
    //   dx^2 + dy^2 - RADIAL_EPSILON^2 < dr^2
    //   3*RADIAL_EPSILON^2 < dr^2
    //
    // which is inconsistent with the hypotheses, thus |dr| <
    // RADIAL_EPSILON is false or the gradient is degenerate.
	
    assert (fabs (dr) >= RADIAL_EPSILON);

    // If a == 0, all the circles are tangent to a line in the
    // focus point. If this line is within the box extents, we
    // should add the circle with infinite radius, but this would
    // make the range unbounded. We will be limiting the range to
    // [0,1] anyway, so we simply add the biggest legitimate
    // circle (it happens for 0 or for 1).
    if (dr < 0) {
      valid = radialExtendRange (range, 0, valid);
    } else {
      valid = radialExtendRange (range, 1, valid);
    }

    // Nondegenerate, nonlimit circles passing through the corners.
    //
    // a == 0 && a*t^2 - 2*b*t + c == 0
    //
    // t = c / (2*b)
    //
    // The b == 0 case has just been handled, so we only have to
    // compute this if b != 0.

	// circles touching each corner
	radialCorner1(xMin, yMin, b, dx, dy, cr, dr, mindr, valid, range);
	radialCorner1(xMin, yMax, b, dx, dy, cr, dr, mindr, valid, range);
	radialCorner1(xMax, yMin, b, dx, dy, cr, dr, mindr, valid, range);
	radialCorner1(xMax, yMax, b, dx, dy, cr, dr, mindr, valid, range);
  } else {
    double inva, b, c, d;

    inva = 1 / a;

    // Nondegenerate, nonlimit circles passing through the corners.
    //
    // a != 0 && a*t^2 - 2*b*t + c == 0
    //
    // t = (b +- sqrt (b*b - a*c)) / a
    //
    // If the argument of sqrt() is negative, then no circle
    // passes through the corner.

    // circles touching each corner
	radialCorner2(xMin, yMin, a, b, c, d, dx, dy, cr, inva, dr, mindr, valid, range);
	radialCorner2(xMin, yMax, a, b, c, d, dx, dy, cr, inva, dr, mindr, valid, range);
	radialCorner2(xMax, yMin, a, b, c, d, dx, dy, cr, inva, dr, mindr, valid, range);
	radialCorner2(xMax, yMax, a, b, c, d, dx, dy, cr, inva, dr, mindr, valid, range);
  }

  *lower = std::max<double>(0., std::min<double>(1., range[0]));
  *upper = std::max<double>(0., std::min<double>(1., range[1]));
}

//------------------------------------------------------------------------
// GfxShadingBitBuf
//------------------------------------------------------------------------

class GfxShadingBitBuf {
public:

  GfxShadingBitBuf(Stream *strA);
  ~GfxShadingBitBuf();
  GfxShadingBitBuf(const GfxShadingBitBuf &) = delete;
  GfxShadingBitBuf& operator=(const GfxShadingBitBuf &) = delete;
  bool getBits(int n, unsigned int *val);
  void flushBits();

private:

  Stream *str;
  int bitBuf;
  int nBits;
};

GfxShadingBitBuf::GfxShadingBitBuf(Stream *strA) {
  str = strA;
  str->reset();
  bitBuf = 0;
  nBits = 0;
}

GfxShadingBitBuf::~GfxShadingBitBuf() {
  str->close();
}

bool GfxShadingBitBuf::getBits(int n, unsigned int *val) {
  unsigned int x;

  if (nBits >= n) {
    x = (bitBuf >> (nBits - n)) & ((1 << n) - 1);
    nBits -= n;
  } else {
    x = 0;
    if (nBits > 0) {
      x = bitBuf & ((1 << nBits) - 1);
      n -= nBits;
      nBits = 0;
    }
    while (n > 0) {
      if ((bitBuf = str->getChar()) == EOF) {
	nBits = 0;
	return false;
      }
      if (n >= 8) {
	x = (x << 8) | bitBuf;
	n -= 8;
      } else {
	x = (x << n) | (bitBuf >> (8 - n));
	nBits = 8 - n;
	n = 0;
      }
    }
  }
  *val = x;
  return true;
}

void GfxShadingBitBuf::flushBits() {
  bitBuf = 0;
  nBits = 0;
}

//------------------------------------------------------------------------
// GfxGouraudTriangleShading
//------------------------------------------------------------------------

GfxGouraudTriangleShading::GfxGouraudTriangleShading(
			       int typeA,
			       GfxGouraudVertex *verticesA, int nVerticesA,
			       int (*trianglesA)[3], int nTrianglesA,
			       Function **funcsA, int nFuncsA):
  GfxShading(typeA)
{
  int i;

  vertices = verticesA;
  nVertices = nVerticesA;
  triangles = trianglesA;
  nTriangles = nTrianglesA;
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
}

GfxGouraudTriangleShading::GfxGouraudTriangleShading(
			       GfxGouraudTriangleShading *shading):
  GfxShading(shading)
{
  int i;

  nVertices = shading->nVertices;
  vertices = (GfxGouraudVertex *)gmallocn(nVertices, sizeof(GfxGouraudVertex));
  memcpy(vertices, shading->vertices, nVertices * sizeof(GfxGouraudVertex));
  nTriangles = shading->nTriangles;
  triangles = (int (*)[3])gmallocn(nTriangles * 3, sizeof(int));
  memcpy(triangles, shading->triangles, nTriangles * 3 * sizeof(int));
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
}

GfxGouraudTriangleShading::~GfxGouraudTriangleShading() {
  int i;

  gfree(vertices);
  gfree(triangles);
  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, int typeA,
							    Dict *dict,
							    Stream *str,
							    OutputDev *out, GfxState *gfxState) {
  GfxGouraudTriangleShading *shading;
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  int coordBits, compBits, flagBits, vertsPerRow, nRows;
  double xMin, xMax, yMin, yMax;
  double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps];
  double xMul, yMul;
  double cMul[gfxColorMaxComps];
  GfxGouraudVertex *verticesA;
  int (*trianglesA)[3];
  int nComps, nVerticesA, nTrianglesA, vertSize, triSize;
  unsigned int x, y, flag;
  unsigned int c[gfxColorMaxComps];
  GfxShadingBitBuf *bitBuf;
  Object obj1;
  int i, j, k, state;

  obj1 = dict->lookup("BitsPerCoordinate");
  if (obj1.isInt()) {
    coordBits = obj1.getInt();
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary");
    return nullptr;
  }
  if (unlikely(coordBits <= 0)) {
    error(errSyntaxWarning, -1, "Invalid BitsPerCoordinate in shading dictionary");
    return nullptr;
  }
  obj1 = dict->lookup("BitsPerComponent");
  if (obj1.isInt()) {
    compBits = obj1.getInt();
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary");
    return nullptr;
  }
  if (unlikely(compBits <= 0 || compBits > 31)) {
    error(errSyntaxWarning, -1, "Invalid BitsPerComponent in shading dictionary");
    return nullptr;
  }
  flagBits = vertsPerRow = 0; // make gcc happy
  if (typeA == 4) {
    obj1 = dict->lookup("BitsPerFlag");
  if (obj1.isInt()) {
      flagBits = obj1.getInt();
    } else {
      error(errSyntaxWarning, -1, "Missing or invalid BitsPerFlag in shading dictionary");
      return nullptr;
    }
  } else {
    obj1 = dict->lookup("VerticesPerRow");
  if (obj1.isInt()) {
      vertsPerRow = obj1.getInt();
    } else {
      error(errSyntaxWarning, -1, "Missing or invalid VerticesPerRow in shading dictionary");
      return nullptr;
    }
  }
  obj1 = dict->lookup("Decode");
  if (obj1.isArray() && obj1.arrayGetLength() >= 6) {
    Object obj2;
    bool decodeOk = true;
    xMin = (obj2 = obj1.arrayGet(0), obj2.getNum(&decodeOk));
    xMax = (obj2 = obj1.arrayGet(1), obj2.getNum(&decodeOk));
    xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1);
    yMin = (obj2 = obj1.arrayGet(2), obj2.getNum(&decodeOk));
    yMax = (obj2 = obj1.arrayGet(3), obj2.getNum(&decodeOk));
    yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1);
    for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) {
      cMin[i] = (obj2 = obj1.arrayGet(4 + 2*i), obj2.getNum(&decodeOk));
      cMax[i] = (obj2 = obj1.arrayGet(5 + 2*i), obj2.getNum(&decodeOk));
      cMul[i] = (cMax[i] - cMin[i]) / (double)((1u << compBits) - 1);
    }
    nComps = i;

    if (!decodeOk) {
      error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
      return nullptr;
    }
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
    return nullptr;
  }

  obj1 = dict->lookup("Function");
  if (!obj1.isNull()) {
    if (obj1.isArray()) {
      nFuncsA = obj1.arrayGetLength();
      if (nFuncsA > gfxColorMaxComps) {
	error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
	return nullptr;
      }
      for (i = 0; i < nFuncsA; ++i) {
	Object obj2 = obj1.arrayGet(i);
	if (!(funcsA[i] = Function::parse(&obj2))) {
	  return nullptr;
	}
      }
    } else {
      nFuncsA = 1;
      if (!(funcsA[0] = Function::parse(&obj1))) {
	return nullptr;
      }
    }
  } else {
    nFuncsA = 0;
  }

  nVerticesA = nTrianglesA = 0;
  verticesA = nullptr;
  trianglesA = nullptr;
  vertSize = triSize = 0;
  state = 0;
  flag = 0; // make gcc happy
  bitBuf = new GfxShadingBitBuf(str);
  while (1) {
    if (typeA == 4) {
      if (!bitBuf->getBits(flagBits, &flag)) {
	break;
      }
    }
    if (!bitBuf->getBits(coordBits, &x) ||
	!bitBuf->getBits(coordBits, &y)) {
      break;
    }
    for (i = 0; i < nComps; ++i) {
      if (!bitBuf->getBits(compBits, &c[i])) {
	break;
      }
    }
    if (i < nComps) {
      break;
    }
    if (nVerticesA == vertSize) {
      int oldVertSize = vertSize;
      vertSize = (vertSize == 0) ? 16 : 2 * vertSize;
      verticesA = (GfxGouraudVertex *)
	              greallocn(verticesA, vertSize, sizeof(GfxGouraudVertex));
      memset(verticesA + oldVertSize, 0, (vertSize - oldVertSize) * sizeof(GfxGouraudVertex));
    }
    verticesA[nVerticesA].x = xMin + xMul * (double)x;
    verticesA[nVerticesA].y = yMin + yMul * (double)y;
    for (i = 0; i < nComps; ++i) {
      verticesA[nVerticesA].color.c[i] =
	  dblToCol(cMin[i] + cMul[i] * (double)c[i]);
    }
    ++nVerticesA;
    bitBuf->flushBits();
    if (typeA == 4) {
      if (state == 0 || state == 1) {
	++state;
      } else if (state == 2 || flag > 0) {
	if (nTrianglesA == triSize) {
	  triSize = (triSize == 0) ? 16 : 2 * triSize;
	  trianglesA = (int (*)[3])
	                   greallocn(trianglesA, triSize * 3, sizeof(int));
	}
	if (state == 2) {
	  trianglesA[nTrianglesA][0] = nVerticesA - 3;
	  trianglesA[nTrianglesA][1] = nVerticesA - 2;
	  trianglesA[nTrianglesA][2] = nVerticesA - 1;
	  ++state;
	} else if (flag == 1) {
	  trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][1];
	  trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2];
	  trianglesA[nTrianglesA][2] = nVerticesA - 1;
	} else { // flag == 2
	  trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][0];
	  trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2];
	  trianglesA[nTrianglesA][2] = nVerticesA - 1;
	}
	++nTrianglesA;
      } else { // state == 3 && flag == 0
	state = 1;
      }
    }
  }
  delete bitBuf;
  if (typeA == 5 && nVerticesA > 0 && vertsPerRow > 0) {
    nRows = nVerticesA / vertsPerRow;
    nTrianglesA = (nRows - 1) * 2 * (vertsPerRow - 1);
    trianglesA = (int (*)[3])gmallocn_checkoverflow(nTrianglesA * 3, sizeof(int));
    if (unlikely(!trianglesA)) {
      gfree(verticesA);
      for (i = 0; i < nFuncsA; ++i) {
	delete funcsA[i];
      }
      return nullptr;
    }
    k = 0;
    for (i = 0; i < nRows - 1; ++i) {
      for (j = 0; j < vertsPerRow - 1; ++j) {
	trianglesA[k][0] = i * vertsPerRow + j;
	trianglesA[k][1] = i * vertsPerRow + j+1;
	trianglesA[k][2] = (i+1) * vertsPerRow + j;
	++k;
	trianglesA[k][0] = i * vertsPerRow + j+1;
	trianglesA[k][1] = (i+1) * vertsPerRow + j;
	trianglesA[k][2] = (i+1) * vertsPerRow + j+1;
	++k;
      }
    }
  }

  shading = new GfxGouraudTriangleShading(typeA, verticesA, nVerticesA,
					  trianglesA, nTrianglesA,
					  funcsA, nFuncsA);
  if (!shading->init(res, dict, out, gfxState)) {
    delete shading;
    return nullptr;
  }
  return shading;
}

GfxShading *GfxGouraudTriangleShading::copy() {
  return new GfxGouraudTriangleShading(this);
}

void GfxGouraudTriangleShading::getTriangle(
				    int i,
				    double *x0, double *y0, GfxColor *color0,
				    double *x1, double *y1, GfxColor *color1,
				    double *x2, double *y2, GfxColor *color2) {
  double in;
  double out[gfxColorMaxComps];
  int v, j;

  assert(!isParameterized()); 

  v = triangles[i][0];
  *x0 = vertices[v].x;
  *y0 = vertices[v].y;
  if (nFuncs > 0) {
    in = colToDbl(vertices[v].color.c[0]);
    for (j = 0; j < nFuncs; ++j) {
      funcs[j]->transform(&in, &out[j]);
    }
    for (j = 0; j < gfxColorMaxComps; ++j) {
      color0->c[j] = dblToCol(out[j]);
    }
  } else {
    *color0 = vertices[v].color;
  }
  v = triangles[i][1];
  *x1 = vertices[v].x;
  *y1 = vertices[v].y;
  if (nFuncs > 0) {
    in = colToDbl(vertices[v].color.c[0]);
    for (j = 0; j < nFuncs; ++j) {
      funcs[j]->transform(&in, &out[j]);
    }
    for (j = 0; j < gfxColorMaxComps; ++j) {
      color1->c[j] = dblToCol(out[j]);
    }
  } else {
    *color1 = vertices[v].color;
  }
  v = triangles[i][2];
  *x2 = vertices[v].x;
  *y2 = vertices[v].y;
  if (nFuncs > 0) {
    in = colToDbl(vertices[v].color.c[0]);
    for (j = 0; j < nFuncs; ++j) {
      funcs[j]->transform(&in, &out[j]);
    }
    for (j = 0; j < gfxColorMaxComps; ++j) {
      color2->c[j] = dblToCol(out[j]);
    }
  } else {
    *color2 = vertices[v].color;
  }
}

void GfxGouraudTriangleShading::getParameterizedColor(double t, GfxColor *color) const {
  double out[gfxColorMaxComps];

  for (int j = 0; j < nFuncs; ++j) {
    funcs[j]->transform(&t, &out[j]);
  }
  for (int j = 0; j < gfxColorMaxComps; ++j) {
    color->c[j] = dblToCol(out[j]);
  }
}

void GfxGouraudTriangleShading::getTriangle(int i,
                                            double *x0, double *y0, double *color0,
                                            double *x1, double *y1, double *color1,
                                            double *x2, double *y2, double *color2) {
  int v;

  assert(isParameterized()); 

  v = triangles[i][0];
  if (likely(v >= 0 && v < nVertices)) {
    *x0 = vertices[v].x;
    *y0 = vertices[v].y;
    *color0 = colToDbl(vertices[v].color.c[0]);
  }
  v = triangles[i][1];
  if (likely(v >= 0 && v < nVertices)) {
    *x1 = vertices[v].x;
    *y1 = vertices[v].y;
    *color1 = colToDbl(vertices[v].color.c[0]);
  }
  v = triangles[i][2];
  if (likely(v >= 0 && v < nVertices)) {
    *x2 = vertices[v].x;
    *y2 = vertices[v].y;
    *color2 = colToDbl(vertices[v].color.c[0]);
  }
}

//------------------------------------------------------------------------
// GfxPatchMeshShading
//------------------------------------------------------------------------

GfxPatchMeshShading::GfxPatchMeshShading(int typeA,
					 GfxPatch *patchesA, int nPatchesA,
					 Function **funcsA, int nFuncsA):
  GfxShading(typeA)
{
  int i;

  patches = patchesA;
  nPatches = nPatchesA;
  nFuncs = nFuncsA;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = funcsA[i];
  }
}

GfxPatchMeshShading::GfxPatchMeshShading(GfxPatchMeshShading *shading):
  GfxShading(shading)
{
  int i;

  nPatches = shading->nPatches;
  patches = (GfxPatch *)gmallocn(nPatches, sizeof(GfxPatch));
  memcpy(patches, shading->patches, nPatches * sizeof(GfxPatch));
  nFuncs = shading->nFuncs;
  for (i = 0; i < nFuncs; ++i) {
    funcs[i] = shading->funcs[i]->copy();
  }
}

GfxPatchMeshShading::~GfxPatchMeshShading() {
  int i;

  gfree(patches);
  for (i = 0; i < nFuncs; ++i) {
    delete funcs[i];
  }
}

GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Dict *dict,
						Stream *str, OutputDev *out, GfxState *state) {
  GfxPatchMeshShading *shading;
  Function *funcsA[gfxColorMaxComps];
  int nFuncsA;
  int coordBits, compBits, flagBits;
  double xMin, xMax, yMin, yMax;
  double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps];
  double xMul, yMul;
  double cMul[gfxColorMaxComps];
  GfxPatch *patchesA, *p;
  int nComps, nPatchesA, patchesSize, nPts, nColors;
  unsigned int flag;
  double x[16], y[16];
  unsigned int xi, yi;
  double c[4][gfxColorMaxComps];
  unsigned int ci;
  Object obj1;
  int i, j;

  obj1 = dict->lookup("BitsPerCoordinate");
  if (obj1.isInt()) {
    coordBits = obj1.getInt();
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary");
    return nullptr;
  }
  if (unlikely(coordBits <= 0)) {
    error(errSyntaxWarning, -1, "Invalid BitsPerCoordinate in shading dictionary");
    return nullptr;
  }
  obj1 = dict->lookup("BitsPerComponent");
  if (obj1.isInt()) {
    compBits = obj1.getInt();
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary");
    return nullptr;
  }
  if (unlikely(compBits <= 0 || compBits > 31)) {
    error(errSyntaxWarning, -1, "Invalid BitsPerComponent in shading dictionary");
    return nullptr;
  }
  obj1 = dict->lookup("BitsPerFlag");
  if (obj1.isInt()) {
    flagBits = obj1.getInt();
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid BitsPerFlag in shading dictionary");
    return nullptr;
  }
  obj1 = dict->lookup("Decode");
  if (obj1.isArray() && obj1.arrayGetLength() >= 6) {
    bool decodeOk = true;
    Object obj2;
    xMin = (obj2 = obj1.arrayGet(0), obj2.getNum(&decodeOk));
    xMax = (obj2 = obj1.arrayGet(1), obj2.getNum(&decodeOk));
    xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1);
    yMin = (obj2 = obj1.arrayGet(2), obj2.getNum(&decodeOk));
    yMax = (obj2 = obj1.arrayGet(3), obj2.getNum(&decodeOk));
    yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1);
    for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) {
      cMin[i] = (obj2 = obj1.arrayGet(4 + 2*i), obj2.getNum(&decodeOk));
      cMax[i] = (obj2 = obj1.arrayGet(5 + 2*i), obj2.getNum(&decodeOk));
      cMul[i] = (cMax[i] - cMin[i]) / (double)((1u << compBits) - 1);
    }
    nComps = i;

    if (!decodeOk) {
      error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
      return nullptr;
    }
  } else {
    error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
    return nullptr;
  }

  obj1 = dict->lookup("Function");
  if (!obj1.isNull()) {
    if (obj1.isArray()) {
      nFuncsA = obj1.arrayGetLength();
      if (nFuncsA > gfxColorMaxComps) {
	error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
	return nullptr;
      }
      for (i = 0; i < nFuncsA; ++i) {
	Object obj2 = obj1.arrayGet(i);
	if (!(funcsA[i] = Function::parse(&obj2))) {
	  return nullptr;
	}
      }
    } else {
      nFuncsA = 1;
      if (!(funcsA[0] = Function::parse(&obj1))) {
	return nullptr;
      }
    }
  } else {
    nFuncsA = 0;
  }

  nPatchesA = 0;
  patchesA = nullptr;
  patchesSize = 0;
  auto bitBuf = std::make_unique<GfxShadingBitBuf>(str);
  while (1) {
    if (!bitBuf->getBits(flagBits, &flag)) {
      break;
    }
    if (typeA == 6) {
      switch (flag) {
      case 0: nPts = 12; nColors = 4; break;
      case 1:
      case 2:
      case 3:
      default: nPts =  8; nColors = 2; break;
      }
    } else {
      switch (flag) {
      case 0: nPts = 16; nColors = 4; break;
      case 1:
      case 2:
      case 3:
      default: nPts = 12; nColors = 2; break;
      }
    }
    for (i = 0; i < nPts; ++i) {
      if (!bitBuf->getBits(coordBits, &xi) ||
	  !bitBuf->getBits(coordBits, &yi)) {
	break;
      }
      x[i] = xMin + xMul * (double)xi;
      y[i] = yMin + yMul * (double)yi;
    }
    if (i < nPts) {
      break;
    }
    for (i = 0; i < nColors; ++i) {
      for (j = 0; j < nComps; ++j) {
	if (!bitBuf->getBits(compBits, &ci)) {
	  break;
	}
	c[i][j] = cMin[j] + cMul[j] * (double)ci;
	if( nFuncsA == 0 ) {
	  // ... and colorspace values can also be stored into doubles.
	  // They will be casted later.
	  c[i][j] = dblToCol(c[i][j]);
	}
      }
      if (j < nComps) {
	break;
      }
    }
    if (i < nColors) {
      break;
    }
    if (nPatchesA == patchesSize) {
      int oldPatchesSize = patchesSize;
      patchesSize = (patchesSize == 0) ? 16 : 2 * patchesSize;
      patchesA = (GfxPatch *)greallocn(patchesA,
				       patchesSize, sizeof(GfxPatch));
      memset(patchesA + oldPatchesSize, 0, (patchesSize - oldPatchesSize) * sizeof(GfxPatch));
    }
    p = &patchesA[nPatchesA];
    if (typeA == 6) {
      switch (flag) {
      case 0:
	p->x[0][0] = x[0];
	p->y[0][0] = y[0];
	p->x[0][1] = x[1];
	p->y[0][1] = y[1];
	p->x[0][2] = x[2];
	p->y[0][2] = y[2];
	p->x[0][3] = x[3];
	p->y[0][3] = y[3];
	p->x[1][3] = x[4];
	p->y[1][3] = y[4];
	p->x[2][3] = x[5];
	p->y[2][3] = y[5];
	p->x[3][3] = x[6];
	p->y[3][3] = y[6];
	p->x[3][2] = x[7];
	p->y[3][2] = y[7];
	p->x[3][1] = x[8];
	p->y[3][1] = y[8];
	p->x[3][0] = x[9];
	p->y[3][0] = y[9];
	p->x[2][0] = x[10];
	p->y[2][0] = y[10];
	p->x[1][0] = x[11];
	p->y[1][0] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = c[0][j];
	  p->color[0][1].c[j] = c[1][j];
	  p->color[1][1].c[j] = c[2][j];
	  p->color[1][0].c[j] = c[3][j];
	}
	break;
      case 1:
	if (nPatchesA == 0) {
          gfree(patchesA);
	  for (int k = 0; k < nFuncsA; ++k) delete funcsA[k];
	  return nullptr;
	}
	p->x[0][0] = patchesA[nPatchesA-1].x[0][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[0][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[1][3];
	p->y[0][1] = patchesA[nPatchesA-1].y[1][3];
	p->x[0][2] = patchesA[nPatchesA-1].x[2][3];
	p->y[0][2] = patchesA[nPatchesA-1].y[2][3];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][3];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 2:
	if (nPatchesA == 0) {
          gfree(patchesA);
	  for (int k = 0; k < nFuncsA; ++k) delete funcsA[k];
	  return nullptr;
	}
	p->x[0][0] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[3][2];
	p->y[0][1] = patchesA[nPatchesA-1].y[3][2];
	p->x[0][2] = patchesA[nPatchesA-1].x[3][1];
	p->y[0][2] = patchesA[nPatchesA-1].y[3][1];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 3:
	if (nPatchesA == 0) {
          gfree(patchesA);
	  for (int k = 0; k < nFuncsA; ++k) delete funcsA[k];
	  return nullptr;
	}
	p->x[0][0] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][0];
	p->x[0][1] = patchesA[nPatchesA-1].x[2][0];
	p->y[0][1] = patchesA[nPatchesA-1].y[2][0];
	p->x[0][2] = patchesA[nPatchesA-1].x[1][0];
	p->y[0][2] = patchesA[nPatchesA-1].y[1][0];
	p->x[0][3] = patchesA[nPatchesA-1].x[0][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[0][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
  }
    } else {
      switch (flag) {
      case 0:
	p->x[0][0] = x[0];
	p->y[0][0] = y[0];
	p->x[0][1] = x[1];
	p->y[0][1] = y[1];
	p->x[0][2] = x[2];
	p->y[0][2] = y[2];
	p->x[0][3] = x[3];
	p->y[0][3] = y[3];
	p->x[1][3] = x[4];
	p->y[1][3] = y[4];
	p->x[2][3] = x[5];
	p->y[2][3] = y[5];
	p->x[3][3] = x[6];
	p->y[3][3] = y[6];
	p->x[3][2] = x[7];
	p->y[3][2] = y[7];
	p->x[3][1] = x[8];
	p->y[3][1] = y[8];
	p->x[3][0] = x[9];
	p->y[3][0] = y[9];
	p->x[2][0] = x[10];
	p->y[2][0] = y[10];
	p->x[1][0] = x[11];
	p->y[1][0] = y[11];
	p->x[1][1] = x[12];
	p->y[1][1] = y[12];
	p->x[1][2] = x[13];
	p->y[1][2] = y[13];
	p->x[2][2] = x[14];
	p->y[2][2] = y[14];
	p->x[2][1] = x[15];
	p->y[2][1] = y[15];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = c[0][j];
	  p->color[0][1].c[j] = c[1][j];
	  p->color[1][1].c[j] = c[2][j];
	  p->color[1][0].c[j] = c[3][j];
	}
	break;
      case 1:
	if (nPatchesA == 0) {
          gfree(patchesA);
	  for (int k = 0; k < nFuncsA; ++k) delete funcsA[k];
	  return nullptr;
	}
	p->x[0][0] = patchesA[nPatchesA-1].x[0][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[0][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[1][3];
	p->y[0][1] = patchesA[nPatchesA-1].y[1][3];
	p->x[0][2] = patchesA[nPatchesA-1].x[2][3];
	p->y[0][2] = patchesA[nPatchesA-1].y[2][3];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][3];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	p->x[1][1] = x[8];
	p->y[1][1] = y[8];
	p->x[1][2] = x[9];
	p->y[1][2] = y[9];
	p->x[2][2] = x[10];
	p->y[2][2] = y[10];
	p->x[2][1] = x[11];
	p->y[2][1] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 2:
	if (nPatchesA == 0) {
          gfree(patchesA);
	  for (int k = 0; k < nFuncsA; ++k) delete funcsA[k];
	  return nullptr;
	}
	p->x[0][0] = patchesA[nPatchesA-1].x[3][3];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][3];
	p->x[0][1] = patchesA[nPatchesA-1].x[3][2];
	p->y[0][1] = patchesA[nPatchesA-1].y[3][2];
	p->x[0][2] = patchesA[nPatchesA-1].x[3][1];
	p->y[0][2] = patchesA[nPatchesA-1].y[3][1];
	p->x[0][3] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[3][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	p->x[1][1] = x[8];
	p->y[1][1] = y[8];
	p->x[1][2] = x[9];
	p->y[1][2] = y[9];
	p->x[2][2] = x[10];
	p->y[2][2] = y[10];
	p->x[2][1] = x[11];
	p->y[2][1] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      case 3:
	if (nPatchesA == 0) {
          gfree(patchesA);
	  for (int k = 0; k < nFuncsA; ++k) delete funcsA[k];
	  return nullptr;
	}
	p->x[0][0] = patchesA[nPatchesA-1].x[3][0];
	p->y[0][0] = patchesA[nPatchesA-1].y[3][0];
	p->x[0][1] = patchesA[nPatchesA-1].x[2][0];
	p->y[0][1] = patchesA[nPatchesA-1].y[2][0];
	p->x[0][2] = patchesA[nPatchesA-1].x[1][0];
	p->y[0][2] = patchesA[nPatchesA-1].y[1][0];
	p->x[0][3] = patchesA[nPatchesA-1].x[0][0];
	p->y[0][3] = patchesA[nPatchesA-1].y[0][0];
	p->x[1][3] = x[0];
	p->y[1][3] = y[0];
	p->x[2][3] = x[1];
	p->y[2][3] = y[1];
	p->x[3][3] = x[2];
	p->y[3][3] = y[2];
	p->x[3][2] = x[3];
	p->y[3][2] = y[3];
	p->x[3][1] = x[4];
	p->y[3][1] = y[4];
	p->x[3][0] = x[5];
	p->y[3][0] = y[5];
	p->x[2][0] = x[6];
	p->y[2][0] = y[6];
	p->x[1][0] = x[7];
	p->y[1][0] = y[7];
	p->x[1][1] = x[8];
	p->y[1][1] = y[8];
	p->x[1][2] = x[9];
	p->y[1][2] = y[9];
	p->x[2][2] = x[10];
	p->y[2][2] = y[10];
	p->x[2][1] = x[11];
	p->y[2][1] = y[11];
	for (j = 0; j < nComps; ++j) {
	  p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
	  p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j];
	  p->color[1][1].c[j] = c[0][j];
	  p->color[1][0].c[j] = c[1][j];
	}
	break;
      }
    }
    ++nPatchesA;
    bitBuf->flushBits();
  }

  if (typeA == 6) {
    for (i = 0; i < nPatchesA; ++i) {
      p = &patchesA[i];
      p->x[1][1] = (-4 * p->x[0][0]
		    +6 * (p->x[0][1] + p->x[1][0])
		    -2 * (p->x[0][3] + p->x[3][0])
		    +3 * (p->x[3][1] + p->x[1][3])
		    - p->x[3][3]) / 9;
      p->y[1][1] = (-4 * p->y[0][0]
		    +6 * (p->y[0][1] + p->y[1][0])
		    -2 * (p->y[0][3] + p->y[3][0])
		    +3 * (p->y[3][1] + p->y[1][3])
		    - p->y[3][3]) / 9;
      p->x[1][2] = (-4 * p->x[0][3]
		    +6 * (p->x[0][2] + p->x[1][3])
		    -2 * (p->x[0][0] + p->x[3][3])
		    +3 * (p->x[3][2] + p->x[1][0])
		    - p->x[3][0]) / 9;
      p->y[1][2] = (-4 * p->y[0][3]
		    +6 * (p->y[0][2] + p->y[1][3])
		    -2 * (p->y[0][0] + p->y[3][3])
		    +3 * (p->y[3][2] + p->y[1][0])
		    - p->y[3][0]) / 9;
      p->x[2][1] = (-4 * p->x[3][0]
		    +6 * (p->x[3][1] + p->x[2][0])
		    -2 * (p->x[3][3] + p->x[0][0])
		    +3 * (p->x[0][1] + p->x[2][3])
		    - p->x[0][3]) / 9;
      p->y[2][1] = (-4 * p->y[3][0]
		    +6 * (p->y[3][1] + p->y[2][0])
		    -2 * (p->y[3][3] + p->y[0][0])
		    +3 * (p->y[0][1] + p->y[2][3])
		    - p->y[0][3]) / 9;
      p->x[2][2] = (-4 * p->x[3][3]
		    +6 * (p->x[3][2] + p->x[2][3])
		    -2 * (p->x[3][0] + p->x[0][3])
		    +3 * (p->x[0][2] + p->x[2][0])
		    - p->x[0][0]) / 9;
      p->y[2][2] = (-4 * p->y[3][3]
		    +6 * (p->y[3][2] + p->y[2][3])
		    -2 * (p->y[3][0] + p->y[0][3])
		    +3 * (p->y[0][2] + p->y[2][0])
		    - p->y[0][0]) / 9;
    }
  }

  shading = new GfxPatchMeshShading(typeA, patchesA, nPatchesA,
				    funcsA, nFuncsA);
  if (!shading->init(res, dict, out, state)) {
    delete shading;
    return nullptr;
  }
  return shading;
}

void GfxPatchMeshShading::getParameterizedColor(double t, GfxColor *color) const {
  double out[gfxColorMaxComps] = {};

  for (int j = 0; j < nFuncs; ++j) {
    funcs[j]->transform(&t, &out[j]);
  }
  for (int j = 0; j < gfxColorMaxComps; ++j) {
    color->c[j] = dblToCol(out[j]);
  }
}

GfxShading *GfxPatchMeshShading::copy() {
  return new GfxPatchMeshShading(this);
}

//------------------------------------------------------------------------
// GfxImageColorMap
//------------------------------------------------------------------------

GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
				   GfxColorSpace *colorSpaceA) {
  GfxIndexedColorSpace *indexedCS;
  GfxSeparationColorSpace *sepCS;
  int maxPixel, indexHigh;
  unsigned char *indexedLookup;
  const Function *sepFunc;
  double x[gfxColorMaxComps];
  double y[gfxColorMaxComps] = {};
  int i, j, k;
  double mapped;
  bool useByteLookup;

  ok = true;
  useMatte = false;

  colorSpace = colorSpaceA;

  // initialize
  for (k = 0; k < gfxColorMaxComps; ++k) {
    lookup[k] = nullptr;
    lookup2[k] = nullptr;
  }
  byte_lookup = nullptr;

  // bits per component and color space
  if (unlikely(bitsA <= 0 || bitsA > 30))
    goto err1;

  bits = bitsA;
  maxPixel = (1 << bits) - 1;

  // this is a hack to support 16 bits images, everywhere
  // we assume a component fits in 8 bits, with this hack
  // we treat 16 bit images as 8 bit ones until it's fixed correctly.
  // The hack has another part on ImageStream::getLine
  if (maxPixel > 255) maxPixel = 255;

  // get decode map
  if (decode->isNull()) {
    nComps = colorSpace->getNComps();
    colorSpace->getDefaultRanges(decodeLow, decodeRange, maxPixel);
  } else if (decode->isArray()) {
    nComps = decode->arrayGetLength() / 2;
    if (nComps < colorSpace->getNComps()) {
      goto err1;
    }
    if (nComps > colorSpace->getNComps()) {
      error(errSyntaxWarning, -1, "Too many elements in Decode array");
      nComps = colorSpace->getNComps();
    }
    for (i = 0; i < nComps; ++i) {
      Object obj = decode->arrayGet(2*i);
      if (!obj.isNum()) {
	goto err1;
      }
      decodeLow[i] = obj.getNum();
      obj = decode->arrayGet(2*i+1);
      if (!obj.isNum()) {
	goto err1;
      }
      decodeRange[i] = obj.getNum() - decodeLow[i];
    }
  } else {
    goto err1;
  }

  // Construct a lookup table -- this stores pre-computed decoded
  // values for each component, i.e., the result of applying the
  // decode mapping to each possible image pixel component value.
  for (k = 0; k < nComps; ++k) {
    lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
					 sizeof(GfxColorComp));
    for (i = 0; i <= maxPixel; ++i) {
      lookup[k][i] = dblToCol(decodeLow[k] +
			      (i * decodeRange[k]) / maxPixel);
    }
  }

  // Optimization: for Indexed and Separation color spaces (which have
  // only one component), we pre-compute a second lookup table with
  // color values
  colorSpace2 = nullptr;
  nComps2 = 0;
  useByteLookup = false;
  switch (colorSpace->getMode()) {
  case csIndexed:
    // Note that indexHigh may not be the same as maxPixel --
    // Distiller will remove unused palette entries, resulting in
    // indexHigh < maxPixel.
    indexedCS = (GfxIndexedColorSpace *)colorSpace;
    colorSpace2 = indexedCS->getBase();
    indexHigh = indexedCS->getIndexHigh();
    nComps2 = colorSpace2->getNComps();
    indexedLookup = indexedCS->getLookup();
    colorSpace2->getDefaultRanges(x, y, indexHigh);
    if (colorSpace2->useGetGrayLine() || colorSpace2->useGetRGBLine() || colorSpace2->useGetCMYKLine() || colorSpace2->useGetDeviceNLine()) {
      byte_lookup = (unsigned char *)gmallocn ((maxPixel + 1), nComps2);
      useByteLookup = true;
    }
    for (k = 0; k < nComps2; ++k) {
      lookup2[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
					   sizeof(GfxColorComp));
      for (i = 0; i <= maxPixel; ++i) {
	j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
	if (j < 0) {
	  j = 0;
	} else if (j > indexHigh) {
	  j = indexHigh;
	}

	mapped = x[k] + (indexedLookup[j*nComps2 + k] / 255.0) * y[k];
	lookup2[k][i] = dblToCol(mapped);
	if (useByteLookup)
	  byte_lookup[i * nComps2 + k] = (unsigned char) (mapped * 255);
      }
    }
    break;
  case csSeparation:
    sepCS = (GfxSeparationColorSpace *)colorSpace;
    colorSpace2 = sepCS->getAlt();
    nComps2 = colorSpace2->getNComps();
    sepFunc = sepCS->getFunc();
    if (colorSpace2->useGetGrayLine() || colorSpace2->useGetRGBLine() || colorSpace2->useGetCMYKLine() || colorSpace2->useGetDeviceNLine()) {
      byte_lookup = (unsigned char *)gmallocn ((maxPixel + 1), nComps2);
      useByteLookup = true;
    }
    for (k = 0; k < nComps2; ++k) {
      lookup2[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
					   sizeof(GfxColorComp));
      for (i = 0; i <= maxPixel; ++i) {
	x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
	sepFunc->transform(x, y);
	lookup2[k][i] = dblToCol(y[k]);
	if (useByteLookup)
	  byte_lookup[i*nComps2 + k] = (unsigned char) (y[k] * 255);
      }
    }
    break;
  default:
    if (colorSpace->useGetGrayLine() || colorSpace->useGetRGBLine() || colorSpace->useGetCMYKLine() || colorSpace->useGetDeviceNLine()) {
      byte_lookup = (unsigned char *)gmallocn ((maxPixel + 1), nComps);
      useByteLookup = true;
    }
    for (k = 0; k < nComps; ++k) {
      lookup2[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
					   sizeof(GfxColorComp));
      for (i = 0; i <= maxPixel; ++i) {
	mapped = decodeLow[k] + (i * decodeRange[k]) / maxPixel;
	lookup2[k][i] = dblToCol(mapped);
	if (useByteLookup) {
	  int byte;

	  byte = (int) (mapped * 255.0 + 0.5);
	  if (byte < 0)
	    byte = 0;
	  else if (byte > 255)
	    byte = 255;
	  byte_lookup[i * nComps + k] = byte;
	}
      }
    }
  }

  return;

 err1:
  ok = false;
}

GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) {
  int n, i, k;

  colorSpace = colorMap->colorSpace->copy();
  bits = colorMap->bits;
  nComps = colorMap->nComps;
  nComps2 = colorMap->nComps2;
  useMatte = colorMap->useMatte;
  matteColor = colorMap->matteColor;
  colorSpace2 = nullptr;
  for (k = 0; k < gfxColorMaxComps; ++k) {
    lookup[k] = nullptr;
    lookup2[k] = nullptr;
  }
  byte_lookup = nullptr;
  n = 1 << bits;
  for (k = 0; k < nComps; ++k) {
    lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
    memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
  }
  if (colorSpace->getMode() == csIndexed) {
    colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase();
    for (k = 0; k < nComps2; ++k) {
      lookup2[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
      memcpy(lookup2[k], colorMap->lookup2[k], n * sizeof(GfxColorComp));
    }
  } else if (colorSpace->getMode() == csSeparation) {
    colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt();
    for (k = 0; k < nComps2; ++k) {
      lookup2[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
      memcpy(lookup2[k], colorMap->lookup2[k], n * sizeof(GfxColorComp));
    }
  } else {
    for (k = 0; k < nComps; ++k) {
      lookup2[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
      memcpy(lookup2[k], colorMap->lookup2[k], n * sizeof(GfxColorComp));
    }
  }
  if (colorMap->byte_lookup) {
    int nc = colorSpace2 ? nComps2 : nComps;

    byte_lookup = (unsigned char *)gmallocn (n, nc);
    memcpy(byte_lookup, colorMap->byte_lookup, n * nc);
  }
  for (i = 0; i < nComps; ++i) {
    decodeLow[i] = colorMap->decodeLow[i];
    decodeRange[i] = colorMap->decodeRange[i];
  }
  ok = true;
}

GfxImageColorMap::~GfxImageColorMap() {
  int i;

  delete colorSpace;
  for (i = 0; i < gfxColorMaxComps; ++i) {
    gfree(lookup[i]);
    gfree(lookup2[i]);
  }
  gfree(byte_lookup);
}

void GfxImageColorMap::getGray(unsigned char *x, GfxGray *gray) {
  GfxColor color;
  int i;

  if (colorSpace2) {
    for (i = 0; i < nComps2; ++i) {
      color.c[i] = lookup2[i][x[0]];
    }
    colorSpace2->getGray(&color, gray);
  } else {
    for (i = 0; i < nComps; ++i) {
      color.c[i] = lookup2[i][x[i]];
    }
    colorSpace->getGray(&color, gray);
  }
}

void GfxImageColorMap::getRGB(unsigned char *x, GfxRGB *rgb) {
  GfxColor color;
  int i;

  if (colorSpace2) {
    for (i = 0; i < nComps2; ++i) {
      color.c[i] = lookup2[i][x[0]];
    }
    colorSpace2->getRGB(&color, rgb);
  } else {
    for (i = 0; i < nComps; ++i) {
      color.c[i] = lookup2[i][x[i]];
    }
    colorSpace->getRGB(&color, rgb);
  }
}

void GfxImageColorMap::getGrayLine(unsigned char *in, unsigned char *out, int length) {
  int i, j;
  unsigned char *inp, *tmp_line;

  if ((colorSpace2 && !colorSpace2->useGetGrayLine ()) ||
      (!colorSpace2 && !colorSpace->useGetGrayLine ())) {
    GfxGray gray;

    inp = in;
    for (i = 0; i < length; i++) {
      getGray (inp, &gray);
      out[i] = colToByte(gray);
      inp += nComps;
    }
    return;
  }

  switch (colorSpace->getMode()) {
  case csIndexed:
  case csSeparation:
    tmp_line = (unsigned char *) gmallocn (length, nComps2);
    for (i = 0; i < length; i++) {
      for (j = 0; j < nComps2; j++) {
	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
      }
    }
    colorSpace2->getGrayLine(tmp_line, out, length);
    gfree (tmp_line);
    break;

  default:
    inp = in;
    for (j = 0; j < length; j++)
      for (i = 0; i < nComps; i++) {
	*inp = byte_lookup[*inp * nComps + i];
	inp++;
      }
    colorSpace->getGrayLine(in, out, length);
    break;
  }

}

void GfxImageColorMap::getRGBLine(unsigned char *in, unsigned int *out, int length) {
  int i, j;
  unsigned char *inp, *tmp_line;

  if (!useRGBLine()) {
    GfxRGB rgb;

    inp = in;
    for (i = 0; i < length; i++) {
      getRGB (inp, &rgb);
      out[i] =
          ((int) colToByte(rgb.r) << 16) |
          ((int) colToByte(rgb.g) << 8) |
	  ((int) colToByte(rgb.b) << 0);
      inp += nComps;
    }
    return;
  }

  switch (colorSpace->getMode()) {
  case csIndexed:
  case csSeparation:
    tmp_line = (unsigned char *) gmallocn (length, nComps2);
    for (i = 0; i < length; i++) {
      for (j = 0; j < nComps2; j++) {
	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
      }
    }
    colorSpace2->getRGBLine(tmp_line, out, length);
    gfree (tmp_line);
    break;

  default:
    inp = in;
    for (j = 0; j < length; j++)
      for (i = 0; i < nComps; i++) {
	*inp = byte_lookup[*inp * nComps + i];
	inp++;
      }
    colorSpace->getRGBLine(in, out, length);
    break;
  }

}

void GfxImageColorMap::getRGBLine(unsigned char *in, unsigned char *out, int length) {
  int i, j;
  unsigned char *inp, *tmp_line;

  if (!useRGBLine()) {
    GfxRGB rgb;

    inp = in;
    for (i = 0; i < length; i++) {
      getRGB (inp, &rgb);
      *out++ = colToByte(rgb.r);
      *out++ = colToByte(rgb.g);
      *out++ = colToByte(rgb.b);
      inp += nComps;
    }
    return;
  }

  switch (colorSpace->getMode()) {
  case csIndexed:
  case csSeparation:
    tmp_line = (unsigned char *) gmallocn (length, nComps2);
    for (i = 0; i < length; i++) {
      for (j = 0; j < nComps2; j++) {
	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
      }
    }
    colorSpace2->getRGBLine(tmp_line, out, length);
    gfree (tmp_line);
    break;

  default:
    inp = in;
    for (j = 0; j < length; j++)
      for (i = 0; i < nComps; i++) {
	*inp = byte_lookup[*inp * nComps + i];
	inp++;
      }
    colorSpace->getRGBLine(in, out, length);
    break;
  }

}

void GfxImageColorMap::getRGBXLine(unsigned char *in, unsigned char *out, int length) {
  int i, j;
  unsigned char *inp, *tmp_line;

  if (!useRGBLine()) {
    GfxRGB rgb;

    inp = in;
    for (i = 0; i < length; i++) {
      getRGB (inp, &rgb);
      *out++ = colToByte(rgb.r);
      *out++ = colToByte(rgb.g);
      *out++ = colToByte(rgb.b);
      *out++ = 255;
      inp += nComps;
    }
    return;
  }

  switch (colorSpace->getMode()) {
  case csIndexed:
  case csSeparation:
    tmp_line = (unsigned char *) gmallocn (length, nComps2);
    for (i = 0; i < length; i++) {
      for (j = 0; j < nComps2; j++) {
	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
      }
    }
    colorSpace2->getRGBXLine(tmp_line, out, length);
    gfree (tmp_line);
    break;

  default:
    inp = in;
    for (j = 0; j < length; j++)
      for (i = 0; i < nComps; i++) {
	*inp = byte_lookup[*inp * nComps + i];
	inp++;
      }
    colorSpace->getRGBXLine(in, out, length);
    break;
  }

}

void GfxImageColorMap::getCMYKLine(unsigned char *in, unsigned char *out, int length) {
  int i, j;
  unsigned char *inp, *tmp_line;

  if (!useCMYKLine()) {
    GfxCMYK cmyk;

    inp = in;
    for (i = 0; i < length; i++) {
      getCMYK (inp, &cmyk);
      *out++ = colToByte(cmyk.c);
      *out++ = colToByte(cmyk.m);
      *out++ = colToByte(cmyk.y);
      *out++ = colToByte(cmyk.k);
      inp += nComps;
    }
    return;
  }

  switch (colorSpace->getMode()) {
  case csIndexed:
  case csSeparation:
    tmp_line = (unsigned char *) gmallocn (length, nComps2);
    for (i = 0; i < length; i++) {
      for (j = 0; j < nComps2; j++) {
	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
      }
    }
    colorSpace2->getCMYKLine(tmp_line, out, length);
    gfree (tmp_line);
    break;

  default:
    inp = in;
    for (j = 0; j < length; j++)
      for (i = 0; i < nComps; i++) {
	*inp = byte_lookup[*inp * nComps + i];
	inp++;
      }
    colorSpace->getCMYKLine(in, out, length);
    break;
  }

}

void GfxImageColorMap::getDeviceNLine(unsigned char *in, unsigned char *out, int length) {
  unsigned char *inp, *tmp_line;

  if (!useDeviceNLine()) {
    GfxColor deviceN;

    inp = in;
    for (int i = 0; i < length; i++) {
      getDeviceN (inp, &deviceN);
      for (int j = 0; j < SPOT_NCOMPS+4; j++)
        *out++ = deviceN.c[j];
      inp += nComps;
    }
    return;
  }

  switch (colorSpace->getMode()) {
  case csIndexed:
  case csSeparation:
    tmp_line = (unsigned char *) gmallocn (length, nComps2);
    for (int i = 0; i < length; i++) {
      for (int j = 0; j < nComps2; j++) {
	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
      }
    }
    colorSpace2->getDeviceNLine(tmp_line, out, length);
    gfree (tmp_line);
    break;

  default:
    inp = in;
    for (int j = 0; j < length; j++)
      for (int i = 0; i < nComps; i++) {
	*inp = byte_lookup[*inp * nComps + i];
	inp++;
      }
    colorSpace->getDeviceNLine(in, out, length);
    break;
  }

}

void GfxImageColorMap::getCMYK(unsigned char *x, GfxCMYK *cmyk) {
  GfxColor color;
  int i;

  if (colorSpace2) {
    for (i = 0; i < nComps2; ++i) {
      color.c[i] = lookup2[i][x[0]];
    }
    colorSpace2->getCMYK(&color, cmyk);
  } else {
    for (i = 0; i < nComps; ++i) {
      color.c[i] = lookup[i][x[i]];
    }
    colorSpace->getCMYK(&color, cmyk);
  }
}

void GfxImageColorMap::getDeviceN(unsigned char *x, GfxColor *deviceN) {
  GfxColor color;
  int i;

  if (colorSpace2) {
    for (i = 0; i < nComps2; ++i) {
      color.c[i] = lookup2[i][x[0]];
    }
    colorSpace2->getDeviceN(&color, deviceN);
  } else {
    for (i = 0; i < nComps; ++i) {
      color.c[i] = lookup[i][x[i]];
    }
    colorSpace->getDeviceN(&color, deviceN);
  }
}

void GfxImageColorMap::getColor(unsigned char *x, GfxColor *color) {
  int maxPixel, i;

  maxPixel = (1 << bits) - 1;
  for (i = 0; i < nComps; ++i) {
    color->c[i] = dblToCol(decodeLow[i] + (x[i] * decodeRange[i]) / maxPixel);
  }
}

//------------------------------------------------------------------------
// GfxSubpath and GfxPath
//------------------------------------------------------------------------

GfxSubpath::GfxSubpath(double x1, double y1) {
  size = 16;
  x = (double *)gmallocn(size, sizeof(double));
  y = (double *)gmallocn(size, sizeof(double));
  curve = (bool *)gmallocn(size, sizeof(bool));
  n = 1;
  x[0] = x1;
  y[0] = y1;
  curve[0] = false;
  closed = false;
}

GfxSubpath::~GfxSubpath() {
  gfree(x);
  gfree(y);
  gfree(curve);
}

// Used for copy().
GfxSubpath::GfxSubpath(const GfxSubpath *subpath) {
  size = subpath->size;
  n = subpath->n;
  x = (double *)gmallocn(size, sizeof(double));
  y = (double *)gmallocn(size, sizeof(double));
  curve = (bool *)gmallocn(size, sizeof(bool));
  memcpy(x, subpath->x, n * sizeof(double));
  memcpy(y, subpath->y, n * sizeof(double));
  memcpy(curve, subpath->curve, n * sizeof(bool));
  closed = subpath->closed;
}

void GfxSubpath::lineTo(double x1, double y1) {
  if (n >= size) {
    size *= 2;
    x = (double *)greallocn(x, size, sizeof(double));
    y = (double *)greallocn(y, size, sizeof(double));
    curve = (bool *)greallocn(curve, size, sizeof(bool));
  }
  x[n] = x1;
  y[n] = y1;
  curve[n] = false;
  ++n;
}

void GfxSubpath::curveTo(double x1, double y1, double x2, double y2,
			 double x3, double y3) {
  if (n+3 > size) {
    size *= 2;
    x = (double *)greallocn(x, size, sizeof(double));
    y = (double *)greallocn(y, size, sizeof(double));
    curve = (bool *)greallocn(curve, size, sizeof(bool));
  }
  x[n] = x1;
  y[n] = y1;
  x[n+1] = x2;
  y[n+1] = y2;
  x[n+2] = x3;
  y[n+2] = y3;
  curve[n] = curve[n+1] = true;
  curve[n+2] = false;
  n += 3;
}

void GfxSubpath::close() {
  if (x[n-1] != x[0] || y[n-1] != y[0]) {
    lineTo(x[0], y[0]);
  }
  closed = true;
}

void GfxSubpath::offset(double dx, double dy) {
  int i;

  for (i = 0; i < n; ++i) {
    x[i] += dx;
    y[i] += dy;
  }
}

GfxPath::GfxPath() {
  justMoved = false;
  size = 16;
  n = 0;
  firstX = firstY = 0;
  subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *));
}

GfxPath::~GfxPath() {
  int i;

  for (i = 0; i < n; ++i)
    delete subpaths[i];
  gfree(subpaths);
}

// Used for copy().
GfxPath::GfxPath(bool justMoved1, double firstX1, double firstY1,
		 GfxSubpath **subpaths1, int n1, int size1) {
  int i;

  justMoved = justMoved1;
  firstX = firstX1;
  firstY = firstY1;
  size = size1;
  n = n1;
  subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *));
  for (i = 0; i < n; ++i)
    subpaths[i] = subpaths1[i]->copy();
}

void GfxPath::moveTo(double x, double y) {
  justMoved = true;
  firstX = x;
  firstY = y;
}

void GfxPath::lineTo(double x, double y) {
  if (justMoved || (n > 0 && subpaths[n-1]->isClosed())) {
    if (n >= size) {
      size *= 2;
      subpaths = (GfxSubpath **)
	           greallocn(subpaths, size, sizeof(GfxSubpath *));
    }
    if (justMoved) {
      subpaths[n] = new GfxSubpath(firstX, firstY);
    } else {
      subpaths[n] = new GfxSubpath(subpaths[n-1]->getLastX(),
				   subpaths[n-1]->getLastY());
    }
    ++n;
    justMoved = false;
  }
  subpaths[n-1]->lineTo(x, y);
}

void GfxPath::curveTo(double x1, double y1, double x2, double y2,
	     double x3, double y3) {
  if (justMoved || (n > 0 && subpaths[n-1]->isClosed())) {
    if (n >= size) {
      size *= 2;
      subpaths = (GfxSubpath **) 
 	         greallocn(subpaths, size, sizeof(GfxSubpath *));
    }
    if (justMoved) {
      subpaths[n] = new GfxSubpath(firstX, firstY);
    } else {
      subpaths[n] = new GfxSubpath(subpaths[n-1]->getLastX(),
				   subpaths[n-1]->getLastY());
    }
    ++n;
    justMoved = false;
  }
  subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3);
}

void GfxPath::close() {
  // this is necessary to handle the pathological case of
  // moveto/closepath/clip, which defines an empty clipping region
  if (justMoved) {
    if (n >= size) {
      size *= 2;
      subpaths = (GfxSubpath **)
	greallocn(subpaths, size, sizeof(GfxSubpath *));
    }
    subpaths[n] = new GfxSubpath(firstX, firstY);
    ++n;
    justMoved = false;
  }
  subpaths[n-1]->close();
}

void GfxPath::append(GfxPath *path) {
  int i;

  if (n + path->n > size) {
    size = n + path->n;
    subpaths = (GfxSubpath **)
                 greallocn(subpaths, size, sizeof(GfxSubpath *));
  }
  for (i = 0; i < path->n; ++i) {
    subpaths[n++] = path->subpaths[i]->copy();
  }
  justMoved = false;
}

void GfxPath::offset(double dx, double dy) {
  int i;

  for (i = 0; i < n; ++i) {
    subpaths[i]->offset(dx, dy);
  }
}

//------------------------------------------------------------------------
//
//------------------------------------------------------------------------
GfxState::ReusablePathIterator::ReusablePathIterator(GfxPath *pathA)
 : path(pathA),
   subPathOff(0),
   coordOff(0),
   numCoords(0),
   curSubPath(nullptr)
{
  if( path->getNumSubpaths() ) {
    curSubPath = path->getSubpath(subPathOff);
    numCoords = curSubPath->getNumPoints();
  }
}

bool GfxState::ReusablePathIterator::isEnd() const {
   return coordOff >= numCoords;
}

void GfxState::ReusablePathIterator::next() {
  ++coordOff;
  if (coordOff == numCoords) {
    ++subPathOff;
    if (subPathOff < path->getNumSubpaths()) {
      coordOff = 0;
      curSubPath = path->getSubpath(subPathOff);
      numCoords = curSubPath->getNumPoints();
    }
  }
}

void GfxState::ReusablePathIterator::setCoord(double x, double y) {
  curSubPath->setX(coordOff, x);
  curSubPath->setY(coordOff, y);
}

void GfxState::ReusablePathIterator::reset() {
  coordOff = 0;
  subPathOff = 0;
  curSubPath = path->getSubpath(0);
  numCoords = curSubPath->getNumPoints();
}

GfxState::GfxState(double hDPIA, double vDPIA, const PDFRectangle *pageBox,
		   int rotateA, bool upsideDown) {
  double kx, ky;

  hDPI = hDPIA;
  vDPI = vDPIA;
  rotate = rotateA;
  px1 = pageBox->x1;
  py1 = pageBox->y1;
  px2 = pageBox->x2;
  py2 = pageBox->y2;
  kx = hDPI / 72.0;
  ky = vDPI / 72.0;
  if (rotate == 90) {
    ctm[0] = 0;
    ctm[1] = upsideDown ? ky : -ky;
    ctm[2] = kx;
    ctm[3] = 0;
    ctm[4] = -kx * py1;
    ctm[5] = ky * (upsideDown ? -px1 : px2);
    pageWidth = kx * (py2 - py1);
    pageHeight = ky * (px2 - px1);
  } else if (rotate == 180) {
    ctm[0] = -kx;
    ctm[1] = 0;
    ctm[2] = 0;
    ctm[3] = upsideDown ? ky : -ky;
    ctm[4] = kx * px2;
    ctm[5] = ky * (upsideDown ? -py1 : py2);
    pageWidth = kx * (px2 - px1);
    pageHeight = ky * (py2 - py1);
  } else if (rotate == 270) {
    ctm[0] = 0;
    ctm[1] = upsideDown ? -ky : ky;
    ctm[2] = -kx;
    ctm[3] = 0;
    ctm[4] = kx * py2;
    ctm[5] = ky * (upsideDown ? px2 : -px1);
    pageWidth = kx * (py2 - py1);
    pageHeight = ky * (px2 - px1);
  } else {
    ctm[0] = kx;
    ctm[1] = 0;
    ctm[2] = 0;
    ctm[3] = upsideDown ? -ky : ky;
    ctm[4] = -kx * px1;
    ctm[5] = ky * (upsideDown ? py2 : -py1);
    pageWidth = kx * (px2 - px1);
    pageHeight = ky * (py2 - py1);
  }

  fillColorSpace = new GfxDeviceGrayColorSpace();
  strokeColorSpace = new GfxDeviceGrayColorSpace();
  fillColor.c[0] = 0;
  strokeColor.c[0] = 0;
  fillPattern = nullptr;
  strokePattern = nullptr;
  blendMode = gfxBlendNormal;
  fillOpacity = 1;
  strokeOpacity = 1;
  fillOverprint = false;
  strokeOverprint = false;
  overprintMode = 0;
  transfer[0] = transfer[1] = transfer[2] = transfer[3] = nullptr;

  lineWidth = 1;
  lineDash = nullptr;
  lineDashLength = 0;
  lineDashStart = 0;
  flatness = 1;
  lineJoin = 0;
  lineCap = 0;
  miterLimit = 10;
  strokeAdjust = false;
  alphaIsShape = false;
  textKnockout = false;

  font = nullptr;
  fontSize = 0;
  textMat[0] = 1; textMat[1] = 0;
  textMat[2] = 0; textMat[3] = 1;
  textMat[4] = 0; textMat[5] = 0;
  charSpace = 0;
  wordSpace = 0;
  horizScaling = 1;
  leading = 0;
  rise = 0;
  render = 0;

  path = new GfxPath();
  curX = curY = 0;
  lineX = lineY = 0;

  clipXMin = 0;
  clipYMin = 0;
  clipXMax = pageWidth;
  clipYMax = pageHeight;

  renderingIntent[0] = 0;

  saved = nullptr;
#ifdef USE_CMS
  GfxColorSpace::setupColorProfiles();
  XYZ2DisplayTransformRelCol = nullptr;
  XYZ2DisplayTransformAbsCol = nullptr;
  XYZ2DisplayTransformSat = nullptr;
  XYZ2DisplayTransformPerc = nullptr;
  localDisplayProfile = nullptr;
  displayProfileRef = 0;
#endif
}

GfxState::~GfxState() {
  int i;

  if (fillColorSpace) {
    delete fillColorSpace;
  }
  if (strokeColorSpace) {
    delete strokeColorSpace;
  }
  if (fillPattern) {
    delete fillPattern;
  }
  if (strokePattern) {
    delete strokePattern;
  }
  for (i = 0; i < 4; ++i) {
    if (transfer[i]) {
      delete transfer[i];
    }
  }
  gfree(lineDash);
  if (path) {
    // this gets set to NULL by restore()
    delete path;
  }
  if (font) {
    font->decRefCnt();
  }
#ifdef USE_CMS
  if (XYZ2DisplayTransformRelCol) {
    if (XYZ2DisplayTransformRelCol->unref() == 0)
      delete XYZ2DisplayTransformRelCol;
  }
  if (XYZ2DisplayTransformAbsCol) {
    if (XYZ2DisplayTransformAbsCol->unref() == 0)
      delete XYZ2DisplayTransformAbsCol;
  }
  if (XYZ2DisplayTransformSat) {
    if (XYZ2DisplayTransformSat->unref() == 0)
      delete XYZ2DisplayTransformSat;
  }
  if (XYZ2DisplayTransformPerc) {
    if (XYZ2DisplayTransformPerc->unref() == 0)
      delete XYZ2DisplayTransformPerc;
  }
  if (--displayProfileRef == 0 && localDisplayProfile != nullptr) {
    cmsCloseProfile(localDisplayProfile);
  }
#endif
}

// Used for copy();
GfxState::GfxState(const GfxState *state, bool copyPath) {
  int i;

  memcpy(this, state, sizeof(GfxState));
  if (fillColorSpace) {
    fillColorSpace = state->fillColorSpace->copy();
  }
  if (strokeColorSpace) {
    strokeColorSpace = state->strokeColorSpace->copy();
  }
  if (fillPattern) {
    fillPattern = state->fillPattern->copy();
  }
  if (strokePattern) {
    strokePattern = state->strokePattern->copy();
  }
  for (i = 0; i < 4; ++i) {
    if (transfer[i]) {
      transfer[i] = state->transfer[i]->copy();
    }
  }
  if (lineDashLength > 0) {
    lineDash = (double *)gmallocn(lineDashLength, sizeof(double));
    memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double));
  }
  if (font)
    font->incRefCnt();

  if (copyPath) {
    path = state->path->copy();
  }
  saved = nullptr;
#ifdef USE_CMS
  if (XYZ2DisplayTransformRelCol) {
    XYZ2DisplayTransformRelCol->ref();
  }
  if (XYZ2DisplayTransformAbsCol) {
    XYZ2DisplayTransformAbsCol->ref();
  }
  if (XYZ2DisplayTransformSat) {
    XYZ2DisplayTransformSat->ref();
  }
  if (XYZ2DisplayTransformPerc) {
    XYZ2DisplayTransformPerc->ref();
  }
  if (localDisplayProfile) {
    displayProfileRef++;
  }
#endif
}

#ifdef USE_CMS
void GfxState::setDisplayProfile(cmsHPROFILE localDisplayProfileA) {
  if (localDisplayProfile != nullptr) {
    cmsCloseProfile(localDisplayProfile);
  }
  localDisplayProfile = localDisplayProfileA;
  if (localDisplayProfileA != nullptr) {
    cmsHTRANSFORM transform;
    unsigned int nChannels;
    unsigned int localDisplayPixelType;

    localDisplayPixelType = getCMSColorSpaceType(cmsGetColorSpace(localDisplayProfile));
    nChannels = getCMSNChannels(cmsGetColorSpace(localDisplayProfile));
    displayProfileRef = 1;
    // create transform from XYZ
    cmsHPROFILE XYZProfile = cmsCreateXYZProfile();
    if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
	   localDisplayProfile,
	   COLORSPACE_SH(localDisplayPixelType) |
	     CHANNELS_SH(nChannels) | BYTES_SH(1),
	  INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
      error(errSyntaxWarning, -1, "Can't create Lab transform");
    } else {
      XYZ2DisplayTransformRelCol = new GfxColorTransform(transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, localDisplayPixelType);
    }
    if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
	   localDisplayProfile,
	   COLORSPACE_SH(localDisplayPixelType) |
	     CHANNELS_SH(nChannels) | BYTES_SH(1),
	  INTENT_ABSOLUTE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
      error(errSyntaxWarning, -1, "Can't create Lab transform");
    } else {
      XYZ2DisplayTransformAbsCol = new GfxColorTransform(transform, INTENT_ABSOLUTE_COLORIMETRIC, PT_XYZ, localDisplayPixelType);
    }
    if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
	   localDisplayProfile,
	   COLORSPACE_SH(localDisplayPixelType) |
	     CHANNELS_SH(nChannels) | BYTES_SH(1),
	  INTENT_SATURATION,LCMS_FLAGS)) == nullptr) {
      error(errSyntaxWarning, -1, "Can't create Lab transform");
    } else {
      XYZ2DisplayTransformSat = new GfxColorTransform(transform, INTENT_SATURATION, PT_XYZ, localDisplayPixelType);
    }
    if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
	   localDisplayProfile,
	   COLORSPACE_SH(localDisplayPixelType) |
	     CHANNELS_SH(nChannels) | BYTES_SH(1),
	  INTENT_PERCEPTUAL,LCMS_FLAGS)) == nullptr) {
      error(errSyntaxWarning, -1, "Can't create Lab transform");
    } else {
      XYZ2DisplayTransformPerc = new GfxColorTransform(transform, INTENT_PERCEPTUAL, PT_XYZ, localDisplayPixelType);
    }
    cmsCloseProfile(XYZProfile);
  }
}

GfxColorTransform *GfxState::getXYZ2DisplayTransform() {
  GfxColorTransform *transform;

  transform = XYZ2DisplayTransformRelCol;
  if (strcmp(renderingIntent, "AbsoluteColorimetric") == 0) {
    transform = XYZ2DisplayTransformAbsCol;
  } else if (strcmp(renderingIntent, "Saturation") == 0) {
    transform = XYZ2DisplayTransformSat;
  } else if (strcmp(renderingIntent, "Perceptual") == 0) {
    transform = XYZ2DisplayTransformPerc;
  }
  if (transform == nullptr) {
    transform = XYZ2DisplayTransform;
  }
  return transform;
}

#endif

void GfxState::setPath(GfxPath *pathA) {
  delete path;
  path = pathA;
}

void GfxState::getUserClipBBox(double *xMin, double *yMin,
			       double *xMax, double *yMax) {
  double ictm[6];
  double xMin1, yMin1, xMax1, yMax1, tx, ty;

  // invert the CTM
  const double det_denominator = (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
  if (unlikely(det_denominator == 0)) {
      *xMin = 0;
      *yMin = 0;
      *xMax = 0;
      *yMax = 0;
      return;
  }
  const double det = 1 / det_denominator;
  ictm[0] = ctm[3] * det;
  ictm[1] = -ctm[1] * det;
  ictm[2] = -ctm[2] * det;
  ictm[3] = ctm[0] * det;
  ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
  ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;

  // transform all four corners of the clip bbox; find the min and max
  // x and y values
  xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4];
  yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5];
  tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4];
  ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5];
  if (tx < xMin1) {
    xMin1 = tx;
  } else if (tx > xMax1) {
    xMax1 = tx;
  }
  if (ty < yMin1) {
    yMin1 = ty;
  } else if (ty > yMax1) {
    yMax1 = ty;
  }
  tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4];
  ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5];
  if (tx < xMin1) {
    xMin1 = tx;
  } else if (tx > xMax1) {
    xMax1 = tx;
  }
  if (ty < yMin1) {
    yMin1 = ty;
  } else if (ty > yMax1) {
    yMax1 = ty;
  }
  tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4];
  ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5];
  if (tx < xMin1) {
    xMin1 = tx;
  } else if (tx > xMax1) {
    xMax1 = tx;
  }
  if (ty < yMin1) {
    yMin1 = ty;
  } else if (ty > yMax1) {
    yMax1 = ty;
  }

  *xMin = xMin1;
  *yMin = yMin1;
  *xMax = xMax1;
  *yMax = yMax1;
}

double GfxState::transformWidth(double w) {
  double x, y;

  x = ctm[0] + ctm[2];
  y = ctm[1] + ctm[3];
  return w * sqrt(0.5 * (x * x + y * y));
}

double GfxState::getTransformedFontSize() {
  double x1, y1, x2, y2;

  x1 = textMat[2] * fontSize;
  y1 = textMat[3] * fontSize;
  x2 = ctm[0] * x1 + ctm[2] * y1;
  y2 = ctm[1] * x1 + ctm[3] * y1;
  return sqrt(x2 * x2 + y2 * y2);
}

void GfxState::getFontTransMat(double *m11, double *m12,
			       double *m21, double *m22) {
  *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize;
  *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize;
  *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
  *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
}

void GfxState::setCTM(double a, double b, double c,
		      double d, double e, double f) {
  ctm[0] = a;
  ctm[1] = b;
  ctm[2] = c;
  ctm[3] = d;
  ctm[4] = e;
  ctm[5] = f;
}

void GfxState::concatCTM(double a, double b, double c,
			 double d, double e, double f) {
  double a1 = ctm[0];
  double b1 = ctm[1];
  double c1 = ctm[2];
  double d1 = ctm[3];

  ctm[0] = a * a1 + b * c1;
  ctm[1] = a * b1 + b * d1;
  ctm[2] = c * a1 + d * c1;
  ctm[3] = c * b1 + d * d1;
  ctm[4] = e * a1 + f * c1 + ctm[4];
  ctm[5] = e * b1 + f * d1 + ctm[5];
}

void GfxState::shiftCTMAndClip(double tx, double ty) {
  ctm[4] += tx;
  ctm[5] += ty;
  clipXMin += tx;
  clipYMin += ty;
  clipXMax += tx;
  clipYMax += ty;
}

void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
  if (fillColorSpace) {
    delete fillColorSpace;
  }
  fillColorSpace = colorSpace;
}

void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) {
  if (strokeColorSpace) {
    delete strokeColorSpace;
  }
  strokeColorSpace = colorSpace;
}

void GfxState::setFillPattern(GfxPattern *pattern) {
  if (fillPattern) {
    delete fillPattern;
  }
  fillPattern = pattern;
}

void GfxState::setStrokePattern(GfxPattern *pattern) {
  if (strokePattern) {
    delete strokePattern;
  }
  strokePattern = pattern;
}

void GfxState::setFont(GfxFont *fontA, double fontSizeA) {
  if (font)
    font->decRefCnt();

  font = fontA;
  fontSize = fontSizeA;
}

void GfxState::setTransfer(Function **funcs) {
  int i;

  for (i = 0; i < 4; ++i) {
    if (transfer[i]) {
      delete transfer[i];
    }
    transfer[i] = funcs[i];
  }
}

void GfxState::setLineDash(double *dash, int length, double start) {
  if (lineDash)
    gfree(lineDash);
  lineDash = dash;
  lineDashLength = length;
  lineDashStart = start;
}

void GfxState::clearPath() {
  delete path;
  path = new GfxPath();
}

void GfxState::clip() {
  double xMin, yMin, xMax, yMax, x, y;
  GfxSubpath *subpath;
  int i, j;

  xMin = xMax = yMin = yMax = 0; // make gcc happy
  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    for (j = 0; j < subpath->getNumPoints(); ++j) {
      transform(subpath->getX(j), subpath->getY(j), &x, &y);
      if (i == 0 && j == 0) {
	xMin = xMax = x;
	yMin = yMax = y;
      } else {
	if (x < xMin) {
	  xMin = x;
	} else if (x > xMax) {
	  xMax = x;
	}
	if (y < yMin) {
	  yMin = y;
	} else if (y > yMax) {
	  yMax = y;
	}
      }
    }
  }
  if (xMin > clipXMin) {
    clipXMin = xMin;
  }
  if (yMin > clipYMin) {
    clipYMin = yMin;
  }
  if (xMax < clipXMax) {
    clipXMax = xMax;
  }
  if (yMax < clipYMax) {
    clipYMax = yMax;
  }
}

void GfxState::clipToStrokePath() {
  double xMin, yMin, xMax, yMax, x, y, t0, t1;
  GfxSubpath *subpath;
  int i, j;

  xMin = xMax = yMin = yMax = 0; // make gcc happy
  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    for (j = 0; j < subpath->getNumPoints(); ++j) {
      transform(subpath->getX(j), subpath->getY(j), &x, &y);
      if (i == 0 && j == 0) {
	xMin = xMax = x;
	yMin = yMax = y;
      } else {
	if (x < xMin) {
	  xMin = x;
	} else if (x > xMax) {
	  xMax = x;
	}
	if (y < yMin) {
	  yMin = y;
	} else if (y > yMax) {
	  yMax = y;
	}
      }
    }
  }

  // allow for the line width
  //~ miter joins can extend farther than this
  t0 = fabs(ctm[0]);
  t1 = fabs(ctm[2]);
  if (t0 > t1) {
    xMin -= 0.5 * lineWidth * t0;
    xMax += 0.5 * lineWidth * t0;
  } else {
    xMin -= 0.5 * lineWidth * t1;
    xMax += 0.5 * lineWidth * t1;
  }
  t0 = fabs(ctm[0]);
  t1 = fabs(ctm[3]);
  if (t0 > t1) {
    yMin -= 0.5 * lineWidth * t0;
    yMax += 0.5 * lineWidth * t0;
  } else {
    yMin -= 0.5 * lineWidth * t1;
    yMax += 0.5 * lineWidth * t1;
  }

  if (xMin > clipXMin) {
    clipXMin = xMin;
  }
  if (yMin > clipYMin) {
    clipYMin = yMin;
  }
  if (xMax < clipXMax) {
    clipXMax = xMax;
  }
  if (yMax < clipYMax) {
    clipYMax = yMax;
  }
}

void GfxState::clipToRect(double xMin, double yMin, double xMax, double yMax) {
  double x, y, xMin1, yMin1, xMax1, yMax1;

  transform(xMin, yMin, &x, &y);
  xMin1 = xMax1 = x;
  yMin1 = yMax1 = y;
  transform(xMax, yMin, &x, &y);
  if (x < xMin1) {
    xMin1 = x;
  } else if (x > xMax1) {
    xMax1 = x;
  }
  if (y < yMin1) {
    yMin1 = y;
  } else if (y > yMax1) {
    yMax1 = y;
  }
  transform(xMax, yMax, &x, &y);
  if (x < xMin1) {
    xMin1 = x;
  } else if (x > xMax1) {
    xMax1 = x;
  }
  if (y < yMin1) {
    yMin1 = y;
  } else if (y > yMax1) {
    yMax1 = y;
  }
  transform(xMin, yMax, &x, &y);
  if (x < xMin1) {
    xMin1 = x;
  } else if (x > xMax1) {
    xMax1 = x;
  }
  if (y < yMin1) {
    yMin1 = y;
  } else if (y > yMax1) {
    yMax1 = y;
  }

  if (xMin1 > clipXMin) {
    clipXMin = xMin1;
  }
  if (yMin1 > clipYMin) {
    clipYMin = yMin1;
  }
  if (xMax1 < clipXMax) {
    clipXMax = xMax1;
  }
  if (yMax1 < clipYMax) {
    clipYMax = yMax1;
  }
}

void GfxState::textShift(double tx, double ty) {
  double dx, dy;

  textTransformDelta(tx, ty, &dx, &dy);
  curX += dx;
  curY += dy;
}

void GfxState::shift(double dx, double dy) {
  curX += dx;
  curY += dy;
}

GfxState *GfxState::save() {
  GfxState *newState;

  newState = copy();
  newState->saved = this;
  return newState;
}

GfxState *GfxState::restore() {
  GfxState *oldState;

  if (saved) {
    oldState = saved;

    // these attributes aren't saved/restored by the q/Q operators
    oldState->path = path;
    oldState->curX = curX;
    oldState->curY = curY;
    oldState->lineX = lineX;
    oldState->lineY = lineY;

    path = nullptr;
    saved = nullptr;
    delete this;

  } else {
    oldState = this;
  }

  return oldState;
}

bool GfxState::parseBlendMode(Object *obj, GfxBlendMode *mode) {
  int i, j;

  if (obj->isName()) {
    for (i = 0; i < nGfxBlendModeNames; ++i) {
      if (!strcmp(obj->getName(), gfxBlendModeNames[i].name)) {
	*mode = gfxBlendModeNames[i].mode;
	return true;
      }
    }
    return false;
  } else if (obj->isArray()) {
    for (i = 0; i < obj->arrayGetLength(); ++i) {
      Object obj2 = obj->arrayGet(i);
      if (!obj2.isName()) {
	return false;
      }
      for (j = 0; j < nGfxBlendModeNames; ++j) {
	if (!strcmp(obj2.getName(), gfxBlendModeNames[j].name)) {
	  *mode = gfxBlendModeNames[j].mode;
	  return true;
	}
      }
    }
    *mode = gfxBlendNormal;
    return true;
  } else {
    return false;
  }
}
