encode method
Future<Uint8List>
encode(
- Image image, {
- JpegChroma chroma = JpegChroma.yuv444,
- bool singleFrame = false,
- Completer? destroy$,
Implementation
Future<Uint8List> encode(
Image image, {
JpegChroma chroma = JpegChroma.yuv444,
bool singleFrame = false,
Completer? destroy$,
}) async {
final fp = OutputBuffer(bigEndian: true);
Future healthCheck() async {
await Future.delayed(const Duration(microseconds: 10));
if (destroy$?.isCompleted == true) {
throw ArgumentError('Kill encode jpg');
}
}
// Add JPEG headers
_writeMarker(fp, JpegMarker.soi);
_writeAPP0(fp);
_writeAPP1(fp, image.exif);
_writeDQT(fp);
_writeSOF0(fp, image.width, image.height, chroma);
_writeDHT(fp);
_writeSOS(fp);
_resetBits();
int dcy = 0, dcu = 0, dcv = 0;
final width = image.width;
final height = image.height;
if (chroma == JpegChroma.yuv444) {
// 4:4:4 chroma: process 8x8 blocks.
final ydu = Float32List(64);
final udu = Float32List(64);
final vdu = Float32List(64);
for (int y = 0; y < height; y += 8) {
for (int x = 0; x < width; x += 8) {
_calculateYUV(image, x, y, width, height, ydu, udu, vdu);
dcy = _processDU(fp, ydu, _fdtblY, dcy, _ydcHuffman, _yacHuffman);
dcu = _processDU(fp, udu, _fdtblUv, dcu, _uvdcHuffman, _uvacHuffman);
dcv = _processDU(fp, vdu, _fdtblUv, dcv, _uvdcHuffman, _uvacHuffman);
}
if (y % 24 == 0) {
await healthCheck();
}
}
} else {
// 4:2:0 chroma: process 8x8 blocks and prepare subsampled U and V.
final ydu = List<Float32List>.generate(4, (i) => Float32List(64));
final udu = List<Float32List>.generate(4, (i) => Float32List(64));
final vdu = List<Float32List>.generate(4, (i) => Float32List(64));
final sudu = Float32List(64);
final svdu = Float32List(64);
for (int y = 0; y < height; y += 16) {
for (int x = 0; x < width; x += 16) {
_calculateYUV(image, x, y, width, height, ydu[0], udu[0], vdu[0]);
_calculateYUV(image, x + 8, y, width, height, ydu[1], udu[1], vdu[1]);
_calculateYUV(image, x, y + 8, width, height, ydu[2], udu[2], vdu[2]);
_calculateYUV(
image, x + 8, y + 8, width, height, ydu[3], udu[3], vdu[3]);
_downsampleDU(sudu, udu[0], udu[1], udu[2], udu[3]);
_downsampleDU(svdu, vdu[0], vdu[1], vdu[2], vdu[3]);
dcy = _processDU(fp, ydu[0], _fdtblY, dcy, _ydcHuffman, _yacHuffman);
dcy = _processDU(fp, ydu[1], _fdtblY, dcy, _ydcHuffman, _yacHuffman);
dcy = _processDU(fp, ydu[2], _fdtblY, dcy, _ydcHuffman, _yacHuffman);
dcy = _processDU(fp, ydu[3], _fdtblY, dcy, _ydcHuffman, _yacHuffman);
dcu = _processDU(fp, sudu, _fdtblUv, dcu, _uvdcHuffman, _uvacHuffman);
dcv = _processDU(fp, svdu, _fdtblUv, dcv, _uvdcHuffman, _uvacHuffman);
}
}
}
////////////////////////////////////////////////////////////////
// Do the bit alignment of the EOI marker
if (_bytePos >= 0) {
final fillBits = [(1 << (_bytePos + 1)) - 1, _bytePos + 1];
_writeBits(fp, fillBits);
}
_writeMarker(fp, JpegMarker.eoi);
return fp.getBytes();
}