ditherPixels function

Uint8List ditherPixels(
  1. Image image,
  2. NeuralQuantizer quantizer,
  3. DitherKernel kernel,
  4. bool serpentine,
)

Implementation

Uint8List ditherPixels(Image image, NeuralQuantizer quantizer,
    DitherKernel kernel, bool serpentine) {
  if (kernel == DitherKernel.None) {
    return quantizer.getIndexMap(image);
  }

  final ds = _ditherKernels[kernel.index];
  final height = image.height;
  final width = image.width;
  final data = Uint8List.fromList(image.getBytes());

  var direction = serpentine ? -1 : 1;

  final indexedPixels = Uint8List(width * height);
  final colorMap = quantizer.colorMap;

  var index = 0;
  for (var y = 0; y < height; y++) {
    if (serpentine) direction = direction * -1;

    final x0 = direction == 1 ? 0 : width - 1;
    final x1 = direction == 1 ? width : 0;
    for (var x = x0; x != x1; x += direction, ++index) {
      // Get original color
      var idx = index * 4;
      final r1 = data[idx];
      final g1 = data[idx + 1];
      final b1 = data[idx + 2];

      // Get converted color
      idx = quantizer.lookupRGB(r1, g1, b1);

      indexedPixels[index] = idx;
      idx *= 3;
      final r2 = colorMap[idx];
      final g2 = colorMap[idx + 1];
      final b2 = colorMap[idx + 2];

      final er = r1 - r2;
      final eg = g1 - g2;
      final eb = b1 - b2;

      if (er == 0 && eg == 0 && eb == 0) {
        continue;
      }

      final i0 = direction == 1 ? 0 : ds.length - 1;
      final i1 = direction == 1 ? ds.length : 0;
      for (var i = i0; i != i1; i += direction) {
        final x1 = ds[i][1].toInt();
        final y1 = ds[i][2].toInt();
        if (x1 + x >= 0 && x1 + x < width && y1 + y >= 0 && y1 + y < height) {
          var d = ds[i][0];
          idx = index + x1 + (y1 * width);
          idx *= 4;

          data[idx] = max(0, min(255, (data[idx] + er * d).toInt()));
          data[idx + 1] = max(0, min(255, (data[idx + 1] + eg * d).toInt()));
          data[idx + 2] = max(0, min(255, (data[idx + 2] + eb * d).toInt()));
        }
      }
    }
  }

  return indexedPixels;
}