BitMiracle.LibTiff.Classic.Tiff.WriteEncodedTile C# (CSharp) Method

WriteEncodedTile() public method

Encodes and writes a tile of data to an open TIFF file/stream.

WriteEncodedTile encodes count bytes of raw data from buffer and append the result to the end of the specified tile. Note that the value of tile is a "raw tile number". That is, the caller must take into account whether or not the data are organized in separate planes (TiffTag.PLANARCONFIG = PlanarConfig.SEPARATE). ComputeTile automatically does this when converting an (x, y, z, plane) coordinate quadruple to a tile number.

There must be space for the data. The function clamps individual writes to a tile to the tile size, but does not (and can not) check that multiple writes to the same tile were performed.

A correct value for the TiffTag.IMAGELENGTH tag must be setup before writing; WriteEncodedTile does not support automatically growing the image on each write (as O:BitMiracle.LibTiff.Classic.Tiff.WriteScanline does).

The library writes encoded data using the native machine byte order. Correctly implemented TIFF readers are expected to do any necessary byte-swapping to correctly process image data with value of TiffTag.BITSPERSAMPLE tag greater than 8.

public WriteEncodedTile ( int tile, byte buffer, int offset, int count ) : int
tile int The zero-based index of the tile to write.
buffer byte The buffer with image data to be encoded and written.
offset int The zero-based byte offset in at which /// to begin reading bytes to be encoded and written.
count int The maximum number of tile bytes to be read from /// .
return int
        public int WriteEncodedTile(int tile, byte[] buffer, int offset, int count)
        {
            const string module = "WriteEncodedTile";

            if (!writeCheckTiles(module))
                return -1;

            if (tile >= m_dir.td_nstrips)
            {
                ErrorExt(this, m_clientdata, module, "{0}: Tile {1} out of range, max {2}", m_name, tile, m_dir.td_nstrips);
                return -1;
            }

            // Handle delayed allocation of data buffer. This permits it to be sized more
            // intelligently (using directory information).
            bufferCheck();

            m_curtile = tile;

            m_rawcc = 0;
            m_rawcp = 0;

            if (m_dir.td_stripbytecount[tile] > 0)
            {
                // this forces appendToStrip() to do a seek
                m_curoff = 0;
            }

            // Compute tiles per row & per column to compute current row and column
            m_row = (tile % howMany(m_dir.td_imagelength, m_dir.td_tilelength)) * m_dir.td_tilelength;
            m_col = (tile % howMany(m_dir.td_imagewidth, m_dir.td_tilewidth)) * m_dir.td_tilewidth;

            if ((m_flags & TiffFlags.CODERSETUP) != TiffFlags.CODERSETUP)
            {
                if (!m_currentCodec.SetupEncode())
                    return -1;

                m_flags |= TiffFlags.CODERSETUP;
            }

            m_flags &= ~TiffFlags.POSTENCODE;
            short sample = (short)(tile / m_dir.td_stripsperimage);
            if (!m_currentCodec.PreEncode(sample))
                return -1;

            // Clamp write amount to the tile size. This is mostly done so that callers can pass
            // in some large number (e.g. -1) and have the tile size used instead.
            if (count < 1 || count > m_tilesize)
                count = m_tilesize;

            // swab if needed - note that source buffer will be altered
            postDecode(buffer, offset, count);

            if (!m_currentCodec.EncodeTile(buffer, offset, count, sample))
                return 0;

            if (!m_currentCodec.PostEncode())
                return -1;

            if (!isFillOrder(m_dir.td_fillorder) && (m_flags & TiffFlags.NOBITREV) != TiffFlags.NOBITREV)
                ReverseBits(m_rawdata, m_rawcc);

            if (m_rawcc > 0 && !appendToStrip(tile, m_rawdata, 0, m_rawcc))
                return -1;

            m_rawcc = 0;
            m_rawcp = 0;
            return count;
        }

Same methods

Tiff::WriteEncodedTile ( int tile, byte buffer, int count ) : int

Usage Example

Example #1
0
        static bool cvt_by_tile(Tiff inImage, Tiff outImage, int width, int height)
        {
            int tile_width = 0;
            int tile_height = 0;

            FieldValue[] result = inImage.GetField(TiffTag.TILEWIDTH);
            if (result != null)
            {
                tile_width = result[0].ToInt();

                result = inImage.GetField(TiffTag.TILELENGTH);
                if (result != null)
                    tile_height = result[0].ToInt();
            }

            if (result == null)
            {
                Tiff.Error(inImage.FileName(), "Source image not tiled");
                return false;
            }

            outImage.SetField(TiffTag.TILEWIDTH, tile_width);
            outImage.SetField(TiffTag.TILELENGTH, tile_height);

            // Allocate tile buffer
            int raster_size = multiply(tile_width, tile_height);
            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}", tile_width, tile_height);
                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[tile_width];

            // Loop over the tiles.
            for (int row = 0; row < height; row += tile_height)
            {
                for (int col = 0; col < width; col += tile_width)
                {
                    // Read the tile into an RGBA array
                    if (!inImage.ReadRGBATile(col, row, raster))
                        return false;

                    // For some reason the ReadRGBATile() function chooses the lower left corner
                    // as the origin. Vertically mirror scanlines.
                    for (int i_row = 0; i_row < tile_height / 2; i_row++)
                    {
                        int topIndex = tile_width * i_row * sizeof(int);
                        int bottomIndex = tile_width * (tile_height - i_row - 1) * sizeof(int);

                        Buffer.BlockCopy(raster, topIndex, wrk_line, 0, tile_width * sizeof(int));
                        Buffer.BlockCopy(raster, bottomIndex, raster, topIndex, tile_width * sizeof(int));
                        Buffer.BlockCopy(wrk_line, 0, raster, bottomIndex, tile_width * sizeof(int));
                    }

                    // Write out the result in a tile.
                    int tile = outImage.ComputeTile(col, row, 0, 0);
                    Buffer.BlockCopy(raster, 0, rasterBytes, 0, rasterByteSize);
                    if (outImage.WriteEncodedTile(tile, rasterBytes, rasterByteSize) == -1)
                        return false;
                }
            }

            return true;
        }
Tiff