private Tile ToTile(int[] pixeldata, int scanline, int x, int y, int w, int h) { var tile = new Tile(); SubRect subrect; var vector = new List <SubRect>(); int currentPixel; int currentX, currentY; int runningX, runningY; int firstX = 0, firstY, firstW, firstH; int secondX = 0, secondY, secondW, secondH; bool firstYflag; int segment; int line; tile.bgpixel = GetBackground(pixeldata, scanline, x, y, w, h); for (currentY = 0; currentY < h; currentY++) { line = (currentY + y) * scanline + x; for (currentX = 0; currentX < w; currentX++) { if (pixeldata[line + currentX] != tile.bgpixel) { currentPixel = pixeldata[line + currentX]; firstY = currentY - 1; firstYflag = true; for (runningY = currentY; runningY < h; runningY++) { segment = (runningY + y) * scanline + x; if (pixeldata[segment + currentX] != currentPixel) { break; } runningX = currentX; while ((runningX < w) && (pixeldata[segment + runningX] == currentPixel)) { runningX++; } runningX--; if (runningY == currentY) { secondX = firstX = runningX; } if (runningX < secondX) { secondX = runningX; } if (firstYflag && (runningX >= firstX)) { firstY++; } else { firstYflag = false; } } secondY = runningY - 1; firstW = firstX - currentX + 1; firstH = firstY - currentY + 1; secondW = secondX - currentX + 1; secondH = secondY - currentY + 1; subrect = new SubRect(); subrect.pixel = currentPixel; subrect.x = currentX; subrect.y = currentY; vector.Add(subrect); if (firstW * firstH > secondW * secondH) { subrect.w = firstW; subrect.h = firstH; } else { subrect.w = secondW; subrect.h = secondH; } for (runningY = subrect.y; runningY < subrect.y + subrect.h; runningY++) { for (runningX = subrect.x; runningX < subrect.x + subrect.w; runningX++) { pixeldata[(runningY + y) * scanline + x + runningX] = tile.bgpixel; } } } } } tile.subrects = new SubRect[vector.Count]; tile.subrects = vector.ToArray(); return(tile); }
public override unsafe void Encode() { var x = 0; //rectangle.X; var y = 0; //rectangle.Y; var w = rectangle.Width; var h = rectangle.Height; SubRect subrect; var vector = new List <SubRect>(); int currentPixel; int runningX, runningY; var firstX = 0; var secondX = 0; bgpixel = GetBackground(pixels, w, x, y, w, h); fixed(int *px = pixels) { for (var currentY = y; currentY < h; currentY++) { var line = currentY * w; for (var currentX = x; currentX < w; currentX++) { if (*(px + (line + currentX)) != bgpixel) { currentPixel = *(px + (line + currentX)); var firstY = currentY - 1; var firstYflag = true; for (runningY = currentY; runningY < h; runningY++) { var segment = runningY * w; if (*(px + (segment + currentX)) != currentPixel) { break; } runningX = currentX; while ((runningX < w) && (*(px + (segment + runningX)) == currentPixel)) { runningX++; } runningX--; if (runningY == currentY) { secondX = firstX = runningX; } if (runningX < secondX) { secondX = runningX; } if (firstYflag && (runningX >= firstX)) { firstY++; } else { firstYflag = false; } } var secondY = runningY - 1; var firstW = firstX - currentX + 1; var firstH = firstY - currentY + 1; var secondW = secondX - currentX + 1; var secondH = secondY - currentY + 1; subrect = new SubRect(); subrect.pixel = currentPixel; subrect.x = (ushort)currentX; subrect.y = (ushort)currentY; if (firstW * firstH > secondW * secondH) { subrect.w = (ushort)firstW; subrect.h = (ushort)firstH; } else { subrect.w = (ushort)secondW; subrect.h = (ushort)secondH; } vector.Add(subrect); for (runningY = subrect.y; runningY < subrect.y + subrect.h; runningY++) { for (runningX = subrect.x; runningX < subrect.x + subrect.w; runningX++) { *(px + (runningY * w + runningX)) = bgpixel; } } } } } } subrects = vector.ToArray(); }
private Tile ToTile(int[] pixeldata, int scanline, int x, int y, int w, int h) { var tile = new Tile(); SubRect subrect; var vector = new List<SubRect>(); int currentPixel; int currentX, currentY; int runningX, runningY; int firstX = 0, firstY, firstW, firstH; int secondX = 0, secondY, secondW, secondH; bool firstYflag; int segment; int line; tile.bgpixel = GetBackground(pixeldata, scanline, x, y, w, h); for (currentY = 0; currentY < h; currentY++) { line = (currentY + y)*scanline + x; for (currentX = 0; currentX < w; currentX++) { if (pixeldata[line + currentX] != tile.bgpixel) { currentPixel = pixeldata[line + currentX]; firstY = currentY - 1; firstYflag = true; for (runningY = currentY; runningY < h; runningY++) { segment = (runningY + y)*scanline + x; if (pixeldata[segment + currentX] != currentPixel) break; runningX = currentX; while ((runningX < w) && (pixeldata[segment + runningX] == currentPixel)) runningX++; runningX--; if (runningY == currentY) secondX = firstX = runningX; if (runningX < secondX) secondX = runningX; if (firstYflag && (runningX >= firstX)) firstY++; else firstYflag = false; } secondY = runningY - 1; firstW = firstX - currentX + 1; firstH = firstY - currentY + 1; secondW = secondX - currentX + 1; secondH = secondY - currentY + 1; subrect = new SubRect(); subrect.pixel = currentPixel; subrect.x = currentX; subrect.y = currentY; vector.Add(subrect); if (firstW*firstH > secondW*secondH) { subrect.w = firstW; subrect.h = firstH; } else { subrect.w = secondW; subrect.h = secondH; } for (runningY = subrect.y; runningY < subrect.y + subrect.h; runningY++) for (runningX = subrect.x; runningX < subrect.x + subrect.w; runningX++) pixeldata[(runningY + y)*scanline + x + runningX] = tile.bgpixel; } } } tile.subrects = new SubRect[vector.Count]; tile.subrects = vector.ToArray(); return tile; }
public unsafe override void Encode() { int x = rectangle.X; int y = rectangle.Y; int w = rectangle.Width; int h = rectangle.Height; SubRect subrect; List<SubRect> vector = new List<SubRect>(); int currentPixel; int runningX, runningY; int firstX = 0; int secondX = 0; bgpixel = GetBackground(pixels, w, 0, 0, w, h); fixed (int* px = pixels) { for (int currentY = 0; currentY < h; currentY++) { int line = currentY * w; for (int currentX = 0; currentX < w; currentX++) { if (*(px + (line + currentX)) != bgpixel) { currentPixel = *(px + (line + currentX)); int firstY = currentY - 1; bool firstYflag = true; for (runningY = currentY; runningY < h; runningY++) { int segment = runningY * w; if ((*(px + (segment + currentX))) != currentPixel) break; runningX = currentX; while ((runningX < w) && (*(px + (segment + runningX)) == currentPixel)) runningX++; runningX--; if (runningY == currentY) secondX = firstX = runningX; if (runningX < secondX) secondX = runningX; if (firstYflag && (runningX >= firstX)) firstY++; else firstYflag = false; } int secondY = runningY - 1; int firstW = firstX - currentX + 1; int firstH = firstY - currentY + 1; int secondW = secondX - currentX + 1; int secondH = secondY - currentY + 1; subrect = new SubRect(); subrect.pixel = currentPixel; subrect.x = (ushort)currentX; subrect.y = (ushort)currentY; if ((firstW * firstH) > (secondW * secondH)) { subrect.w = (ushort)firstW; subrect.h = (ushort)firstH; } else { subrect.w = (ushort)secondW; subrect.h = (ushort)secondH; } vector.Add(subrect); for (runningY = subrect.y; runningY < (subrect.y + subrect.h); runningY++) for (runningX = subrect.x; runningX < (subrect.x + subrect.w); runningX++) *(px + (runningY * w + runningX)) = bgpixel; } } } } subrects = vector.ToArray(); }
private static Rect FindLargestRectangle(bool[] grid, int width, int height) { //http://www.drdobbs.com/database/the-maximal-rectangle-problem/184410529 // These variable will hold the best results. int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; // Initialize cache with 0s. // This will hold the number of 'true' values in this cell or to the right, for each cell in a column. int[] cache = new int[height]; Stack <SubRect> stack = new Stack <SubRect>(); SubRect subRect = new SubRect(); int x, y, w; for (x = width - 1; x >= 0; --x) { // Update cache. for (y = 0; y < height; ++y) { if (grid[(x * height) + y]) { ++cache[y]; } else { cache[y] = 0; } } w = 0; for (y = 0; y < height; ++y) { if (cache[y] > w) { stack.Push(new SubRect { y = y, width = w }); w = cache[y]; } else if (cache[y] < w) { do { subRect = stack.Pop(); // Note that the area is actually missing one pixel from each row and column to be more optimal. if (w * (y - subRect.y) > (x1 - x0) * (y1 - y0)) { x0 = x; y0 = subRect.y; x1 = x + w - 1; y1 = y - 1; } w = subRect.width; } while (cache[y] < w); w = cache[y]; if (w != 0) { stack.Push(subRect); } } } } return(new Rect(x0 * Stride, y0 * Stride, x1 * Stride, y1 * Stride)); }
public override unsafe void Encode() { var x = 0; //rectangle.X; var y = 0; //rectangle.Y; var w = rectangle.Width; var h = rectangle.Height; SubRect subrect; var vector = new List<SubRect>(); int currentPixel; int runningX, runningY; var firstX = 0; var secondX = 0; bgpixel = GetBackground(pixels, w, x, y, w, h); fixed (int* px = pixels) { for (var currentY = y; currentY < h; currentY++) { var line = currentY*w; for (var currentX = x; currentX < w; currentX++) { if (*(px + (line + currentX)) != bgpixel) { currentPixel = *(px + (line + currentX)); var firstY = currentY - 1; var firstYflag = true; for (runningY = currentY; runningY < h; runningY++) { var segment = runningY*w; if (*(px + (segment + currentX)) != currentPixel) break; runningX = currentX; while ((runningX < w) && (*(px + (segment + runningX)) == currentPixel)) runningX++; runningX--; if (runningY == currentY) secondX = firstX = runningX; if (runningX < secondX) secondX = runningX; if (firstYflag && (runningX >= firstX)) firstY++; else firstYflag = false; } var secondY = runningY - 1; var firstW = firstX - currentX + 1; var firstH = firstY - currentY + 1; var secondW = secondX - currentX + 1; var secondH = secondY - currentY + 1; subrect = new SubRect(); subrect.pixel = currentPixel; subrect.x = (ushort) currentX; subrect.y = (ushort) currentY; if (firstW*firstH > secondW*secondH) { subrect.w = (ushort) firstW; subrect.h = (ushort) firstH; } else { subrect.w = (ushort) secondW; subrect.h = (ushort) secondH; } vector.Add(subrect); for (runningY = subrect.y; runningY < subrect.y + subrect.h; runningY++) for (runningX = subrect.x; runningX < subrect.x + subrect.w; runningX++) *(px + (runningY*w + runningX)) = bgpixel; } } } } subrects = vector.ToArray(); }