decodeRgba4bpp method

Image decodeRgba4bpp(
  1. int width,
  2. int height,
  3. TypedData data
)

Implementation

Image decodeRgba4bpp(int width, int height, TypedData data) {
  final result = Image(width, height, channels: Channels.rgb);

  final blocks = width ~/ 4;
  final blockMask = blocks - 1;

  final packet = PvrtcPacket(data);
  final p0 = PvrtcPacket(data);
  final p1 = PvrtcPacket(data);
  final p2 = PvrtcPacket(data);
  final p3 = PvrtcPacket(data);
  final c = PvrtcColorRgba();
  const factors = PvrtcPacket.BILINEAR_FACTORS;
  const weights = PvrtcPacket.WEIGHTS;

  for (var y = 0; y < blocks; ++y) {
    for (var x = 0; x < blocks; ++x) {
      packet.setBlock(x, y);

      var mod = packet.modulationData;
      final weightIndex = 4 * packet.usePunchthroughAlpha;
      var factorIndex = 0;

      for (var py = 0; py < 4; ++py) {
        final yOffset = (py < 2) ? -1 : 0;
        final y0 = (y + yOffset) & blockMask;
        final y1 = (y0 + 1) & blockMask;
        final pyi = (py + y * 4) * width;

        for (var px = 0; px < 4; ++px) {
          final xOffset = (px < 2) ? -1 : 0;
          final x0 = (x + xOffset) & blockMask;
          final x1 = (x0 + 1) & blockMask;

          p0.setBlock(x0, y0);
          p1.setBlock(x1, y0);
          p2.setBlock(x0, y1);
          p3.setBlock(x1, y1);

          final ca = p0.getColorRgbaA() * factors[factorIndex][0] +
              p1.getColorRgbaA() * factors[factorIndex][1] +
              p2.getColorRgbaA() * factors[factorIndex][2] +
              p3.getColorRgbaA() * factors[factorIndex][3];

          final cb = p0.getColorRgbaB() * factors[factorIndex][0] +
              p1.getColorRgbaB() * factors[factorIndex][1] +
              p2.getColorRgbaB() * factors[factorIndex][2] +
              p3.getColorRgbaB() * factors[factorIndex][3];

          final w = weights[weightIndex + mod & 3];

          c.r = (ca.r * w[0] + cb.r * w[1]) >> 7;
          c.g = (ca.g * w[0] + cb.g * w[1]) >> 7;
          c.b = (ca.b * w[0] + cb.b * w[1]) >> 7;
          c.a = (ca.a * w[2] + cb.a * w[3]) >> 7;

          final pi = (pyi + (px + x * 4));

          result[pi] = getColor(c.r, c.g, c.b, c.a);

          mod >>= 2;
          factorIndex++;
        }
      }
    }
  }

  return result;
}