TIFF图像数据的排列方式的装换
来源:互联网 发布:皇室战争烈焰精灵数据 编辑:程序博客网 时间:2024/05/16 08:05
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个空字节#define KB 1024#define MB 1024 * KB#define MAX_MSIZE 128 * MBextern 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;}
0 0
- TIFF图像数据的排列方式的装换
- VTK学习笔记-2-TIFF图像数据的重切片
- Matlab读取的图像的数据排列
- TIFF坐标的转换,生成新的图像
- 用Java输出分辨率300dpi以上的TIFF图像
- 压缩BMP图像为1像素的黑白图TIFF
- Tiff图像高位转低位的处理方法
- MATLAB对tiff格式图像序列的读取与导出
- 用Java输出分辨率300dpi以上的TIFF图像
- 【python图像处理】tiff文件的保存与解析
- java读取tiff格式图片信息的方式。
- openCV获取图像数据的方式
- 使用指针的方式遍历图像数据
- opencv读取图像数据的方式总结
- 换零钱方式的统计
- 换零钱方式的统计
- 数据互的装换问题
- 排列数据的输出
- 无意间锁死了STM32F042
- 【BZOJ 1020】 [SHOI2008]安全的航线flight
- Managing DbContext the right way with Entity Framework 6: an in-depth guide
- ABP入门系列(13)——Redis缓存用起来
- Ubuntu安装汇编器as86和链接器ld86
- TIFF图像数据的排列方式的装换
- 简单的Makefile编写
- 面试中重要的排序算法
- 初探Javascript
- 定时刷新之轮播图
- C++--第二次作业
- 《Ray Tracing from the Ground Up》中的坐标系是怎么确定的
- 在路上前行的小牛
- vector