/// <summary> /// Get a strip-organized image that has /// PlanarConfiguration contiguous if SamplesPerPixel > 1 /// or /// SamplesPerPixel == 1 /// </summary> private static bool gtStripContig(TiffRgbaImage img, int[] raster, int offset, int width, int height) { byte[] buf = new byte[img.tif.StripSize()]; int flip = img.setorientation(); int y; int rasterShift; if ((flip & FLIP_VERTICALLY) != 0) { y = height - 1; rasterShift = -(width + width); } else { y = 0; rasterShift = -(width - width); } FieldValue[] result = img.tif.GetFieldDefaulted(TiffTag.RowsPerStrip); int rowsperstrip = result[0].ToInt(); if (rowsperstrip == -1) { // San Chen <*****@*****.**> // HACK: should be UInt32.MaxValue rowsperstrip = Int32.MaxValue; } result = img.tif.GetFieldDefaulted(TiffTag.YCBCRSUBSAMPLING); short subsamplingver = result[1].ToShort(); int scanline = img.tif.newScanlineSize(); int bufferShift = (width < img.width ? img.width - width : 0); bool ret = true; for (int row = 0; row < height; ) { int rowstoread = rowsperstrip - (row + img.row_offset) % rowsperstrip; int nrow = (row + rowstoread > height ? height - row : rowstoread); int nrowsub = nrow; if ((nrowsub % subsamplingver) != 0) nrowsub += subsamplingver - nrowsub % subsamplingver; if (img.tif.ReadEncodedStrip(img.tif.ComputeStrip(row + img.row_offset, 0), buf, 0, ((row + img.row_offset) % rowsperstrip + nrowsub) * scanline) < 0 && img.stoponerr) { ret = false; break; } int pos = ((row + img.row_offset) % rowsperstrip) * scanline; img.putContig(img, raster, offset + y * width, rasterShift, 0, y, width, nrow, buf, pos, bufferShift); y += (flip & FLIP_VERTICALLY) != 0 ? -nrow : nrow; row += nrow; } if ((flip & FLIP_HORIZONTALLY) != 0) { for (int line = 0; line < height; line++) { int left = offset + line * width; int right = left + width - 1; while (left < right) { int temp = raster[left]; raster[left] = raster[right]; raster[right] = temp; left++; right--; } } } return ret; }
/// <summary> /// Get an tile-organized image that has /// PlanarConfiguration contiguous if SamplesPerPixel > 1 /// or /// SamplesPerPixel == 1 /// </summary> private static bool gtTileContig(TiffRgbaImage img, int[] raster, int offset, int width, int height) { byte[] buf = new byte[img.tif.TileSize()]; FieldValue[] result = img.tif.GetField(TiffTag.TileWidth); int tileWidth = result[0].ToInt(); result = img.tif.GetField(TiffTag.TileLength); int tileHeight = result[0].ToInt(); int flip = img.setorientation(); int y; int rasterShift; if ((flip & FLIP_VERTICALLY) != 0) { y = height - 1; rasterShift = -(tileWidth + width); } else { y = 0; rasterShift = -(tileWidth - width); } bool ret = true; for (int row = 0; row < height; ) { int rowstoread = tileHeight - (row + img.row_offset) % tileHeight; int nrow = (row + rowstoread > height ? height - row : rowstoread); for (int col = 0; col < width; col += tileWidth) { if (img.tif.ReadTile(buf, 0, col + img.col_offset, row + img.row_offset, 0, 0) < 0 && img.stoponerr) { ret = false; break; } int pos = ((row + img.row_offset) % tileHeight) * img.tif.TileRowSize(); if (col + tileWidth > width) { // Tile is clipped horizontally. Calculate visible portion and // skewing factors. int npix = width - col; int bufferShift = tileWidth - npix; img.putContig(img, raster, offset + y * width + col, rasterShift + bufferShift, col, y, npix, nrow, buf, pos, bufferShift); } else { img.putContig(img, raster, offset + y * width + col, rasterShift, col, y, tileWidth, nrow, buf, pos, 0); } } y += ((flip & FLIP_VERTICALLY) != 0 ? -nrow : nrow); row += nrow; } if ((flip & FLIP_HORIZONTALLY) != 0) { for (int line = 0; line < height; line++) { int left = offset + line * width; int right = left + width - 1; while (left < right) { int temp = raster[left]; raster[left] = raster[right]; raster[right] = temp; left++; right--; } } } return ret; }