srecord noeq Hi15ImageStreaks(Hi15Image inputImage) { // x values of streak ends new IntBuffer streakData; int[] lineStarts; gettable int w; run { var streakData = this.streakData; int w = this.w = inputImage.w(), h = inputImage.h(); lineStarts = new int[h+1]; short[] pixels = inputImage.pixels; int iPixel = 0; for y to h: { lineStarts[y] = streakData.size(); int lineEnd = iPixel+w; while (iPixel < lineEnd) { short color = pixels[iPixel]; do ++iPixel; while (iPixel < lineEnd && pixels[iPixel] == color); streakData.add(iPixel); } } lineStarts[l(lineStarts)-1] = streakData.size(); } selfType runAndReturn() { run(); this; } int nStreaks() { ret streakData.size(); } int h() { ret lineStarts.length-1; } int lineEnd(int y) { ret lineStarts[y+1]; } ItIt streaksAsRectsIterator() { ret iffNull(new IF0 { int iStreak; int x, y; public Rect get() { if (y >= h()) null; if (iStreak >= nStreaks()) null; if (y+1 < h() && iStreak >= lineStarts[y+1]) { ++y; x = 0; } int x2 = ((streakData.get(iStreak++)-1) % w)+1; Rect r = rect(x, y, x2-x, 1); x = x2; ret r; } }); } }