-------- Forwarded Message --------Subject: Re: [FFmpeg-devel] [PATCH] lavf: Add DICOM demuxer, lavc: Add DICOM decoder
Date: Thu, 22 Aug 2019 00:27:55 +0530 From: Shivam <shi...@iitk.ac.in> To: Michael Niedermayer <mich...@niedermayer.cc> On 8/21/19 2:00 AM, Michael Niedermayer wrote:
On Tue, Aug 20, 2019 at 08:53:43PM +0530, Shivam wrote:Sorry, for my previous mail, i forgot to attach the patch.The patch contains support for Dicom files. The below features are supportedyet:-Uncompressed DICOM files using any of the Implicit and Explicit VR formats.Multiframe files are also supported.To extract the metadata or info about the procedure, I have added an option"-metadata." (The tags present in Dicom dictionary would be demuxed). I have also uploaded DICOM samples here. https://1drv.ms/u/s!AosJ9_SrP4Tsh2WoPfQAI8cSsqUs?e=ZMd5fR Please review, Thank you, Shivam Goyal Changelog | 1 libavcodec/Makefile | 1 libavcodec/allcodecs.c | 1 libavcodec/avcodec.h | 1 libavcodec/codec_desc.c | 7 libavcodec/dicom.c | 189 ++++++++++++ libavcodec/version.h | 2 libavformat/Makefile | 1 libavformat/allformats.c | 1 libavformat/dicom.h | 108 +++++++ libavformat/dicomdec.c | 594 ++++++++++++++++++++++++++++++++++++++libavformat/dicomdict.c | 716 +++++++++++++++++++++++++++++++++++++++++++++++libavformat/version.h | 2 13 files changed, 1622 insertions(+), 2 deletions(-) d47b7ad6a9f16ce4e29a67a99800183f9056062d add_dicom.patch From cd7ebe834278b29b0429b3f5b377154490ee159f Mon Sep 17 00:00:00 2001 From: Shivam Goyal <1998.goyal.shi...@gmail.com> Date: Tue, 20 Aug 2019 20:03:02 +0530 Subject: [PATCH] lavc: add DICOM decoder, lavf: add DICOM demuxer --- Changelog | 1 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 7 + libavcodec/dicom.c | 189 +++++++++++ libavcodec/version.h | 2 +- libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/dicom.h | 108 ++++++ libavformat/dicomdec.c | 594 ++++++++++++++++++++++++++++++++ libavformat/dicomdict.c | 716 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +-libavformat and libavcodec changes should be in seperate patches13 files changed, 1622 insertions(+), 2 deletions(-) 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/Changelog b/Changelog index c1f1237770..e04c3aa5f6 100644 --- a/Changelog +++ b/Changelog @@ -4,6 +4,7 @@ releases are sorted from youngest to oldest. version <next>: - Intel QSV-accelerated MJPEG decoding - Intel QSV-accelerated VP9 decoding +- DICOM decoder and demxer version 4.2: - tpad filter diff --git a/libavcodec/Makefile b/libavcodec/Makefile index e49188357b..799da8aef7 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.oOBJS-$(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 22985325e0..02a1afa7e8 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 d234271c5b..756e168c75 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..ae9abdb2ba 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c@@ -1403,6 +1403,13 @@ static const AVCodecDescriptor codec_descriptors[] = {.long_name = NULL_IF_CONFIG_SMALL("AVS2-P2/IEEE1857.4"), .props = AV_CODEC_PROP_LOSSY, }, + { + .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_Y41P, .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/dicom.c b/libavcodec/dicom.c new file mode 100644 index 0000000000..eaa378d944 --- /dev/null +++ b/libavcodec/dicom.c @@ -0,0 +1,189 @@ +/* + * 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 "libavutil/dict.h" +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" + +typedef struct DICOMopts { + const AVClass *class; + int interpret; // streams extradata + int pixrep; + int pixpad; + int slope; + int intcpt; +} DICOMopts; + + +static int extract_ed(AVCodecContext *avctx) +{ + DICOMopts *dcmopts = avctx->priv_data; + uint8_t *ed = avctx->extradata; + int ed_s = avctx->extradata_size; + const uint8_t **b = &avctx->extradata; + + dcmopts->interpret = 0x02; // Set defaults + dcmopts->slope = 1; + dcmopts->intcpt = 0; + dcmopts->pixpad = 1 << 31; + dcmopts->pixrep = 0; + + if (ed_s <= AV_INPUT_BUFFER_PADDING_SIZE) + return -1;This check looks odd, the input padding size would be after the specified size of extradata
Ok, i will change this.
+ dcmopts->interpret = bytestream_get_le32(b); + dcmopts->pixrep = bytestream_get_le32(b); + dcmopts->pixpad = bytestream_get_le32(b); + dcmopts->slope = bytestream_get_le32(b); + dcmopts->intcpt = bytestream_get_le32(b); + avctx->extradata = ed;I think its less confusing if you dont modify avctx->extradata
change it too;
+ return 0; +} + +static uint8_t apply_transfm(int64_t val, int64_t bitmask, int pix_pad, + int slope, int intercept, int w, int l, int interpret) +{ + int max, min; + uint8_t ret; + + if (val == pix_pad) + return 0; + if (val > 0) + val = (val & bitmask); + val = slope * val + intercept; // Linear Transformation + + max = l + w / 2 - 1; + min = l - w / 2; + if (val > max) + ret = 255; + else if (val <= min) + ret = 0; + else + ret = (val - min) * 255 / (max - min); + if (interpret == 0x01) // Monochrome1 + ret = 255 - ret; + return ret; +} + +// DICOM MONOCHROME1 and MONOCHROME2 decoder +static int decode_mono( AVCodecContext *avctx, + const uint8_t *buf, + AVFrame *p) +{ + int w, l, bitsalloc, pixrep, pixpad, slope, intcpt, interpret, ret; + DICOMopts *dcmopts = avctx->priv_data; + uint8_t *out; + int64_t bitmask, pix; + uint64_t i, size; + + 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; + out = p->data[0]; + + w = avctx->profile; + l = avctx->level; + size = avctx->width * avctx->height; + bitsalloc = avctx->bits_per_raw_sample; + bitmask = (1 << avctx->bits_per_coded_sample) - 1; + interpret = dcmopts->interpret; + pixrep = dcmopts->pixrep; + pixpad = dcmopts->pixpad; + slope = dcmopts->slope; + intcpt = dcmopts->intcpt; + + switch (bitsalloc) { + case 8: + for (i = 0; i < size; i++) { + if (pixrep) + pix = (int8_t)bytestream_get_byte(&buf); + else + pix = (uint8_t)bytestream_get_byte(&buf); + out[i] = pix; + } + break; + case 16: + for (i = 0; i < size; i++) { + if (pixrep) + pix = (int16_t)bytestream_get_le16(&buf); + else + pix = (uint16_t)bytestream_get_le16(&buf);+ out[i] = apply_transfm(pix, bitmask, pixpad, slope, intcpt, w, l, interpret);+ } + break; + case 32: + for (i = 0; i < size; i++) { + if (pixrep) + pix = (int32_t)bytestream_get_le32(&buf); + else + pix = (uint32_t)bytestream_get_le32(&buf);+ out[i] = apply_transfm(pix, bitmask, pixpad, slope, intcpt, w, l, interpret);+ } + break; + default:+ av_log(avctx, AV_LOG_ERROR, "Bits allocated %d not supported\n", bitsalloc);+ return AVERROR_INVALIDDATA; + } + return 0; +} + +static int dicom_decode_frame(AVCodecContext *avctx, + void *data, int *got_frame, + AVPacket *avpkt) +{ + DICOMopts *dcmopts = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + AVFrame *p = data; + int ret, req_buf_size; ++ req_buf_size = avctx->width * avctx->height * avctx->bits_per_raw_sample / 8;+ if (buf_size < req_buf_size) {+ av_log(avctx, AV_LOG_ERROR, "Required buffer size is %d but recieved only %d\n", req_buf_size, buf_size);+ return AVERROR_INVALIDDATA; + } + extract_ed(avctx); + switch (dcmopts->interpret) { + case 0x01: // MONOCHROME1 + case 0x02: // MONOCHROME2 + ret = decode_mono(avctx, buf, p); + if (ret < 0) + return ret; + break; + default:+ av_log(avctx, AV_LOG_ERROR, "Provided photometric interpretation not supported\n");+ return AVERROR_INVALIDDATA; + } + *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, + .priv_data_size = sizeof(DICOMopts), + .id = AV_CODEC_ID_DICOM, + .decode = dicom_decode_frame, +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index 43c8cdb59f..ed767c8867 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 55 +#define LIBAVCODEC_VERSION_MINOR 56 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ 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..cffe80ada1 --- /dev/null +++ b/libavformat/dicom.h @@ -0,0 +1,108 @@ +/* + * 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 MF_GR_NB 0x0018 +#define PIXEL_GR_NB 0x7FE0 +#define PIXELDATA_EL_NB 0x0010 +#define TS_GR_NB 0x0002 +#define TS_EL_NB 0x0010 +#define UNDEFINED_VL 0xFFFFFFFF +#define DEFAULT_WINDOW 1100 +#define DEFAULT_LEVEL 125 + +#define SEQ_GR_NB 0xFFFE +#define SEQ_DEL_EL_NB 0xE0DD +#define SEQ_ITEM_BEG_EL_NB 0xE000 +#define SEQ_ITEM_DEL_EL_NB 0xE00D +#define MAX_UNDEF_LENGTH 10000 // max undefined length +#define MAX_SEQ_LENGTH 20 // max sequence length (items) + +typedef enum { + UNSUPPORTED_TS = 0, + IMPLICIT_VR = 1, + EXPLICIT_VR = 2, + DEFLATE_EXPLICIT_VR = 3, + JPEG_BASE_8 = 4, + JPEG_EXT_12 = 5, + JPEG_LOSSLESS_NH_P14 = 6, + JPEG_LOSSLESS_NH_P14_S1 = 7, + JPEG_LS_LOSSLESS = 8, + JPEG_LS_LOSSY = 9, + JPEG2000_LOSSLESS = 10, + JPEG2000 = 11, + RLE = 12 +} TransferSyntax; + +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; + int64_t VL; + void* bytes; + int is_found; // is found in DICOM dictionary + char* desc; // description (from dicom dictionary) +} 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..c38d4311f9 --- /dev/null +++ b/libavformat/dicomdec.c @@ -0,0 +1,594 @@ +/* + * 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 "libavcodec/bytestream.h" +#include "avformat.h" +#include "internal.h" +#include "dicom.h" + + +typedef struct DICOMContext { + const AVClass *class; + + int interpret, pixrep, slope, intcpt, samples_ppix; + uint16_t width; + uint16_t height; + uint64_t nb_frames; + uint64_t frame_size; + int frame_nb; + double delay; + int duration; + int inheader; + int inseq; + int32_t pixpad; + TransferSyntax transfer_syntax; + + int window; // Options + int level; + int metadata; +} 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 DataElement *alloc_de(void) { + DataElement *de = (DataElement *) av_malloc(sizeof(DataElement)); + de->is_found = 0; + de->desc = NULL; + de->bytes = NULL; + return de; +} + +static void free_de(DataElement *de) { + if (!de) + return; + if (de->bytes) + av_free(de->bytes); + if (de->desc) + av_free(de->desc);av_free(NULL) is safe, no check needed
at first, it was giving error. So, i added a check, i would check it again.
+ av_free(de); +} + +static void set_context_defaults(DICOMContext *dicom) { + dicom->interpret = 0x02; // 2 for MONOCHROME2, 1 for MONOCHROME1 + dicom->pixrep = 1; + dicom->pixpad = 1 << 31; + dicom->slope = 1; + dicom->intcpt = 0; + dicom->samples_ppix = 1; + + dicom->delay = 100; + dicom->frame_nb = 1; + dicom->nb_frames = 1; + dicom->inseq = 0; +} + +// detects transfer syntax +static TransferSyntax get_transfer_sytax (const char *ts) { + if (!strcmp(ts, "1.2.840.10008.1.2")) + return IMPLICIT_VR; + else if (!strcmp(ts, "1.2.840.10008.1.2.1")) + return EXPLICIT_VR; + else + return UNSUPPORTED_TS; +} + +static int find_PI(const char *pi) { + if (!strcmp(pi, "MONOCHROME1 ")) + return 0x01; + else if (!strcmp(pi, "MONOCHROME2 ")) + return 0x02; + else if (!strcmp(pi, "PALETTE COLOR ")) + return 0x03; + else if (!strcmp(pi, "RGB ")) + return 0x04; + else return 0x00; +} + +static void set_dec_extradata(AVFormatContext *s, AVStream *st) { + DICOMContext *dicom = s->priv_data; + uint8_t *edp; + int size = 20 + AV_INPUT_BUFFER_PADDING_SIZE; + + st->codecpar->extradata = (uint8_t *)av_malloc(size); + edp = st->codecpar->extradata; + bytestream_put_le32(&st->codecpar->extradata, dicom->interpret); + bytestream_put_le32(&st->codecpar->extradata, dicom->pixrep); + bytestream_put_le32(&st->codecpar->extradata, dicom->pixpad); + bytestream_put_le32(&st->codecpar->extradata, dicom->slope); + bytestream_put_le32(&st->codecpar->extradata, dicom->intcpt); + st->codecpar->extradata = edp; + st->codecpar->extradata_size = size; +} + +static double conv_DS(DataElement *de) { + double ret; + char *cbytes = av_malloc(de->VL + 1); + + memcpy(cbytes, de->bytes, de->VL); + cbytes[de->VL] = 0; + ret = atof(cbytes); + av_free(cbytes); + return ret; +} + +static int conv_IS(DataElement *de) { + int ret; + char *cbytes = av_malloc(de->VL + 1); + + memcpy(cbytes, de->bytes, de->VL); + cbytes[de->VL] = 0; + ret = atoi(cbytes);this doesnt check for any errors
would change it, too
+ av_free(cbytes); + return ret; +} + + +static char *get_key_str(DataElement *de) { + char *key; + if (!de->GroupNumber || !de->ElementNumber) + return 0; + key = (char *) av_malloc(15 + strlen(de->desc));+ sprintf(key, "(%04x,%04x) %s", de->GroupNumber, de->ElementNumber, de->desc);please use snprintf() or some other function which checks the output space
ok,
[...]++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: // rows + dicom->height = *(uint16_t *)bytes;does this work on big endian ? maybe you where looking for AV_RL16()
Big endian DICOM files are retired and no longer supported by the standard.
[...]+int dicom_dict_find_elem_info(DataElement *de) { + int len; + DICOMDictionary *out; + + if (!de->GroupNumber || !de->ElementNumber) + return -2; + len = FF_ARRAY_ELEMS(dicom_dictionary); + + out = (DICOMDictionary *) bsearch(de, &dicom_dictionary, len, + sizeof(dicom_dictionary[0]), dcm_dict_comp); + + if (!out) + return -1; + de->VR = out->vr; + de->desc = av_strdup(out->desc);missing malloc failure check
would change it. Thanks for the review, 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-requ...@ffmpeg.org with subject "unsubscribe".