sclass Hi15ScanlineIndex { Hi15Image image; int w, h; int[] indexed; // scanlines contains 2 consecutive ints for each scanline: // -index of first pixel in scanline // -index of last pixel in scanline + 1 // // Colors are not stored and have to be gathered from the // original image. IntBuffer scanlines; *() {} *(Hi15Image *image) {} run { int w = this.w = image.getWidth(); int h = this.h = image.getHeight(); short[] pixels = image.pixels; int lineStart = 0; var indexed = this.indexed = new int[w*h]; int guess = 128*1024; var scanlines = this.scanlines = new IntBuffer(guess); for y to h: { int i = lineStart; int lineEnd = lineStart+w; while (i < lineEnd) { short color = pixels[i]; int j = i+1; if (j < lineEnd && pixels[j] == color) { do ++j; while (j < lineEnd && pixels[j] == color); scanlines.add(i); scanlines.add(j); int iScanline = scanlines.size(); for (int k = i; k < j; k++) indexed[k] = iScanline; } i = j; } lineStart = lineEnd; } } int nScanlines() { ret scanlines.size()/2; } // Render all scanlines in an image. // Isolated pixels (those different from their left and right // neighbor) will be left transparent. BufferedImage scanlinesAsImage() { int[] pixels = new[w*h]; int n = nScanlines(); for i to n: { int from = scanlines.get(i*2); int to = scanlines.get(i*2+1); int color = withFullAlpha(hi15ToRGBInt_clean(image.getHi15Pixel_noRangeCheck(from))); for (int pixel = from; pixel < to; pixel++) pixels[pixel] = color; } ret bufferedImageWithAlpha(w, h, pixels); } }