decodeFrame method
Decode the frame (assuming startDecode has already been called).
Implementation
@override
Image? decodeFrame(int frame) {
if (_info == null) {
return null;
}
final imageData = <int>[];
int? width = _info!.width;
int? height = _info!.height;
if (!_info!.isAnimated || frame == 0) {
for (var i = 0, len = _info!.idat.length; i < len; ++i) {
_input.offset = _info!.idat[i];
final chunkSize = _input.readUint32();
final chunkType = _input.readString(4);
final data = _input.readBytes(chunkSize).toUint8List();
imageData.addAll(data);
final crc = _input.readUint32();
final computedCrc = _crc(chunkType, data);
if (crc != computedCrc) {
throw ImageException('Invalid $chunkType checksum');
}
}
} else {
if (frame < 0 || frame >= _info!.frames.length) {
throw ImageException('Invalid Frame Number: $frame');
}
final f = _info!.frames[frame] as InternalPngFrame;
width = f.width;
height = f.height;
for (var i = 0; i < f.fdat.length; ++i) {
_input.offset = f.fdat[i];
final chunkSize = _input.readUint32();
/*String chunkType =*/
_input.readString(4);
_input.skip(4); // sequence number
final data = _input.readBytes(chunkSize).toUint8List();
imageData.addAll(data);
}
//_frame = frame;
//_numFrames = _info.numFrames;
}
Channels channels;
if (_info!.colorType == GRAYSCALE_ALPHA ||
_info!.colorType == RGBA ||
_info!.transparency != null) {
channels = Channels.rgba;
} else {
channels = Channels.rgb;
}
final image = Image(width!, height!, channels: channels);
final uncompressed = const ZLibDecoder().decodeBytes(imageData);
// input is the decompressed data.
final input = InputBuffer(uncompressed, bigEndian: true);
_resetBits();
// Set up a LUT to transform colors for gamma correction.
if (_info!.colorLut == null) {
_info!.colorLut = List<int>.generate(256, (i) {
final c = i;
/*if (info.gamma != null) {
c = (Math.pow((c / 255.0), info.gamma) * 255.0).toInt();
}*/
return c;
}, growable: false);
// Apply the LUT to the palette, if necessary.
if (_info!.palette != null && _info!.gamma != null) {
for (var i = 0; i < _info!.palette!.length; ++i) {
_info!.palette![i] = _info!.colorLut![_info!.palette![i]!];
}
}
}
final origW = _info!.width;
final origH = _info!.height;
_info!.width = width;
_info!.height = height;
final w = width;
final h = height;
_progressY = 0;
if (_info!.interlaceMethod != 0) {
_processPass(input, image, 0, 0, 8, 8, (w + 7) >> 3, (h + 7) >> 3);
_processPass(input, image, 4, 0, 8, 8, (w + 3) >> 3, (h + 7) >> 3);
_processPass(input, image, 0, 4, 4, 8, (w + 3) >> 2, (h + 3) >> 3);
_processPass(input, image, 2, 0, 4, 4, (w + 1) >> 2, (h + 3) >> 2);
_processPass(input, image, 0, 2, 2, 4, (w + 1) >> 1, (h + 1) >> 2);
_processPass(input, image, 1, 0, 2, 2, w >> 1, (h + 1) >> 1);
_processPass(input, image, 0, 1, 1, 2, w, h >> 1);
} else {
_process(input, image);
}
_info!.width = origW;
_info!.height = origH;
if (_info!.iCCPData != null) {
image.iccProfile = ICCProfileData(
_info!.iCCPName, ICCPCompression.deflate, _info!.iCCPData!);
}
return image;
}