Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RangeError (index): Index out of range: index should be less than 3: 3 #673

Open
stephane-archer opened this issue Aug 14, 2024 · 4 comments

Comments

@stephane-archer
Copy link

Here is the error I observe, I might do something wrong:

RangeError (index): Index out of range: index should be less than 3: 3
dart:typed_data                                   Uint8List.[]
package:image/src/image/palette_uint8.dart 66:35  PaletteUint8.get
package:image/src/image/pixel_uint1.dart 166:18   PixelUint1._getChannel

The input is a simple png of 5x5 yellow pixels.

Here is the code:

Iterable<img.Image> getUniqTiles(img.Image image, int tileSize) {
  // Map to store unique tiles
  final Map<String, img.Image> uniqueTiles = {};

  // Split image into tiles
  for (int y = 0; y < image.height; y += tileSize) {
    for (int x = 0; x < image.width; x += tileSize) {
      if (y + tileSize > image.height || x + tileSize > image.width) {
        dev.log("skip too small tile");
        continue;
      }
      final img.Image tile = img.copyCrop(
        image,
        x: x,
        y: y,
        width: tileSize,
        height: tileSize,
        antialias: false,
      );

      // Convert tile to a unique key
      final tileKey = _tileToKey(tile);

      uniqueTiles[tileKey] = tile;
    }
  }
  return uniqueTiles.values;
}

String _tileToKey(img.Image tile) {
  if (!tile.isValid) {
    throw StateError("tile invalid");
  }
  if (tile.isEmpty) {
    throw StateError("tile empty");
  }
  final buffer = StringBuffer();
  for (int y = 0; y < tile.height; y++) {
    for (int x = 0; x < tile.width; x++) {
      final pixel = tile.getPixel(x, y);
      if (!pixel.isValid) {
        throw StateError("invalid pixel");
      }
      num red = pixel.r;
      num green = pixel.g;
      num blue = pixel.b;
      num alpha = pixel.a;
      buffer.write('$red,$green,$blue,$alpha;');
    }
  }
  return buffer.toString();
}

void main() {
  test('Counter value should be incremented', () async {
    img.Image? image = await img.decodePngFile('test/testData/5x5yellow.png');
    if (image == null) {
      throw StateError("bad input");
    }
    var tiles = getUniqTiles(image, 5);
    expect(tiles.length, 1);
  });
}

The error occurs on num red = pixel.r; (when I try to access the pixel value) in _tileToKey

my usage ofimg.copyCrop might be the issue.

@stephane-archer
Copy link
Author

stephane-archer commented Aug 15, 2024

here is the image:
New Project (11)

@stephane-archer
Copy link
Author

if I do in the main:

   image =  image.convert(format: img.Format.uint8, numChannels: 3);

I don't get the Index out of range exception but:

if (!pixel.isValid) {
        throw StateError("invalid pixel");
}

some pixels are not valid (but their RGB values are correct) so doing the convert and removing the isValid check makes the code work but I still don't understand what is going on, and there is something wrong here with what I do or the library

@stephane-archer
Copy link
Author

I think this is related to the fact that my image has a PaletteUint8
that make things go out of bounds on:

  num get(int index, int channel) =>
      channel < numChannels ? data[index * numChannels + channel] : 0;

called from:

  num _getChannel(int ci) => palette == null
      ? numChannels > ci
          ? _get(ci)
          : 0
      : palette!.get(_get(0), ci);

but I'm not able to understand this code and what it is doing:

  int _get(int ci) {
    var i = _index;
    var bi = 7 - (_bitIndex + ci);
    if (bi < 0) {
      bi += 8;
      i++;
    }
    if (i >= image.data.length) {
      return 0;
    }
    return (image.data[i] >> bi) & 0x1;
  }

@stephane-archer
Copy link
Author

converting my input file not to use the palette removes the issue so there is something wrong with nt _get(int ci) and PNG palette support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant