33 #ifndef __INCLUDE_MIST_DICOM__
34 #define __INCLUDE_MIST_DICOM__
37 #ifndef __INCLUDE_MIST_CONF_H__
38 #include "../config/mist_conf.h"
41 #ifndef __INCLUDE_MIST_H__
45 #ifndef __INCLUDE_MIST_ENDIAN__
46 #include "../config/endian.h"
49 #ifndef __INCLUDE_MIST_LIMITS__
50 #include "../limits.h"
54 #ifndef __INCLUDE_MIST_COLOR_H__
55 #include "../config/color.h"
58 #ifndef __INCLUDE_MIST_DICOM_TAG__
62 #ifndef __INCLUDE_MIST_DICOM_INFO__
66 #ifndef __INCLUDE_MIST_SINGLETON__
67 #include "../singleton.h"
111 if( p == NULL || p + 4 >= e )
116 char *dicm =
reinterpret_cast< char *
>( p ) + 128;
117 if( dicm[ 0 ] ==
'D' && dicm[ 1 ] ==
'I' && dicm[ 2 ] ==
'C' && dicm[ 3 ] ==
'M' )
119 if( p + 4 + 128 >= e )
125 return( p + 128 + 4 );
148 return( p[ 0 ] == 0xfe && p[ 1 ] == 0xff && p[ 2 ] == 0x00 && p[ 3 ] == 0xe0 );
165 return( p[ 0 ] == 0xfe && p[ 1 ] == 0xff && p[ 2 ] == 0x0d && p[ 3 ] == 0xe0 && p[ 4 ] == 0x00 && p[ 5 ] == 0x00 && p[ 6 ] == 0x00 && p[ 7 ] == 0x00 );
182 return( p[ 0 ] == 0xfe && p[ 1 ] == 0xff && p[ 2 ] == 0xdd && p[ 3 ] == 0xe0 && p[ 4 ] == 0x00 && p[ 5 ] == 0x00 && p[ 6 ] == 0x00 && p[ 7 ] == 0x00 );
185 template <
bool _IS_SIGNED_ >
186 struct __check_num_bytes_function__
189 static ptrdiff_t check(
const T &nbytes )
203 struct __check_num_bytes_function__< true >
206 static ptrdiff_t check(
const T &nbytes )
213 inline ptrdiff_t __check_num_bytes__(
const T &nbytes )
215 return( __check_num_bytes_function__< std::numeric_limits< T >::is_signed >::check( nbytes ) );
233 inline unsigned char *
read_dicom_tag(
unsigned char *p,
unsigned char *e,
dicom_tag &tag, difference_type &numBytes,
bool from_little_endian =
true )
235 if( p == NULL || p + 8 > e )
241 unsigned char *data = p;
248 char VR[ 3 ] = {
static_cast< char >( data[ 0 ] ), static_cast< char >( data[ 1 ] ),
'\0' };
251 difference_type num_bytes = 0;
253 tag = dicom_table.
get_tag( group, element, vr );
255 if( tag.
tag != 0xffffffff )
304 numBytes = num_bytes;
305 return( reinterpret_cast< unsigned char * >( data + 4 ) );
351 #if defined( __SHOW_DICOM_ZEROBYTE_TAG__ ) && defined( __SHOW_DICOM_UNKNOWN_TAG__ )
352 printf(
"( %04x, %04x, %s, % 8d ) = Unknown Tags!!\n", group, element, VR, num_bytes );
358 numBytes = num_bytes;
361 else if( data + 4 + 4 <= e && data[ 0 ] == 0xff && data[ 1 ] == 0xff && data[ 2 ] == 0xff && data[ 3 ] == 0xff &&
is_sequence_separate_tag( data + 4, e ) )
365 numBytes = num_bytes;
368 else if( data + 4 + num_bytes <= e )
370 if( element == 0x0000 )
374 sprintf( str,
"Group %04d Length", group );
376 numBytes = num_bytes;
377 return( reinterpret_cast< unsigned char * >( data + 4 ) );
382 numBytes = num_bytes;
383 return( reinterpret_cast< unsigned char * >( data + 4 ) );
415 if( tag.
vm != -1 && num_bytes > 16 * tag.
vm )
432 if( tag.
vm != -1 && ( num_bytes % 4 != 0 || (
int)( num_bytes / 4 ) > tag.
vm ) )
446 if( tag.
vm != -1 && ( num_bytes % 4 != 0 || (
int)( num_bytes / 4 ) > tag.
vm ) )
453 for(
long i = 0 ; i < num_bytes ; i += 4 )
455 unsigned char v0 = byte[ i + 0 ];
456 unsigned char v1 = byte[ i + 1 ];
457 unsigned char v2 = byte[ i + 2 ];
458 unsigned char v3 = byte[ i + 3 ];
474 if( tag.
vm != -1 && num_bytes > 16 * tag.
vm )
488 if( tag.
vm != -1 && ( num_bytes % 8 != 0 || (
int)( num_bytes / 8 ) > tag.
vm ) && ( num_bytes % 10 != 0 || (
int)( num_bytes / 10 ) > tag.
vm ) )
501 if( tag.
vm != -1 && num_bytes > 16 * tag.
vm )
514 if( tag.
vm != -1 && num_bytes > 26 * tag.
vm )
523 if( tag.
vm != -1 && ( num_bytes % 4 != 0 || (
int)( num_bytes / 4 ) > tag.
vm ) )
530 byte[ 0 ] = tmp[ 0 ];
531 byte[ 1 ] = tmp[ 1 ];
532 byte[ 2 ] = tmp[ 2 ];
533 byte[ 3 ] = tmp[ 3 ];
540 if( tag.
vm != -1 && ( num_bytes % 8 != 0 || (
int)( num_bytes / 8 ) > tag.
vm ) )
547 byte[ 0 ] = tmp[ 0 ];
548 byte[ 1 ] = tmp[ 1 ];
549 byte[ 2 ] = tmp[ 2 ];
550 byte[ 3 ] = tmp[ 3 ];
551 byte[ 4 ] = tmp[ 4 ];
552 byte[ 5 ] = tmp[ 5 ];
553 byte[ 6 ] = tmp[ 6 ];
554 byte[ 7 ] = tmp[ 7 ];
564 if( tag.
vm != -1 && num_bytes > 16 * tag.
vm )
576 if( tag.
vm != -1 && num_bytes > 64 * tag.
vm )
588 if( tag.
vm != -1 && num_bytes > 10240 * tag.
vm )
607 for(
long i = 0 ; i < num_bytes ; i += 4 )
609 unsigned char v1 = byte[ i + 0 ];
610 unsigned char v2 = byte[ i + 1 ];
611 unsigned char v3 = byte[ i + 2 ];
612 unsigned char v4 = byte[ i + 3 ];
627 for(
long i = 0 ; i < num_bytes ; i += 2 )
629 unsigned char tmp = byte[ i ];
630 byte[ i ] = byte[ i + 1 ];
642 if( tag.
vm != -1 && num_bytes > 64 * tag.
vm )
654 if( tag.
vm != -1 && num_bytes > 16 * tag.
vm )
663 if( tag.
vm != -1 && ( num_bytes % 4 != 0 || (
int)( num_bytes / 4 ) > tag.
vm ) )
670 byte[ 0 ] = tmp[ 0 ];
671 byte[ 1 ] = tmp[ 1 ];
672 byte[ 2 ] = tmp[ 2 ];
673 byte[ 3 ] = tmp[ 3 ];
686 if( tag.
vm != -1 && ( num_bytes % 2 != 0 || (
int)( num_bytes / 2 ) > tag.
vm ) )
693 byte[ 0 ] = tmp[ 0 ];
694 byte[ 1 ] = tmp[ 1 ];
703 if( tag.
vm != -1 && num_bytes > 1024 * tag.
vm )
716 if( tag.
vm != -1 && num_bytes > 16 * tag.
vm )
726 if( tag.
vm != -1 && num_bytes > 64 * tag.
vm )
735 if( tag.
vm != -1 && ( num_bytes % 4 != 0 || (
int)( num_bytes / 4 ) > tag.
vm ) )
742 byte[ 0 ] = tmp[ 0 ];
743 byte[ 1 ] = tmp[ 1 ];
744 byte[ 2 ] = tmp[ 2 ];
745 byte[ 3 ] = tmp[ 3 ];
756 if( tag.
vm != -1 && ( num_bytes % 2 != 0 || (
int)( num_bytes / 2 ) > tag.
vm ) )
763 byte[ 0 ] = tmp[ 0 ];
764 byte[ 1 ] = tmp[ 1 ];
798 difference_type numBytes = 0;
801 pointer =
read_dicom_tag( pointer, end_pointer, tag, numBytes, from_little_endian );
805 unsigned char *sp = pointer;
806 if( numBytes != -1 && pointer + numBytes <= end_pointer )
812 unsigned char *ep = numBytes == -1 ? end_pointer : pointer + numBytes;
813 if( ep > end_pointer )
818 while( pointer + 8 <= ep )
836 unsigned char *epp = numBytes == -1 ? ep : pointer + numBytes;
842 while( pointer + 8 <= epp )
852 if( pointer == NULL )
862 if( !is_in_sequence_tag )
867 #ifdef __SHOW_DICOM_TAG__
868 if( ite != dicm.end( ) )
870 ite->second.show_tag( );
875 else if( numBytes < -1 )
879 else if( numBytes == -1 )
888 unsigned char *p = pointer;
889 while( p + 8 <= end_pointer )
907 if( numBytes < 0 || p > end_pointer )
913 if( p <= end_pointer )
915 numBytes = p - pointer;
916 if( !is_in_sequence_tag )
936 #ifdef __SHOW_DICOM_TAG__
937 if( !is_in_sequence_tag && ite != dicm.end( ) )
939 ite->second.show_tag( );
943 else if( numBytes > 0 )
946 if( pointer + numBytes > end_pointer )
951 #ifndef __CHECK_TAG_FORMAT__
955 std::cout <<
"Illegal DICOM tag is found!" << std::endl;
964 if( !is_in_sequence_tag )
969 #ifdef __SHOW_DICOM_TAG__
970 if( ite != dicm.end( ) )
972 ite->second.show_tag( );
979 else if( tag.
vr !=
UNKNOWN && !is_in_sequence_tag )
985 #if defined( __SHOW_DICOM_ZEROBYTE_TAG__ ) && defined( __SHOW_DICOM_TAG__ )
986 if( ite != dicm.end( ) )
988 ite->second.show_tag( );
1009 unsigned char *pointer = buff;
1010 unsigned char *end_pointer = buff + numBytes;
1017 unsigned char *group_end_pointer = NULL;
1018 bool ret =
true, from_little_endian = is_little_endian, once =
true;
1019 while( pointer < end_pointer )
1022 if( pointer == NULL )
1028 if( group_end_pointer == NULL && dicm.
contain( 0x0002, 0x0000 ) )
1031 group_end_pointer = pointer +
find_tag( dicm, 0x0002, 0x0000, static_cast< unsigned int >( 0 ) );
1034 if( group_end_pointer != NULL && once && dicm.
contain( 0x0002, 0x0010 ) )
1040 from_little_endian =
find_tag( dicm, 0x0002, 0x0010,
"" ) !=
"1.2.840.10008.1.2.2";
1043 if( !from_little_endian )
1045 while( pointer < group_end_pointer )
1048 if( pointer == NULL )
1050 pointer = end_pointer;
1059 #ifdef __SHOW_DICOM_TAG__
1079 if( ( fp = fopen( filename.c_str( ),
"rb" ) ) == NULL )
1085 fseek( fp, 0, SEEK_END );
1086 filesize = ftell( fp );
1087 fseek( fp, 0, SEEK_SET );
1089 unsigned char *buff =
new unsigned char[ filesize + 1 ];
1090 unsigned char *pointer = buff;
1091 size_type read_size = 0;
1092 while( feof( fp ) == 0 )
1094 read_size = fread( pointer,
sizeof(
unsigned char ), 1024, fp );
1095 if( read_size < 1024 )
1099 pointer += read_size;
1108 #ifdef __SHOW_DICOM_TAG__
1116 for( ; ite != dicm.end( ) ; ++ite )
1118 if( ite->second.comment !=
"UNKNOWN" )
1148 unsigned char ZERO[] = { 0, 0, 0, 0 };
1149 unsigned char FFFF[] = { 0xff, 0xff, 0xff, 0xff };
1158 fwrite( ZERO, 1, 2, fp );
1163 fwrite( FFFF, 1, 4, fp );
1172 fwrite( data, 1, num_bytes, fp );
1179 if( num_bytes % 2 == 0 )
1181 for(
size_t i = 0 ; i < num_bytes ; i += 2 )
1195 if( num_bytes % 4 == 0 )
1197 for(
size_t i = 0 ; i < num_bytes ; i += 4 )
1225 fwrite( data, 1, num_bytes, fp );
1234 if( num_bytes % 2 == 0 )
1236 for(
size_t i = 0 ; i < num_bytes ; i += 2 )
1251 if( num_bytes % 4 == 0 )
1253 for(
size_t i = 0 ; i < num_bytes ; i += 4 )
1267 if( num_bytes % 8 == 0 )
1269 for(
size_t i = 0 ; i < num_bytes ; i += 8 )
1291 fwrite( ZERO, 1, 2, fp );
1295 fwrite( FFFF, 1, 4, fp );
1296 fwrite( data, 1, num_bytes, fp );
1301 fwrite( data, 1, num_bytes, fp );
1308 fwrite(
"UN", 1, 2, fp );
1311 fwrite( data, 1, num_bytes, fp );
1319 fwrite( data, 1, num_bytes, fp );
1343 unsigned char FFFF[] = { 0xff, 0xff, 0xff, 0xff };
1356 fwrite( FFFF, 1, 4, fp );
1357 fwrite( data, 1, num_bytes, fp );
1364 fwrite( data, 1, num_bytes, fp );
1372 fwrite( data, 1, num_bytes, fp );
1423 size_t num_bytes = 0;
1449 return( num_bytes );
1461 std::map< unsigned short, size_t > group_length;
1463 for( ite = dicm.begin( ) ; ite != dicm.end( ) ; ++ite )
1473 if( element != 0x0000 )
1476 if( group_length.find( group ) != group_length.end( ) )
1478 group_length[ group ] += num_bytes;
1482 group_length[ group ] = num_bytes;
1488 for( ite = dicm.begin( ) ; ite != dicm.end( ) ; ++ite )
1494 if( element == 0x0000 )
1497 size_t num_bytes = group_length[ group ];
1532 if( ( fp = fopen( filename.c_str( ),
"wb" ) ) == NULL )
1538 bool hasPreamble =
false;
1540 unsigned short elements[] = { 0x0001, 0x0002, 0x0003, 0x0010, 0x0012, 0x0013, 0x0016, 0x0100, 0x0102 };
1541 size_t num =
sizeof( elements ) /
sizeof(
unsigned short );
1542 for(
size_t i = 0 ; i < num ; i++ )
1544 if( dicom.
contain( 0x0002, elements[ i ] ) )
1554 bool implicitVR =
true;
1559 unsigned char ZERO[ 128 ];
1560 unsigned char DICM[ 4 ];
1561 memset( ZERO, 0,
sizeof(
unsigned char ) * 128 );
1566 fwrite( ZERO,
sizeof(
unsigned char ), 128, fp );
1567 fwrite( DICM,
sizeof(
unsigned char ), 4, fp );
1571 if( !dicm.
contain( 0x0002, 0x0010 ) )
1574 std::string syntax =
"1.2.840.10008.1.2";
1575 dicm.
append(
dicom_element( 0x0002, 0x0010, reinterpret_cast< const unsigned char * >( syntax.c_str( ) ), syntax.length( ) ) );
1577 else if(
find_tag( dicm, 0x0002, 0x0010,
"" ) ==
"1.2.840.10008.1.2.1" )
1582 else if(
find_tag( dicm, 0x0002, 0x0010,
"" ) ==
"1.2.840.10008.1.2.2" )
1586 std::string syntax =
"1.2.840.10008.1.2.1";
1587 dicm( 0x0002, 0x0010 ).copy( reinterpret_cast< const unsigned char * >( syntax.c_str( ) ), syntax.length( ) );
1596 if( !dicm.
contain( 0x0002, 0x0000 ) )
1611 for( ; ite != dicm.end( ) ; ++ite )
1613 if( ite->second.enable )
1616 if( implicitVR && ite->second.get_group( ) != 0x0002 )
1646 template <
class T,
class Allocator >
1651 typedef _pixel_converter_< T > pixel_converter;
1652 typedef typename pixel_converter::color_type color_type;
1667 if( dicm.
contain( 0x7fe0, 0x0010 ) )
1698 for( size_type j = 0 ; j < image.
height( ) ; j++ )
1700 unsigned char *r = element.
data + j * info.
cols;
1702 unsigned char *b = element.
data + j * info.
cols + info.
cols * info.
rows * 2;
1703 for( size_type i = 0 ; i < image.
width( ) ; i++ )
1705 image( i, j ) = pixel_converter::convert_to( r[ i ], g[ i ], b[ i ] );
1711 for( size_type j = 0 ; j < image.
height( ) ; j++ )
1713 unsigned char *data = element.
data + j * image.
width( ) * 3;
1714 for( size_type i = 0 ; i < image.
width( ) ; i++ )
1716 size_type ii = i * 3;
1717 image( i, j ) = pixel_converter::convert_to( data[ ii + 2 ], data[ ii + 1 ], data[ ii + 0 ] );
1724 if( dicm.
contain( 0x0028, 0x1201 ) && dicm.
contain( 0x0028, 0x1202 ) && dicm.
contain( 0x0028, 0x1203 ) )
1730 const short *r =
reinterpret_cast< const short *
>( red.
data );
1731 const short *g =
reinterpret_cast< const short *
>( green.
data );
1732 const short *b =
reinterpret_cast< const short *
>( blue.
data );
1734 bool is_big_endian =
false;
1737 for(
size_t i = 0 ; i < red.
num_bytes / 2 ; i++ )
1739 if( r[ i ] > max_value || g[ i ] > max_value || b[ i ] > max_value )
1741 is_big_endian =
true;
1749 for( size_type j = 0 ; j < image.
height( ) ; j++ )
1751 unsigned char *data = element.
data + j * image.
width( );
1752 for( size_type i = 0 ; i < image.
width( ) ; i++ )
1757 image( i, j ) = pixel_converter::convert_to( R, G, B );
1764 for( size_type j = 0 ; j < image.
height( ) ; j++ )
1766 unsigned char *data = element.
data + j * image.
width( );
1767 for( size_type i = 0 ; i < image.
width( ) ; i++ )
1769 unsigned char R =
static_cast< unsigned char >( r[ data[ i ] ] );
1770 unsigned char G =
static_cast< unsigned char >( g[ data[ i ] ] );
1771 unsigned char B =
static_cast< unsigned char >( b[ data[ i ] ] );
1772 image( i, j ) = pixel_converter::convert_to( R, G, B );
1784 for( size_type j = 0 ; j < image.
height( ) ; j++ )
1786 unsigned char *data = element.
data + j * image.
width( );
1787 for( size_type i = 0 ; i < image.
width( ) ; i++ )
1789 image( i, j ) = data[ i ];
1799 window_width = -window_width;
1803 if( dicm.
contain( 0x0028, 0x1050 ) && dicm.
contain( 0x0028, 0x1051 ) && dicm( 0x0028, 0x1050 ).num_bytes > 0 && dicm( 0x0028, 0x1051 ).num_bytes > 0 )
1805 const short *bytes =
reinterpret_cast< const short *
>( element.
data );
1806 for( size_type j = 0 ; j < image.
height( ) ; j++ )
1808 const short *data = bytes + j * image.
width( );
1809 for( size_type i = 0 ; i < image.
width( ) ; i++ )
1811 double pix = ( ( data[ i ] + offset - window_level ) / window_width + 0.5 ) * 255.0;
1812 pix = pix > 255.0 ? 255.0 : pix;
1813 pix = pix < 0.0 ? 0.0 : pix;
1814 image( i, j ) =
static_cast< unsigned char >( pix );
1821 const unsigned short *bytes =
reinterpret_cast< const unsigned short *
>( element.
data );
1822 double min = bytes[ 0 ], max = bytes[ 0 ];
1823 for(
size_t l = 1 ; l < element.
num_bytes / 2 ; l++ )
1825 if( bytes[ l ] < min )
1829 else if( max < bytes[ l ] )
1835 double ww = max - min + 1;
1836 double wl = ( max + min ) / 2.0;
1845 for( size_type j = 0 ; j < image.
height( ) ; j++ )
1847 const unsigned short *data = bytes + j * image.
width( );
1848 for( size_type i = 0 ; i < image.
width( ) ; i++ )
1850 double pix = ( ( data[ i ] - wl ) / ww + 0.5 ) * 255.0;
1851 pix = pix > 255.0 ? 255.0 : pix;
1852 pix = pix < 0.0 ? 0.0 : pix;
1853 image( i, j ) =
static_cast< unsigned char >( pix );
1885 #endif // __INCLUDE_MIST_DICOM__