(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports", "three"], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports, require("three"));
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports, global.three);
    global.PVRLoader = mod.exports;
  }
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three) {
  "use strict";

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

  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }

  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } Object.defineProperty(subClass, "prototype", { value: Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }), writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }

  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }

  function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }

  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

  /*
   *	 PVR v2 (legacy) parser
   *   TODO : Add Support for PVR v3 format
   *   TODO : implement loadMipmaps option
   */
  var PVRLoader = /*#__PURE__*/function (_CompressedTextureLoa) {
    _inherits(PVRLoader, _CompressedTextureLoa);

    var _super = _createSuper(PVRLoader);

    function PVRLoader(manager) {
      _classCallCheck(this, PVRLoader);

      return _super.call(this, manager);
    }

    _createClass(PVRLoader, [{
      key: "parse",
      value: function parse(buffer, loadMipmaps) {
        var headerLengthInt = 13;
        var header = new Uint32Array(buffer, 0, headerLengthInt);
        var pvrDatas = {
          buffer: buffer,
          header: header,
          loadMipmaps: loadMipmaps
        };

        if (header[0] === 0x03525650) {
          // PVR v3
          return _parseV3(pvrDatas);
        } else if (header[11] === 0x21525650) {
          // PVR v2
          return _parseV2(pvrDatas);
        } else {
          console.error('THREE.PVRLoader: Unknown PVR format.');
        }
      }
    }]);

    return PVRLoader;
  }(_three.CompressedTextureLoader);

  _exports.PVRLoader = PVRLoader;

  function _parseV3(pvrDatas) {
    var header = pvrDatas.header;
    var bpp, format;
    var metaLen = header[12],
        pixelFormat = header[2],
        height = header[6],
        width = header[7],
        // numSurfs = header[ 9 ],
    numFaces = header[10],
        numMipmaps = header[11];

    switch (pixelFormat) {
      case 0:
        // PVRTC 2bpp RGB
        bpp = 2;
        format = _three.RGB_PVRTC_2BPPV1_Format;
        break;

      case 1:
        // PVRTC 2bpp RGBA
        bpp = 2;
        format = _three.RGBA_PVRTC_2BPPV1_Format;
        break;

      case 2:
        // PVRTC 4bpp RGB
        bpp = 4;
        format = _three.RGB_PVRTC_4BPPV1_Format;
        break;

      case 3:
        // PVRTC 4bpp RGBA
        bpp = 4;
        format = _three.RGBA_PVRTC_4BPPV1_Format;
        break;

      default:
        console.error('THREE.PVRLoader: Unsupported PVR format:', pixelFormat);
    }

    pvrDatas.dataPtr = 52 + metaLen;
    pvrDatas.bpp = bpp;
    pvrDatas.format = format;
    pvrDatas.width = width;
    pvrDatas.height = height;
    pvrDatas.numSurfaces = numFaces;
    pvrDatas.numMipmaps = numMipmaps;
    pvrDatas.isCubemap = numFaces === 6;
    return _extract(pvrDatas);
  }

  function _parseV2(pvrDatas) {
    var header = pvrDatas.header;
    var headerLength = header[0],
        height = header[1],
        width = header[2],
        numMipmaps = header[3],
        flags = header[4],
        // dataLength = header[ 5 ],
    // bpp =  header[ 6 ],
    // bitmaskRed = header[ 7 ],
    // bitmaskGreen = header[ 8 ],
    // bitmaskBlue = header[ 9 ],
    bitmaskAlpha = header[10],
        // pvrTag = header[ 11 ],
    numSurfs = header[12];
    var TYPE_MASK = 0xff;
    var PVRTC_2 = 24,
        PVRTC_4 = 25;
    var formatFlags = flags & TYPE_MASK;
    var bpp, format;

    var _hasAlpha = bitmaskAlpha > 0;

    if (formatFlags === PVRTC_4) {
      format = _hasAlpha ? _three.RGBA_PVRTC_4BPPV1_Format : _three.RGB_PVRTC_4BPPV1_Format;
      bpp = 4;
    } else if (formatFlags === PVRTC_2) {
      format = _hasAlpha ? _three.RGBA_PVRTC_2BPPV1_Format : _three.RGB_PVRTC_2BPPV1_Format;
      bpp = 2;
    } else {
      console.error('THREE.PVRLoader: Unknown PVR format:', formatFlags);
    }

    pvrDatas.dataPtr = headerLength;
    pvrDatas.bpp = bpp;
    pvrDatas.format = format;
    pvrDatas.width = width;
    pvrDatas.height = height;
    pvrDatas.numSurfaces = numSurfs;
    pvrDatas.numMipmaps = numMipmaps + 1; // guess cubemap type seems tricky in v2
    // it juste a pvr containing 6 surface (no explicit cubemap type)

    pvrDatas.isCubemap = numSurfs === 6;
    return _extract(pvrDatas);
  }

  function _extract(pvrDatas) {
    var pvr = {
      mipmaps: [],
      width: pvrDatas.width,
      height: pvrDatas.height,
      format: pvrDatas.format,
      mipmapCount: pvrDatas.numMipmaps,
      isCubemap: pvrDatas.isCubemap
    };
    var buffer = pvrDatas.buffer;
    var dataOffset = pvrDatas.dataPtr,
        dataSize = 0,
        blockSize = 0,
        blockWidth = 0,
        blockHeight = 0,
        widthBlocks = 0,
        heightBlocks = 0;
    var bpp = pvrDatas.bpp,
        numSurfs = pvrDatas.numSurfaces;

    if (bpp === 2) {
      blockWidth = 8;
      blockHeight = 4;
    } else {
      blockWidth = 4;
      blockHeight = 4;
    }

    blockSize = blockWidth * blockHeight * bpp / 8;
    pvr.mipmaps.length = pvrDatas.numMipmaps * numSurfs;
    var mipLevel = 0;

    while (mipLevel < pvrDatas.numMipmaps) {
      var sWidth = pvrDatas.width >> mipLevel,
          sHeight = pvrDatas.height >> mipLevel;
      widthBlocks = sWidth / blockWidth;
      heightBlocks = sHeight / blockHeight; // Clamp to minimum number of blocks

      if (widthBlocks < 2) widthBlocks = 2;
      if (heightBlocks < 2) heightBlocks = 2;
      dataSize = widthBlocks * heightBlocks * blockSize;

      for (var surfIndex = 0; surfIndex < numSurfs; surfIndex++) {
        var byteArray = new Uint8Array(buffer, dataOffset, dataSize);
        var mipmap = {
          data: byteArray,
          width: sWidth,
          height: sHeight
        };
        pvr.mipmaps[surfIndex * pvrDatas.numMipmaps + mipLevel] = mipmap;
        dataOffset += dataSize;
      }

      mipLevel++;
    }

    return pvr;
  }
});