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

ReadEncodedTile() public method

Reads a tile of data from an open TIFF file/stream, decompresses it and places specified amount of decompressed bytes into the user supplied buffer.

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.

To read a full tile of data the data buffer should typically be at least as large as the number returned by TileSize. If the -1 passed in count parameter, the whole tile will be read. You should be sure you have enough space allocated for the buffer.

The library attempts to hide bit- and byte-ordering differences between the image and the native machine by converting data to the native machine order. Bit reversal is done if the TiffTag.FILLORDER tag is opposite to the native machine bit order. 16- and 32-bit samples are automatically byte-swapped if the file was written with a byte order opposite to the native machine byte order.

public ReadEncodedTile ( int tile, byte buffer, int offset, int count ) : int
tile int The zero-based index of the tile to read.
buffer byte The buffer to place decompressed tile bytes to.
offset int The zero-based byte offset in buffer at which to begin storing /// decompressed tile bytes.
count int The maximum number of decompressed tile bytes to be stored /// to buffer.
return int
        public int ReadEncodedTile(int tile, byte[] buffer, int offset, int count)
        {
            if (!checkRead(true))
                return -1;

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

            if (count == -1)
                count = m_tilesize;
            else if (count > m_tilesize)
                count = m_tilesize;

            if (fillTile(tile) && m_currentCodec.DecodeTile(buffer, offset, count, (short)(tile / m_dir.td_stripsperimage)))
            {
                postDecode(buffer, offset, count);
                return count;
            }

            return -1;
        }

Usage Example

Example #1
0
        /*
        * This function reads the raster image data from the input TIFF for an image
        * tile and writes the data to the output PDF XObject image dictionary stream
        * for the tile.  It returns the amount written or zero on error.
        */
        private int readwrite_pdf_image_tile(Tiff input, int tile)
        {
            bool edge = false;
            edge |= tile_is_right_edge(m_tiff_pages[m_pdf_page], tile);
            edge |= tile_is_bottom_edge(m_tiff_pages[m_pdf_page], tile);

            byte[] buffer = null;
            int bufferoffset = 0;
            FieldValue[] result = null;

            if ((m_pdf_transcode == t2p_transcode_t.T2P_TRANSCODE_RAW) && (!edge || (m_pdf_compression == t2p_compress_t.T2P_COMPRESS_JPEG)))
            {
                if (m_pdf_compression == t2p_compress_t.T2P_COMPRESS_G4)
                {
                    buffer = new byte [m_tiff_datasize];
                    input.ReadRawTile(tile, buffer, 0, m_tiff_datasize);
                    if (m_tiff_fillorder == FillOrder.LSB2MSB)
                        Tiff.ReverseBits(buffer, m_tiff_datasize);

                    writeToFile(buffer, m_tiff_datasize);
                    return m_tiff_datasize;
                }
                
                if (m_pdf_compression == t2p_compress_t.T2P_COMPRESS_ZIP)
                {
                    buffer = new byte [m_tiff_datasize];
                    input.ReadRawTile(tile, buffer, 0, m_tiff_datasize);
                    if (m_tiff_fillorder == FillOrder.LSB2MSB)
                        Tiff.ReverseBits(buffer, m_tiff_datasize);

                    writeToFile(buffer, m_tiff_datasize);
                    return m_tiff_datasize;
                }
                
                if (m_tiff_compression == Compression.JPEG)
                {
                    byte[] table_end = new byte[2];
                    buffer = new byte [m_tiff_datasize];
                    result = input.GetField(TiffTag.JPEGTABLES);
                    if (result != null)
                    {
                        int count = result[0].ToInt();
                        byte[] jpt = result[1].ToByteArray();
                        if (count > 0)
                        {
                            Buffer.BlockCopy(jpt, 0, buffer, 0, count);
                            bufferoffset += count - 2;
                            table_end[0] = buffer[bufferoffset - 2];
                            table_end[1] = buffer[bufferoffset - 1];
                        }

                        if (count > 0)
                        {
                            int xuint32 = bufferoffset;
                            bufferoffset += input.ReadRawTile(tile, buffer, bufferoffset - 2, -1);
                            buffer[xuint32 - 2] = table_end[0];
                            buffer[xuint32 - 1] = table_end[1];
                        }
                        else
                        {
                            bufferoffset += input.ReadRawTile(tile, buffer, bufferoffset, -1);
                        }
                    }

                    writeToFile(buffer, bufferoffset);
                    return bufferoffset;
                }
            }

            if (m_pdf_sample == t2p_sample_t.T2P_SAMPLE_NOTHING)
            {
                buffer = new byte [m_tiff_datasize];
                int read = input.ReadEncodedTile(tile, buffer, bufferoffset, m_tiff_datasize);
                if (read == -1)
                {
                    Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                        "Error on decoding tile {0} of {1}", tile, input.FileName());
                    m_error = true;
                    return 0;
                }
            }
            else
            {
                if (m_pdf_sample == t2p_sample_t.T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG)
                {
                    int septilesize = input.TileSize();
                    int septilecount = input.NumberOfTiles();
                    int tilecount = septilecount / m_tiff_samplesperpixel;
                    buffer = new byte [m_tiff_datasize];
                    byte[] samplebuffer = new byte [m_tiff_datasize];
                    int samplebufferoffset = 0;
                    for (short i = 0; i < m_tiff_samplesperpixel; i++)
                    {
                        int read = input.ReadEncodedTile(tile + i * tilecount, samplebuffer, samplebufferoffset, septilesize);
                        if (read == -1)
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                "Error on decoding tile {0} of {1}", 
                                tile + i * tilecount, input.FileName());
                            m_error = true;
                            return 0;
                        }

                        samplebufferoffset += read;
                    }

                    sample_planar_separate_to_contig(buffer, bufferoffset, samplebuffer, samplebufferoffset);
                    bufferoffset += samplebufferoffset;
                }

                if (buffer == null)
                {
                    buffer = new byte [m_tiff_datasize];
                    int read = input.ReadEncodedTile(tile, buffer, bufferoffset, m_tiff_datasize);
                    if (read == -1)
                    {
                        Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                            "Error on decoding tile {0} of {1}",
                            tile, input.FileName());
                        m_error = true;
                        return 0;
                    }
                }

                if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_RGBA_TO_RGB) != 0)
                    m_tiff_datasize = sample_rgba_to_rgb(buffer, m_tiff_pages[m_pdf_page].tiles_tilewidth * m_tiff_pages[m_pdf_page].tiles_tilelength);

                if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_RGBAA_TO_RGB) != 0)
                    m_tiff_datasize = sample_rgbaa_to_rgb(buffer, m_tiff_pages[m_pdf_page].tiles_tilewidth * m_tiff_pages[m_pdf_page].tiles_tilelength);

                if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_YCBCR_TO_RGB) != 0)
                {
                    Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                        "No support for YCbCr to RGB in tile for {0}", input.FileName());
                    m_error = true;
                    return 0;
                }

                if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED) != 0)
                    m_tiff_datasize = sample_lab_signed_to_unsigned(buffer, m_tiff_pages[m_pdf_page].tiles_tilewidth * m_tiff_pages[m_pdf_page].tiles_tilelength);
            }

            if (tile_is_right_edge(m_tiff_pages[m_pdf_page], tile))
                tile_collapse_left(buffer, input.TileRowSize(), m_tiff_pages[m_pdf_page].tiles_tilewidth, m_tiff_pages[m_pdf_page].tiles_edgetilewidth, m_tiff_pages[m_pdf_page].tiles_tilelength);

            disable(m_output);
            m_output.SetField(TiffTag.PHOTOMETRIC, m_tiff_photometric);
            m_output.SetField(TiffTag.BITSPERSAMPLE, m_tiff_bitspersample);
            m_output.SetField(TiffTag.SAMPLESPERPIXEL, m_tiff_samplesperpixel);

            if (!tile_is_right_edge(m_tiff_pages[m_pdf_page], tile))
                m_output.SetField(TiffTag.IMAGEWIDTH, m_tiff_pages[m_pdf_page].tiles_tilewidth);
            else
                m_output.SetField(TiffTag.IMAGEWIDTH, m_tiff_pages[m_pdf_page].tiles_edgetilewidth);

            if (!tile_is_bottom_edge(m_tiff_pages[m_pdf_page], tile))
            {
                m_output.SetField(TiffTag.IMAGELENGTH, m_tiff_pages[m_pdf_page].tiles_tilelength);
                m_output.SetField(TiffTag.ROWSPERSTRIP, m_tiff_pages[m_pdf_page].tiles_tilelength);
            }
            else
            {
                m_output.SetField(TiffTag.IMAGELENGTH, m_tiff_pages[m_pdf_page].tiles_edgetilelength);
                m_output.SetField(TiffTag.ROWSPERSTRIP, m_tiff_pages[m_pdf_page].tiles_edgetilelength);
            }

            m_output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
            m_output.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);

            switch (m_pdf_compression)
            {
                case t2p_compress_t.T2P_COMPRESS_NONE:
                    m_output.SetField(TiffTag.COMPRESSION, Compression.NONE);
                    break;

                case t2p_compress_t.T2P_COMPRESS_G4:
                    m_output.SetField(TiffTag.COMPRESSION, Compression.CCITTFAX4);
                    break;
                
                case t2p_compress_t.T2P_COMPRESS_JPEG:
                    if (m_tiff_photometric == Photometric.YCBCR)
                    {
                        result = input.GetField(TiffTag.YCBCRSUBSAMPLING);
                        if (result != null)
                        {
                            short hor = result[0].ToShort();
                            short ver = result[1].ToShort();
                            if (hor != 0 && ver != 0)
                                m_output.SetField(TiffTag.YCBCRSUBSAMPLING, hor, ver);
                        }

                        result = input.GetField(TiffTag.REFERENCEBLACKWHITE);
                        if (result != null)
                        {
                            float[] xfloatp = result[0].ToFloatArray();
                            m_output.SetField(TiffTag.REFERENCEBLACKWHITE, xfloatp);
                        }
                    }
                    
                    m_output.SetField(TiffTag.COMPRESSION, Compression.JPEG);
                    m_output.SetField(TiffTag.JPEGTABLESMODE, 0); /* JpegTablesMode.NONE */

                    if ((m_pdf_colorspace & (t2p_cs_t.T2P_CS_RGB | t2p_cs_t.T2P_CS_LAB)) != 0)
                    {
                        m_output.SetField(TiffTag.PHOTOMETRIC, Photometric.YCBCR);
                        if (m_tiff_photometric != Photometric.YCBCR)
                            m_output.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RGB);
                        else
                            m_output.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RAW);
                    }

                    if (m_pdf_defaultcompressionquality != 0)
                        m_output.SetField(TiffTag.JPEGQUALITY, m_pdf_defaultcompressionquality);

                    break;

                case t2p_compress_t.T2P_COMPRESS_ZIP:
                    m_output.SetField(TiffTag.COMPRESSION, Compression.DEFLATE);
                    if (m_pdf_defaultcompressionquality % 100 != 0)
                        m_output.SetField(TiffTag.PREDICTOR, m_pdf_defaultcompressionquality % 100);

                    if (m_pdf_defaultcompressionquality / 100 != 0)
                        m_output.SetField(TiffTag.ZIPQUALITY, (m_pdf_defaultcompressionquality / 100));

                    break;

                default:
                    break;
            }

            enable(m_output);
            m_outputwritten = 0;
            bufferoffset = m_output.WriteEncodedStrip(0, buffer, m_output.StripSize());
            buffer = null;

            if (bufferoffset == -1)
            {
                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                    "Error writing encoded tile to output PDF {0}", m_output.FileName());
                m_error = true;
                return 0;
            }

            return m_outputwritten;
        }
Tiff