encodeImage method

  1. @override
List<int> encodeImage(
  1. Image image
)
override

Encode a single image.

Implementation

@override
List<int> encodeImage(Image image) {
  final fp = OutputBuffer(bigEndian: true);

  // Add JPEG headers
  _writeMarker(fp, Jpeg.M_SOI);
  _writeAPP0(fp);
  _writeAPP1(fp, image.exif);
  _writeDQT(fp);
  _writeSOF0(fp, image.width, image.height);
  _writeDHT(fp);
  _writeSOS(fp);

  // Encode 8x8 macroblocks
  int? DCY = 0;
  int? DCU = 0;
  int? DCV = 0;

  _resetBits();

  final width = image.width;
  final height = image.height;

  final imageData = image.getBytes();
  final quadWidth = width * 4;
  //int tripleWidth = width * 3;
  //bool first = true;

  var y = 0;
  while (y < height) {
    var x = 0;
    while (x < quadWidth) {
      final start = quadWidth * y + x;
      for (var pos = 0; pos < 64; pos++) {
        final row = pos >> 3; // / 8
        final col = (pos & 7) * 4; // % 8
        var p = start + (row * quadWidth) + col;

        if (y + row >= height) {
          // padding bottom
          p -= (quadWidth * (y + 1 + row - height));
        }

        if (x + col >= quadWidth) {
          // padding right
          p -= ((x + col) - quadWidth + 4);
        }

        final r = imageData[p++];
        final g = imageData[p++];
        final b = imageData[p++];

        // calculate YUV values
        YDU[pos] = ((RGB_YUV_TABLE[r] +
                    RGB_YUV_TABLE[(g + 256)] +
                    RGB_YUV_TABLE[(b + 512)]) >>
                16) -
            128.0;

        UDU[pos] = ((RGB_YUV_TABLE[(r + 768)] +
                    RGB_YUV_TABLE[(g + 1024)] +
                    RGB_YUV_TABLE[(b + 1280)]) >>
                16) -
            128.0;

        VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)] +
                    RGB_YUV_TABLE[(g + 1536)] +
                    RGB_YUV_TABLE[(b + 1792)]) >>
                16) -
            128.0;
      }

      DCY = _processDU(fp, YDU, fdtbl_Y, DCY!, YDC_HT, YAC_HT);
      DCU = _processDU(fp, UDU, fdtbl_UV, DCU!, UVDC_HT, UVAC_HT);
      DCV = _processDU(fp, VDU, fdtbl_UV, DCV!, UVDC_HT, UVAC_HT);

      x += 32;
    }

    y += 8;
  }

  ////////////////////////////////////////////////////////////////

  // Do the bit alignment of the EOI marker
  if (_bytepos >= 0) {
    final fillBits = [(1 << (_bytepos + 1)) - 1, _bytepos + 1];
    _writeBits(fp, fillBits);
  }

  _writeMarker(fp, Jpeg.M_EOI);

  return fp.getBytes();
}