TIFF添加坐标信息

来源:互联网 发布:中国 歼31 沙特 知乎 编辑:程序博客网 时间:2024/06/05 15:40

  处理tiff图片过程中,需要给TIFF图片加上相应的坐标信息,来表示当前图片的坐标范围。下面就给出如何在一张空白的TIFF图片中添加坐标信息。
1.头文件

#pragma once#include"tiflib.h"#include<string>#include <vector>#include <algorithm>  using namespace std;#define TIFF_HEADER_SIZE 8    //文件头字节数#define DE_START 10           //tiff TAG开始的位置#define ONE_DE_SIZE 12        //每个TAG的大小#define IDF_END_FLAG_SIZE 4   //IFD最后结尾的4个空字节typedef struct{    int i_tag;    const char* text;}TagText;typedef struct{    TIFF_UINT16_T type;    char* type_name;    TIFF_UINT16_T type_size;}DataType;typedef struct{    TIFF_UINT16_T tag;    TIFF_UINT16_T type;    TIFF_UINT32_T count;    TIFF_UINT32_T offset;}DirectoryEntry;typedef struct{    DirectoryEntry de;    int data_source; //0 - offset本身值 1 - offset对应的源文件偏移量 2 - 来自内存    TIFF_UINT8_T* mem_data; //当 data_soure = 2 时 ,指向内存}deInfo;class tiffTrans{public:    tiffTrans();    tiffTrans( const char* tiff_path );    ~tiffTrans();public:    int open( const char* tiff_path );    void coord_box( geoRECT geo_rect );    int save_to_trans( const char* new_path = NULL );protected:    int arrangement();//0 - tile  1 - line    bool analysis( char* ret_error );  //分析tiff是否可以进行转换 true - 可以 false - 不可以  private:    string new_tiff_name();    void write_file_header();    TIFF_UINT64_T double_to_long( double d_ );    void cs_pixel_scale( double cx , double cy );    void cs_tie_point( double x , double y );    void cs_coord( deInfo* coord_list );    int get_src_tag_list();    const char* tag_text( int i_tag );    deInfo* cts_strip_offsets();      deInfo* cts_rows_per_strip();    deInfo* cts_strip_byte_counts();    deInfo* cts_line_tag();    deInfo* delete_coord_tag();    int cts_new_tag_list();    void print_tag_info_list();    void write_tag_list();    void modify_strip_offset();    void modify_line_strip();    void modify_tile_strip();    void sort_byte_order( TIFF_UINT8_T* buf , TIFF_UINT16_T data_type , TIFF_UINT16_T data_count );    TIFF_UINT64_T file_disk_data( DirectoryEntry de , TIFF_UINT64_T buffer_size );    void write_img_data();    void write_img_data2();    void write_line_img();    void write_tile_img();    void write_data( TIFF_UINT32_T data_start , TIFF_UINT32_T data_size );private:    FILE* _tile_tiff;    FILE* _line_tiff;    TiffFile* _tiff_src;    string _src_name;    TIFF_UINT64_T _current_file_point; //写入当前文件操作的指针    deInfo* de_list;    TIFF_UINT16_T _de_num;             //标签的数量    int _coord_tag_num; //包含坐标信息的TAG的数量    TIFF_UINT32_T _strip_offset_pos;   //TAG StripOffset or TileOffset 的文件偏移位置    TIFF_UINT32_T _count_one_offset_pos;    TIFF_UINT64_T pixel_scale[3];//像元比例    TIFF_UINT64_T tie_point[6];//控制点坐标对    geoRECT _geo_rect;};

2.cpp文件

#include "tifftrans.h"TagText tag_text_list[] ={    { 254 , "NewSubfileType" },    { 256 , "ImageWidth" },    { 257 , "ImageLength" },    { 258 , "BitsPerSample" },    { 259 , "Compression" },    { 262 , "PhotometricInterpretation" },    { 273 , "StripOffsets" },    { 274 , "相对于图像的行和列的方向" },    { 277 , "SamplesPerPixel" },    { 278 , "RowsPerStrip" },    { 279 , "StripByteCounts" },    { 282 , "XResolution" },    { 283 , "YResolution" },    { 284 , "PlanarConfiguration" },    { 296 , "ResolutionUnit" },    { 305 , "Software" },    { 306 , "DateTime" },    { 322 , "TileWidth" },    { 323 , "TileLength" },    { 324 , "TileOffsets" },    { 325 , "TileByteCounts" },    { 339 , "SampleFormat" },    { 33550 , "ModelPixelScaleTag" },    { 33922 , "ModelTiepointTag" },    { 34264 , "ModelTransformationTag" },    { 34735 , "GeoKeyDirectoryTag" },    { 34736 , "GeoDoubleParamsTag" },    { 34737 , "GeoAsciiParamsTag" },    { -1 , "" }};DataType data_type_list[] ={    { 0  , "NULL"     , 0 },//NULL    { 1  , "BYTE"     , 1 },//BYTE 8-bit unsigned integer    { 2  , "ASCII"    , 1 },//ASCII 8-bit byte that contains a 7-bit ASCII code; the last byte must be NUL (binary zero)    { 3  , "SHORT"    , 2 },//SHORT 16-bit (2-byte) unsigned integer    { 4  , "LONG"     , 4 },//LONG 32-bit (4-byte) unsigned integer    { 5  , "RATIONAL" , 8 },//RATIONAL Two LONGs: the first represents the numerator    { 6  , "SBYTE"    , 1 },//SBYTE An 8-bit signed (twos-complement) integer.    { 7  , "UNDEFINED", 1 },//UNDEFINED An 8-bit byte that may contain anything, depending on the definition of the field.    { 8  , "SSHORT"   , 2 },//SSHORT A 16-bit (2-byte) signed (twos-complement) integer    { 9  , "SLONG"    , 4 },//SLONG A 32-bit (4-byte) signed (twos-complement) integer    { 10 , "SRATIONAL", 8 },//SRATIONAL Two SLONG’s: the first represents the numerator of afraction, the second the denominator    { 11 , "FLOAT"    , 4 },//FLOAT Single precision (4-byte) IEEE format    { 12 , "DOUBLE"   , 8 } //DOUBLE Double precision (8-byte) IEEE format.};tiffTrans::tiffTrans(){    _tiff_src = new TiffFile;    memset( _tiff_src , 0 , sizeof(TiffFile) );    _coord_tag_num = 0 ;}tiffTrans::tiffTrans( const char* tiff_path ){    _src_name = tiff_path;    _tiff_src = new TiffFile;    memset( _tiff_src , 0 , sizeof(TiffFile) );    _coord_tag_num = 0 ;}tiffTrans::~tiffTrans(){    if ( _tiff_src != NULL )    {        delete _tiff_src;        _tiff_src = NULL;    }}int tiffTrans::open( const char* tiff_path ){    _src_name = tiff_path;    int ret = tif_open( tiff_path , _tiff_src );    _tile_tiff = _tiff_src->pfile;    return  ret;}void tiffTrans::coord_box( geoRECT geo_rect ){    _geo_rect = geo_rect;    double scaleX = ( _geo_rect.right - _geo_rect.left ) / _tiff_src->tif_width;    double scaleY = ( _geo_rect.top - _geo_rect.botton  ) / _tiff_src->tif_height;    cs_pixel_scale( scaleX , scaleY );    cs_tie_point( _geo_rect.left , _geo_rect.top );}int tiffTrans::arrangement(){    if( _tiff_src->tile.is_tile == true )    {        return 0;    }    else    {        return 1;    }}const char* tiffTrans::tag_text( int i_tag ){    int i = 0 ;    while ( tag_text_list[i].i_tag != -1 )    {        if ( tag_text_list[i].i_tag == i_tag )        {            return tag_text_list[i].text;        }        i++;    }    return "";}void tiffTrans::write_file_header( ){    //字节序       fwrite( "II" , 2 , 1 , _line_tiff );    //版本号    TIFF_UINT16_T ver = 0x002a;    fwrite( &ver , 2 , 1 , _line_tiff );    //Tag偏移量    TIFF_UINT32_T offset = 0x00000008;    fwrite( &offset , 4 , 1 , _line_tiff );}bool tiffTrans::analysis( char* ret_error ){    bool b = true;    if ( _tiff_src->bit_per_samples == 1 )    {        strcpy( ret_error , "错误:这是一张1位图片" );        b = false;    }    else if ( _tiff_src->bit_per_samples == 4 )    {        strcpy( ret_error , "错误:这是一张4位图片" );        b = false;    }    else if ( _tiff_src->bit_per_samples == 8 )    {        strcpy( ret_error , "错误:这是一张8位图片" );        b = false;    }    if ( _tiff_src->compression != 1 )    {        strcpy( ret_error , "错误:这是一张经过压缩的图片" );        b = false;    }    if( _tiff_src->planar_config != 1 )    {        strcpy( ret_error , "错误:Planar Config 为 Sperate ,暂时无法处理" );        b = false;    }    if ( _tiff_src->tile.is_tile == false )    {        strcpy( ret_error , "错误:TIFF按线性方式排列数据" );        b = false;    }    return b;}string tiffTrans::new_tiff_name(){    int pos = _src_name.rfind( '\\' );    string tiff_name = _src_name.substr( pos + 1 );    string dir = _src_name.substr( 0 , pos + 1 );    string temp_name = "line_";    temp_name += tiff_name ;    return ( dir + temp_name ) ;}int tiffTrans::get_src_tag_list(){    TIFF_UINT32_T ifd_offset;      //第一个IFD的偏移量    fseek( _tile_tiff , 0 , SEEK_SET );    fseek( _tile_tiff ,4 ,SEEK_SET );    ifd_offset = get4( _tile_tiff , _tiff_src->tiff_byte_order ) ;    //定位到IFD的位置    fseek( _tile_tiff , ifd_offset , SEEK_SET );    //得到IFD的数量    _de_num = get2( _tile_tiff , _tiff_src->tiff_byte_order );    de_list = new deInfo[ _de_num ];    memset( de_list , 0 , _de_num * sizeof( deInfo ) );    //循环得到DE    for ( TIFF_UINT16_T i = 0x0000 ; i < _de_num ; i++ )    {        fseek( _tile_tiff , ifd_offset + ONE_DE_SIZE * i + 2 , SEEK_SET );//文件指针复原指向        de_list[i].de.tag = get2( _tile_tiff , _tiff_src->tiff_byte_order );        de_list[i].de.type = get2( _tile_tiff , _tiff_src->tiff_byte_order );        de_list[i].de.count = get4( _tile_tiff , _tiff_src->tiff_byte_order );        //如果是大端字节序并且是short类型,则只会读取四个字节中的前两个字节        if ( de_list[i].de.type == 3 && _tiff_src->tiff_byte_order == 0x4d4d/*Motor*/ && de_list[i].de.count == 1 )        {            de_list[i].de.offset = (TIFF_UINT32_T)get2( _tile_tiff , _tiff_src->tiff_byte_order );        }        else        {            de_list[i].de.offset = get4( _tile_tiff , _tiff_src->tiff_byte_order );        }        //如果是 SHORT 或者 LONG 并且数量为1,则直接存储在Offset中,并不存储地址        if( ( de_list[i].de.type == 3 || de_list[i].de.type == 4 ) && de_list[i].de.count == 1 )        {            de_list[i].data_source = 0 ;        }        else        {            de_list[i].data_source = 1 ;        }        if ( de_list[i].de.tag == 33550             || de_list[i].de.tag == 33922            || de_list[i].de.tag == 34735            || de_list[i].de.tag == 34736            || de_list[i].de.tag == 34737)//关于坐标的TAG        {            _coord_tag_num ++ ;        }    }    print_tag_info_list();    return _de_num ;}deInfo* tiffTrans::cts_strip_offsets(){    deInfo* temp_de = new deInfo;    temp_de->de.tag = 273;    temp_de->de.type = 4;//long    temp_de->de.count = _tiff_src->tif_height;    temp_de->de.offset = 0;    temp_de->data_source = 2;    TIFF_UINT32_T* mem = new TIFF_UINT32_T[_tiff_src->tif_height];    memset( mem , 0 , sizeof(TIFF_UINT32_T)*_tiff_src->tif_height );    temp_de->mem_data = (TIFF_UINT8_T*)mem;    return temp_de;}deInfo* tiffTrans::cts_rows_per_strip(){    deInfo* temp_de = new deInfo;    temp_de->de.tag = 278;    temp_de->de.type = 3;//short    temp_de->de.count = 1;    temp_de->de.offset = 1;    temp_de->data_source = 0;    temp_de->mem_data = NULL;    return temp_de;}deInfo* tiffTrans::cts_strip_byte_counts(){    deInfo* temp_de = new deInfo;    temp_de->de.tag = 279;    temp_de->de.type = 4;//short    temp_de->de.count = _tiff_src->tif_height;    temp_de->de.offset = 0;    temp_de->data_source = 2;    TIFF_UINT32_T* mem = new TIFF_UINT32_T[_tiff_src->tif_height];    memset( mem , 0 , sizeof(TIFF_UINT32_T)*_tiff_src->tif_height );    for ( int i = 0 ; i < _tiff_src->tif_height ; i++ )    {        mem[i] = _tiff_src->tif_width * _tiff_src->samples_per_pixel;    }    temp_de->mem_data = (TIFF_UINT8_T*)mem;    return temp_de;}deInfo* tiffTrans::cts_line_tag(){    deInfo* temp_line_tag_list = new deInfo[3];    memset( temp_line_tag_list , 0 , sizeof(deInfo) * 3 );    deInfo* temp = cts_strip_offsets();    memcpy( temp_line_tag_list , temp , sizeof(deInfo) ) ;    delete temp;    temp = cts_rows_per_strip();    memcpy( temp_line_tag_list + 1 , temp , sizeof(deInfo));    delete temp;    temp = cts_strip_byte_counts();    memcpy( temp_line_tag_list + 2 , temp , sizeof(deInfo));    delete temp;    temp = NULL;    return temp_line_tag_list;}deInfo* tiffTrans::delete_coord_tag(){    deInfo* temp_de_list = new deInfo[ _de_num - _coord_tag_num ];//删除坐标TAG    memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num - _coord_tag_num ) );    int j = 0;    for ( int i = 0 ; i < _de_num ; i ++ )    {        if ( ( de_list[i].de.tag != 33550 )&&             ( de_list[i].de.tag != 33922 )&&             ( de_list[i].de.tag != 34735 )&&             ( de_list[i].de.tag != 34736 )&&            ( de_list[i].de.tag != 34737 )            )        {            memcpy ( temp_de_list + j , de_list + i , sizeof(deInfo) );            j++;        }    }    delete[] de_list;    de_list = NULL;    de_list = temp_de_list;    _de_num -= _coord_tag_num ;    return de_list;}int tiffTrans::cts_new_tag_list( ){    delete_coord_tag( );//删除所有的关于坐标的TAG    deInfo* temp_line = new deInfo[2];    memset( temp_line , 0 ,  2 * sizeof( deInfo ) );    cs_coord( temp_line );    deInfo* temp_de_list = new deInfo[ _de_num + 2 ];//tile 4个标签 line 只需要3个标签    memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num + 2 ) );    int j = 0 , k = 0 ;    for ( int i = 0 ; i < _de_num ; i++ )    {        if ( k < 2 )//只有二个标签        {            if ( de_list[i].de.tag < temp_line[k].de.tag )            {                memcpy( temp_de_list + j , de_list + i , sizeof( deInfo ) );                j++;            }            else            {                memcpy( temp_de_list + j , temp_line + k , sizeof( deInfo ) );                j++;                k++;                i--;            }        }        else        {            memcpy( temp_de_list + j , de_list + i , sizeof( deInfo ) );            j++;        }    }    if ( k < 2 )    {        int temp = k;        for ( int i = temp ; i < 2 ; i++ )        {            temp_de_list[ j ] = temp_line[ k ];            j ++;            k ++;        }    }    delete[] de_list;    de_list = NULL;    de_list = temp_de_list;    _de_num += 2;    print_tag_info_list();    return 0;}void tiffTrans::print_tag_info_list(){    printf( "\n" );    for ( int i = 0 ; i < _de_num ; i++ )    {        char outStr[1024];        memset( outStr , 0 , 1024 * sizeof( char ) );        sprintf( outStr , "0x%04x[ %5d %-26s ] , 0x%02x , 0x%04x( %5d ) , 0x%08x , %d \n"             , de_list[i].de.tag             , de_list[i].de.tag            , tag_text( de_list[i].de.tag )            , de_list[i].de.type             , de_list[i].de.count            , de_list[i].de.count            , de_list[i].de.offset             , de_list[i].data_source ) ;        printf( outStr );    }}void tiffTrans::write_tag_list(){    _strip_offset_pos = 0;    _count_one_offset_pos = 0;    for ( int i = 0 ; i < _de_num ; i++ )    {        fseek( _line_tiff , DE_START + ONE_DE_SIZE * i , SEEK_SET );        fwrite( &( de_list[i].de.tag ) , 2 , 1 , _line_tiff );   //TAG 2字节        fwrite( &( de_list[i].de.type ) , 2 , 1 , _line_tiff );  //数据类型 2字节        fwrite( &( de_list[i].de.count ) , 4 , 1 , _line_tiff ); //count 4字节            if( ( de_list[i].de.tag == 273 || de_list[i].de.tag == 324 ) && de_list[i].de.count > 1 )//Strip offset or TileOffset        {            fseek( _line_tiff , 0 , SEEK_END );            _strip_offset_pos = ftell( _line_tiff );        }        else if(  de_list[i].de.tag == 273 && de_list[i].de.count == 1 )//Strip offset or TileOffset值保存在OFFSET中        {            fseek( _line_tiff , DE_START + ONE_DE_SIZE * i + 8 , SEEK_SET );            _count_one_offset_pos = ftell( _line_tiff );            fseek( _line_tiff , 0 , SEEK_END );        }        //写入offset        if( de_list[i].data_source == 0 )//直接写入值        {            fwrite( &( de_list[i].de.offset ) , 4 , 1 , _line_tiff );        }        else if ( de_list[i].data_source == 1 )//文件对应的偏移量        {            fseek( _line_tiff , 0 , SEEK_END );            TIFF_UINT32_T pos = ftell( _line_tiff );            TIFF_UINT64_T buffer_size = data_type_list[de_list[i].de.type].type_size * de_list[i].de.count;            file_disk_data( de_list[i].de , buffer_size );            //修改TAG对应的数据存放的地址            fseek( _line_tiff , DE_START + ONE_DE_SIZE * i + 8 , SEEK_SET );            fwrite( &pos , 1 , 4 , _line_tiff );        }        else if ( de_list[i].data_source == 2 )//内存        {            fseek( _line_tiff , 0 , SEEK_END );            TIFF_UINT32_T pos = ftell( _line_tiff );            fwrite ( de_list[i].mem_data , 1 ,  data_type_list[de_list[i].de.type].type_size * de_list[i].de.count  , _line_tiff );            //修改TAG对应的数据存放的地址            fseek( _line_tiff , DE_START + ONE_DE_SIZE * i + 8 , SEEK_SET );            fwrite( &pos , 1 , 4 , _line_tiff );            if ( !( ( de_list[i].de.tag == 33550 ) || ( de_list[i].de.tag == 33922 ) ) )            {                delete[] de_list[i].mem_data;            }        }    }}TIFF_UINT64_T tiffTrans::file_disk_data( DirectoryEntry de , TIFF_UINT64_T buffer_size ){    fseek( _tile_tiff , de.offset , SEEK_SET );    TIFF_UINT8_T* buf = new TIFF_UINT8_T[1024];    memset( buf , 0 , 1024 );    TIFF_UINT64_T fs = 0;    TIFF_UINT16_T read_size = 0;    if ( buffer_size <= 1024 )//若小于1024字节,则读取之后直接写入即可    {        read_size = fread( buf , 1 , buffer_size , _tile_tiff );        if( _tiff_src->tiff_byte_order == TIFF_BIGENDIAN && data_type_list[de.type].type_size != 1 )        {            sort_byte_order( buf , de.type , de.count );        }        fs += fwrite ( buf , 1 , read_size , _line_tiff );    }    else//若大于1024字节,则分批写入1024字节,最后写入不足1024的字节    {        TIFF_UINT16_T tile_num = ( int )(buffer_size / 1024) ;        TIFF_UINT16_T last_num = buffer_size % 1024;        for ( int i = 0 ; i < tile_num ; i++ )        {            read_size = fread( buf , 1 , 1024 , _tile_tiff );//注意参数的顺序            if( _tiff_src->tiff_byte_order == TIFF_BIGENDIAN && data_type_list[de.type].type_size != 1 )            {                sort_byte_order( buf , de.type , de.count );            }            fs += fwrite ( buf , 1 , read_size , _line_tiff );        }        read_size = fread( buf , 1 , last_num , _tile_tiff );        if( _tiff_src->tiff_byte_order == TIFF_BIGENDIAN && data_type_list[de.type].type_size != 1 )        {            sort_byte_order( buf , de.type , de.count );        }        fs += fwrite ( buf , 1 , last_num , _line_tiff );    }    delete[] buf;    buf = NULL;    return fs;}void tiffTrans::sort_byte_order( TIFF_UINT8_T* buf , TIFF_UINT16_T data_type , TIFF_UINT16_T data_count ){    TIFF_UINT8_T* p = buf;    for ( TIFF_UINT16_T i = 0 ; i < data_count ; i++ )    {        if ( data_type == 3 || data_type == 8 )//SHORT        {            TIFF_UINT16_T ret = sget2( p , TIFF_BIGENDIAN );            memcpy( p , &ret , 2 );            p += 2;        }        else if ( data_type == 4 ||  data_type == 9 ||  data_type == 11 )//LONG        {            TIFF_UINT32_T ret = sget4( p , TIFF_BIGENDIAN );            memcpy( p , &ret , 4 );            p += 4;        }        if ( data_type == 5 || data_type == 10 )        {            TIFF_UINT32_T ret = sget4( p , TIFF_BIGENDIAN );            memcpy( p , &ret , 4 );            p += 4;            ret = sget4( p , TIFF_BIGENDIAN );            memcpy( p , &ret , 4 );            p += 4;        }        else if ( data_type == 12 )//DOUBLE        {            TIFF_UINT64_T ret = sget8( p , TIFF_BIGENDIAN );            memcpy( p , &ret , 8 );            p += 8;        }    }}void tiffTrans::modify_line_strip(){    fseek( _line_tiff , 0 , SEEK_END );    TIFF_UINT32_T current_size = ftell( _line_tiff );    if( _count_one_offset_pos > 0 )//Strip offset or TileOffset值保存在OFFSET中    {        fseek( _line_tiff , _count_one_offset_pos , SEEK_SET );        fwrite( &current_size , 1 , 4 , _line_tiff );    }    else if ( _strip_offset_pos > 0 )    {        fseek( _line_tiff , _strip_offset_pos , SEEK_SET );        for ( int i = 0 ; i < _tiff_src->bcount_strip_offset ; i++ )        {            TIFF_UINT32_T offset_pos = current_size + i * _tiff_src->strip_byte_counts[i];            fwrite( &offset_pos , 1 , 4 , _line_tiff );        }    }}void tiffTrans::modify_tile_strip(){    fseek( _line_tiff , 0 , SEEK_END );    TIFF_UINT32_T current_size = ftell( _line_tiff );    fseek( _line_tiff , _strip_offset_pos , SEEK_SET );    TIFF_UINT32_T tile_bytes = _tiff_src->tile.tile_height * _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel ;    TIFF_UINT32_T tile_satrt = current_size ;    for ( int i = 0 ; i < _tiff_src->tile.tile_offset_count ; i++ )    {        TIFF_UINT32_T tile_satrt = current_size ;        tile_satrt += i * tile_bytes ;        fwrite( &tile_satrt , 1 , 4 , _line_tiff );    }}void tiffTrans::modify_strip_offset(){    if( _tiff_src->tile.is_tile )    {        modify_tile_strip( );    }    else    {        modify_line_strip( );    }}void tiffTrans::write_img_data(){    int table_w = (int)( _tiff_src->tif_width / _tiff_src->tile.tile_width );    if ( _tiff_src->tif_width % _tiff_src->tile.tile_width > 0 )    {        table_w ++ ;    }    int table_h = (int)( _tiff_src->tif_height/ _tiff_src->tile.tile_height)+1;    if (  _tiff_src->tif_height % _tiff_src->tile.tile_height > 0 )    {        table_h ++ ;    }    fseek( _line_tiff , 0 , SEEK_END );    TIFF_UINT64_T cur_size = ftell( _line_tiff );    for( int i_height = 0 ; i_height < _tiff_src->tif_height ; i_height++ )//按行添加    {        system("cls");        printf( "%s\n Tile -> Line %d / %d \n" ,_src_name.c_str(), i_height+1 , _tiff_src->tif_height  );        fseek( _line_tiff , cur_size + i_height * ( _tiff_src->tif_width * _tiff_src->samples_per_pixel ) , SEEK_SET );        int temp_table_h = i_height / _tiff_src->tile.tile_height;//确定tile的行高        int tile_h = i_height % _tiff_src->tile.tile_height;        for ( int i_w_table = 0 ; i_w_table < table_w ; i_w_table ++ )//按tile的列填充        {            TIFF_UINT32_T table_pos = temp_table_h * table_w + i_w_table;            TIFF_UINT32_T table_start = _tiff_src->tile.tile_offset_list[ table_pos ] + ( _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel) *tile_h ;            fseek( _tile_tiff , table_start , SEEK_SET );            TIFF_UINT8_T* buf = new TIFF_UINT8_T[ _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel ];            fread( buf , 1 , _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel , _tile_tiff );            fwrite( buf , 1 , _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel , _line_tiff );            delete[] buf;            buf = NULL;        }    }}void tiffTrans::write_img_data2(){    if ( _tiff_src->tile.is_tile )    {        write_tile_img( );    }    else    {        write_line_img( );    }}void tiffTrans::write_line_img( ){    fseek( _line_tiff , 0 , SEEK_END );    for ( int i = 0 ; i < _tiff_src->bcount_strip_offset ; i ++ )    {        write_data( _tiff_src->strip_line[i] , _tiff_src->strip_byte_counts[i] );    }}void tiffTrans::write_tile_img( ){    fseek( _line_tiff , 0 , SEEK_END );    for ( int i = 0 ; i < _tiff_src->tile.tile_offset_count ; i ++ )    {        write_data( _tiff_src->tile.tile_offset_list[i] , _tiff_src->tile.tile_byte_num_list[i] );    }}void tiffTrans::write_data( TIFF_UINT32_T data_start , TIFF_UINT32_T buffer_size ){    fseek( _tile_tiff , data_start , SEEK_SET );    TIFF_UINT8_T* buf = new TIFF_UINT8_T[1024];    memset( buf , 0 , 1024 );    TIFF_UINT16_T read_size = 0;    if ( buffer_size <= 1024 )//若小于1024字节,则读取之后直接写入即可    {        read_size = fread( buf , 1 , buffer_size , _tile_tiff );        fwrite ( buf , 1 , read_size , _line_tiff );    }    else//若大于1024字节,则分批写入1024字节,最后写入不足1024的字节    {        TIFF_UINT16_T tile_num = ( int )(buffer_size / 1024) ;        TIFF_UINT16_T last_num = buffer_size % 1024;        for ( int i = 0 ; i < tile_num ; i++ )        {            read_size = fread( buf , 1 , 1024 , _tile_tiff );//注意参数的顺序            fwrite ( buf , 1 , read_size , _line_tiff );        }        read_size = fread( buf , 1 , last_num , _tile_tiff );        fwrite ( buf , 1 , last_num , _line_tiff );    }    delete[] buf;    buf = NULL;}int tiffTrans::save_to_trans( const char* new_path ){    string temp_path;    if (  new_path == NULL )    {        temp_path = new_tiff_name() ;    }    else    {        temp_path = new_path;    }    _line_tiff = fopen( temp_path.c_str() , "wb" );    if ( _line_tiff == NULL )    {        return -1 ;    }    //1.写入TIFF的文件头    write_file_header( );    //读取原来的TIFF中的TAG标签    get_src_tag_list( );    //生成新的TAG列表    cts_new_tag_list( );    //2.写入tag的数量    fwrite( &( _de_num ) , 1 , 2 , _line_tiff );    //3.写入空的DE占位空间    TIFF_UINT8_T* place_holder = new TIFF_UINT8_T[ _de_num * ONE_DE_SIZE + IDF_END_FLAG_SIZE ];    memset( place_holder , 0 , _de_num * ONE_DE_SIZE + IDF_END_FLAG_SIZE );    fwrite( place_holder , 1 , _de_num * ONE_DE_SIZE + IDF_END_FLAG_SIZE , _line_tiff );    TIFF_UINT64_T write_file_size = ftell( _line_tiff );    //4.写入具体的TAG内容和对应的偏移量    write_tag_list();    //5.修改图像数据的偏移量    modify_strip_offset();    //6.写入图像数据    write_img_data2();    fclose( _line_tiff );    delete[] place_holder;    place_holder = NULL;    return 0;}TIFF_UINT64_T tiffTrans::double_to_long( double d_ ){    union { TIFF_UINT64_T i; double f; } u;    u.f = d_ ;    return u.i ;}void tiffTrans::cs_pixel_scale( double cx , double cy ){    pixel_scale[0] = double_to_long ( cx );    pixel_scale[1] = double_to_long ( cy );    pixel_scale[2] = 0 ;}void tiffTrans::cs_tie_point( double x , double y ){    tie_point[0] = 0;    tie_point[1] = 0;    tie_point[2] = 0;    tie_point[3] = double_to_long( x ) ;    tie_point[4] = double_to_long( y ) ;    tie_point[5] = 0;}void tiffTrans::cs_coord( deInfo* coord_list ){    coord_list[0].de.tag = 33550;//GeoTagPixelScale    coord_list[0].de.type = 12;//double    coord_list[0].de.count = 3 ;    coord_list[0].data_source = 2;//内存数据    coord_list[0].mem_data = ( TIFF_UINT8_T* )pixel_scale;    coord_list[1].de.tag = 33922;//GeoTagTiePoint    coord_list[1].de.type = 12;//double    coord_list[1].de.count = 6 ;    coord_list[1].data_source = 2;//内存数据    coord_list[1].mem_data = ( TIFF_UINT8_T* )tie_point;}

3.使用方法:

#include <stdio.h>#include <string>using namespace std;#include "tifftrans.h"string save_name( string str_path , string str_save_dir );int main( int argc, char* argv[] ){    if ( argc < 7 )    {        printf( "参数输入的不正确!\n[D:\\xxx.tif] [上] [下] [左] [右] 四个方向上的坐标 [D:\\xxx] " );        return -1;    }    string str_path( argv[1] );    string str_top ( argv[2] );    string str_botton ( argv[3] );    string str_left ( argv[4] );    string str_right ( argv[5] );    string str_save_dir ( argv[6] );    tiffTrans tiff_trans;    tiff_trans.open( str_path.c_str() );    geoRECT geo_box;    geo_box.top = atof( str_top.c_str() );    geo_box.botton = atof( str_botton.c_str() );    geo_box.left = atof( str_left.c_str() );    geo_box.right = atof( str_right.c_str() );    tiff_trans.coord_box( geo_box );    tiff_trans.save_to_trans( /*"D:\\123.tiff"*/ save_name( str_path , str_save_dir ).c_str() );    return 0;}string save_name( string str_path , string str_save_dir ){    int pos = str_path.rfind('\\');    string tif_name = str_path.substr( pos + 1 );    string temp = "\\coord_";    temp += tif_name ;    return str_save_dir + temp;}
0 0
原创粉丝点击