diff mbox

[FFmpeg-devel] Add DICOM Support

Message ID 79072192-5b9d-5255-255f-24e289e0efb7@iitk.ac.in
State New
Headers show

Commit Message

Shivam Goyal June 24, 2019, 3:48 p.m. UTC
Hi!

     The code is to add DICOM Support. The patch is only for 
uncompressed dicom files using explicit value representation. I would 
extend it, once i clarify some doubts.     As dicom image files contain 
lots of metadata about the patient. So, should i display that data while 
demuxing or should i ignore and only demux the image data ?. In the 
current patch, i have made an option "-metadata", which when used will 
print the data on the terminal while demuxing.


Also, in the dicomdict.c ( which is only required for implicit dicom 
files, and for metadata), till now i have only specified ~200 data 
elements. but the dicom specification, specifies a total of ~4000 data 
elements (would do binary search if all the tags are needed ). So, is 
there a better way to specifiy that data?. (I mean if we ignore the 
metadata about the patient, then we only need to specify ~150 data 
elements for image data).


I have uploaded some samples of dicom files with explicit value 
representation here (in case needed).

https://drive.google.com/drive/folders/1V8HUNeX3EYiPLj_dcFt8C68tAh7C7v4X?usp=sharing


Please comment,

Thank you ,

Shivam Goyal

Comments

Michael Niedermayer June 24, 2019, 8:42 p.m. UTC | #1
On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
> Hi!
> 
>     The code is to add DICOM Support. The patch is only for uncompressed
> dicom files using explicit value representation. I would extend it, once i
> clarify some doubts.     As dicom image files contain lots of metadata about
> the patient. So, should i display that data while demuxing or should i
> ignore and only demux the image data ?. In the current patch, i have made an
> option "-metadata", which when used will print the data on the terminal
> while demuxing.

metadata should be exported to be usable by applications.

For teh API design a one test is that it should be possible to have a
dicom file as input and a format with similar features as output and not 
loose any significant data.
Printing to the terminal cannot achieve that easily.

Either way i would suggest to support only a subset of these 4000 elements
for now but try to ensure that the deisgn can handle most of the important
elements


> 
> 
> Also, in the dicomdict.c ( which is only required for implicit dicom files,
> and for metadata), till now i have only specified ~200 data elements. but
> the dicom specification, specifies a total of ~4000 data elements (would do
> binary search if all the tags are needed ). So, is there a better way to
> specifiy that data?. (I mean if we ignore the metadata about the patient,
> then we only need to specify ~150 data elements for image data).
> 
> 
> I have uploaded some samples of dicom files with explicit value
> representation here (in case needed).
> 
> https://drive.google.com/drive/folders/1V8HUNeX3EYiPLj_dcFt8C68tAh7C7v4X?usp=sharing
> 
> 
> Please comment,

breaks fate tests

make: *** [fate-codec_desc] Error 1
make: *** [fate-source] Error 1


Thanks

[...]
Shivam Goyal June 25, 2019, 8:22 a.m. UTC | #2
On 6/25/19 2:12 AM, Michael Niedermayer wrote:
> On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
>> Hi!
>>
>>      The code is to add DICOM Support. The patch is only for uncompressed
>> dicom files using explicit value representation. I would extend it, once i
>> clarify some doubts.     As dicom image files contain lots of metadata about
>> the patient. So, should i display that data while demuxing or should i
>> ignore and only demux the image data ?. In the current patch, i have made an
>> option "-metadata", which when used will print the data on the terminal
>> while demuxing.
> metadata should be exported to be usable by applications.
>
> For teh API design a one test is that it should be possible to have a
> dicom file as input and a format with similar features as output and not
> loose any significant data.
> Printing to the terminal cannot achieve that easily.

So, should i export it to a csv file ?

> Either way i would suggest to support only a subset of these 4000 elements
> for now but try to ensure that the deisgn can handle most of the important
> elements

Okay , for now i would add only important tags (including all the image 
and pixel data group tags and some about the patient info) to the 
dictionary. and the demuxer would skip unknown tags.

>
>>
>> Also, in the dicomdict.c ( which is only required for implicit dicom files,
>> and for metadata), till now i have only specified ~200 data elements. but
>> the dicom specification, specifies a total of ~4000 data elements (would do
>> binary search if all the tags are needed ). So, is there a better way to
>> specifiy that data?. (I mean if we ignore the metadata about the patient,
>> then we only need to specify ~150 data elements for image data).
>>
>>
>> I have uploaded some samples of dicom files with explicit value
>> representation here (in case needed).
>>
>> https://drive.google.com/drive/folders/1V8HUNeX3EYiPLj_dcFt8C68tAh7C7v4X?usp=sharing
>>
>>
>> Please comment,

Thank you,

Shivam Goyal
Michael Niedermayer June 26, 2019, 7:50 a.m. UTC | #3
On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
> 
> On 6/25/19 2:12 AM, Michael Niedermayer wrote:
> >On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
> >>Hi!
> >>
> >>     The code is to add DICOM Support. The patch is only for uncompressed
> >>dicom files using explicit value representation. I would extend it, once i
> >>clarify some doubts.     As dicom image files contain lots of metadata about
> >>the patient. So, should i display that data while demuxing or should i
> >>ignore and only demux the image data ?. In the current patch, i have made an
> >>option "-metadata", which when used will print the data on the terminal
> >>while demuxing.
> >metadata should be exported to be usable by applications.
> >
> >For teh API design a one test is that it should be possible to have a
> >dicom file as input and a format with similar features as output and not
> >loose any significant data.
> >Printing to the terminal cannot achieve that easily.
> 
> So, should i export it to a csv file ?

does it fit into the metadata system we have ?

thx

[...]
Paul B Mahol June 26, 2019, 7:54 a.m. UTC | #4
On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
> On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
>>
>> On 6/25/19 2:12 AM, Michael Niedermayer wrote:
>> >On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
>> >>Hi!
>> >>
>> >>     The code is to add DICOM Support. The patch is only for
>> >> uncompressed
>> >>dicom files using explicit value representation. I would extend it, once
>> >> i
>> >>clarify some doubts.     As dicom image files contain lots of metadata
>> >> about
>> >>the patient. So, should i display that data while demuxing or should i
>> >>ignore and only demux the image data ?. In the current patch, i have
>> >> made an
>> >>option "-metadata", which when used will print the data on the terminal
>> >>while demuxing.
>> >metadata should be exported to be usable by applications.
>> >
>> >For teh API design a one test is that it should be possible to have a
>> >dicom file as input and a format with similar features as output and not
>> >loose any significant data.
>> >Printing to the terminal cannot achieve that easily.
>>
>> So, should i export it to a csv file ?
>
> does it fit into the metadata system we have ?
>

To clarify, you mean frame metadata system?
Michael Niedermayer June 26, 2019, 11:07 a.m. UTC | #5
On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
> On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
> > On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
> >>
> >> On 6/25/19 2:12 AM, Michael Niedermayer wrote:
> >> >On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
> >> >>Hi!
> >> >>
> >> >>     The code is to add DICOM Support. The patch is only for
> >> >> uncompressed
> >> >>dicom files using explicit value representation. I would extend it, once
> >> >> i
> >> >>clarify some doubts.     As dicom image files contain lots of metadata
> >> >> about
> >> >>the patient. So, should i display that data while demuxing or should i
> >> >>ignore and only demux the image data ?. In the current patch, i have
> >> >> made an
> >> >>option "-metadata", which when used will print the data on the terminal
> >> >>while demuxing.
> >> >metadata should be exported to be usable by applications.
> >> >
> >> >For teh API design a one test is that it should be possible to have a
> >> >dicom file as input and a format with similar features as output and not
> >> >loose any significant data.
> >> >Printing to the terminal cannot achieve that easily.
> >>
> >> So, should i export it to a csv file ?
> >
> > does it fit into the metadata system we have ?
> >
> 
> To clarify, you mean frame metadata system?

data that is specific to a frame would belong in the frame metadata
data that is specific to a stream would belong into that streams metadata
data that is specific to the container would belong to its metadata

iam not sure if multiple streams or frames can be in a single dicom
"container" / file. If they can then it should be clear what goes where
if not then all 3 options would from the point of view of dicom be the
same. And in that case what is most convenient for interoperation with
other formats should be picked. That is lets introduce the least amount
of differences to how similar data is handled in other formats


[...]
Shivam Goyal June 26, 2019, 6:03 p.m. UTC | #6
On 6/26/19 4:37 PM, Michael Niedermayer wrote:
> On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
>> On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
>>> On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
>>>> On 6/25/19 2:12 AM, Michael Niedermayer wrote:
>>>>> On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
>>>>>> Hi!
>>>>>>
>>>>>>      The code is to add DICOM Support. The patch is only for
>>>>>> uncompressed
>>>>>> dicom files using explicit value representation. I would extend it, once
>>>>>> i
>>>>>> clarify some doubts.     As dicom image files contain lots of metadata
>>>>>> about
>>>>>> the patient. So, should i display that data while demuxing or should i
>>>>>> ignore and only demux the image data ?. In the current patch, i have
>>>>>> made an
>>>>>> option "-metadata", which when used will print the data on the terminal
>>>>>> while demuxing.
>>>>> metadata should be exported to be usable by applications.
>>>>>
>>>>> For teh API design a one test is that it should be possible to have a
>>>>> dicom file as input and a format with similar features as output and not
>>>>> loose any significant data.
>>>>> Printing to the terminal cannot achieve that easily.
>>>> So, should i export it to a csv file ?
>>> does it fit into the metadata system we have ?
>>>
>> To clarify, you mean frame metadata system?
> data that is specific to a frame would belong in the frame metadata
> data that is specific to a stream would belong into that streams metadata
> data that is specific to the container would belong to its metadata
>
> iam not sure if multiple streams or frames can be in a single dicom
> "container" / file. If they can then it should be clear what goes where
> if not then all 3 options would from the point of view of dicom be the
> same. And in that case what is most convenient for interoperation with
> other formats should be picked. That is lets introduce the least amount
> of differences to how similar data is handled in other formats

Dicom files contain multiple frames, but number of streams is always one 
(video) like GIF,( I haven't done multiframe support yet i am working on 
it ), The data specific to image/frames/pixels can be fit in the three 
categories of our metadata system, but their is extradata in DICOM files 
like : patient_name, medical_device_name , medical_procedure_done, 
study_date....

i have downloaded many samples from internet, the average number of 
these extra tags in a file is ~80

so, should i skip this data while demuxing or to extract it from the 
file format and do something with it.

also a complete list of DICOM tags is here:

https://www.dicomlibrary.com/dicom/dicom-tags/

https://dicom.innolitics.com/ciods/


Thank You

Shivam Goyal


>
>
> [...]
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Michael Niedermayer June 27, 2019, 3:51 p.m. UTC | #7
On Wed, Jun 26, 2019 at 11:33:05PM +0530, Shivam wrote:
> 
> On 6/26/19 4:37 PM, Michael Niedermayer wrote:
> >On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
> >>On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
> >>>On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
> >>>>On 6/25/19 2:12 AM, Michael Niedermayer wrote:
> >>>>>On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
> >>>>>>Hi!
> >>>>>>
> >>>>>>     The code is to add DICOM Support. The patch is only for
> >>>>>>uncompressed
> >>>>>>dicom files using explicit value representation. I would extend it, once
> >>>>>>i
> >>>>>>clarify some doubts.     As dicom image files contain lots of metadata
> >>>>>>about
> >>>>>>the patient. So, should i display that data while demuxing or should i
> >>>>>>ignore and only demux the image data ?. In the current patch, i have
> >>>>>>made an
> >>>>>>option "-metadata", which when used will print the data on the terminal
> >>>>>>while demuxing.
> >>>>>metadata should be exported to be usable by applications.
> >>>>>
> >>>>>For teh API design a one test is that it should be possible to have a
> >>>>>dicom file as input and a format with similar features as output and not
> >>>>>loose any significant data.
> >>>>>Printing to the terminal cannot achieve that easily.
> >>>>So, should i export it to a csv file ?
> >>>does it fit into the metadata system we have ?
> >>>
> >>To clarify, you mean frame metadata system?
> >data that is specific to a frame would belong in the frame metadata
> >data that is specific to a stream would belong into that streams metadata
> >data that is specific to the container would belong to its metadata
> >
> >iam not sure if multiple streams or frames can be in a single dicom
> >"container" / file. If they can then it should be clear what goes where
> >if not then all 3 options would from the point of view of dicom be the
> >same. And in that case what is most convenient for interoperation with
> >other formats should be picked. That is lets introduce the least amount
> >of differences to how similar data is handled in other formats
> 
> Dicom files contain multiple frames, but number of streams is always one
> (video) like GIF,( I haven't done multiframe support yet i am working on it
> ), The data specific to image/frames/pixels can be fit in the three
> categories of our metadata system, 

> but their is extradata in DICOM files
> like : patient_name, medical_device_name , medical_procedure_done,
> study_date....

why could this not be fit in metadata ?

thx

[...]
Shivam Goyal June 28, 2019, 8:32 a.m. UTC | #8
On 6/27/19 9:21 PM, Michael Niedermayer wrote:
> On Wed, Jun 26, 2019 at 11:33:05PM +0530, Shivam wrote:
>> On 6/26/19 4:37 PM, Michael Niedermayer wrote:
>>> On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
>>>> On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
>>>>> On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
>>>>>> On 6/25/19 2:12 AM, Michael Niedermayer wrote:
>>>>>>> On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
>>>>>>>> Hi!
>>>>>>>>
>>>>>>>>      The code is to add DICOM Support. The patch is only for
>>>>>>>> uncompressed
>>>>>>>> dicom files using explicit value representation. I would extend it, once
>>>>>>>> i
>>>>>>>> clarify some doubts.     As dicom image files contain lots of metadata
>>>>>>>> about
>>>>>>>> the patient. So, should i display that data while demuxing or should i
>>>>>>>> ignore and only demux the image data ?. In the current patch, i have
>>>>>>>> made an
>>>>>>>> option "-metadata", which when used will print the data on the terminal
>>>>>>>> while demuxing.
>>>>>>> metadata should be exported to be usable by applications.
>>>>>>>
>>>>>>> For teh API design a one test is that it should be possible to have a
>>>>>>> dicom file as input and a format with similar features as output and not
>>>>>>> loose any significant data.
>>>>>>> Printing to the terminal cannot achieve that easily.
>>>>>> So, should i export it to a csv file ?
>>>>> does it fit into the metadata system we have ?
>>>>>
>>>> To clarify, you mean frame metadata system?
>>> data that is specific to a frame would belong in the frame metadata
>>> data that is specific to a stream would belong into that streams metadata
>>> data that is specific to the container would belong to its metadata
>>>
>>> iam not sure if multiple streams or frames can be in a single dicom
>>> "container" / file. If they can then it should be clear what goes where
>>> if not then all 3 options would from the point of view of dicom be the
>>> same. And in that case what is most convenient for interoperation with
>>> other formats should be picked. That is lets introduce the least amount
>>> of differences to how similar data is handled in other formats
>> Dicom files contain multiple frames, but number of streams is always one
>> (video) like GIF,( I haven't done multiframe support yet i am working on it
>> ), The data specific to image/frames/pixels can be fit in the three
>> categories of our metadata system,
>> but their is extradata in DICOM files
>> like : patient_name, medical_device_name , medical_procedure_done,
>> study_date....
> why could this not be fit in metadata ?

Yeah this can fit in the key, value pair of our AVDictionaryEntry (and 
can be written with "-f ffmetadata"). So, should i assign this to 
streams metadata or containers metadata as this data is not stream 
specific or container specific ?.


Thank you,

Shivam Goyal
Michael Niedermayer June 28, 2019, 10:05 p.m. UTC | #9
On Fri, Jun 28, 2019 at 02:02:29PM +0530, Shivam wrote:
> 
> On 6/27/19 9:21 PM, Michael Niedermayer wrote:
> >On Wed, Jun 26, 2019 at 11:33:05PM +0530, Shivam wrote:
> >>On 6/26/19 4:37 PM, Michael Niedermayer wrote:
> >>>On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
> >>>>On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
> >>>>>On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
> >>>>>>On 6/25/19 2:12 AM, Michael Niedermayer wrote:
> >>>>>>>On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
> >>>>>>>>Hi!
> >>>>>>>>
> >>>>>>>>     The code is to add DICOM Support. The patch is only for
> >>>>>>>>uncompressed
> >>>>>>>>dicom files using explicit value representation. I would extend it, once
> >>>>>>>>i
> >>>>>>>>clarify some doubts.     As dicom image files contain lots of metadata
> >>>>>>>>about
> >>>>>>>>the patient. So, should i display that data while demuxing or should i
> >>>>>>>>ignore and only demux the image data ?. In the current patch, i have
> >>>>>>>>made an
> >>>>>>>>option "-metadata", which when used will print the data on the terminal
> >>>>>>>>while demuxing.
> >>>>>>>metadata should be exported to be usable by applications.
> >>>>>>>
> >>>>>>>For teh API design a one test is that it should be possible to have a
> >>>>>>>dicom file as input and a format with similar features as output and not
> >>>>>>>loose any significant data.
> >>>>>>>Printing to the terminal cannot achieve that easily.
> >>>>>>So, should i export it to a csv file ?
> >>>>>does it fit into the metadata system we have ?
> >>>>>
> >>>>To clarify, you mean frame metadata system?
> >>>data that is specific to a frame would belong in the frame metadata
> >>>data that is specific to a stream would belong into that streams metadata
> >>>data that is specific to the container would belong to its metadata
> >>>
> >>>iam not sure if multiple streams or frames can be in a single dicom
> >>>"container" / file. If they can then it should be clear what goes where
> >>>if not then all 3 options would from the point of view of dicom be the
> >>>same. And in that case what is most convenient for interoperation with
> >>>other formats should be picked. That is lets introduce the least amount
> >>>of differences to how similar data is handled in other formats
> >>Dicom files contain multiple frames, but number of streams is always one
> >>(video) like GIF,( I haven't done multiframe support yet i am working on it
> >>), The data specific to image/frames/pixels can be fit in the three
> >>categories of our metadata system,
> >>but their is extradata in DICOM files
> >>like : patient_name, medical_device_name , medical_procedure_done,
> >>study_date....
> >why could this not be fit in metadata ?
> 
> Yeah this can fit in the key, value pair of our AVDictionaryEntry (and can
> be written with "-f ffmetadata"). So, should i assign this to streams
> metadata or containers metadata as this data is not stream specific or
> container specific ?.

whatever paul preferrs, if he has an oppinion on it. Otherwise choose
what feels better to you.


Thanks

[...]
Paul B Mahol June 28, 2019, 10:09 p.m. UTC | #10
On 6/29/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
> On Fri, Jun 28, 2019 at 02:02:29PM +0530, Shivam wrote:
>>
>> On 6/27/19 9:21 PM, Michael Niedermayer wrote:
>> >On Wed, Jun 26, 2019 at 11:33:05PM +0530, Shivam wrote:
>> >>On 6/26/19 4:37 PM, Michael Niedermayer wrote:
>> >>>On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
>> >>>>On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
>> >>>>>On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
>> >>>>>>On 6/25/19 2:12 AM, Michael Niedermayer wrote:
>> >>>>>>>On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
>> >>>>>>>>Hi!
>> >>>>>>>>
>> >>>>>>>>     The code is to add DICOM Support. The patch is only for
>> >>>>>>>>uncompressed
>> >>>>>>>>dicom files using explicit value representation. I would extend
>> >>>>>>>> it, once
>> >>>>>>>>i
>> >>>>>>>>clarify some doubts.     As dicom image files contain lots of
>> >>>>>>>> metadata
>> >>>>>>>>about
>> >>>>>>>>the patient. So, should i display that data while demuxing or
>> >>>>>>>> should i
>> >>>>>>>>ignore and only demux the image data ?. In the current patch, i
>> >>>>>>>> have
>> >>>>>>>>made an
>> >>>>>>>>option "-metadata", which when used will print the data on the
>> >>>>>>>> terminal
>> >>>>>>>>while demuxing.
>> >>>>>>>metadata should be exported to be usable by applications.
>> >>>>>>>
>> >>>>>>>For teh API design a one test is that it should be possible to have
>> >>>>>>> a
>> >>>>>>>dicom file as input and a format with similar features as output
>> >>>>>>> and not
>> >>>>>>>loose any significant data.
>> >>>>>>>Printing to the terminal cannot achieve that easily.
>> >>>>>>So, should i export it to a csv file ?
>> >>>>>does it fit into the metadata system we have ?
>> >>>>>
>> >>>>To clarify, you mean frame metadata system?
>> >>>data that is specific to a frame would belong in the frame metadata
>> >>>data that is specific to a stream would belong into that streams
>> >>> metadata
>> >>>data that is specific to the container would belong to its metadata
>> >>>
>> >>>iam not sure if multiple streams or frames can be in a single dicom
>> >>>"container" / file. If they can then it should be clear what goes
>> >>> where
>> >>>if not then all 3 options would from the point of view of dicom be the
>> >>>same. And in that case what is most convenient for interoperation with
>> >>>other formats should be picked. That is lets introduce the least
>> >>> amount
>> >>>of differences to how similar data is handled in other formats
>> >>Dicom files contain multiple frames, but number of streams is always
>> >> one
>> >>(video) like GIF,( I haven't done multiframe support yet i am working on
>> >> it
>> >>), The data specific to image/frames/pixels can be fit in the three
>> >>categories of our metadata system,
>> >>but their is extradata in DICOM files
>> >>like : patient_name, medical_device_name , medical_procedure_done,
>> >>study_date....
>> >why could this not be fit in metadata ?
>>
>> Yeah this can fit in the key, value pair of our AVDictionaryEntry (and
>> can
>> be written with "-f ffmetadata"). So, should i assign this to streams
>> metadata or containers metadata as this data is not stream specific or
>> container specific ?.
>
> whatever paul preferrs, if he has an oppinion on it. Otherwise choose
> what feels better to you.

Depends where is metadata stored, if its on container level, then
obviously as stream metadata, otherwise as frame metadata.

>
>
> Thanks
>
> [...]
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Avoid a single point of failure, be that a person or equipment.
>
Shivam Goyal June 30, 2019, 2:04 p.m. UTC | #11
On 6/29/19 3:35 AM, Michael Niedermayer wrote:
> On Fri, Jun 28, 2019 at 02:02:29PM +0530, Shivam wrote:
>> On 6/27/19 9:21 PM, Michael Niedermayer wrote:
>>> On Wed, Jun 26, 2019 at 11:33:05PM +0530, Shivam wrote:
>>>> On 6/26/19 4:37 PM, Michael Niedermayer wrote:
>>>>> On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
>>>>>> On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
>>>>>>> On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
>>>>>>>> On 6/25/19 2:12 AM, Michael Niedermayer wrote:
>>>>>>>>> On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
>>>>>>>>>> Hi!
>>>>>>>>>>
>>>>>>>>>>      The code is to add DICOM Support. The patch is only for
>>>>>>>>>> uncompressed
>>>>>>>>>> dicom files using explicit value representation. I would extend it, once
>>>>>>>>>> i
>>>>>>>>>> clarify some doubts.     As dicom image files contain lots of metadata
>>>>>>>>>> about
>>>>>>>>>> the patient. So, should i display that data while demuxing or should i
>>>>>>>>>> ignore and only demux the image data ?. In the current patch, i have
>>>>>>>>>> made an
>>>>>>>>>> option "-metadata", which when used will print the data on the terminal
>>>>>>>>>> while demuxing.
>>>>>>>>> metadata should be exported to be usable by applications.
>>>>>>>>>
>>>>>>>>> For teh API design a one test is that it should be possible to have a
>>>>>>>>> dicom file as input and a format with similar features as output and not
>>>>>>>>> loose any significant data.
>>>>>>>>> Printing to the terminal cannot achieve that easily.
>>>>>>>> So, should i export it to a csv file ?
>>>>>>> does it fit into the metadata system we have ?
>>>>>>>
>>>>>> To clarify, you mean frame metadata system?
>>>>> data that is specific to a frame would belong in the frame metadata
>>>>> data that is specific to a stream would belong into that streams metadata
>>>>> data that is specific to the container would belong to its metadata
>>>>>
>>>>> iam not sure if multiple streams or frames can be in a single dicom
>>>>> "container" / file. If they can then it should be clear what goes where
>>>>> if not then all 3 options would from the point of view of dicom be the
>>>>> same. And in that case what is most convenient for interoperation with
>>>>> other formats should be picked. That is lets introduce the least amount
>>>>> of differences to how similar data is handled in other formats
>>>> Dicom files contain multiple frames, but number of streams is always one
>>>> (video) like GIF,( I haven't done multiframe support yet i am working on it
>>>> ), The data specific to image/frames/pixels can be fit in the three
>>>> categories of our metadata system,
>>>> but their is extradata in DICOM files
>>>> like : patient_name, medical_device_name , medical_procedure_done,
>>>> study_date....
>>> why could this not be fit in metadata ?
>> Yeah this can fit in the key, value pair of our AVDictionaryEntry (and can
>> be written with "-f ffmetadata"). So, should i assign this to streams
>> metadata or containers metadata as this data is not stream specific or
>> container specific ?.
> whatever paul preferrs, if he has an oppinion on it. Otherwise choose
> what feels better to you.

Ok,

Thank You,

Shivam Goyal
Shivam Goyal June 30, 2019, 2:05 p.m. UTC | #12
On 6/29/19 3:39 AM, Paul B Mahol wrote:
> On 6/29/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
>> On Fri, Jun 28, 2019 at 02:02:29PM +0530, Shivam wrote:
>>> On 6/27/19 9:21 PM, Michael Niedermayer wrote:
>>>> On Wed, Jun 26, 2019 at 11:33:05PM +0530, Shivam wrote:
>>>>> On 6/26/19 4:37 PM, Michael Niedermayer wrote:
>>>>>> On Wed, Jun 26, 2019 at 09:54:56AM +0200, Paul B Mahol wrote:
>>>>>>> On 6/26/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
>>>>>>>> On Tue, Jun 25, 2019 at 01:52:09PM +0530, Shivam wrote:
>>>>>>>>> On 6/25/19 2:12 AM, Michael Niedermayer wrote:
>>>>>>>>>> On Mon, Jun 24, 2019 at 09:18:13PM +0530, Shivam wrote:
>>>>>>>>>>> Hi!
>>>>>>>>>>>
>>>>>>>>>>>      The code is to add DICOM Support. The patch is only for
>>>>>>>>>>> uncompressed
>>>>>>>>>>> dicom files using explicit value representation. I would extend
>>>>>>>>>>> it, once
>>>>>>>>>>> i
>>>>>>>>>>> clarify some doubts.     As dicom image files contain lots of
>>>>>>>>>>> metadata
>>>>>>>>>>> about
>>>>>>>>>>> the patient. So, should i display that data while demuxing or
>>>>>>>>>>> should i
>>>>>>>>>>> ignore and only demux the image data ?. In the current patch, i
>>>>>>>>>>> have
>>>>>>>>>>> made an
>>>>>>>>>>> option "-metadata", which when used will print the data on the
>>>>>>>>>>> terminal
>>>>>>>>>>> while demuxing.
>>>>>>>>>> metadata should be exported to be usable by applications.
>>>>>>>>>>
>>>>>>>>>> For teh API design a one test is that it should be possible to have
>>>>>>>>>> a
>>>>>>>>>> dicom file as input and a format with similar features as output
>>>>>>>>>> and not
>>>>>>>>>> loose any significant data.
>>>>>>>>>> Printing to the terminal cannot achieve that easily.
>>>>>>>>> So, should i export it to a csv file ?
>>>>>>>> does it fit into the metadata system we have ?
>>>>>>>>
>>>>>>> To clarify, you mean frame metadata system?
>>>>>> data that is specific to a frame would belong in the frame metadata
>>>>>> data that is specific to a stream would belong into that streams
>>>>>> metadata
>>>>>> data that is specific to the container would belong to its metadata
>>>>>>
>>>>>> iam not sure if multiple streams or frames can be in a single dicom
>>>>>> "container" / file. If they can then it should be clear what goes
>>>>>> where
>>>>>> if not then all 3 options would from the point of view of dicom be the
>>>>>> same. And in that case what is most convenient for interoperation with
>>>>>> other formats should be picked. That is lets introduce the least
>>>>>> amount
>>>>>> of differences to how similar data is handled in other formats
>>>>> Dicom files contain multiple frames, but number of streams is always
>>>>> one
>>>>> (video) like GIF,( I haven't done multiframe support yet i am working on
>>>>> it
>>>>> ), The data specific to image/frames/pixels can be fit in the three
>>>>> categories of our metadata system,
>>>>> but their is extradata in DICOM files
>>>>> like : patient_name, medical_device_name , medical_procedure_done,
>>>>> study_date....
>>>> why could this not be fit in metadata ?
>>> Yeah this can fit in the key, value pair of our AVDictionaryEntry (and
>>> can
>>> be written with "-f ffmetadata"). So, should i assign this to streams
>>> metadata or containers metadata as this data is not stream specific or
>>> container specific ?.
>> whatever paul preferrs, if he has an oppinion on it. Otherwise choose
>> what feels better to you.
> Depends where is metadata stored, if its on container level, then
> obviously as stream metadata, otherwise as frame metadata.

Ok,

Thank You

Shivam Goyal
diff mbox

Patch

From d394fba8d63c3a81495b42958e9abd42757d2495 Mon Sep 17 00:00:00 2001
From: Shivam Goyal <shivamgoyal1506@outlook.com>
Date: Mon, 24 Jun 2019 21:09:14 +0530
Subject: [PATCH] lavf: Add DICOM demuxer, lavc: Add DICOM decoder

---
 libavcodec/Makefile      |   1 +
 libavcodec/allcodecs.c   |   1 +
 libavcodec/avcodec.h     |   1 +
 libavcodec/codec_desc.c  |   7 +
 libavcodec/dicom.c       |  94 ++++++++++++
 libavformat/Makefile     |   1 +
 libavformat/allformats.c |   1 +
 libavformat/dicom.h      |  83 +++++++++++
 libavformat/dicomdec.c   | 308 +++++++++++++++++++++++++++++++++++++++
 libavformat/dicomdict.c  | 280 +++++++++++++++++++++++++++++++++++
 10 files changed, 777 insertions(+)
 create mode 100644 libavcodec/dicom.c
 create mode 100644 libavformat/dicom.h
 create mode 100644 libavformat/dicomdec.c
 create mode 100644 libavformat/dicomdict.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index edccd73037..87ae3ea048 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -263,6 +263,7 @@  OBJS-$(CONFIG_DCA_DECODER)             += dcadec.o dca.o dcadata.o dcahuff.o \
 OBJS-$(CONFIG_DCA_ENCODER)             += dcaenc.o dca.o dcadata.o dcahuff.o \
                                           dcaadpcm.o
 OBJS-$(CONFIG_DDS_DECODER)             += dds.o
+OBJS-$(CONFIG_DICOM_DECODER)           += dicom.o
 OBJS-$(CONFIG_DIRAC_DECODER)           += diracdec.o dirac.o diracdsp.o diractab.o \
                                           dirac_arith.o dirac_dwt.o dirac_vlc.o
 OBJS-$(CONFIG_DFA_DECODER)             += dfa.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index d2f9a39ce5..59d7b83625 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -83,6 +83,7 @@  extern AVCodec ff_cscd_decoder;
 extern AVCodec ff_cyuv_decoder;
 extern AVCodec ff_dds_decoder;
 extern AVCodec ff_dfa_decoder;
+extern AVCodec ff_dicom_decoder;
 extern AVCodec ff_dirac_decoder;
 extern AVCodec ff_dnxhd_encoder;
 extern AVCodec ff_dnxhd_decoder;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 586bbbca4e..5d5e71cf10 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -410,6 +410,7 @@  enum AVCodecID {
     AV_CODEC_ID_SCREENPRESSO,
     AV_CODEC_ID_RSCC,
     AV_CODEC_ID_AVS2,
+    AV_CODEC_ID_DICOM,
 
     AV_CODEC_ID_Y41P = 0x8000,
     AV_CODEC_ID_AVRP,
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 4d033c20ff..edab71f815 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -1656,6 +1656,13 @@  static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("FITS (Flexible Image Transport System)"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
     },
+    {
+        .id        = AV_CODEC_ID_DICOM,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "dicom",
+        .long_name = NULL_IF_CONFIG_SMALL("DICOM (Digital Imaging and Communications in Medicine)"),
+        .props     = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS,
+    },
     {
         .id        = AV_CODEC_ID_IMM4,
         .type      = AVMEDIA_TYPE_VIDEO,
diff --git a/libavcodec/dicom.c b/libavcodec/dicom.c
new file mode 100644
index 0000000000..226f3fece3
--- /dev/null
+++ b/libavcodec/dicom.c
@@ -0,0 +1,94 @@ 
+/*
+ * DICOM decoder
+ * Copyright (c) 2019 Shivam Goyal
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <inttypes.h>
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "bmp.h"
+#include "internal.h"
+
+
+static void apply_window_level(short * vals, uint8_t *ptr, int window, int level, int bitmask, int size)
+{
+    int i, max, min;
+    short val;
+
+    max = level + window / 2;
+    min = level - window / 2;
+
+    for (i = 0; i < size; i++){
+        val = vals[i];
+
+        if (val > max) {
+            ptr[i] = 255;
+        } else if (val < min) {
+            ptr[i] = 0;
+        } else {
+            ptr[i] = ((val & bitmask) - min) * 255 / (max - min);
+        }
+    }
+    return;
+
+}
+
+static int dicom_decode_frame(AVCodecContext *avctx,
+                            void *data, int *got_frame,
+                            AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+    AVFrame *p         = data;
+    short *vals;
+    int width;
+    int height;
+    uint8_t *ptr;
+    int ret, bitmask, window, level;
+
+    width = avctx->width;
+    height = avctx->height;
+    window = avctx->profile;
+    level = avctx->level;
+    avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
+        return ret;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
+
+    vals = (short *) buf;
+    bitmask = (1 << 16) - 1;
+
+    ptr      = p->data[0];
+
+    apply_window_level(vals, ptr, window, level, bitmask, width * height);
+
+    *got_frame = 1;
+    return buf_size;
+}
+
+AVCodec ff_dicom_decoder = {
+    .name           = "dicom",
+    .long_name      = NULL_IF_CONFIG_SMALL("DICOM (Digital Imaging and Communications in Medicine)"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_DICOM,
+    .decode         = dicom_decode_frame,
+    .capabilities   = AV_CODEC_CAP_DR1,
+};
diff --git a/libavformat/Makefile b/libavformat/Makefile
index a434b005a4..58ba6a4c36 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -150,6 +150,7 @@  OBJS-$(CONFIG_DAUD_MUXER)                += daudenc.o
 OBJS-$(CONFIG_DCSTR_DEMUXER)             += dcstr.o
 OBJS-$(CONFIG_DFA_DEMUXER)               += dfa.o
 OBJS-$(CONFIG_DHAV_DEMUXER)              += dhav.o
+OBJS-$(CONFIG_DICOM_DEMUXER)             += dicomdec.o dicomdict.o
 OBJS-$(CONFIG_DIRAC_DEMUXER)             += diracdec.o rawdec.o
 OBJS-$(CONFIG_DIRAC_MUXER)               += rawenc.o
 OBJS-$(CONFIG_DNXHD_DEMUXER)             += dnxhddec.o rawdec.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index cd00834807..c5120ef1df 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -111,6 +111,7 @@  extern AVOutputFormat ff_daud_muxer;
 extern AVInputFormat  ff_dcstr_demuxer;
 extern AVInputFormat  ff_dfa_demuxer;
 extern AVInputFormat  ff_dhav_demuxer;
+extern AVInputFormat  ff_dicom_demuxer;
 extern AVInputFormat  ff_dirac_demuxer;
 extern AVOutputFormat ff_dirac_muxer;
 extern AVInputFormat  ff_dnxhd_demuxer;
diff --git a/libavformat/dicom.h b/libavformat/dicom.h
new file mode 100644
index 0000000000..51ad99b2e8
--- /dev/null
+++ b/libavformat/dicom.h
@@ -0,0 +1,83 @@ 
+/*
+ * DICOM demuxer
+ *
+ * Copyright (c) 2019 Shivam Goyal
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#define DICOM_PREAMBLE_SIZE 128
+#define DICOM_PREFIX_SIZE 4
+
+#define IMAGE_GR_NB 0x0028
+#define PIXEL_GR_NB 0x7FE0
+#define PIXELDATA_EL_NB 0x0010
+#define TRANSFER_SYNTEX_UID_GR_NB 0x0002
+#define TRANSFER_SYNTEX_UID_EL_NB 0x0010
+#define DEFAULT_WINDOW 1100
+#define DEFAULT_LEVEL 125
+
+typedef enum {
+    AE = 0x4145,
+    AS = 0x4153,
+    AT = 0x4154,
+    CS = 0x4353,
+    DA = 0x4441,
+    DS = 0x4453,
+    DT = 0x4454,
+    FD = 0x4644,
+    FL = 0x464c,
+    IS = 0x4953,
+    LO = 0x4c4f,
+    LT = 0x4c54,
+    OB = 0x4f42,
+    OD = 0x4f44,
+    OF = 0x4f46,
+    OL = 0x4f4c,
+    OV = 0x4f56,
+    OW = 0x4f57,
+    PN = 0x504e,
+    SH = 0x5348,
+    SL = 0x534c,
+    SQ = 0x5351,
+    SS = 0x5353,
+    ST = 0x5354,
+    SV = 0x5356,
+    TM = 0x544d,
+    UC = 0x5543,
+    UI = 0x5549,
+    UL = 0x554c,
+    UN = 0x554e,
+    UR = 0x5552,
+    US = 0x5553,
+    UT = 0x5554,
+    UV = 0x5556
+} ValueRepresentation;
+
+
+typedef struct DataElement{
+    uint16_t GroupNumber;
+    uint16_t ElementNumber;
+    ValueRepresentation VR;
+    uint32_t VL;
+    void* bytes;
+    int index;  // Index in dicom dictionary
+    char* desc;
+} DataElement;
+
+int dicom_dict_find_elem_info (DataElement *de);
diff --git a/libavformat/dicomdec.c b/libavformat/dicomdec.c
new file mode 100644
index 0000000000..9ab560c2b1
--- /dev/null
+++ b/libavformat/dicomdec.c
@@ -0,0 +1,308 @@ 
+/*
+ * DICOM demuxer
+ *
+ * Copyright (c) 2019 Shivam Goyal
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
+#include "libavutil/opt.h"
+#include "libavutil/bprint.h"
+#include "avformat.h"
+#include "internal.h"
+#include "dicom.h"
+
+
+typedef struct DICOMContext {
+    const AVClass *class; ///< Class for private options.
+    int big_endian;
+
+    uint64_t nb_frames;
+    uint16_t bits_allocated;
+    uint16_t bits_stored;
+    uint16_t high_bit;
+    uint16_t rows;
+    uint16_t columns;
+    uint32_t nb_DEs;
+    int window;
+    int level;
+    int metadata;
+    char *transer_syntext_uid;
+} DICOMContext;
+
+
+static int dicom_probe(const AVProbeData *p)
+{
+    const uint8_t *d = p->buf;
+
+    if (d[DICOM_PREAMBLE_SIZE] == 'D' &&
+        d[DICOM_PREAMBLE_SIZE + 1] == 'I' &&
+        d[DICOM_PREAMBLE_SIZE + 2] == 'C' &&
+        d[DICOM_PREAMBLE_SIZE + 3] == 'M') {
+        return AVPROBE_SCORE_MAX;
+    }
+    return 0;
+}
+
+static int set_imagegroup_data(AVFormatContext *s, AVStream* st, DataElement *de)
+{
+    DICOMContext *dicom = s->priv_data;
+    void *bytes = de->bytes;
+    int len = de->VL;
+    char *cbytes;
+
+    if (de->GroupNumber != IMAGE_GR_NB)
+        return 0;
+
+    switch (de->ElementNumber) {
+        case 0x0010:
+            dicom->rows = *(uint16_t *)bytes;
+            st->codecpar->height = dicom->rows;
+            break;
+        case 0x0011:
+            dicom->columns = *(uint16_t *)bytes;
+            st->codecpar->width = dicom->columns;
+            break;
+        case 0x0100:
+            dicom->bits_allocated = *(uint16_t *)bytes;
+            st->codecpar->bits_per_raw_sample = dicom->bits_allocated;
+            break;
+        case 0x0101:
+            dicom->bits_stored = *(uint16_t *)bytes;
+            st->codecpar->bits_per_coded_sample = dicom->bits_stored;
+            break;
+        case 0x0102:
+            dicom->high_bit = *(uint16_t *)bytes;
+            break;
+        case 0x0008:
+            dicom->nb_frames = *(uint32_t *)bytes;
+            break;
+        case 0x1050:
+            if (dicom->level == -1) {
+                cbytes = av_malloc(len + 1);
+                memcpy(cbytes, bytes, len);
+                cbytes[len] = 0;
+                st->codecpar->level = atoi(cbytes);
+                dicom->level = st->codecpar->level;
+                av_free(cbytes);
+            }
+            break;
+        case 0x1051:
+            if (dicom->window == -1) {
+                cbytes = av_malloc(len + 1);
+                memcpy(cbytes, bytes, len);
+                cbytes[len] = 0;
+                st->codecpar->profile = atoi(cbytes);
+                dicom->level = st->codecpar->profile;
+                av_free(cbytes);
+            }
+            break;
+    }
+    return 0;
+}
+
+
+
+static int read_data_element_metainfo(AVFormatContext *s, DataElement *de)
+{
+    ValueRepresentation vr;
+    int ret;
+
+    ret = avio_rl16(s->pb);
+    if (ret < 0)
+        return ret;
+    de->GroupNumber = ret;
+
+    de->ElementNumber =  avio_rl16(s->pb);
+
+    vr = avio_rb16(s->pb); // Stored in Big Endian in dicom.h
+    de->VR = vr;
+
+    switch (vr) {
+        case OB:
+        case OD:
+        case OF:
+        case OL:
+        case OV:
+        case OW:
+        case SQ:
+        case SV:
+        case UC:
+        case UR:
+        case UT:
+        case UN:
+        case UV:
+            avio_skip(s->pb, 2); // Padding always 0x0000
+            de->VL = avio_rl32(s->pb);
+            if (de->VL % 2)
+                av_log(s, AV_LOG_WARNING,"Data Element Value length:%d can't be odd\n", de->VL);
+            break;
+        default:
+            de->VL = avio_rl16(s->pb);
+            if (de->VL % 2)
+                av_log(s, AV_LOG_WARNING,"Data Element Value length:%d can't be odd\n", de->VL);
+            break;
+    }
+    return de->VL;
+}
+
+static int read_data_element_valuefield(AVFormatContext *s, DataElement *de)
+{
+    int ret;
+    uint32_t len = de->VL;
+
+    de->bytes = av_malloc(len);
+    ret = avio_read(s->pb, de->bytes, len);
+    return ret;
+}
+
+static int print_data_element_metadata(AVFormatContext *s, DataElement *de) {
+    av_log(s, AV_LOG_INFO,"(%04x, %04x)\tVR=%c%c\tVL=%d\t",de->GroupNumber, de->ElementNumber, de->VR>>8, de->VR - ((de->VR>>8)<<8), de->VL);
+    return 0;
+}
+
+static int print_data_element_value(AVFormatContext *s, DataElement *de) {
+    ValueRepresentation vr = de->VR;
+    uint32_t len = de->VL;
+    void *data = de->bytes;
+    char *cdata;
+
+    switch (vr) {
+        case AT:
+            if (len < 4) {
+                printf("[Invalid]\n");
+                return 0;
+            }
+            cdata = data;
+            av_log(s, AV_LOG_INFO, "%04d %04d", cdata[1] << 8 + cdata[0], cdata[4] << 8 + cdata[3]);
+            break;
+        case FL:
+            av_log(s, AV_LOG_INFO, "%f\n", ((float *)data)[0]);
+            break;
+        default:
+            cdata = av_malloc(len + 1);
+            memcpy(cdata, data, len);
+            cdata[len] = 0;
+            av_log(s, AV_LOG_INFO, "%s\n", cdata);
+            av_free(cdata);
+    }
+    return 0;
+}
+
+static int dicom_read_header(AVFormatContext *s)
+{
+    AVIOContext     *pb = s->pb;
+    int ret;
+
+    ret = avio_skip(pb, DICOM_PREAMBLE_SIZE + DICOM_PREFIX_SIZE);
+    if (ret < 0)
+        return ret;
+
+    s->ctx_flags |= AVFMTCTX_NOHEADER;
+    s->start_time = 0;
+    return 0;
+}
+
+static int dicom_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    DICOMContext *dicom = s->priv_data;
+    int metadata = dicom->metadata;
+    AVStream  *st;
+    DataElement *de;
+    int ret;
+
+    if (s->nb_streams < 1) {
+        st = avformat_new_stream(s, NULL);
+        if (!st)
+            return AVERROR(ENOMEM);
+        st->codecpar->codec_id = AV_CODEC_ID_DICOM;
+        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+        if (st->codecpar->profile != -1) {
+            st->codecpar->profile = dicom->window;
+        }
+        if (st->codecpar->level != -1) {
+            st->codecpar->level = dicom->level;
+        }
+    } else
+        st = s->streams[0];
+
+    for (;;) {
+        ret = avio_feof(s->pb);
+        if (ret)
+            return AVERROR_EOF;
+        
+        de = av_malloc(sizeof(DataElement));
+        ret = read_data_element_metainfo(s,de);
+        if (ret < 0)
+            return ret;
+
+        if (de->GroupNumber == IMAGE_GR_NB) {
+            ret = read_data_element_valuefield(s, de);
+            if (ret < 0)
+                return ret;
+            set_imagegroup_data(s, st, de);
+        } else if (de->GroupNumber == PIXEL_GR_NB && de->ElementNumber == PIXELDATA_EL_NB) {
+            if (av_new_packet(pkt, de->VL) < 0)
+                return AVERROR(ENOMEM);
+            pkt->pos = avio_tell(s->pb);
+            pkt->stream_index = 0;
+            pkt->size = de->VL;
+            ret = avio_read(s->pb, pkt->data, de->VL);
+            if (ret < 0)
+                av_packet_unref(pkt);
+            return ret;
+        }
+        else {
+            ret = read_data_element_valuefield(s, de);
+            if (ret < 0)
+                return ret;
+            if (metadata) {
+                print_data_element_metadata(s, de);
+                print_data_element_value(s,de);
+            }
+        }
+        av_free(de);
+    }
+    return AVERROR_EOF;
+}
+
+static const AVOption options[] = {
+    { "window", "window", offsetof(DICOMContext, window), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 99999, AV_OPT_FLAG_DECODING_PARAM },
+    { "level", "level", offsetof(DICOMContext, level), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 99999   , AV_OPT_FLAG_DECODING_PARAM },
+    { "metadata", "Print metadata present in dicom file", offsetof(DICOMContext, metadata)  , AV_OPT_TYPE_BOOL,{.i64 = 0}, 0,1, AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass dicom_class = {
+    .class_name = "dicomdec",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_dicom_demuxer = {
+    .name           = "dicom",
+    .long_name      = NULL_IF_CONFIG_SMALL("DICOM (Digital Imaging and Communications in Medicine)"),
+    .priv_data_size = sizeof(DICOMContext),
+    .read_probe     = dicom_probe,
+    .read_header    = dicom_read_header,
+    .read_packet    = dicom_read_packet,
+    .extensions     = "dcm",
+    .priv_class     = &dicom_class,
+};
\ No newline at end of file
diff --git a/libavformat/dicomdict.c b/libavformat/dicomdict.c
new file mode 100644
index 0000000000..c70c03e8a9
--- /dev/null
+++ b/libavformat/dicomdict.c
@@ -0,0 +1,280 @@ 
+/*
+ * DICOM Dictionary
+ *
+ * Copyright (c) 2019 Shivam Goyal
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avstring.h"
+#include "dicom.h"
+
+typedef struct DICOMDictionary {
+    uint16_t GroupNumber;
+    uint16_t ElementNumber;
+    ValueRepresentation vr;
+    char *desc;
+} DICOMDictionary;
+
+DICOMDictionary dicom_dictionary[] = {
+    {0x0002, 0x0000, UL, "File Meta Elements Group Len"},
+    {0x0002, 0x0001, OB, "File Meta Information Version"},
+    {0x0002, 0x0002, UI, "Media Storage SOP Class UID"},
+    {0x0002, 0x0003, UI, "Media Storage SOP Inst UID"},
+    {0x0002, 0x0010, UI, "Transfer Syntax UID"},
+    {0x0002, 0x0012, UI, "Implementation Class UID"},
+    {0x0002, 0x0013, SH, "Implementation Version Name"},
+    {0x0002, 0x0016, AE, "Source Application Entity Title"},
+    {0x0002, 0x0017, AE, "Sending Application Entity Title"},
+    {0x0002, 0x0018, AE, "Receiving Application Entity Title"},
+    {0x0002, 0x0100, UI, "Private Information Creator UID"},
+    {0x0002, 0x0102, OB, "Private Information"},
+
+
+    {0x0004, 0x1130, CS, "File-set ID"},
+    {0x0004, 0x1141, CS, "File-set Descriptor File ID"},
+    {0x0004, 0x1142, CS, "Specific Character Set of File-set Descriptor File"},
+    {0x0004, 0x1200, UL, "Offset of the First Directory Record of the Root Directory Entity"},
+    {0x0004, 0x1202, UL, "Offset of the Last Directory Record of the Root Directory Entity"},
+    {0x0004, 0x1212, US, "File-set Consistency Flag"},
+    {0x0004, 0x1220, SQ, "Directory Record Sequence"},
+    {0x0004, 0x1400, UL, "Offset of the Next Directory Record"},
+    {0x0004, 0x1410, US, "Record In-use Flag"},
+    {0x0004, 0x1420, UL, "Offset of Referenced Lower-Level Directory Entity"},
+    {0x0004, 0x1430, CS, "Directory Record Type"},
+    {0x0004, 0x1432, UI, "Private Record UID"},
+    {0x0004, 0x1500, CS, "Referenced File ID"},
+    {0x0004, 0x1504, UL, "MRDR Directory Record Offset"},
+    {0x0004, 0x1510, UI, "Referenced SOP Class UID in File"},
+    {0x0004, 0x1511, UI, "Referenced SOP Instance UID in File"},
+    {0x0004, 0x1512, UI, "Referenced Transfer Syntax UID in File"},
+    {0x0004, 0x151A, UI, "Referenced Related General SOP Class UID in File"},
+    {0x0004, 0x1600, UL, "Number of References"},
+
+
+    {0x0008, 0x0001, UL, "Length to End"},
+    {0x0008, 0x0005, CS, "Specific Character Set"},
+    {0x0008, 0x0006, SQ, "Language Code Sequence"},
+    {0x0008, 0x0008, CS, "Image Type"},
+    {0x0008, 0x0010, SH, "Recognition Code"},
+    {0x0008, 0x0012, DA, "Instance Creation Date"},
+    {0x0008, 0x0013, TM, "Instance Creation Time"},
+    {0x0008, 0x0014, UI, "Instance Creator UID"},
+    {0x0008, 0x0015, DT, "Instance Create UID"},
+    {0x0008, 0x0016, UI, "SOP Class UID"},
+    {0x0008, 0x0018, UI, "SOP Instance UID"},
+    {0x0008, 0x001A, UI, "Related General SOP Class UID"},
+    {0x0008, 0x001B, UI, "Original Specialized SOP Class UID"},
+    {0x0008, 0x0020, DA, "Study Date"},
+    {0x0008, 0x0021, DA, "Series Date"},
+    {0x0008, 0x0022, DA, "Acquisition Date"},
+    {0x0008, 0x0023, DA, "Content Date"},
+    {0x0008, 0x0024, DA, "Overlay Date"},
+    {0x0008, 0x0025, DA, "Curve Date"},
+    {0x0008, 0x002A, DT, "Acquisition DateTime"},
+    {0x0008, 0x0030, TM, "Study Time"},
+    {0x0008, 0x0031, TM, "Series Time"},
+    {0x0008, 0x0032, TM, "Acquisition Time"},
+    {0x0008, 0x0033, TM, "Content Time"},
+    {0x0008, 0x0034, TM, "Overlay Time"},
+    {0x0008, 0x0035, TM, "Curve Time"},
+    {0x0008, 0x0040, US, "Data Set Type"},
+    {0x0008, 0x0041, LO, "Data Set Subtype"},
+    {0x0008, 0x0042, CS, "Nuclear Medicine Series Type"},
+    {0x0008, 0x0050, SH, "Accession Number"},
+    {0x0008, 0x0051, SQ, "Issuer of Accession Number Sequence"},
+    {0x0008, 0x0052, CS, "Query/Retrieve Level"},
+    {0x0008, 0x0053, CS, "Query/Retrieve View"},
+    {0x0008, 0x0054, AE, "Retrieve AE Title"},
+    {0x0008, 0x0055, AE, "Station AE Title"},
+    {0x0008, 0x0056, CS, "Instance Availability"},
+    {0x0008, 0x0058, UI, "Failed SOP Instance UID List"},
+    {0x0008, 0x0060, CS, "Modality"},
+    {0x0008, 0x0061, CS, "Modalities in Study"},
+    {0x0008, 0x0062, UI, "SOP Classes in Study"},
+    {0x0008, 0x0064, CS, "Conversion Type"},
+    {0x0008, 0x0068, CS, "Presentation Intent Type"},
+    {0x0008, 0x0070, LO, "Manufacturer"},
+    {0x0008, 0x0080, LO, "Institution Name"},
+    {0x0008, 0x0081, ST, "Institution Address"},
+    {0x0008, 0x0082, SQ, "Institution Code Sequence"},
+    {0x0008, 0x0090, PN, "Referring Physician's Name"},
+    {0x0008, 0x0092, ST, "Referring Physician's Address"},
+    {0x0008, 0x0094, SH, "Referring Physician's Telephone Numbers"},
+    {0x0008, 0x0096, SQ, "Referring Physician Identification Sequence"},
+    {0x0008, 0x009C, PN, "Consulting Physician's Name"},
+    {0x0008, 0x009D, SQ, "Consulting Physician Identification Sequence"},
+    {0x0008, 0x0100, SH, "Code Value"},
+    {0x0008, 0x0101, LO, "Extended Code Value"},
+    {0x0008, 0x0102, SH, "Coding Scheme Designator"},
+    {0x0008, 0x0104, LO, "Code Meaning"},
+    {0x0008, 0x0105, CS, "Mapping Resource"},
+    {0x0008, 0x0106, DT, "Context Group Version"},
+    {0x0008, 0x0107, DT, "Context Group Local Version"},
+    {0x0008, 0x0108, LT, "Extended Code Meaning"},
+    {0x0008, 0x010C, UI, "Coding Scheme UID"},
+    {0x0008, 0x010D, UI, "Context Group Extension Creator UID"},
+    {0x0008, 0x010F, CS, "Context Identifier"},
+    {0x0008, 0x0110, SQ, "Coding Scheme Identification Sequence"},
+    {0x0008, 0x0112, LO, "Coding Scheme Registry"},
+    {0x0008, 0x0114, ST, "Coding Scheme External ID"},
+    {0x0008, 0x0115, ST, "Coding Scheme Name"},
+    {0x0008, 0x0116, ST, "Coding Scheme Responsible Organization"},
+    {0x0008, 0x0117, UI, "Context UID"},
+    {0x0008, 0x0118, UI, "Mapping Resource UID"},
+    {0x0008, 0x0119, UC, "Long Code Value"},
+    {0x0008, 0x0120, UR, "URN Code Value"},
+    {0x0008, 0x0121, SQ, "Equivalent Code Sequence"},
+    {0x0008, 0x0122, LO, "Mapping Resource Name"},
+    {0x0008, 0x0123, SQ, "Context Group Identification Sequence"},
+    {0x0008, 0x0124, SQ, "Mapping Resource Identification Sequence"},
+    {0x0008, 0x0201, SH, "Timezone Offset From UTC"},
+    {0x0008, 0x0300, SQ, "Private Data Element Characteristics Sequence"},
+    {0x0008, 0x0301, US, "Private Group Reference"},
+    {0x0008, 0x0302, LO, "Private Creator Reference"},
+    {0x0008, 0x0303, CS, "Block Identifying Information Status"},
+    {0x0008, 0x0304, US, "Nonidentifying PrivateElements"},
+    {0x0008, 0x0305, SQ, "Deidentification ActionSequence"},
+    {0x0008, 0x0306, US, "Identifying PrivateElements"},
+    {0x0008, 0x0307, CS, "Deidentification Action"},
+    {0x0008, 0x1000, AE, "Network ID"},
+    {0x0008, 0x1010, SH, "Station Name"},
+    {0x0008, 0x1030, LO, "Study Description"},
+    {0x0008, 0x1032, SQ, "Procedure Code Sequence"},
+    {0x0008, 0x103E, LO, "Series Description"},
+    {0x0008, 0x103F, SQ, "Series Description CodeSequence"},
+    {0x0008, 0x1040, LO, "Institutional Department Name"},
+    {0x0008, 0x1048, PN, "Physician(s) of Record"},
+    {0x0008, 0x1049, SQ, "Physician(s) of Record Identification Sequence"},
+    {0x0008, 0x1050, PN, "Attending Physician's Name"},
+    {0x0008, 0x1052, SQ, "Performing Physician Identification Sequence"},
+    {0x0008, 0x1060, PN, "Name of Physician(s) Reading Study"},
+    {0x0008, 0x1062, SQ, "Physician(s) ReadingStudy Identification Sequenc"},
+    {0x0008, 0x1070, PN, "Operator's Name"},
+    {0x0008, 0x1072, SQ, "Operator Identification Sequence"},
+    {0x0008, 0x1080, LO, "Admitting Diagnosis Description"},
+    {0x0008, 0x1084, SQ, "Admitting Diagnosis Code Sequence"},
+    {0x0008, 0x1090, LO, "Manufacturer's Model Name"},
+    {0x0008, 0x1100, SQ, "Referenced Results Sequence"},
+    {0x0008, 0x1110, SQ, "Referenced Study Sequence"},
+    {0x0008, 0x1111, SQ, "Referenced Study Component Sequence"},
+    {0x0008, 0x1115, SQ, "Referenced Series Sequence"},
+    {0x0008, 0x1120, SQ, "Referenced Patient Sequence"},
+    {0x0008, 0x1125, SQ, "Referenced Visit Sequence"},
+    {0x0008, 0x1130, SQ, "Referenced Overlay Sequence"},
+    {0x0008, 0x1134, SQ, "Referenced Stereometric Instance Sequence"},
+    {0x0008, 0x113A, SQ, "Referenced Waveform Sequence"},
+    {0x0008, 0x1140, SQ, "Referenced Image Sequence"},
+    {0x0008, 0x1145, SQ, "Referenced Curve Sequence"},
+    {0x0008, 0x114A, SQ, "Referenced InstanceSequence"},
+    {0x0008, 0x114B, SQ, "Referenced Real World Value Mapping InstanceSequence"},
+    {0x0008, 0x1150, UI, "Referenced SOP Class UID"},
+    {0x0008, 0x1155, UI, "Referenced SOP Instance UID"},
+    {0x0008, 0x115A, UI, "SOP Classes Supported"},
+    {0x0008, 0x1160, IS, "Referenced Frame Number"},
+    {0x0008, 0x1161, UL, "Simple Frame List"},
+    {0x0008, 0x1162, UL, "Calculated Frame List"},
+    {0x0008, 0x1163, FD, "Time Range"},
+    {0x0008, 0x1164, SQ, "Frame Extraction Sequence"},
+    {0x0008, 0x1167, UI, "Multi-frame Source SOP Instance UID"},
+    {0x0008, 0x1190, UR, "Retrieve URL"},
+    {0x0008, 0x1195, UI, "Transaction UID"},
+    {0x0008, 0x1196, US, "Warning Reason"},
+    {0x0008, 0x1197, US, "Failure Reason"},
+    {0x0008, 0x1198, SQ, "Failed SOP Sequence"},
+    {0x0008, 0x1199, SQ, "Referenced SOP Sequence"},
+    {0x0008, 0x119A, SQ, "Other Failures Sequence"},
+    {0x0008, 0x1200, SQ, "Studies Containing OtherReferenced InstancesSequence"},
+    {0x0008, 0x1250, SQ, "Related Series Sequence"},
+    {0x0008, 0x2110, CS, "Lossy Image Compression(Retired)"},
+    {0x0008, 0x2111, ST, "Derivation Description"},
+    {0x0008, 0x2112, SQ, "Source Image Sequence"},
+    {0x0008, 0x2120, SH, "Stage Name"},
+    {0x0008, 0x2122, IS, "Stage Number"},
+    {0x0008, 0x2124, IS, "Number of Stages"},
+    {0x0008, 0x2127, SH, "View Name"},
+    {0x0008, 0x2128, IS, "View Number"},
+    {0x0008, 0x2129, IS, "Number of Event Timers"},
+    {0x0008, 0x212A, IS, "Number of Views in Stage"},
+    {0x0008, 0x2130, DS, "Event Elapsed Time(s)"},
+    {0x0008, 0x2132, LO, "Event Timer Name(s)"},
+    {0x0008, 0x2133, SQ, "Event Timer Sequence"},
+    {0x0008, 0x2134, FD, "Event Time Offset"},
+    {0x0008, 0x2135, SQ, "Event Code Sequence"},
+    {0x0008, 0x2142, IS, "Start Trim"},
+    {0x0008, 0x2143, IS, "Stop Trim"},
+    {0x0008, 0x2144, IS, "Recommended Display Frame Rate"},
+    {0x0008, 0x2200, CS, "Transducer Position"},
+    {0x0008, 0x2204, CS, "Transducer Orientation"},
+    {0x0008, 0x2208, CS, "Anatomic Structure"},
+    {0x0008, 0x2218, SQ, "Anatomic RegionSequence"},
+    {0x0008, 0x2220, SQ, "Anatomic Region ModifierSequence"},
+    {0x0008, 0x2228, SQ, "Primary Anatomic Structure Sequence"},
+    {0x0008, 0x2229, SQ, "Anatomic Structure, Spaceor Region Sequence"},
+    {0x0008, 0x2230, SQ, "Primary Anatomic Structure ModifierSequence"},
+    {0x0008, 0x2240, SQ, "Transducer Position Sequence"},
+    {0x0008, 0x2242, SQ, "Transducer Position Modifier Sequence"},
+    {0x0008, 0x2244, SQ, "Transducer Orientation Sequence"},
+    {0x0008, 0x2246, SQ, "Transducer Orientation Modifier Sequence"},
+    {0x0008, 0x2251, SQ, "Anatomic Structure SpaceOr Region Code Sequence(Trial)"},
+    {0x0008, 0x2253, SQ, "Anatomic Portal Of Entrance Code Sequence(Trial)"},
+    {0x0008, 0x2255, SQ, "Anatomic ApproachDirection Code Sequence(Trial)"},
+    {0x0008, 0x2256, ST, "Anatomic Perspective Description (Trial)"},
+    {0x0008, 0x2257, SQ, "Anatomic Perspective Code Sequence (Trial)"},
+    {0x0008, 0x2258, ST, "Anatomic Location Of Examining InstrumentDescription (Trial)"},
+    {0x0008, 0x2259, SQ, "Anatomic Location Of Examining InstrumentCode Sequence (Trial)"},
+    {0x0008, 0x225A, SQ, "Anatomic Structure SpaceOr Region Modifier CodeSequence (Trial)"},
+    {0x0008, 0x225C, SQ, "On Axis Background Anatomic Structure CodeSequence (Trial)"},
+    {0x0008, 0x3001, SQ, "Alternate Representation Sequence"},
+    {0x0008, 0x3010, UI, "Irradiation Event UID"},
+    {0x0008, 0x3011, SQ, "Source Irradiation Event Sequence"},
+    {0x0008, 0x2012, UI, "Radiopharmaceutical Administration Event UID"},
+    {0x0008, 0x4000, LT, "Identifying Comments"},
+    {0x0008, 0x9007, CS, "Frame Type"},
+    {0x0008, 0x9092, SQ, "Referenced ImageEvidence Sequence"},
+    {0x0008, 0x9121, SQ, "Referenced Raw DataSequence"},
+    {0x0008, 0x9123, UI, "Creator-Version UID"},
+    {0x0008, 0x9124, SQ, "Derivation ImageSequence"},
+    {0x0008, 0x9154, SQ, "Source Image EvidenceSequence"},
+    {0x0008, 0x9205, CS, "Pixel Presentation"},
+    {0x0008, 0x9206, CS, "Volumetric Properties"},
+    {0x0008, 0x9207, CS, "Volume Based Calculation Technique"},
+    {0x0008, 0x9208, CS, "Complex Image Component"},
+    {0x0008, 0x9209, CS, "Acquisition Contrast"},
+    {0x0008, 0x9215, SQ, "Derivation Code Sequence"},
+    {0x0008, 0x9237, SQ, "Referenced Presentation State Sequence"},
+    {0x0008, 0x9410, SQ, "Referenced Other Plane Sequence"},
+    {0x0008, 0x9458, SQ, "Frame Display Sequence"},
+    {0x0008, 0x9459, FL, "Recommended DisplayFrame Rate in Float"},
+    {0x0008, 0x9460, CS, "Skip Frame Range Flag"},
+};
+
+int dicom_dict_find_elem_info(DataElement *de) {
+    int i, len;
+
+    if (!de->GroupNumber || !de->ElementNumber)
+        return -2;
+    len = sizeof(dicom_dictionary) / sizeof(dicom_dictionary[0]);
+    for (int i = 0; i < len; i++) {
+        if (de->GroupNumber == dicom_dictionary[i].GroupNumber 
+            && de->ElementNumber == dicom_dictionary[i].ElementNumber) {
+            de->VR = dicom_dictionary[i].vr;
+            return 0;
+        }
+    }
+    return -1;
+}
\ No newline at end of file
-- 
2.22.0