private bool cvt_by_strip(Tiff inImage, Tiff outImage, int width, int height)
{
FieldValue[] result = inImage.GetField(TiffTag.ROWSPERSTRIP);
if (result == null)
{
Tiff.Error(inImage.FileName(), "Source image not in strips");
return false;
}
m_rowsPerStrip = result[0].ToInt();
outImage.SetField(TiffTag.ROWSPERSTRIP, m_rowsPerStrip);
// Allocate strip buffer
int raster_size = multiply(width, m_rowsPerStrip);
int rasterByteSize = multiply(raster_size, sizeof(int));
if (raster_size == 0 || rasterByteSize == 0)
{
Tiff.Error(inImage.FileName(),
"Can't allocate buffer for raster of size {0}x{1}", width, m_rowsPerStrip);
return false;
}
int[] raster = new int[raster_size];
byte[] rasterBytes = new byte[rasterByteSize];
// Allocate a scanline buffer for swapping during the vertical mirroring pass.
// (Request can't overflow given prior checks.)
int[] wrk_line = new int[width];
// Loop over the strips.
for (int row = 0; row < height; row += m_rowsPerStrip)
{
// Read the strip into an RGBA array
if (!inImage.ReadRGBAStrip(row, raster))
return false;
// Figure out the number of scanlines actually in this strip.
int rows_to_write;
if (row + m_rowsPerStrip > height)
rows_to_write = height - row;
else
rows_to_write = m_rowsPerStrip;
// For some reason the TIFFReadRGBAStrip() function chooses the lower left corner
// as the origin. Vertically mirror scanlines.
for (int i_row = 0; i_row < rows_to_write / 2; i_row++)
{
int topIndex = width * i_row * sizeof(int);
int bottomIndex = width * (rows_to_write - i_row - 1) * sizeof(int);
Buffer.BlockCopy(raster, topIndex, wrk_line, 0, width * sizeof(int));
Buffer.BlockCopy(raster, bottomIndex, raster, topIndex, width * sizeof(int));
Buffer.BlockCopy(wrk_line, 0, raster, bottomIndex, width * sizeof(int));
}
// Write out the result in a strip
int bytesToWrite = rows_to_write * width * sizeof(int);
Buffer.BlockCopy(raster, 0, rasterBytes, 0, bytesToWrite);
if (outImage.WriteEncodedStrip(row / m_rowsPerStrip, rasterBytes, bytesToWrite) == -1)
return false;
}
return true;
}