For those who work with Dicom Files, you may encounter a Dicom file containing video data (mpeg-2, mpeg-4, hevc). In order to extract the video data and save as Media File, the following info may be useful:
- Video is encapsulated data in pixel tag (7fe0,0010)
- All data is in 1 frame
- Basic offset table is empty (8 bytes)
- In frame, first 4 bytes contain frame content length as Cardinal (this is the size of the video data)
So, to extract video data:
- Get TDicomReadContext.ImagePos
- Content length is Cardinal at ImagePos + 12 (skip 8 bytes of Basic Offset Table and 4 bytes for sequence tag (FFFE,E000).
- Video Data Starts at ImagePos + 16 (after content length)
Code below to get you started. Refer also to https://stackoverflow.com/questions/20880303/dicom-undefined-tag-length-pixels#:~:text=%22If%20the%20Value%20Field%20has,end%20of%20the%20Value%20Field.%20%22.
Regards, Ronald
procedure SaveDicomVideoToFile(ADicomFile, AMediaFile: string);
var
Ms: TMemoryStream;
p,n: Cardinal;
begin
Ms := TMemoryStream.Create;
with Ms do
try
LoadFromFile(ADicomFile);
p := GetVideoDataOffset(Ms); <- ImagePos + 16
n := GetVideoDataLength(Ms); <- ImagePos + 12
Position := p;
with TMemoryStream.Create do
try
CopyFrom(Ms, n);
SaveToFile(AMediaFile);
finally
Free;
end;
finally
Free;
end;
end;
//------------------------------------------------------------------------------------------------//
//
//------------------------------------------------------------------------------------------------//
function GetVideoDataOffset(AStream: TStream): Cardinal;
var
Pr: TProgressRec;
b: Boolean;
begin
Pr := NullProgressRec(b, False);
with TImageEnIO.Create(nil) do
try
AStream.Position := 0;
with TDicomReadContext.Create(AStream, Pr) do
try
ReadHeader;
ReadTags(Params);
Result := ImagePos + 16;
finally
Free;
end;
finally
Free;
end;
end;