encode method

  1. @override
Uint8List encode(
  1. Image image, {
  2. JpegChroma chroma = JpegChroma.yuv444,
  3. bool singleFrame = false,
})
override

Encode an image to an image format. If singleFrame is true, only the one Image will be encoded; otherwise if image has animation, all frames of the image will be encoded if the encoder supports animation.

Implementation

@override
Uint8List encode(
  Image image, {
  JpegChroma chroma = JpegChroma.yuv444,
  bool singleFrame = false,
}) {
  final fp = OutputBuffer(bigEndian: true);

  // 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);
      }
    }
  } 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();
}