ReadRGBAStrip() public method

Reads a whole strip of a strip-based image, decodes it and converts it to RGBA format.

ReadRGBAStrip reads a single strip of a strip-based image into memory, storing the result in the user supplied RGBA raster. If specified strip is the last strip, then it will only contain the portion of the strip that is actually within the image space. The raster is assumed to be an array of width times rowsperstrip 32-bit entries, where width is the width of the image (TiffTag.IMAGEWIDTH) and rowsperstrip is the maximum lines in a strip (TiffTag.ROWSPERSTRIP).

The row value should be the row of the first row in the strip (strip * rowsperstrip, zero based).

Note that the raster is assumed to be organized such that the pixel at location (x, y) is raster[y * width + x]; with the raster origin in the lower-left hand corner of the strip. That is bottom to top organization. When reading a partial last strip in the file the last line of the image will begin at the beginning of the buffer.

Raster pixels are 8-bit packed red, green, blue, alpha samples. The Tiff.GetR, Tiff.GetG, Tiff.GetB, and Tiff.GetA should be used to access individual samples. Images without Associated Alpha matting information have a constant Alpha of 1.0 (255).

See TiffRgbaImage for more details on how various image types are converted to RGBA values.

Samples must be either 1, 2, 4, 8, or 16 bits. Colorimetric samples/pixel must be either 1, 3, or 4 (i.e. SamplesPerPixel minus ExtraSamples).

Palette image colormaps that appear to be incorrectly written as 8-bit values are automatically scaled to 16-bits.

ReadRGBAStrip's main advantage over the similar O:BitMiracle.LibTiff.Classic.Tiff.ReadRGBAImage function is that for large images a single buffer capable of holding the whole image doesn't need to be allocated, only enough for one strip. The ReadRGBATile function does a similar operation for tiled images.

ReadRGBAStrip is just a wrapper around the more general TiffRgbaImage facilities.

All error messages are directed to the current error handler.

public ReadRGBAStrip ( int row, int raster ) : bool
row int The row.
raster int The RGBA raster.
return bool
Esempio n. 1
0
        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;
        }