decodePVR2 method
Implementation
Image? decodePVR2(List<int> data) {
final length = data.length;
const HEADER_SIZE = 52;
const PVRTEX_CUBEMAP = (1 << 12);
const PVR_PIXELTYPE_MASK = 0xff;
const PVR_TYPE_RGBA4444 = 0x10;
const PVR_TYPE_RGBA5551 = 0x11;
const PVR_TYPE_RGBA8888 = 0x12;
const PVR_TYPE_RGB565 = 0x13;
const PVR_TYPE_RGB555 = 0x14;
const PVR_TYPE_RGB888 = 0x15;
const PVR_TYPE_I8 = 0x16;
const PVR_TYPE_AI8 = 0x17;
const PVR_TYPE_PVRTC2 = 0x18;
const PVR_TYPE_PVRTC4 = 0x19;
if (length < HEADER_SIZE) {
return null;
}
final input = InputBuffer(data);
// Header
final size = input.readUint32();
final height = input.readUint32();
final width = input.readUint32();
/*int mipcount =*/ input.readUint32();
final flags = input.readUint32();
/*int texdatasize =*/ input.readUint32();
final bpp = input.readUint32();
/*int rmask =*/ input.readUint32();
/*int gmask =*/ input.readUint32();
/*int bmask =*/ input.readUint32();
final amask = input.readUint32();
final magic = input.readUint32();
var numtex = input.readUint32();
if (size != HEADER_SIZE || magic != 0x21525650) {
return null;
}
if (numtex < 1) {
numtex = (flags & PVRTEX_CUBEMAP) != 0 ? 6 : 1;
}
if (numtex != 1) {
// only 1 surface supported currently
return null;
}
if (width * height * bpp / 8 > length - HEADER_SIZE) {
return null;
}
final ptype = flags & PVR_PIXELTYPE_MASK;
switch (ptype) {
case PVR_TYPE_RGBA4444:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
final v1 = input.readByte();
final v2 = input.readByte();
final a = (v1 & 0x0f) << 4;
final b = (v1 & 0xf0);
final g = (v2 & 0x0f) << 4;
final r = (v2 & 0xf0);
out[oi++] = r;
out[oi++] = g;
out[oi++] = b;
out[oi++] = a;
}
}
return image;
case PVR_TYPE_RGBA5551:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
final v = input.readUint16();
final r = (v & 0xf800) >> 8;
final g = (v & 0x07c0) >> 3;
final b = (v & 0x003e) << 2;
final a = (v & 0x0001) != 0 ? 255 : 0;
out[oi++] = r;
out[oi++] = g;
out[oi++] = b;
out[oi++] = a;
}
}
return image;
case PVR_TYPE_RGBA8888:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
out[oi++] = input.readByte();
out[oi++] = input.readByte();
out[oi++] = input.readByte();
out[oi++] = input.readByte();
}
}
return image;
case PVR_TYPE_RGB565:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
final v = input.readUint16();
final b = (v & 0x001f) << 3;
final g = (v & 0x07e0) >> 3;
final r = (v & 0xf800) >> 8;
const a = 255;
out[oi++] = r;
out[oi++] = g;
out[oi++] = b;
out[oi++] = a;
}
}
return image;
case PVR_TYPE_RGB555:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
final v = input.readUint16();
final r = (v & 0x001f) << 3;
final g = (v & 0x03e0) >> 2;
final b = (v & 0x7c00) >> 7;
const a = 255;
out[oi++] = r;
out[oi++] = g;
out[oi++] = b;
out[oi++] = a;
}
}
return image;
case PVR_TYPE_RGB888:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
out[oi++] = input.readByte();
out[oi++] = input.readByte();
out[oi++] = input.readByte();
out[oi++] = 255;
}
}
return image;
case PVR_TYPE_I8:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
final i = input.readByte();
out[oi++] = i;
out[oi++] = i;
out[oi++] = i;
out[oi++] = 255;
}
}
return image;
case PVR_TYPE_AI8:
final image = Image(width, height);
final out = image.getBytes();
var oi = 0;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
final i = input.readByte();
final a = input.readByte();
out[oi++] = i;
out[oi++] = i;
out[oi++] = i;
out[oi++] = a;
}
}
return image;
case PVR_TYPE_PVRTC2:
// Currently unsupported
return null;
case PVR_TYPE_PVRTC4:
return amask == 0
? decodeRgb4bpp(width, height, input.toUint8List())
: decodeRgba4bpp(width, height, input.toUint8List());
}
// Unknown format
return null;
}