TIFF图像数据的排列方式的装换
2017-03-08 22:08
483 查看
tiff图片在图片数据的排列方式有两种:一种是线性排列方式,一种是块状(瓦片状)的排列方式。线性排列方式的数据在读取的时候还是比较快的,但是块状的排列方式读取的时候就是比较慢了。现在要把块状的数据转换成线状的数据。
1.头文件
2.cpp文件
3.调用
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个空字节 #define KB 1024 #define MB 1024 * KB #define MAX_MSIZE 128 * MB extern TIFF_UINT8_T g_big_memory[ MAX_MSIZE ]; extern TIFF_UINT8_T g_line_memory[ 8*MB ]; 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 ); int arrangement();//0 - tile 1 - line bool analysis( char* ret_error ); //分析tiff是否可以进行转换 true - 可以 false - 不可以 int save_to_trans( const char* new_path = NULL ); private: string new_tiff_name(); void write_file_header(); 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_tile_tag(); int cts_new_tag_list(); void print_tag_info_list(); void write_tag_list(); void modify_strip_offset(); 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(); 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; //标签的数量 TIFF_UINT32_T _strip_offset_pos; //TAG StripOffset的文件偏移位置 };
2.cpp文件
#include "tifftrans.h" TIFF_UINT8_T g_big_memory[MAX_MSIZE]; TIFF_UINT8_T g_line_memory[ 8*MB ]; 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) ); } tiffTrans::tiffTrans( const char* tiff_path ) { _src_name = tiff_path; _tiff_src = new TiffFile; memset( _tiff_src , 0 , sizeof(TiffFile) ); } 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; } 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++ ) { _fseeki64( _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 ; } } 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_tile_tag() { deInfo* temp_de_list = new deInfo[ _de_num - 4 ];//tile 共4个标签 memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num - 4) ); int j = 0; for ( int i = 0 ; i < _de_num ; i ++ ) { if ( ( de_list[i].de.tag != 322 )&& ( de_list[i].de.tag != 323 )&& ( de_list[i].de.tag != 324 )&& ( de_list[i].de.tag != 325 ) ) { memcpy ( temp_de_list + j , de_list + i , sizeof(deInfo) ); j++; } } delete[] de_list; de_list = NULL; de_list = temp_de_list; _de_num -= 4 ; return de_list; } int tiffTrans::cts_new_tag_list( ) { de_list = delete_tile_tag(); deInfo* temp_line = cts_line_tag(); deInfo* temp_de_list = new deInfo[ _de_num + 3 ];//tile 4个标签 line 只需要3个标签 memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num + 3 ) ); int j = 0 , k = 0 ; for ( int i = 0 ; i < _de_num ; i++ ) { if ( k < 3 )//line只有三个标签 { 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++; } } delete[] de_list; de_list = NULL; de_list = temp_de_list; _de_num += 3; 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() { 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 )//Strip offset { _fseeki64( _line_tiff , 0 , SEEK_END ); _strip_offset_pos = ftell( _line_tiff ); } //写入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 )//文件对应的偏移量 { _fseeki64( _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对应的数据存放的地址 _fseeki64( _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 )//内存 { _fseeki64( _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对应的数据存放的地址 _fseeki64( _line_tiff , DE_START + ONE_DE_SIZE * i + 8 , SEEK_SET ); fwrite( &pos , 1 , 4 , _line_tiff ); delete[] de_list[i].mem_data; } } } TIFF_UINT64_T tiffTrans::file_disk_data( DirectoryEntry de , TIFF_UINT64_T buffer_size ) { _fseeki64( _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_strip_offset() { 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 width_bytes = _tiff_src->tif_width * _tiff_src->samples_per_pixel ; for ( int i = 0 ; i < _tiff_src->tif_height ; i++ ) { TIFF_UINT32_T height_start = current_size + i * width_bytes; fwrite( &height_start , 1 , 4 , _line_tiff ); } } 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*/_fseeki64( _line_tiff , 0 , SEEK_END ); TIFF_UINT64_T cur_size = ftell( _line_tiff ); #if 0 #if 0 for( int i_height = 0 ; i_height < _tiff_src->tif_height ; i_height++ )//按行添加 { if( i_height % 10000 == 0) { 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; } } #endif TIFF_UINT32_T tiff_width_bytes = _tiff_src->tif_width * _tiff_src->samples_per_pixel ; TIFF_UINT32_T tile_line_bytes = _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel; TIFF_UINT8_T* buf = new TIFF_UINT8_T[ tiff_width_bytes ]; memset( buf , 0 , tiff_width_bytes ); TIFF_UINT8_T* temp_buf = buf; for( int i_height = 0 ; i_height < _tiff_src->tif_height ; i_height++ )//按行添加 { fseek( _line_tiff , cur_size + i_height * tiff_width_bytes , 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 ); fread( temp_buf , 1 ,tile_line_bytes , _tile_tiff ); temp_buf += tile_line_bytes; } fwrite( buf , 1 , tiff_width_bytes , _line_tiff ); memset( buf , 0 , tiff_width_bytes ); temp_buf = buf; } delete[] buf; buf = NULL; #else TIFF_UINT32_T table_size = _tiff_src -> tile.tile_width * _tiff_src -> tile.tile_height * _tiff_src -> samples_per_pixel ; TIFF_UINT32_T tiff_width_bytes = _tiff_src->tif_width * _tiff_src->samples_per_pixel ; if( tiff_width_bytes > 8*MB ) { printf( "图片的行数据 %ld 太大,暂时无法处理!\n" , tiff_width_bytes ); return ; } /*TIFF_UINT8_T* buf = new TIFF_UINT8_T[ tiff_width_bytes ]; if ( buf == NULL ) { printf( "行数据内存分配失败!\n" ); return; }*/ //TIFF_UINT8_T* buf = ( TIFF_UINT8_T* )malloc( sizeof( TIFF_UINT8_T) * tiff_width_bytes ); TIFF_UINT8_T *buf = g_line_memory ; memset( buf , 0 , tiff_width_bytes ); TIFF_UINT32_T tile_width_bytes = _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel; for ( int i_tb_h = 0 ; i_tb_h < table_h ; i_tb_h ++ ) { TIFF_UINT8_T* pbig = g_big_memory; for( int i_tb_w = 0 ; i_tb_w < table_w ; i_tb_w ++ ) { TIFF_UINT32_T table_pos = i_tb_h * table_w + i_tb_w; TIFF_UINT32_T table_start = _tiff_src->tile.tile_offset_list[ table_pos ] ; _fseeki64( _tile_tiff , table_start , SEEK_SET ); TIFF_UINT32_T read_bytes = fread( pbig , 1 , table_size , _tile_tiff ); //if ( read_bytes == 0/*table_size*/ ) //{ // fclose( _line_tiff ); // return; //} pbig += table_size ; } for ( int i_h_tile = 0 ; i_h_tile < _tiff_src->tile.tile_height ; i_h_tile ++ ) { TIFF_UINT8_T* temp_buf = buf ; for ( int i_tb_w = 0 ; i_tb_w < table_w ; i_tb_w ++ ) { TIFF_UINT8_T* p = g_big_memory + ( i_tb_w * table_size + tile_width_bytes * i_h_tile ); memcpy( temp_buf , p , tile_width_bytes ); temp_buf += tile_width_bytes; } TIFF_UINT32_T write_count = fwrite( buf , 1 , tiff_width_bytes , _line_tiff ); memset( buf , 0 , tiff_width_bytes ); temp_buf = NULL ; } pbig = NULL ; } //free( buf ); //buf = NULL ; //delete[] buf; //buf = NULL; #endif } 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_data(); return 0; }
3.调用
#include <Windows.h> #include "tifftrans.h" char parse_cmd( char* sz_cmd );//解析命令 void print_help_info(); //打印帮助信息 int get_all_path_list( const TCHAR* rootDir, vector<wstring>&srcFiles); bool is_tiff( wstring file_name ); wstring new_dir_path( wstring dir_path ); wstring mbcs_to_unicode(const std::string& str ); string unicode_to_mbcs(const std::wstring& wstr ); string new_name( string tiff_name , string save_dir ); int main( int argc, char* argv[] ) { for ( int i = 0 ; i < argc ; i++ ) { printf( "%d): " , i+1 ); printf( argv[i] ); printf( "\n" ); } if ( argc < 4 ) { printf("error : 请输入正确的命令和参数!"); return -1; } char cmd_symble = parse_cmd( argv[1] ); switch ( cmd_symble ) { case '?': case 'h': case 'H': { print_help_info(); } break; case 't'://单张图片 { tiffTrans tiff_trans; tiff_trans.open( argv[2] ); char error_text[1024] = { 0 }; if ( tiff_trans.analysis( error_text ) ) { string save_name = new_name( argv[2] , argv[3] ); if( 0 == tiff_trans.save_to_trans( save_name.c_str() ) ) { printf("处理完成!\n\n"); } } else { printf( error_text ); } } break; case 'd'://批量处理 { wstring dir_path = mbcs_to_unicode( argv[2] ); dir_path = new_dir_path( dir_path ); vector<wstring> tiff_list; get_all_path_list( dir_path.c_str() , tiff_list ); for ( int i = 0 ; i < tiff_list.size() ; i++ ) { tiffTrans tiff_trans; tiff_trans.open( unicode_to_mbcs( tiff_list.at( i ) ).c_str() ); char error_text[1024] = { 0 }; if ( tiff_trans.analysis( error_text ) ) { if( 0 == tiff_trans.save_to_trans( ) ) { printf("处理完成!\n\n"); } } } } break; default: print_help_info(); break; } return 0; } char parse_cmd( char* sz_cmd ) { char ch = 'h'; if ( strlen( sz_cmd ) <= 1 ) { return ch ; } if ( sz_cmd[0]!='-' ) { return ch; } ch = sz_cmd[1]; return ch; } void print_help_info() { printf( "命令格式:[-x][x:\\xxx.tif][D:\\xxx]\n" ); printf( " -h - H -? 显示帮助信息\n"); printf( " -t 处理单张tiff图片。参数:tiff图片的完整的路径\n"); printf( " -d 批量处理tiff图片。参数:所有tiff图片所在的文件夹目录\n"); } wstring new_dir_path( wstring dir_path ) { int len = dir_path.size(); if ( dir_path.at( len - 1 ) == L'\\' ) { return dir_path.substr( 0 , len - 1 ); } return dir_path; } string new_name( string tiff_name , string save_dir ) { int pos = tiff_name.rfind('\\'); string name = tiff_name.substr( pos + 1 ); string name2 = "\\line_"; name2 += name ; wstring new_name2 = new_dir_path( mbcs_to_unicode(save_dir) ); return unicode_to_mbcs( new_name2 ) + name2; } int get_all_path_list( const TCHAR* rootDir, vector<wstring>&srcFiles) { WIN32_FIND_DATA fd; ZeroMemory(&fd, sizeof(WIN32_FIND_DATA)); HANDLE hFile; TCHAR tmpPath[256]; TCHAR subPath[256]; ZeroMemory( tmpPath, 256*sizeof(TCHAR) ); ZeroMemory( subPath, 256*sizeof(TCHAR) ); BOOL bRet = TRUE; static int nFileSize = 0 ; //define the format of the basepath wcscpy(tmpPath, rootDir); if(tmpPath[wcslen(tmpPath) -1] != L'\\') { wcscat(tmpPath, L"\\"); } wcscat(tmpPath, L"*"); hFile = FindFirstFile(tmpPath, &fd); while (hFile != INVALID_HANDLE_VALUE && bRet) { if (fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && wcscmp(fd.cFileName, L".") && wcscmp(fd.cFileName, L"..")) { wcscpy(subPath, rootDir); if(subPath[wcslen(subPath) -1] != L'\\') { wcscat(subPath, L"\\"); } wcscat(subPath, fd.cFileName); get_all_path_list( subPath , srcFiles ); } else if(!wcscmp(fd.cFileName, L".") || !wcscmp(fd.cFileName, L"..")) { } else { if ( is_tiff( fd.cFileName ) ) { nFileSize++; wstring strdir = rootDir; strdir += L"\\"; strdir += fd.cFileName; srcFiles.push_back( strdir ); } } bRet = FindNextFile(hFile, &fd); } FindClose(hFile); return nFileSize; } bool is_tiff( wstring file_name ) { int pos = file_name.rfind(L'.'); wstring ext_name = file_name.substr( pos + 1 ); transform(ext_name.begin(), ext_name.end(), ext_name.begin(), ::tolower); if ( ext_name == L"tif" ) { return true; } return false; } wstring mbcs_to_unicode(const std::string& str ) { int len = 0; len = (int)str.length(); int unicodeLen = ::MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, NULL, 0 ); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen ); wstring wstr = pUnicode; delete[] pUnicode; return wstr; } string unicode_to_mbcs(const std::wstring& wstr ) { int len = 0; len = (int)wstr.length(); int ansiLen = ::WideCharToMultiByte( CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL); char* pAnsi; pAnsi = new char[ansiLen+1]; memset(pAnsi,0,(ansiLen+1)*sizeof(char)); ::WideCharToMultiByte( CP_ACP, 0, wstr.c_str(), -1, (LPSTR)pAnsi, ansiLen, NULL, NULL); string str = pAnsi; delete[] pAnsi; return str; }
相关文章推荐
- VTK学习笔记-2-TIFF图像数据的重切片
- Java_对数据外螺旋方式排列
- 神经网络训练中图像数据预处理的一些方式(一)
- C# Python 读取txt中的文件,将16进制的数据按照小端方式排列,处理为有符号的数字,并写入text文件;控制台和界面两种方式
- 遥感图像——多波段数据存储的方式
- (转)在C#中使用WIA获取扫描仪数据(四、通过编程方式扫描图像)
- 斯坦福李飞飞-深度学习与计算机视觉 数据驱动的图像分类方式:K最近邻与线性分类器
- SamplePairing:针对图像处理领域的高效数据增强方式 | PaperDaily #34
- Stanford CS231n Lecture 2 数据驱动的图像分类方式:K近邻与线性分类器
- linux应用Xlib来显示内存图像数据到窗口的方式
- 任意语言,任意大小,任意字体,任意格式,任意范围,任意字符,任意扫描方式取模,生成字节,UNICODE_Font_宋体16_ 纵向取模下高位_数据排列_从左到右从上到下
- libjpeg库解码jpeg图像输出数据排列问题
- opencv读取图像数据的方式总结
- Cimage类处理图像像素(数据)的3种方式(转)
- openCV获取图像数据的方式
- Cimage类处理图像像素(数据)的3种方式
- 如何将RGB图像数据保存成tiff,可以保存曝光,增益,白平衡参数
- [Kinect&Emgu]拉数据方式(延时)获得图像的方法
- 关于C语言多维数组和VB语言多维数组的实际数据在内存中的储存排列方式
- java server 传输给 ios 图像数据的三种方式