⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grfmt_tiff.cpp

📁 OPENCV系列的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            case 1:
                if( photometric == 0 || photometric == 1 && channels == 1 )
                {
                    FillGrayPalette( m_palette, m_bpp, photometric == 0 );
                    result = true;
                    m_iscolor = false;
                }
                break;
            case 4:
            case 8:
                if( (photometric == 0 || photometric == 1 ||
                     photometric == 3 && pal_length == (1 << m_bpp)) &&
                    m_compression != TIFF_HUFFMAN && channels == 1 )
                {
                    if( pal_length < 0 )
                    {
                        FillGrayPalette( m_palette, m_bpp, photometric == 0 );
                        m_iscolor = false;
                    }
                    else
                    {
                        m_iscolor = IsColorPalette( m_palette, m_bpp );
                    }
                    result = true;
                }
                else if( photometric == 2 && pal_length < 0 &&
                         (channels == 3 || channels == 4) &&
                         m_compression == TIFF_UNCOMP )
                {
                    m_bpp = 8*channels;
                    m_iscolor = true;
                    result = true;
                }
                break;
            default:
                BAD_HEADER_ERR();
            }
        }
    }
    catch( int )
    {
    }

    if( !result )
    {
        m_strips = -1;
        m_width = m_height = -1;
        m_strm.Close();
    }

    return result;
}


bool  GrFmtTiffReader::ReadData( uchar* data, int step, int color )
{
    const  int buffer_size = 1 << 12;
    uchar  buffer[buffer_size];
    uchar  gray_palette[256];
    bool   result = false;
    uchar* src = buffer;
    int    src_pitch = (m_width*m_bpp + 7)/8;
    int    y = 0;

    if( m_strips < 0 || !m_strm.IsOpened())
        return false;
    
    if( src_pitch+32 > buffer_size )
        src = new uchar[src_pitch+32];

    if( !color )
        if( m_bpp <= 8 )
        {
            CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );
        }

    try
    {
        for( int s = 0; s < m_strips; s++ )
        {
            int y_limit = m_rows_per_strip;

            y_limit += y;
            if( y_limit > m_height ) y_limit = m_height;

            m_strm.SetPos( m_offsets[s] );

            if( m_compression == TIFF_UNCOMP )
            {
                for( ; y < y_limit; y++, data += step )
                {
                    m_strm.GetBytes( src, src_pitch );
                    if( color )
                        switch( m_bpp )
                        {
                        case 1:
                            FillColorRow1( data, src, m_width, m_palette );
                            break;
                        case 4:
                            FillColorRow4( data, src, m_width, m_palette );
                            break;
                        case 8:
                            FillColorRow8( data, src, m_width, m_palette );
                            break;
                        case 24:
                            CvtRGBToBGR( src, data, m_width );
                            break;
                        case 32:
                            CvtRGBAToBGR( src, data, m_width );
                            break;
                        default:
                            assert(0);
                            goto bad_decoding_end;
                        }
                    else
                        switch( m_bpp )
                        {
                        case 1:
                            FillGrayRow1( data, src, m_width, gray_palette );
                            break;
                        case 4:
                            FillGrayRow4( data, src, m_width, gray_palette );
                            break;
                        case 8:
                            FillGrayRow8( data, src, m_width, gray_palette );
                            break;
                        case 24:
                            CvtRGBToGray( src, data, m_width );
                            break;
                        case 32:
                            CvtRGBAToGray( src, data, m_width );
                            break;
                        default:
                            assert(0);
                            goto bad_decoding_end;
                        }
                }
            }
            else
            {
            }

            result = true;

bad_decoding_end:

            ;
        }
    }
    catch( int )
    {
    }

    if( src != buffer ) delete src; 
    return true;
}


//////////////////////////////////////////////////////////////////////////////////////////

GrFmtTiffWriter::GrFmtTiffWriter()
{
    m_description = fmtDescrTiff;
}


GrFmtTiffWriter::~GrFmtTiffWriter()
{
}


void  GrFmtTiffWriter::WriteTag( TiffTag tag, TiffFieldType fieldType,
                                 int count, int value )
{
    m_strm.PutWord( tag );
    m_strm.PutWord( fieldType );
    m_strm.PutDWord( count );
    m_strm.PutDWord( value );
}


bool  GrFmtTiffWriter::WriteImage( const char* filename,
                                   const uchar* data, int step,
                                   int width, int height, bool isColor )
{
    bool result = false;
    int nch  = isColor ? 3 : 1;
    int fileStep = width*nch;

    assert( data && width > 0 && height > 0 && step >= fileStep);
    
    if( m_strm.Open( filename ) )
    {
        int rowsPerStrip = (1 << 13)/fileStep;

        if( rowsPerStrip < 1 )
            rowsPerStrip = 1;

        if( rowsPerStrip > height )
            rowsPerStrip = height;

        int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip;
        int uncompressedRowSize = rowsPerStrip * fileStep;
        int directoryOffset = 0;

        int* stripOffsets = new int[stripCount];
        short* stripCounts = new short[stripCount];
        uchar* buffer = new uchar[fileStep + 32];
        int  stripOffsetsOffset = 0;
        int  stripCountsOffset = 0; 
        int  bitsPerSample = 8;
        int  y = 0;
        
        uncompressedRowSize;

        m_strm.PutBytes( fmtSignTiffII, 4 );
        m_strm.PutDWord( directoryOffset );

        // write an image data first (the most reasonable way
        // for compressed images)
        for( i = 0; i < stripCount; i++ )
        {
            int limit = y + rowsPerStrip;

            if( limit > height )
                limit = height;
            
            stripOffsets[i] = m_strm.GetPos();

            for( ; y < limit; y++, data += step )
            {
                if( isColor ) CvtRGBToBGR( data, buffer, width );
                m_strm.PutBytes( isColor ? buffer : data, fileStep );
            }

            stripCounts[i] = (short)(m_strm.GetPos() - stripOffsets[i]);
            assert( stripCounts[i] == uncompressedRowSize ||
                    stripCounts[i] < uncompressedRowSize &&
                    i == stripCount - 1);
        }

        if( stripCount > 1 )
        {
            stripOffsetsOffset = m_strm.GetPos();
            for( i = 0; i < stripCount; i++ )
                m_strm.PutDWord( stripOffsets[i] );

            stripCountsOffset = m_strm.GetPos();
            for( i = 0; i < stripCount; i++ )
                m_strm.PutWord( stripCounts[i] );
        }
        else
        {
            stripOffsetsOffset = stripOffsets[0];
            stripCountsOffset = stripCounts[0];
        }

        if( isColor )
        {
            bitsPerSample = m_strm.GetPos();
            m_strm.PutWord(8);
            m_strm.PutWord(8);
            m_strm.PutWord(8);
        }

        directoryOffset = m_strm.GetPos();

        // write header
        m_strm.PutWord( 9 );

        WriteTag( TIFF_TAG_WIDTH, TIFF_TYPE_LONG, 1, width );
        WriteTag( TIFF_TAG_HEIGHT, TIFF_TYPE_LONG, 1, height );
        WriteTag( TIFF_TAG_BITS_PER_SAMPLE,
                  TIFF_TYPE_SHORT, nch, bitsPerSample );
        WriteTag( TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP );
        WriteTag( TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, isColor ? 2 : 1 );

        WriteTag( TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, nch );
        WriteTag( TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip );
        
        WriteTag( TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG,
                  stripCount, stripOffsetsOffset );

        WriteTag( TIFF_TAG_STRIP_COUNTS,
                  stripCount > 1 ? TIFF_TYPE_SHORT : TIFF_TYPE_LONG,
                  stripCount, stripCountsOffset );

        m_strm.PutDWord(0);
        m_strm.Close();

        // write directory offset
        FILE* f = fopen( filename, "r+" );
        buffer[0] = (uchar)directoryOffset;
        buffer[1] = (uchar)(directoryOffset >> 8);
        buffer[2] = (uchar)(directoryOffset >> 16);
        buffer[3] = (uchar)(directoryOffset >> 24);

        fseek( f, 4, SEEK_SET );
        fwrite( buffer, 1, 4, f );
        fclose(f);

        delete  stripOffsets;
        delete  stripCounts;

        result = true;
    }
    return result;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -