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

📄 grfmt_tiff.cpp

📁 OPENCV系列的
💻 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*/

#include "stdwin.h"

#include "grfmt_tiff.h"
#include <assert.h>
#include <string.h>

static const char fmtDescrTiff[] = "TIFF (*.tiff;*.tif)";
static const char fmtSignTiffII[] = "II\x2a\x00";
static const char fmtSignTiffMM[] = "MM\x00\x2a";
static const int  tiffMask[] = { 0xff, 0xff, 0xffffffff, 0xffff, 0xffffffff };

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

GrFmtTiffReader::GrFmtTiffReader()
{
    m_sign_len = 4;
    m_signature = fmtSignTiffII;
    m_description = fmtDescrTiff;
    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;
}


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

    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;
    }
}


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;

    try
    {
        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:
                m_height = value;
                break;

            case  TIFF_TAG_BITS_PER_SAMPLE:
                {
                    int* bpp_arr_ref = bpp_arr;

                    if( count > MAX_CHANNELS )
                        BAD_HEADER_ERR();

                    ReadTable( value, count, fieldType, bpp_arr_ref, count );
                
                    for( j = 1; j < count; j++ )
                    {
                        if( bpp_arr[j] != bpp_arr[0] )
                        {
                            BAD_HEADER_ERR();
                        }
                    }

                    m_bpp = bpp_arr[0];
                }

                break;

            case  TIFF_TAG_COMPRESSION:
                m_compression = (TiffCompression)value;
                if( m_compression != TIFF_UNCOMP &&
                    m_compression != TIFF_HUFFMAN &&
                    m_compression != TIFF_PACKBITS )
                    BAD_HEADER_ERR();
                break;

            case  TIFF_TAG_PHOTOMETRIC:
                photometric = value;
                if( (unsigned)photometric > 3 )
                    BAD_HEADER_ERR();
                break;

            case  TIFF_TAG_STRIP_OFFSETS:
                m_strips = count;
                ReadTable( value, count, fieldType, m_offsets, m_maxoffsets );
                break;

            case  TIFF_TAG_SAMPLES_PER_PIXEL:
                channels = value;
                if( channels != 1 && channels != 3 && channels != 4 )
                    BAD_HEADER_ERR();
                break;

            case  TIFF_TAG_ROWS_PER_STRIP:
                m_rows_per_strip = value;
                break;

            case  TIFF_TAG_PLANAR_CONFIG:
                {
                int planar_config = value;
                if( planar_config != 1 )
                    BAD_HEADER_ERR();
                }
                break;

            case  TIFF_TAG_COLOR_MAP:
                if( fieldType != TIFF_TYPE_SHORT || count < 2 )
                    BAD_HEADER_ERR();
                ReadTable( value, count, fieldType,
                           m_temp_palette, m_max_pal_length );
                pal_length = count / 3;
                if( pal_length > 256 )
                    BAD_HEADER_ERR();
                for( i = 0; i < pal_length; i++ )
                {
                    m_palette[i].r = (uchar)(m_temp_palette[i*3] >> 3);
                    m_palette[i].g = (uchar)(m_temp_palette[i*3 + 1] >> 3);
                    m_palette[i].b = (uchar)(m_temp_palette[i*3 + 2] >> 3);
                }
                break;
            }
        }

        if( m_strips == 1 && m_rows_per_strip == -1 )
            m_rows_per_strip = m_height;

        if( m_width > 0 && m_height > 0 && m_strips > 0 &&
            (m_height + m_rows_per_strip - 1)/m_rows_per_strip == m_strips )
        {
            switch( m_bpp )
            {

⌨️ 快捷键说明

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