/**
 * @licstart The following is the entire license notice for the
 * Javascript code in this page
 *
 * Copyright 2020 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @licend The above is the entire license notice for the
 * Javascript code in this page
 */
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.PDFImage = void 0;

var _util = require("../shared/util.js");

var _primitives = require("./primitives.js");

var _colorspace = require("./colorspace.js");

var _stream = require("./stream.js");

var _jpeg_stream = require("./jpeg_stream.js");

var _jpx = require("./jpx.js");

function decodeAndClamp(value, addend, coefficient, max) {
  value = addend + value * coefficient;

  if (value < 0) {
    value = 0;
  } else if (value > max) {
    value = max;
  }

  return value;
}

function resizeImageMask(src, bpc, w1, h1, w2, h2) {
  var length = w2 * h2;
  let dest;

  if (bpc <= 8) {
    dest = new Uint8Array(length);
  } else if (bpc <= 16) {
    dest = new Uint16Array(length);
  } else {
    dest = new Uint32Array(length);
  }

  var xRatio = w1 / w2;
  var yRatio = h1 / h2;
  var i,
      j,
      py,
      newIndex = 0,
      oldIndex;
  var xScaled = new Uint16Array(w2);
  var w1Scanline = w1;

  for (i = 0; i < w2; i++) {
    xScaled[i] = Math.floor(i * xRatio);
  }

  for (i = 0; i < h2; i++) {
    py = Math.floor(i * yRatio) * w1Scanline;

    for (j = 0; j < w2; j++) {
      oldIndex = py + xScaled[j];
      dest[newIndex++] = src[oldIndex];
    }
  }

  return dest;
}

class PDFImage {
  constructor({
    xref,
    res,
    image,
    isInline = false,
    smask = null,
    mask = null,
    isMask = false,
    pdfFunctionFactory,
    localColorSpaceCache
  }) {
    this.image = image;
    var dict = image.dict;
    const filter = dict.get("Filter");

    if ((0, _primitives.isName)(filter)) {
      switch (filter.name) {
        case "JPXDecode":
          var jpxImage = new _jpx.JpxImage();
          jpxImage.parseImageProperties(image.stream);
          image.stream.reset();
          image.width = jpxImage.width;
          image.height = jpxImage.height;
          image.bitsPerComponent = jpxImage.bitsPerComponent;
          image.numComps = jpxImage.componentsCount;
          break;

        case "JBIG2Decode":
          image.bitsPerComponent = 1;
          image.numComps = 1;
          break;
      }
    }

    let width = dict.get("Width", "W");
    let height = dict.get("Height", "H");

    if (Number.isInteger(image.width) && image.width > 0 && Number.isInteger(image.height) && image.height > 0 && (image.width !== width || image.height !== height)) {
      (0, _util.warn)("PDFImage - using the Width/Height of the image data, " + "rather than the image dictionary.");
      width = image.width;
      height = image.height;
    }

    if (width < 1 || height < 1) {
      throw new _util.FormatError(`Invalid image width: ${width} or height: ${height}`);
    }

    this.width = width;
    this.height = height;
    this.interpolate = dict.get("Interpolate", "I") || false;
    this.imageMask = dict.get("ImageMask", "IM") || false;
    this.matte = dict.get("Matte") || false;
    var bitsPerComponent = image.bitsPerComponent;

    if (!bitsPerComponent) {
      bitsPerComponent = dict.get("BitsPerComponent", "BPC");

      if (!bitsPerComponent) {
        if (this.imageMask) {
          bitsPerComponent = 1;
        } else {
          throw new _util.FormatError(`Bits per component missing in image: ${this.imageMask}`);
        }
      }
    }

    this.bpc = bitsPerComponent;

    if (!this.imageMask) {
      let colorSpace = dict.getRaw("ColorSpace") || dict.getRaw("CS");

      if (!colorSpace) {
        (0, _util.info)("JPX images (which do not require color spaces)");

        switch (image.numComps) {
          case 1:
            colorSpace = _primitives.Name.get("DeviceGray");
            break;

          case 3:
            colorSpace = _primitives.Name.get("DeviceRGB");
            break;

          case 4:
            colorSpace = _primitives.Name.get("DeviceCMYK");
            break;

          default:
            throw new Error(`JPX images with ${image.numComps} ` + "color components not supported.");
        }
      }

      this.colorSpace = _colorspace.ColorSpace.parse({
        cs: colorSpace,
        xref,
        resources: isInline ? res : null,
        pdfFunctionFactory,
        localColorSpaceCache
      });
      this.numComps = this.colorSpace.numComps;
    }

    this.decode = dict.getArray("Decode", "D");
    this.needsDecode = false;

    if (this.decode && (this.colorSpace && !this.colorSpace.isDefaultDecode(this.decode, bitsPerComponent) || isMask && !_colorspace.ColorSpace.isDefaultDecode(this.decode, 1))) {
      this.needsDecode = true;
      var max = (1 << bitsPerComponent) - 1;
      this.decodeCoefficients = [];
      this.decodeAddends = [];
      const isIndexed = this.colorSpace && this.colorSpace.name === "Indexed";

      for (var i = 0, j = 0; i < this.decode.length; i += 2, ++j) {
        var dmin = this.decode[i];
        var dmax = this.decode[i + 1];
        this.decodeCoefficients[j] = isIndexed ? (dmax - dmin) / max : dmax - dmin;
        this.decodeAddends[j] = isIndexed ? dmin : max * dmin;
      }
    }

    if (smask) {
      this.smask = new PDFImage({
        xref,
        res,
        image: smask,
        isInline,
        pdfFunctionFactory,
        localColorSpaceCache
      });
    } else if (mask) {
      if ((0, _primitives.isStream)(mask)) {
        var maskDict = mask.dict,
            imageMask = maskDict.get("ImageMask", "IM");

        if (!imageMask) {
          (0, _util.warn)("Ignoring /Mask in image without /ImageMask.");
        } else {
          this.mask = new PDFImage({
            xref,
            res,
            image: mask,
            isInline,
            isMask: true,
            pdfFunctionFactory,
            localColorSpaceCache
          });
        }
      } else {
        this.mask = mask;
      }
    }
  }

  static async buildImage({
    xref,
    res,
    image,
    isInline = false,
    pdfFunctionFactory,
    localColorSpaceCache
  }) {
    const imageData = image;
    let smaskData = null;
    let maskData = null;
    const smask = image.dict.get("SMask");
    const mask = image.dict.get("Mask");

    if (smask) {
      smaskData = smask;
    } else if (mask) {
      if ((0, _primitives.isStream)(mask) || Array.isArray(mask)) {
        maskData = mask;
      } else {
        (0, _util.warn)("Unsupported mask format.");
      }
    }

    return new PDFImage({
      xref,
      res,
      image: imageData,
      isInline,
      smask: smaskData,
      mask: maskData,
      pdfFunctionFactory,
      localColorSpaceCache
    });
  }

  static createMask({
    imgArray,
    width,
    height,
    imageIsFromDecodeStream,
    inverseDecode
  }) {
    var computedLength = (width + 7 >> 3) * height;
    var actualLength = imgArray.byteLength;
    var haveFullData = computedLength === actualLength;
    var data, i;

    if (imageIsFromDecodeStream && (!inverseDecode || haveFullData)) {
      data = imgArray;
    } else if (!inverseDecode) {
      data = new Uint8ClampedArray(actualLength);
      data.set(imgArray);
    } else {
      data = new Uint8ClampedArray(computedLength);
      data.set(imgArray);

      for (i = actualLength; i < computedLength; i++) {
        data[i] = 0xff;
      }
    }

    if (inverseDecode) {
      for (i = 0; i < actualLength; i++) {
        data[i] ^= 0xff;
      }
    }

    return {
      data,
      width,
      height
    };
  }

  get drawWidth() {
    return Math.max(this.width, this.smask && this.smask.width || 0, this.mask && this.mask.width || 0);
  }

  get drawHeight() {
    return Math.max(this.height, this.smask && this.smask.height || 0, this.mask && this.mask.height || 0);
  }

  decodeBuffer(buffer) {
    var bpc = this.bpc;
    var numComps = this.numComps;
    var decodeAddends = this.decodeAddends;
    var decodeCoefficients = this.decodeCoefficients;
    var max = (1 << bpc) - 1;
    var i, ii;

    if (bpc === 1) {
      for (i = 0, ii = buffer.length; i < ii; i++) {
        buffer[i] = +!buffer[i];
      }

      return;
    }

    var index = 0;

    for (i = 0, ii = this.width * this.height; i < ii; i++) {
      for (var j = 0; j < numComps; j++) {
        buffer[index] = decodeAndClamp(buffer[index], decodeAddends[j], decodeCoefficients[j], max);
        index++;
      }
    }
  }

  getComponents(buffer) {
    var bpc = this.bpc;

    if (bpc === 8) {
      return buffer;
    }

    var width = this.width;
    var height = this.height;
    var numComps = this.numComps;
    var length = width * height * numComps;
    var bufferPos = 0;
    let output;

    if (bpc <= 8) {
      output = new Uint8Array(length);
    } else if (bpc <= 16) {
      output = new Uint16Array(length);
    } else {
      output = new Uint32Array(length);
    }

    var rowComps = width * numComps;
    var max = (1 << bpc) - 1;
    var i = 0,
        ii,
        buf;

    if (bpc === 1) {
      var mask, loop1End, loop2End;

      for (var j = 0; j < height; j++) {
        loop1End = i + (rowComps & ~7);
        loop2End = i + rowComps;

        while (i < loop1End) {
          buf = buffer[bufferPos++];
          output[i] = buf >> 7 & 1;
          output[i + 1] = buf >> 6 & 1;
          output[i + 2] = buf >> 5 & 1;
          output[i + 3] = buf >> 4 & 1;
          output[i + 4] = buf >> 3 & 1;
          output[i + 5] = buf >> 2 & 1;
          output[i + 6] = buf >> 1 & 1;
          output[i + 7] = buf & 1;
          i += 8;
        }

        if (i < loop2End) {
          buf = buffer[bufferPos++];
          mask = 128;

          while (i < loop2End) {
            output[i++] = +!!(buf & mask);
            mask >>= 1;
          }
        }
      }
    } else {
      var bits = 0;
      buf = 0;

      for (i = 0, ii = length; i < ii; ++i) {
        if (i % rowComps === 0) {
          buf = 0;
          bits = 0;
        }

        while (bits < bpc) {
          buf = buf << 8 | buffer[bufferPos++];
          bits += 8;
        }

        var remainingBits = bits - bpc;
        let value = buf >> remainingBits;

        if (value < 0) {
          value = 0;
        } else if (value > max) {
          value = max;
        }

        output[i] = value;
        buf = buf & (1 << remainingBits) - 1;
        bits = remainingBits;
      }
    }

    return output;
  }

  fillOpacity(rgbaBuf, width, height, actualHeight, image) {
    var smask = this.smask;
    var mask = this.mask;
    var alphaBuf, sw, sh, i, ii, j;

    if (smask) {
      sw = smask.width;
      sh = smask.height;
      alphaBuf = new Uint8ClampedArray(sw * sh);
      smask.fillGrayBuffer(alphaBuf);

      if (sw !== width || sh !== height) {
        alphaBuf = resizeImageMask(alphaBuf, smask.bpc, sw, sh, width, height);
      }
    } else if (mask) {
      if (mask instanceof PDFImage) {
        sw = mask.width;
        sh = mask.height;
        alphaBuf = new Uint8ClampedArray(sw * sh);
        mask.numComps = 1;
        mask.fillGrayBuffer(alphaBuf);

        for (i = 0, ii = sw * sh; i < ii; ++i) {
          alphaBuf[i] = 255 - alphaBuf[i];
        }

        if (sw !== width || sh !== height) {
          alphaBuf = resizeImageMask(alphaBuf, mask.bpc, sw, sh, width, height);
        }
      } else if (Array.isArray(mask)) {
        alphaBuf = new Uint8ClampedArray(width * height);
        var numComps = this.numComps;

        for (i = 0, ii = width * height; i < ii; ++i) {
          var opacity = 0;
          var imageOffset = i * numComps;

          for (j = 0; j < numComps; ++j) {
            var color = image[imageOffset + j];
            var maskOffset = j * 2;

            if (color < mask[maskOffset] || color > mask[maskOffset + 1]) {
              opacity = 255;
              break;
            }
          }

          alphaBuf[i] = opacity;
        }
      } else {
        throw new _util.FormatError("Unknown mask format.");
      }
    }

    if (alphaBuf) {
      for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) {
        rgbaBuf[j] = alphaBuf[i];
      }
    } else {
      for (i = 0, j = 3, ii = width * actualHeight; i < ii; ++i, j += 4) {
        rgbaBuf[j] = 255;
      }
    }
  }

  undoPreblend(buffer, width, height) {
    var matte = this.smask && this.smask.matte;

    if (!matte) {
      return;
    }

    var matteRgb = this.colorSpace.getRgb(matte, 0);
    var matteR = matteRgb[0];
    var matteG = matteRgb[1];
    var matteB = matteRgb[2];
    var length = width * height * 4;

    for (var i = 0; i < length; i += 4) {
      var alpha = buffer[i + 3];

      if (alpha === 0) {
        buffer[i] = 255;
        buffer[i + 1] = 255;
        buffer[i + 2] = 255;
        continue;
      }

      var k = 255 / alpha;
      buffer[i] = (buffer[i] - matteR) * k + matteR;
      buffer[i + 1] = (buffer[i + 1] - matteG) * k + matteG;
      buffer[i + 2] = (buffer[i + 2] - matteB) * k + matteB;
    }
  }

  createImageData(forceRGBA = false) {
    var drawWidth = this.drawWidth;
    var drawHeight = this.drawHeight;
    var imgData = {
      width: drawWidth,
      height: drawHeight,
      kind: 0,
      data: null
    };
    var numComps = this.numComps;
    var originalWidth = this.width;
    var originalHeight = this.height;
    var bpc = this.bpc;
    var rowBytes = originalWidth * numComps * bpc + 7 >> 3;
    var imgArray;

    if (!forceRGBA) {
      var kind;

      if (this.colorSpace.name === "DeviceGray" && bpc === 1) {
        kind = _util.ImageKind.GRAYSCALE_1BPP;
      } else if (this.colorSpace.name === "DeviceRGB" && bpc === 8 && !this.needsDecode) {
        kind = _util.ImageKind.RGB_24BPP;
      }

      if (kind && !this.smask && !this.mask && drawWidth === originalWidth && drawHeight === originalHeight) {
        imgData.kind = kind;
        imgArray = this.getImageBytes(originalHeight * rowBytes);

        if (this.image instanceof _stream.DecodeStream) {
          imgData.data = imgArray;
        } else {
          var newArray = new Uint8ClampedArray(imgArray.length);
          newArray.set(imgArray);
          imgData.data = newArray;
        }

        if (this.needsDecode) {
          (0, _util.assert)(kind === _util.ImageKind.GRAYSCALE_1BPP, "PDFImage.createImageData: The image must be grayscale.");
          var buffer = imgData.data;

          for (var i = 0, ii = buffer.length; i < ii; i++) {
            buffer[i] ^= 0xff;
          }
        }

        return imgData;
      }

      if (this.image instanceof _jpeg_stream.JpegStream && !this.smask && !this.mask) {
        let imageLength = originalHeight * rowBytes;

        switch (this.colorSpace.name) {
          case "DeviceGray":
            imageLength *= 3;

          case "DeviceRGB":
          case "DeviceCMYK":
            imgData.kind = _util.ImageKind.RGB_24BPP;
            imgData.data = this.getImageBytes(imageLength, drawWidth, drawHeight, true);
            return imgData;
        }
      }
    }

    imgArray = this.getImageBytes(originalHeight * rowBytes);
    var actualHeight = 0 | imgArray.length / rowBytes * drawHeight / originalHeight;
    var comps = this.getComponents(imgArray);
    var alpha01, maybeUndoPreblend;

    if (!forceRGBA && !this.smask && !this.mask) {
      imgData.kind = _util.ImageKind.RGB_24BPP;
      imgData.data = new Uint8ClampedArray(drawWidth * drawHeight * 3);
      alpha01 = 0;
      maybeUndoPreblend = false;
    } else {
      imgData.kind = _util.ImageKind.RGBA_32BPP;
      imgData.data = new Uint8ClampedArray(drawWidth * drawHeight * 4);
      alpha01 = 1;
      maybeUndoPreblend = true;
      this.fillOpacity(imgData.data, drawWidth, drawHeight, actualHeight, comps);
    }

    if (this.needsDecode) {
      this.decodeBuffer(comps);
    }

    this.colorSpace.fillRgb(imgData.data, originalWidth, originalHeight, drawWidth, drawHeight, actualHeight, bpc, comps, alpha01);

    if (maybeUndoPreblend) {
      this.undoPreblend(imgData.data, drawWidth, actualHeight);
    }

    return imgData;
  }

  fillGrayBuffer(buffer) {
    var numComps = this.numComps;

    if (numComps !== 1) {
      throw new _util.FormatError(`Reading gray scale from a color image: ${numComps}`);
    }

    var width = this.width;
    var height = this.height;
    var bpc = this.bpc;
    var rowBytes = width * numComps * bpc + 7 >> 3;
    var imgArray = this.getImageBytes(height * rowBytes);
    var comps = this.getComponents(imgArray);
    var i, length;

    if (bpc === 1) {
      length = width * height;

      if (this.needsDecode) {
        for (i = 0; i < length; ++i) {
          buffer[i] = comps[i] - 1 & 255;
        }
      } else {
        for (i = 0; i < length; ++i) {
          buffer[i] = -comps[i] & 255;
        }
      }

      return;
    }

    if (this.needsDecode) {
      this.decodeBuffer(comps);
    }

    length = width * height;
    var scale = 255 / ((1 << bpc) - 1);

    for (i = 0; i < length; ++i) {
      buffer[i] = scale * comps[i];
    }
  }

  getImageBytes(length, drawWidth, drawHeight, forceRGB = false) {
    this.image.reset();
    this.image.drawWidth = drawWidth || this.width;
    this.image.drawHeight = drawHeight || this.height;
    this.image.forceRGB = !!forceRGB;
    return this.image.getBytes(length, true);
  }

}

exports.PDFImage = PDFImage;