@@ -83,6 +83,12 @@ struct _DcmFilehandle {
8383 // push and pop these while we parse
8484 UT_array * dataset_stack ;
8585 UT_array * sequence_stack ;
86+
87+ // skip to tags during parse
88+ uint32_t * skip_to_tags ;
89+
90+ // set if we see an ext offset table
91+ bool have_extended_offset_table ;
8692};
8793
8894
@@ -1003,6 +1009,8 @@ static bool read_frame_index(DcmError **error,
10031009 .stop = parse_frame_index_stop ,
10041010 };
10051011
1012+ dcm_log_debug ("Reading per frame functional group sequence." );
1013+
10061014 filehandle -> frame_index = DCM_NEW_ARRAY (error ,
10071015 filehandle -> num_tiles ,
10081016 uint32_t );
@@ -1029,10 +1037,10 @@ static bool read_frame_index(DcmError **error,
10291037}
10301038
10311039
1032- static bool parse_skip_to_index (void * client ,
1033- uint32_t tag ,
1034- DcmVR vr ,
1035- uint32_t length )
1040+ static bool parse_skip_to (void * client ,
1041+ uint32_t tag ,
1042+ DcmVR vr ,
1043+ uint32_t length )
10361044{
10371045 DcmFilehandle * filehandle = (DcmFilehandle * ) client ;
10381046
@@ -1041,21 +1049,25 @@ static bool parse_skip_to_index(void *client,
10411049
10421050 filehandle -> last_tag = tag ;
10431051
1044- return tag == TAG_PER_FRAME_FUNCTIONAL_GROUP_SEQUENCE ||
1045- tag == TAG_PIXEL_DATA ||
1046- tag == TAG_FLOAT_PIXEL_DATA ||
1047- tag == TAG_DOUBLE_PIXEL_DATA ;
1052+ for (int i = 0 ; filehandle -> skip_to_tags [i ]; i ++ )
1053+ if (tag == filehandle -> skip_to_tags [i ])
1054+ return true;
1055+
1056+ return false;
1057+
10481058}
10491059
10501060
1051- static bool read_skip_to_index (DcmError * * error ,
1052- DcmFilehandle * filehandle )
1061+ static bool read_skip_to (DcmError * * error ,
1062+ DcmFilehandle * filehandle ,
1063+ uint32_t * skip_to_tags )
10531064
10541065{
10551066 static DcmParse parse = {
1056- .stop = parse_skip_to_index ,
1067+ .stop = parse_skip_to ,
10571068 };
10581069
1070+ filehandle -> skip_to_tags = skip_to_tags ;
10591071 if (!dcm_parse_dataset (error ,
10601072 filehandle -> io ,
10611073 filehandle -> implicit ,
@@ -1068,10 +1080,36 @@ static bool read_skip_to_index(DcmError **error,
10681080}
10691081
10701082
1071- static bool parse_skip_to_pixel_data (void * client ,
1072- uint32_t tag ,
1073- DcmVR vr ,
1074- uint32_t length )
1083+ static bool parse_extended_offsets_element_create (DcmError * * error ,
1084+ void * client ,
1085+ uint32_t tag ,
1086+ DcmVR vr ,
1087+ char * value ,
1088+ uint32_t length )
1089+ {
1090+ USED (error );
1091+ USED (vr );
1092+
1093+ DcmFilehandle * filehandle = (DcmFilehandle * ) client ;
1094+ int64_t expected_size = filehandle -> num_frames * sizeof (int64_t );
1095+
1096+ if (tag == TAG_EXTENDED_OFFSET_TABLE && length == expected_size ) {
1097+ memcpy (filehandle -> offset_table , value , length );
1098+ filehandle -> have_extended_offset_table = true;
1099+
1100+ // the size of the pixeldata header, plus the size of the empty frame
1101+ // 0 (the BOT)
1102+ filehandle -> first_frame_offset = 20 ;
1103+ }
1104+
1105+ return true;
1106+ }
1107+
1108+
1109+ static bool parse_extended_offsets_stop (void * client ,
1110+ uint32_t tag ,
1111+ DcmVR vr ,
1112+ uint32_t length )
10751113{
10761114 DcmFilehandle * filehandle = (DcmFilehandle * ) client ;
10771115
@@ -1080,18 +1118,17 @@ static bool parse_skip_to_pixel_data(void *client,
10801118
10811119 filehandle -> last_tag = tag ;
10821120
1083- return tag == TAG_PIXEL_DATA ||
1084- tag == TAG_FLOAT_PIXEL_DATA ||
1085- tag == TAG_DOUBLE_PIXEL_DATA ;
1121+ return tag != TAG_EXTENDED_OFFSET_TABLE ;
10861122}
10871123
10881124
1089- static bool read_skip_to_pixel_data ( DcmError * * error ,
1090- DcmFilehandle * filehandle )
1091-
1125+ static bool
1126+ read_extended_offsets ( DcmError * * error ,
1127+ DcmFilehandle * filehandle )
10921128{
10931129 static DcmParse parse = {
1094- .stop = parse_skip_to_pixel_data ,
1130+ .element_create = parse_extended_offsets_element_create ,
1131+ .stop = parse_extended_offsets_stop ,
10951132 };
10961133
10971134 if (!dcm_parse_dataset (error ,
@@ -1110,6 +1147,13 @@ bool dcm_filehandle_prepare_read_frame(DcmError **error,
11101147 DcmFilehandle * filehandle )
11111148{
11121149 if (filehandle -> offset_table == NULL ) {
1150+ filehandle -> offset_table = DCM_NEW_ARRAY (error ,
1151+ filehandle -> num_frames ,
1152+ int64_t );
1153+ if (filehandle -> offset_table == NULL ) {
1154+ return false;
1155+ }
1156+
11131157 // move to the first of our stop tags
11141158 if (dcm_filehandle_get_metadata_subset (error , filehandle ) == NULL ) {
11151159 return false;
@@ -1122,24 +1166,49 @@ bool dcm_filehandle_prepare_read_frame(DcmError **error,
11221166 return false;
11231167 }
11241168
1125- // we may have previously stopped for many reasons ... skip ahead to per
1126- // frame functional group, or pixel data
1127- if (!read_skip_to_index (error , filehandle )) {
1169+ // skip ahead to per frame functional group, if present, and read it
1170+ uint32_t skip_to_per_frame [] = {
1171+ TAG_PER_FRAME_FUNCTIONAL_GROUP_SEQUENCE ,
1172+ TAG_EXTENDED_OFFSET_TABLE ,
1173+ TAG_PIXEL_DATA ,
1174+ TAG_FLOAT_PIXEL_DATA ,
1175+ TAG_DOUBLE_PIXEL_DATA ,
1176+ 0
1177+ };
1178+ if (!read_skip_to (error , filehandle , skip_to_per_frame )) {
11281179 return false;
11291180 }
1130-
1131- // if we're on per frame func, read that in
11321181 if (filehandle -> last_tag == TAG_PER_FRAME_FUNCTIONAL_GROUP_SEQUENCE &&
11331182 !read_frame_index (error , filehandle )) {
11341183 return false;
11351184 }
11361185
1137- // now skip over things like extended offset table
1138- if (!read_skip_to_pixel_data (error , filehandle )) {
1186+ // skip ahead to extended offset table, if present
1187+ uint32_t skip_to_offset [] = {
1188+ TAG_EXTENDED_OFFSET_TABLE ,
1189+ TAG_PIXEL_DATA ,
1190+ TAG_FLOAT_PIXEL_DATA ,
1191+ TAG_DOUBLE_PIXEL_DATA ,
1192+ 0
1193+ };
1194+ if (!read_skip_to (error , filehandle , skip_to_offset )) {
1195+ return false;
1196+ }
1197+ if (filehandle -> last_tag == TAG_EXTENDED_OFFSET_TABLE &&
1198+ !read_extended_offsets (error , filehandle )) {
11391199 return false;
11401200 }
11411201
1142- // and we must now be on pixel data
1202+ // skip to pixel data
1203+ uint32_t skip_to_pixel_data [] = {
1204+ TAG_PIXEL_DATA ,
1205+ TAG_FLOAT_PIXEL_DATA ,
1206+ TAG_DOUBLE_PIXEL_DATA ,
1207+ 0
1208+ };
1209+ if (!read_skip_to (error , filehandle , skip_to_pixel_data )) {
1210+ return false;
1211+ }
11431212 if (filehandle -> last_tag != TAG_PIXEL_DATA &&
11441213 filehandle -> last_tag != TAG_FLOAT_PIXEL_DATA &&
11451214 filehandle -> last_tag != TAG_DOUBLE_PIXEL_DATA ) {
@@ -1153,37 +1222,32 @@ bool dcm_filehandle_prepare_read_frame(DcmError **error,
11531222 return false;
11541223 }
11551224
1156- // read the BOT, or build it
1157- dcm_log_debug ("Reading PixelData." );
1158- filehandle -> offset_table = DCM_NEW_ARRAY (error ,
1159- filehandle -> num_frames ,
1160- int64_t );
1161- if (filehandle -> offset_table == NULL ) {
1162- return false;
1163- }
1164-
1165- const char * syntax = dcm_filehandle_get_transfer_syntax_uid (filehandle );
1166- if (dcm_is_encapsulated_transfer_syntax (syntax )) {
1167- // read the bot if available, otherwise parse pixeldata to find
1168- // offsets
1169- if (!dcm_parse_pixeldata_offsets (error ,
1170- filehandle -> io ,
1171- filehandle -> implicit ,
1172- & filehandle -> first_frame_offset ,
1173- filehandle -> offset_table ,
1174- filehandle -> num_frames )) {
1175- return false;
1176- }
1177- } else {
1178- for (uint32_t i = 0 ; i < filehandle -> num_frames ; i ++ ) {
1179- filehandle -> offset_table [i ] = i *
1180- filehandle -> desc .rows *
1181- filehandle -> desc .columns *
1182- filehandle -> desc .samples_per_pixel ;
1225+ // if there was no ext offset table, we must read the basic one, or
1226+ // create it
1227+ if (!filehandle -> have_extended_offset_table ) {
1228+ const char * syntax =
1229+ dcm_filehandle_get_transfer_syntax_uid (filehandle );
1230+ if (dcm_is_encapsulated_transfer_syntax (syntax )) {
1231+ // read the bot if available, otherwise parse pixeldata to find
1232+ // offsets
1233+ if (!dcm_parse_pixeldata_offsets (error ,
1234+ filehandle -> io ,
1235+ filehandle -> implicit ,
1236+ & filehandle -> first_frame_offset ,
1237+ filehandle -> offset_table ,
1238+ filehandle -> num_frames )) {
1239+ return false;
1240+ }
1241+ } else {
1242+ for (uint32_t i = 0 ; i < filehandle -> num_frames ; i ++ ) {
1243+ filehandle -> offset_table [i ] = i *
1244+ filehandle -> desc .rows *
1245+ filehandle -> desc .columns *
1246+ filehandle -> desc .samples_per_pixel ;
1247+ }
1248+
1249+ filehandle -> first_frame_offset = 12 ;
11831250 }
1184-
1185- // Header of Pixel Data Element
1186- filehandle -> first_frame_offset = 12 ;
11871251 }
11881252 } else {
11891253 // always position at pixel_data
0 commit comments