@@ -52,6 +52,7 @@ struct _DcmFilehandle {
5252 uint32_t frame_width ;
5353 uint32_t frame_height ;
5454 uint32_t num_frames ;
55+ uint32_t frame_offset ;
5556 struct PixelDescription desc ;
5657 DcmLayout layout ;
5758
@@ -313,6 +314,24 @@ static bool get_num_frames(DcmError **error,
313314}
314315
315316
317+ static bool get_frame_offset (DcmError * * error ,
318+ const DcmDataSet * metadata ,
319+ uint32_t * frame_offset )
320+ {
321+ // optional, defaults to 0
322+ int64_t value ;
323+ if (!get_tag_int (error ,
324+ metadata , "ConcatenationFrameOffsetNumber" , & value )) {
325+ value = 0 ;
326+ }
327+
328+ // it's a uint32 in the DICOM file
329+ * frame_offset = (uint32_t ) value ;
330+
331+ return true;
332+ }
333+
334+
316335static bool get_frame_size (DcmError * * error ,
317336 const DcmDataSet * metadata ,
318337 uint32_t * frame_width ,
@@ -868,6 +887,7 @@ const DcmDataSet *dcm_filehandle_get_metadata_subset(DcmError **error,
868887 & filehandle -> frame_width ,
869888 & filehandle -> frame_height ) ||
870889 !get_num_frames (error , meta , & filehandle -> num_frames ) ||
890+ !get_frame_offset (error , meta , & filehandle -> frame_offset ) ||
871891 !get_tiles (error , meta ,
872892 & filehandle -> tiles_across , & filehandle -> tiles_down ) ||
873893 !set_pixel_description (error , meta , & filehandle -> desc )) {
@@ -1345,15 +1365,16 @@ DcmFrame *dcm_filehandle_read_frame(DcmError **error,
13451365}
13461366
13471367
1348- DcmFrame * dcm_filehandle_read_frame_position (DcmError * * error ,
1349- DcmFilehandle * filehandle ,
1350- uint32_t column ,
1351- uint32_t row )
1368+ bool dcm_filehandle_get_frame_number (DcmError * * error ,
1369+ DcmFilehandle * filehandle ,
1370+ uint32_t column ,
1371+ uint32_t row ,
1372+ uint32_t * frame_number )
13521373{
1353- dcm_log_debug ("Read frame position (%u, %u)" , column , row );
1374+ dcm_log_debug ("Get frame number at (%u, %u)" , column , row );
13541375
13551376 if (!dcm_filehandle_prepare_read_frame (error , filehandle )) {
1356- return NULL ;
1377+ return false ;
13571378 }
13581379
13591380 if (column >= filehandle -> tiles_across ||
@@ -1363,22 +1384,51 @@ DcmFrame *dcm_filehandle_read_frame_position(DcmError **error,
13631384 "column and Row must be less than %u, %u" ,
13641385 filehandle -> tiles_across ,
13651386 filehandle -> tiles_down );
1366- return NULL ;
1387+ return false ;
13671388 }
13681389
1369- uint32_t index = column + row * filehandle -> tiles_across ;
1390+ int64_t index = column + row * filehandle -> tiles_across ;
13701391 if (filehandle -> layout == DCM_LAYOUT_SPARSE ) {
13711392 index = filehandle -> frame_index [index ];
13721393 if (index == 0xffffffff ) {
13731394 dcm_error_set (error , DCM_ERROR_CODE_MISSING_FRAME ,
13741395 "no frame" ,
13751396 "no frame at position (%u, %u)" , column , row );
1376- return NULL ;
1397+ return false;
1398+ }
1399+ } else {
1400+ // subtract the start of this file, for catenation support
1401+ index -= filehandle -> frame_offset ;
1402+ if (index < 0 || index >= (int64_t ) filehandle -> num_frames ) {
1403+ dcm_error_set (error , DCM_ERROR_CODE_MISSING_FRAME ,
1404+ "no frame" ,
1405+ "no frame at position (%u, %u)" , column , row );
1406+ return false;
13771407 }
13781408 }
13791409
1380- // read_frame() numbers from 1
1381- return dcm_filehandle_read_frame (error , filehandle , index + 1 );
1410+ // frame numbers are from 1, and are always uint32
1411+ if (frame_number )
1412+ * frame_number = (uint32_t ) (index + 1 );
1413+
1414+ return true;
1415+ }
1416+
1417+
1418+ DcmFrame * dcm_filehandle_read_frame_position (DcmError * * error ,
1419+ DcmFilehandle * filehandle ,
1420+ uint32_t column ,
1421+ uint32_t row )
1422+ {
1423+ dcm_log_debug ("Read frame position (%u, %u)" , column , row );
1424+
1425+ uint32_t frame_number ;
1426+ if (!dcm_filehandle_get_frame_number (error ,
1427+ filehandle , column , row , & frame_number )) {
1428+ return NULL ;
1429+ }
1430+
1431+ return dcm_filehandle_read_frame (error , filehandle , frame_number );
13821432}
13831433
13841434
0 commit comments