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

📄 grfmt_tiff.cpp

📁 这个是基于在CCS开发环境下
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

/****************************************************************************************\
    A part of the file implements TIFF reader on base of libtiff library
    (see otherlibs/_graphics/readme.txt for copyright notice)
\****************************************************************************************/

#include "_highgui.h"
#include "grfmt_tiff.h"

static const char fmtSignTiffII[] = "II\x2a\x00";
static const char fmtSignTiffMM[] = "MM\x00\x2a";

GrFmtTiff::GrFmtTiff()
{
    m_sign_len = 4;
    m_signature = "";
    m_description = "TIFF Files (*.tiff;*.tif)";
}

GrFmtTiff::~GrFmtTiff()
{
}

bool GrFmtTiff::CheckSignature( const char* signature )
{
    return memcmp( signature, fmtSignTiffII, 4 ) == 0 ||
           memcmp( signature, fmtSignTiffMM, 4 ) == 0;
}


GrFmtReader* GrFmtTiff::NewReader( const char* filename )
{
    return new GrFmtTiffReader( filename );
}


GrFmtWriter* GrFmtTiff::NewWriter( const char* filename )
{
    return new GrFmtTiffWriter( filename );
}


#ifdef HAVE_TIFF

#include "tiff.h"
#include "tiffio.h"

static int grfmt_tiff_err_handler_init = 0;

static void GrFmtSilentTIFFErrorHandler( const char*, const char*, va_list ) {}

GrFmtTiffReader::GrFmtTiffReader( const char* filename ) : GrFmtReader( filename )
{
    m_tif = 0;

    if( !grfmt_tiff_err_handler_init )
    {
        grfmt_tiff_err_handler_init = 1;

        TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler );
        TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler );
    }
}


GrFmtTiffReader::~GrFmtTiffReader()
{
}


void  GrFmtTiffReader::Close()
{
    if( m_tif )
    {
        TIFF* tif = (TIFF*)m_tif;
        TIFFClose( tif );
        m_tif = 0;
    }
}


bool  GrFmtTiffReader::CheckFormat( const char* signature )
{
    return memcmp( signature, fmtSignTiffII, 4 ) == 0 ||
           memcmp( signature, fmtSignTiffMM, 4 ) == 0;
}


bool  GrFmtTiffReader::ReadHeader()
{
    char errmsg[1024];
    bool result = false;

    Close();
    TIFF* tif = TIFFOpen( m_filename, "r" );

    if( tif )
    {
        int width = 0, height = 0, photometric = 0, compression = 0;
        m_tif = tif;

        if( TIFFRGBAImageOK( tif, errmsg ) &&
            TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &width ) &&
            TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &height ) &&
            TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ) && 
            (!TIFFGetField( tif, TIFFTAG_COMPRESSION, &compression ) ||
            (compression != COMPRESSION_LZW &&
             compression != COMPRESSION_OJPEG)))
        {
            m_width = width;
            m_height = height;
            m_iscolor = photometric > 1;
            
            result = true;
        }
    }

    if( !result )
        Close();

    return result;
}


bool  GrFmtTiffReader::ReadData( uchar* data, int step, int color )
{
    bool result = false;
    uchar* buffer = 0;

    color = color > 0 || (color < 0 && m_iscolor);

    if( m_tif && m_width && m_height )
    {
        TIFF* tif = (TIFF*)m_tif;
        int tile_width0 = m_width, tile_height0 = 0;
        int x, y, i;
        int is_tiled = TIFFIsTiled(tif);
        
        if( !is_tiled &&
            TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 ) ||
            is_tiled &&
            TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) &&
            TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 ))
        {
            if( tile_width0 <= 0 )
                tile_width0 = m_width;

            if( tile_height0 <= 0 )
                tile_height0 = m_height;
            
            buffer = new uchar[tile_height0*tile_width0*4];

            for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 )
            {
                int tile_height = tile_height0;

                if( y + tile_height > m_height )
                    tile_height = m_height - y;

                for( x = 0; x < m_width; x += tile_width0 )
                {
                    int tile_width = tile_width0, ok;

                    if( x + tile_width > m_width )
                        tile_width = m_width - x;

                    if( !is_tiled )
                        ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
                    else
                        ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );

                    if( !ok )
                        goto exit_func;

                    for( i = 0; i < tile_height; i++ )
                        if( color )
                            icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0,
                                          data + x*3 + step*(tile_height - i - 1), 0,
                                          cvSize(tile_width,1), 2 );
                        else
                            icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0,
                                           data + x + step*(tile_height - i - 1), 0,
                                           cvSize(tile_width,1), 2 );
                }
            }

            result = true;
        }
    }

exit_func:

    Close();
    delete[] buffer;

    return result;
}

#else

static const int  tiffMask[] = { 0xff, 0xff, 0xffffffff, 0xffff, 0xffffffff };

/************************ TIFF reader *****************************/

GrFmtTiffReader::GrFmtTiffReader( const char* filename ) : GrFmtReader( filename )
{
    m_offsets = 0;
    m_maxoffsets = 0;
    m_strips = -1;
    m_max_pal_length = 0;
    m_temp_palette = 0;
}


GrFmtTiffReader::~GrFmtTiffReader()
{
    Close();

    delete[] m_offsets;
    delete[] m_temp_palette;
}

void  GrFmtTiffReader::Close()
{
    m_strm.Close();
}


bool  GrFmtTiffReader::CheckFormat( const char* signature )
{
    return memcmp( signature, fmtSignTiffII, 4 ) == 0 ||
           memcmp( signature, fmtSignTiffMM, 4 ) == 0;
}


int   GrFmtTiffReader::GetWordEx()
{
    int val = m_strm.GetWord();
    if( m_byteorder == TIFF_ORDER_MM )
        val = ((val)>>8)|(((val)&0xff)<<8);
    return val;
}


int   GrFmtTiffReader::GetDWordEx()
{
    int val = m_strm.GetDWord();
    if( m_byteorder == TIFF_ORDER_MM )
        val = BSWAP( val );
    return val;
}


int  GrFmtTiffReader::ReadTable( int offset, int count,
                                 TiffFieldType fieldType,
                                 int*& array, int& arraysize )
{
    int i;
    
    if( count < 0 )
        return RBS_BAD_HEADER;
    
    if( fieldType != TIFF_TYPE_SHORT &&
        fieldType != TIFF_TYPE_LONG &&
        fieldType != TIFF_TYPE_BYTE )
        return RBS_BAD_HEADER;

    if( count > arraysize )
    {
        delete[] array;
        arraysize = arraysize*3/2;
        if( arraysize < count )
            arraysize = count;
        array = new int[arraysize];
    }

    if( count > 1 )
    {
        int pos = m_strm.GetPos();
        m_strm.SetPos( offset );

        if( fieldType == TIFF_TYPE_LONG )
        {
            if( m_byteorder == TIFF_ORDER_MM )
                for( i = 0; i < count; i++ )
                    array[i] = ((RMByteStream&)m_strm).GetDWord();
            else
                for( i = 0; i < count; i++ )
                    array[i] = ((RLByteStream&)m_strm).GetDWord();
        }
        else if( fieldType == TIFF_TYPE_SHORT )
        {
            if( m_byteorder == TIFF_ORDER_MM )
                for( i = 0; i < count; i++ )
                    array[i] = ((RMByteStream&)m_strm).GetWord();
            else
                for( i = 0; i < count; i++ )
                    array[i] = ((RLByteStream&)m_strm).GetWord();
        }
        else // fieldType == TIFF_TYPE_BYTE
            for( i = 0; i < count; i++ )
                array[i] = m_strm.GetByte();

        m_strm.SetPos(pos);
    }
    else
    {
        assert( (offset & ~tiffMask[fieldType]) == 0 );
        array[0] = offset;
    }

    return 0;
}


bool  GrFmtTiffReader::ReadHeader()
{
    bool result = false;
    int  photometric = -1;
    int  channels = 1;
    int  pal_length = -1;

    const int MAX_CHANNELS = 4;
    int  bpp_arr[MAX_CHANNELS];

    assert( strlen(m_filename) != 0 );
    if( !m_strm.Open( m_filename )) return false;

    m_width = -1;
    m_height = -1;
    m_strips = -1;
    m_bpp = 1;
    m_compression = TIFF_UNCOMP;
    m_rows_per_strip = -1;
    m_iscolor = false;

    if( setjmp( m_strm.JmpBuf()) == 0 )
    {
        m_byteorder = (TiffByteOrder)m_strm.GetWord();
        m_strm.Skip( 2 );
        int header_offset = GetDWordEx();

        m_strm.SetPos( header_offset );

        // read the first tag directory
        int i, j, count = GetWordEx();

        for( i = 0; i < count; i++ )
        {
            // read tag
            TiffTag tag = (TiffTag)GetWordEx();
            TiffFieldType fieldType = (TiffFieldType)GetWordEx();
            int count = GetDWordEx();
            int value = GetDWordEx();
            if( count == 1 )
            {
                if( m_byteorder == TIFF_ORDER_MM )
                {
                    if( fieldType == TIFF_TYPE_SHORT )
                        value = (unsigned)value >> 16;
                    else if( fieldType == TIFF_TYPE_BYTE )
                        value = (unsigned)value >> 24;
                }

                value &= tiffMask[fieldType];
            }

            switch( tag )
            {
            case  TIFF_TAG_WIDTH:
                m_width = value;
                break;

            case  TIFF_TAG_HEIGHT:

⌨️ 快捷键说明

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