decodeApplePVRTC method
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);
}