@@ -955,65 +955,38 @@ bool dcm_parse_pixeldata_offsets(DcmError **error,
955955 // each frame
956956
957957 dcm_log_info ("building Offset Table from Pixel Data" );
958+ // by definition the first offset is 0
959+ offsets [0 ] = 0 ;
958960
959961 // 0 in the BOT is the offset to the start of frame 1, ie. here
960962 * first_frame_offset = position ;
961- // each frame may consist of several fragments, so we need to scan each fragment to find the next frame
962- if (!read_tag (& state , & tag , & position )) {
963- dcm_error_set (error , DCM_ERROR_CODE_PARSE ,
964- "building BasicOffsetTable failed" ,
965- "failed to read tag" );
966- return false;
967- }
968- // all fragments belong to the only frame
969- if ( num_frames == 1 ) {
970- // according to the standard the first frame's offset is 0
971- offsets [0 ] = 0 ;
972- } else {
973- // 1 fragment shall contain 1 frame
974- int fragment_idx = 0 ;
975- offsets [fragment_idx ] = 0 ; // by definition the first fragment is at offset 0
976- fragment_idx ++ ;
977- while ( tag != TAG_SQ_DELIM ) {
978- if ( tag != TAG_ITEM || !read_uint32 (& state , & length , & position )) {
979- dcm_error_set (error , DCM_ERROR_CODE_PARSE ,
980- "building BasicOffsetTable failed" ,
981- "failed to read fragment" );
982- return false;
983- }
984- // skip actual content to find next offset
985- dcm_seekcur (& state , length , & position );
986- if (!read_tag (& state , & tag , & position )) {
987- dcm_error_set (error , DCM_ERROR_CODE_PARSE ,
988- "building BasicOffsetTable failed" ,
989- "failed to read tag" );
990- return false;
991- }
992- if ( fragment_idx < num_frames ) {
993- offsets [fragment_idx ] = offsets [fragment_idx - 1 ] + 8 /*tag and length field size*/ + length ;
994- }
995- fragment_idx ++ ;
996- }
997- // fragment_idx shall equal to num_frames+1 at the end
998- fragment_idx -- ;
999- if ( fragment_idx > num_frames ) {
1000- dcm_error_set (error , DCM_ERROR_CODE_INVALID ,
1001- "building BasicOffsetTable failed" ,
1002- "Too many fragments" );
963+ for (int i = 1 ; i < num_frames ; i ++ ) {
964+ if (!read_tag (& state , & tag , & position ) ||
965+ !read_uint32 (& state , & length , & position )) {
1003966 return false;
1004967 }
1005968
1006- if ( num_frames < fragment_idx ) {
1007- dcm_error_set (error , DCM_ERROR_CODE_INVALID ,
1008- "building BasicOffsetTable failed" ,
1009- "Too many frames" );
969+ if (tag == TAG_SQ_DELIM ) {
970+ dcm_error_set (error , DCM_ERROR_CODE_PARSE ,
971+ "reading BasicOffsetTable failed" ,
972+ "too few frames in PixelData" );
1010973 return false;
1011974 }
1012-
1013- if ( ! read_uint32 ( & state , & length , & position ) || length != 0 ) {
975+
976+ if (tag != TAG_ITEM ) {
1014977 dcm_error_set (error , DCM_ERROR_CODE_PARSE ,
1015978 "building BasicOffsetTable failed" ,
1016- "Sequence Delimiter Tag failure" );
979+ "frame Item #%d has wrong tag '%08x'" ,
980+ i + 1 ,
981+ tag );
982+ return false;
983+ }
984+
985+ // step back to the start of the item for this frame
986+ offsets [i ] = position - 8 ;
987+
988+ // and seek forward over the value
989+ if (!dcm_seekcur (& state , length , & position )) {
1017990 return false;
1018991 }
1019992 }
@@ -1070,6 +1043,7 @@ char *dcm_parse_encapsulated_frame(DcmError **error,
10701043 * length = 0 ;
10711044 uint32_t tag ;
10721045 uint32_t fragment_length = 0 ;
1046+ uint64_t frame_length = 0 ;
10731047
10741048 // first determine the total length of bytes to be read
10751049 while (position < frame_end_offset ) {
@@ -1089,10 +1063,13 @@ char *dcm_parse_encapsulated_frame(DcmError **error,
10891063 return NULL ;
10901064 }
10911065 dcm_seekcur (& state , fragment_length , & position );
1092- * length += fragment_length ;
1066+ frame_length += fragment_length ;
1067+ }
1068+ if ( frame_length > 0xFFFFFFFF ) {
1069+ return NULL ;
10931070 }
10941071
1095- char * value = DCM_MALLOC (error , * length );
1072+ char * value = DCM_MALLOC (error , frame_length );
10961073 if (value == NULL ) {
10971074 return NULL ;
10981075 }
@@ -1115,6 +1092,6 @@ char *dcm_parse_encapsulated_frame(DcmError **error,
11151092 }
11161093 fragment += fragment_length ;
11171094 }
1118-
1095+ * length = ( uint32_t ) frame_length ;
11191096 return value ;
11201097}
0 commit comments