decodeApplePVRTC method

Image? decodeApplePVRTC(
  1. List<int> data
)

Implementation

Image? decodeApplePVRTC(List<int> data) {
  // additional heuristic
  const HEADER_SIZE = 52;
  if (data.length > HEADER_SIZE) {
    final input = InputBuffer(data);
    // Header
    final size = input.readUint32();
    if (size == HEADER_SIZE) {
      return null;
    }
    /*int height =*/ input.readUint32();
    /*int width =*/ input.readUint32();
    /*int mipcount =*/ input.readUint32();
    /*int flags =*/ input.readUint32();
    /*int texdatasize =*/ input.readUint32();
    /*int bpp =*/ input.readUint32();
    /*int rmask =*/ input.readUint32();
    /*int gmask =*/ input.readUint32();
    /*int bmask =*/ input.readUint32();
    final magic = input.readUint32();
    if (magic == 0x21525650) {
      // this looks more like a PowerVR file.
      return null;
    }
  }

  //const PVRTC2 = 1;
  //const PVRTC4 = 2;

  var mode = 1;
  var res = 8;
  final size = data.length;
  //int format = 0;

  // this is a tough one, could be 2bpp 8x8, 4bpp 8x8
  if (size == 32) {
    // assume 4bpp, 8x8
    mode = 0;
    res = 8;
  } else {
    // Detect if it's 2bpp or 4bpp
    var shift = 0;
    const test2bpp = 0x40; // 16x16
    const test4bpp = 0x80; // 16x16

    while (shift < 10) {
      final s2 = shift << 1;

      if ((test2bpp << s2) & size != 0) {
        res = 16 << shift;
        mode = 1;
        //format = PVRTC2;
        break;
      }

      if ((test4bpp << s2) & size != 0) {
        res = 16 << shift;
        mode = 0;
        //format = PVRTC4;
        break;
      }

      ++shift;
    }

    if (shift == 10) {
      // no mode could be found.
      return null;
    }
  }

  // there is no reliable way to know if it's a 2bpp or 4bpp file. Assuming
  final width = res;
  final height = res;
  final bpp = (mode + 1) * 2;
  //int numMips = 0;

  if (bpp == 4) {
    // 2bpp is currently unsupported
    return null;
  }

  return decodeRgba4bpp(width, height, data as TypedData);
}