From: Cristy Date: Sat, 30 Jun 2018 22:04:43 +0000 (-0400) Subject: https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=34265 X-Git-Tag: 7.0.8-4~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d44af3cc2a2623fe4d9b942248bdd2bde7b7153;p=imagemagick https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=34265 --- diff --git a/coders/dcm.c b/coders/dcm.c index eab855087..fa5b99bd6 100644 --- a/coders/dcm.c +++ b/coders/dcm.c @@ -190,6 +190,7 @@ static const DicomInfo { 0x0008, 0x0023, "DA", "Image 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" }, @@ -2021,6 +2022,7 @@ static const DicomInfo { 0x0070, 0x0082, "DA", "Presentation Creation Date" }, { 0x0070, 0x0083, "TM", "Presentation Creation Time" }, { 0x0070, 0x0084, "PN", "Presentation Creator's Name" }, + { 0x0070, 0x031a, "UI", "Fiducial UID" }, { 0x0087, 0x0010, "CS", "Media Type" }, { 0x0087, 0x0020, "CS", "Media Location" }, { 0x0087, 0x0050, "IS", "Estimated Retrieve Time" }, @@ -2579,6 +2581,21 @@ static const DicomInfo { 0x7000, 0x0004, "ST", "TextAnnotation" }, { 0x7000, 0x0005, "IS", "Box" }, { 0x7000, 0x0007, "IS", "ArrowEnd" }, + { 0x7001, 0x0001, "SL", "Private Group Length To End" }, + { 0x7001, 0x0002, "OB", "Unknown" }, + { 0x7001, 0x0011, "SL", "Private Creator" }, + { 0x7001, 0x0021, "SL", "Private Creator" }, + { 0x7001, 0x0022, "SQ", "Private Creator" }, + { 0x7001, 0x0041, "SL", "Private Creator" }, + { 0x7001, 0x0042, "SL", "Private Creator" }, + { 0x7001, 0x0051, "SL", "Private Creator" }, + { 0x7001, 0x0052, "SL", "Private Creator" }, + { 0x7001, 0x0075, "SL", "Private Creator" }, + { 0x7001, 0x0076, "SL", "Private Creator" }, + { 0x7001, 0x0077, "OB", "Private Creator" }, + { 0x7001, 0x0101, "SL", "Unknown" }, + { 0x7001, 0x0121, "SL", "Unknown" }, + { 0x7001, 0x0122, "SQ", "Unknown" }, { 0x7fe0, 0x0000, "UL", "Pixel Data Group Length" }, { 0x7fe0, 0x0010, "xs", "Pixel Data" }, { 0x7fe0, 0x0020, "OW", "Coefficients SDVN" }, @@ -2777,7 +2794,7 @@ static unsigned short ReadDCMShort(DCMStreamInfo *stream_info,Image *image) { int shift, - val; + byte; unsigned short value; @@ -2785,11 +2802,11 @@ static unsigned short ReadDCMShort(DCMStreamInfo *stream_info,Image *image) if (image->compression != RLECompression) return(ReadBlobLSBShort(image)); shift=image->depth < 16 ? 4 : 8; - value=ReadDCMByte(stream_info,image); - val=ReadDCMByte(stream_info,image); - if (val < 0) + value=(unsigned short) ReadDCMByte(stream_info,image); + byte=ReadDCMByte(stream_info,image); + if (byte < 0) return(0); - value|=(unsigned short)(val << shift); + value|=(unsigned short) (byte << shift); return(value); } @@ -3125,897 +3142,807 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception) use_explicit=MagickFalse; explicit_retry = MagickFalse; width=0; - for (group=0; (group != 0x7FE0) || (element != 0x0010) ; ) + while (TellBlob(image) < (MagickOffsetType) GetBlobSize(image)) { - /* - Read a group. - */ - image->offset=(ssize_t) TellBlob(image); - group=ReadBlobLSBShort(image); - element=ReadBlobLSBShort(image); - if ((group != 0x0002) && (image->endian == MSBEndian)) - { - group=(unsigned short) ((group << 8) | ((group >> 8) & 0xFF)); - element=(unsigned short) ((element << 8) | ((element >> 8) & 0xFF)); - } - quantum=0; - /* - Find corresponding VR for this group and element. - */ - for (i=0; dicom_info[i].group < 0xffff; i++) - if ((group == dicom_info[i].group) && (element == dicom_info[i].element)) + for (group=0; (group != 0x7FE0) || (element != 0x0010) ; ) + { + /* + Read a group. + */ + image->offset=(ssize_t) TellBlob(image); + group=ReadBlobLSBShort(image); + element=ReadBlobLSBShort(image); + if ((group == 0xfffc) && (element == 0xfffc)) break; - (void) CopyMagickString(implicit_vr,dicom_info[i].vr,MagickPathExtent); - count=ReadBlob(image,2,(unsigned char *) explicit_vr); - if (count != 2) - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - /* - Check for "explicitness", but meta-file headers always explicit. - */ - if ((explicit_file == MagickFalse) && (group != 0x0002)) - explicit_file=(isupper((unsigned char) *explicit_vr) != MagickFalse) && - (isupper((unsigned char) *(explicit_vr+1)) != MagickFalse) ? - MagickTrue : MagickFalse; - use_explicit=((group == 0x0002) && (explicit_retry == MagickFalse)) || - (explicit_file != MagickFalse) ? MagickTrue : MagickFalse; - if ((use_explicit != MagickFalse) && (strncmp(implicit_vr,"xs",2) == 0)) - (void) CopyMagickString(implicit_vr,explicit_vr,MagickPathExtent); - if ((use_explicit == MagickFalse) || (strncmp(implicit_vr,"!!",2) == 0)) - { - offset=SeekBlob(image,(MagickOffsetType) -2,SEEK_CUR); - if (offset < 0) - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - quantum=4; - } - else - { - /* - Assume explicit type. - */ - quantum=2; - if ((strncmp(explicit_vr,"OB",2) == 0) || - (strncmp(explicit_vr,"UN",2) == 0) || - (strncmp(explicit_vr,"OW",2) == 0) || - (strncmp(explicit_vr,"SQ",2) == 0)) - { - (void) ReadBlobLSBShort(image); - quantum=4; - } - } - datum=0; - if (quantum == 4) - { - if (group == 0x0002) - datum=ReadBlobLSBSignedLong(image); - else - datum=ReadBlobSignedLong(image); - } - else - if (quantum == 2) + if ((group != 0x0002) && (image->endian == MSBEndian)) + { + group=(unsigned short) ((group << 8) | ((group >> 8) & 0xFF)); + element=(unsigned short) ((element << 8) | ((element >> 8) & 0xFF)); + } + quantum=0; + /* + Find corresponding VR for this group and element. + */ + for (i=0; dicom_info[i].group < 0xffff; i++) + if ((group == dicom_info[i].group) && + (element == dicom_info[i].element)) + break; + (void) CopyMagickString(implicit_vr,dicom_info[i].vr,MagickPathExtent); + count=ReadBlob(image,2,(unsigned char *) explicit_vr); + if (count != 2) + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); + /* + Check for "explicitness", but meta-file headers always explicit. + */ + if ((explicit_file == MagickFalse) && (group != 0x0002)) + explicit_file=(isupper((unsigned char) *explicit_vr) != MagickFalse) && + (isupper((unsigned char) *(explicit_vr+1)) != MagickFalse) ? + MagickTrue : MagickFalse; + use_explicit=((group == 0x0002) && (explicit_retry == MagickFalse)) || + (explicit_file != MagickFalse) ? MagickTrue : MagickFalse; + if ((use_explicit != MagickFalse) && (strncmp(implicit_vr,"xs",2) == 0)) + (void) CopyMagickString(implicit_vr,explicit_vr,MagickPathExtent); + if ((use_explicit == MagickFalse) || (strncmp(implicit_vr,"!!",2) == 0)) + { + offset=SeekBlob(image,(MagickOffsetType) -2,SEEK_CUR); + if (offset < 0) + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); + quantum=4; + } + else + { + /* + Assume explicit type. + */ + quantum=2; + if ((strncmp(explicit_vr,"OB",2) == 0) || + (strncmp(explicit_vr,"UN",2) == 0) || + (strncmp(explicit_vr,"OW",2) == 0) || + (strncmp(explicit_vr,"SQ",2) == 0)) + { + (void) ReadBlobLSBShort(image); + quantum=4; + } + } + datum=0; + if (quantum == 4) { if (group == 0x0002) - datum=ReadBlobLSBSignedShort(image); + datum=ReadBlobLSBSignedLong(image); else - datum=ReadBlobSignedShort(image); + datum=ReadBlobSignedLong(image); } - quantum=0; - length=1; - if (datum != 0) - { - if ((strncmp(implicit_vr,"OW",2) == 0) || - (strncmp(implicit_vr,"SS",2) == 0) || - (strncmp(implicit_vr,"US",2) == 0)) - quantum=2; - else - if ((strncmp(implicit_vr,"FL",2) == 0) || - (strncmp(implicit_vr,"OF",2) == 0) || - (strncmp(implicit_vr,"SL",2) == 0) || - (strncmp(implicit_vr,"UL",2) == 0)) - quantum=4; - else - if (strncmp(implicit_vr,"FD",2) == 0) - quantum=8; - else - quantum=1; - if (datum != ~0) - length=(size_t) datum/quantum; - else + else + if (quantum == 2) { - /* - Sequence and item of undefined length. - */ - quantum=0; - length=0; + if (group == 0x0002) + datum=ReadBlobLSBSignedShort(image); + else + datum=ReadBlobSignedShort(image); } - } - if (image_info->verbose != MagickFalse) - { - /* - Display Dicom info. - */ - if (use_explicit == MagickFalse) - explicit_vr[0]='\0'; - for (i=0; dicom_info[i].description != (char *) NULL; i++) - if ((group == dicom_info[i].group) && - (element == dicom_info[i].element)) - break; - (void) FormatLocaleFile(stdout,"0x%04lX %4ld %s-%s (0x%04lx,0x%04lx)", - (unsigned long) image->offset,(long) length,implicit_vr,explicit_vr, - (unsigned long) group,(unsigned long) element); - if (dicom_info[i].description != (char *) NULL) - (void) FormatLocaleFile(stdout," %s",dicom_info[i].description); - (void) FormatLocaleFile(stdout,": "); - } - if ((group == 0x7FE0) && (element == 0x0010)) - { - if (image_info->verbose != MagickFalse) - (void) FormatLocaleFile(stdout,"\n"); - break; - } - /* - Allocate space and read an array. - */ - data=(unsigned char *) NULL; - if ((length == 1) && (quantum == 1)) - datum=ReadBlobByte(image); - else - if ((length == 1) && (quantum == 2)) + quantum=0; + length=1; + if (datum != 0) { - if (group == 0x0002) - datum=ReadBlobLSBSignedShort(image); + if ((strncmp(implicit_vr,"OW",2) == 0) || + (strncmp(implicit_vr,"SS",2) == 0) || + (strncmp(implicit_vr,"US",2) == 0)) + quantum=2; + else + if ((strncmp(implicit_vr,"FL",2) == 0) || + (strncmp(implicit_vr,"OF",2) == 0) || + (strncmp(implicit_vr,"SL",2) == 0) || + (strncmp(implicit_vr,"UL",2) == 0)) + quantum=4; + else + if (strncmp(implicit_vr,"FD",2) == 0) + quantum=8; + else + quantum=1; + if (datum != ~0) + length=(size_t) datum/quantum; else - datum=ReadBlobSignedShort(image); + { + /* + Sequence and item of undefined length. + */ + quantum=0; + length=0; + } + } + if (image_info->verbose != MagickFalse) + { + /* + Display Dicom info. + */ + if (use_explicit == MagickFalse) + explicit_vr[0]='\0'; + for (i=0; dicom_info[i].description != (char *) NULL; i++) + if ((group == dicom_info[i].group) && + (element == dicom_info[i].element)) + break; + (void) FormatLocaleFile(stdout,"0x%04lX %4ld %s-%s (0x%04lx,0x%04lx)", + (unsigned long) image->offset,(long) length,implicit_vr,explicit_vr, + (unsigned long) group,(unsigned long) element); + if (dicom_info[i].description != (char *) NULL) + (void) FormatLocaleFile(stdout," %s",dicom_info[i].description); + (void) FormatLocaleFile(stdout,": "); + } + if ((group == 0x7FE0) && (element == 0x0010)) + { + if (image_info->verbose != MagickFalse) + (void) FormatLocaleFile(stdout,"\n"); + break; } + /* + Allocate space and read an array. + */ + data=(unsigned char *) NULL; + if ((length == 1) && (quantum == 1)) + datum=ReadBlobByte(image); else - if ((length == 1) && (quantum == 4)) + if ((length == 1) && (quantum == 2)) { if (group == 0x0002) - datum=ReadBlobLSBSignedLong(image); + datum=ReadBlobLSBSignedShort(image); else - datum=ReadBlobSignedLong(image); + datum=ReadBlobSignedShort(image); } else - if ((quantum != 0) && (length != 0)) + if ((length == 1) && (quantum == 4)) { - if (length > GetBlobSize(image)) - ThrowDCMException(CorruptImageError, - "InsufficientImageDataInFile"); - if (~length >= 1) - data=(unsigned char *) AcquireQuantumMemory(length+1,quantum* - sizeof(*data)); - if (data == (unsigned char *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - count=ReadBlob(image,(size_t) quantum*length,data); - if (count != (ssize_t) (quantum*length)) - { - if (image_info->verbose != MagickFalse) - (void) FormatLocaleFile(stdout,"count=%d quantum=%d " - "length=%d group=%d\n",(int) count,(int) quantum,(int) - length,(int) group); - ThrowDCMException(CorruptImageError, - "InsufficientImageDataInFile"); - } - data[length*quantum]='\0'; + if (group == 0x0002) + datum=ReadBlobLSBSignedLong(image); + else + datum=ReadBlobSignedLong(image); } - if ((((unsigned int) group << 16) | element) == 0xFFFEE0DD) - { - if (data != (unsigned char *) NULL) - data=(unsigned char *) RelinquishMagickMemory(data); - continue; - } - switch (group) - { - case 0x0002: + else + if ((quantum != 0) && (length != 0)) + { + if (length > (size_t) GetBlobSize(image)) + ThrowDCMException(CorruptImageError, + "InsufficientImageDataInFile"); + if (~length >= 1) + data=(unsigned char *) AcquireQuantumMemory(length+1,quantum* + sizeof(*data)); + if (data == (unsigned char *) NULL) + ThrowDCMException(ResourceLimitError, + "MemoryAllocationFailed"); + count=ReadBlob(image,(size_t) quantum*length,data); + if (count != (ssize_t) (quantum*length)) + { + if (image_info->verbose != MagickFalse) + (void) FormatLocaleFile(stdout,"count=%d quantum=%d " + "length=%d group=%d\n",(int) count,(int) quantum,(int) + length,(int) group); + ThrowDCMException(CorruptImageError, + "InsufficientImageDataInFile"); + } + data[length*quantum]='\0'; + } + if ((((unsigned int) group << 16) | element) == 0xFFFEE0DD) + { + if (data != (unsigned char *) NULL) + data=(unsigned char *) RelinquishMagickMemory(data); + continue; + } + switch (group) { - switch (element) + case 0x0002: { - case 0x0010: + switch (element) { - char - transfer_syntax[MagickPathExtent]; - - /* - Transfer Syntax. - */ - if ((datum == 0) && (explicit_retry == MagickFalse)) - { - explicit_retry=MagickTrue; - (void) SeekBlob(image,(MagickOffsetType) 0,SEEK_SET); - group=0; - element=0; - if (image_info->verbose != MagickFalse) - (void) FormatLocaleFile(stdout, - "Corrupted image - trying explicit format\n"); - break; - } - *transfer_syntax='\0'; - if (data != (unsigned char *) NULL) - (void) CopyMagickString(transfer_syntax,(char *) data, - MagickPathExtent); - if (image_info->verbose != MagickFalse) - (void) FormatLocaleFile(stdout,"transfer_syntax=%s\n", - (const char *) transfer_syntax); - if (strncmp(transfer_syntax,"1.2.840.10008.1.2",17) == 0) - { - int - subtype, - type; + case 0x0010: + { + char + transfer_syntax[MagickPathExtent]; - type=1; - subtype=0; - if (strlen(transfer_syntax) > 17) - { - count=(ssize_t) sscanf(transfer_syntax+17,".%d.%d",&type, - &subtype); - if (count < 1) - ThrowDCMException(CorruptImageError, - "ImproperImageHeader"); - } - switch (type) + /* + Transfer Syntax. + */ + if ((datum == 0) && (explicit_retry == MagickFalse)) { - case 1: - { - image->endian=LSBEndian; - break; - } - case 2: - { - image->endian=MSBEndian; - break; - } - case 4: + explicit_retry=MagickTrue; + (void) SeekBlob(image,(MagickOffsetType) 0,SEEK_SET); + group=0; + element=0; + if (image_info->verbose != MagickFalse) + (void) FormatLocaleFile(stdout, + "Corrupted image - trying explicit format\n"); + break; + } + *transfer_syntax='\0'; + if (data != (unsigned char *) NULL) + (void) CopyMagickString(transfer_syntax,(char *) data, + MagickPathExtent); + if (image_info->verbose != MagickFalse) + (void) FormatLocaleFile(stdout,"transfer_syntax=%s\n", + (const char *) transfer_syntax); + if (strncmp(transfer_syntax,"1.2.840.10008.1.2",17) == 0) + { + int + subtype, + type; + + type=1; + subtype=0; + if (strlen(transfer_syntax) > 17) + { + count=(ssize_t) sscanf(transfer_syntax+17,".%d.%d",&type, + &subtype); + if (count < 1) + ThrowDCMException(CorruptImageError, + "ImproperImageHeader"); + } + switch (type) { - if ((subtype >= 80) && (subtype <= 81)) - image->compression=JPEGCompression; - else - if ((subtype >= 90) && (subtype <= 93)) - image->compression=JPEG2000Compression; - else + case 1: + { + image->endian=LSBEndian; + break; + } + case 2: + { + image->endian=MSBEndian; + break; + } + case 4: + { + if ((subtype >= 80) && (subtype <= 81)) image->compression=JPEGCompression; - break; - } - case 5: - { - image->compression=RLECompression; - break; + else + if ((subtype >= 90) && (subtype <= 93)) + image->compression=JPEG2000Compression; + else + image->compression=JPEGCompression; + break; + } + case 5: + { + image->compression=RLECompression; + break; + } } } - } - break; + break; + } + default: + break; } - default: - break; + break; } - break; - } - case 0x0028: - { - switch (element) + case 0x0028: { - case 0x0002: - { - /* - Samples per pixel. - */ - info.samples_per_pixel=(size_t) datum; - if ((info.samples_per_pixel == 0) || (info.samples_per_pixel > 4)) - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - break; - } - case 0x0004: + switch (element) { - /* - Photometric interpretation. - */ - if (data == (unsigned char *) NULL) + case 0x0002: + { + /* + Samples per pixel. + */ + info.samples_per_pixel=(size_t) datum; + if ((info.samples_per_pixel == 0) || (info.samples_per_pixel > 4)) + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); break; - for (i=0; i < (ssize_t) MagickMin(length,MagickPathExtent-1); i++) - photometric[i]=(char) data[i]; - photometric[i]='\0'; - info.polarity=LocaleCompare(photometric,"MONOCHROME1 ") == 0 ? - MagickTrue : MagickFalse; - break; - } - case 0x0006: - { - /* - Planar configuration. - */ - if (datum == 1) - image->interlace=PlaneInterlace; - break; - } - case 0x0008: - { - /* - Number of frames. - */ - if (data == (unsigned char *) NULL) + } + case 0x0004: + { + /* + Photometric interpretation. + */ + if (data == (unsigned char *) NULL) + break; + for (i=0; i < (ssize_t) MagickMin(length,MagickPathExtent-1); i++) + photometric[i]=(char) data[i]; + photometric[i]='\0'; + info.polarity=LocaleCompare(photometric,"MONOCHROME1 ") == 0 ? + MagickTrue : MagickFalse; break; - number_scenes=StringToUnsignedLong((char *) data); - break; - } - case 0x0010: - { - /* - Image rows. - */ - height=(size_t) datum; - break; - } - case 0x0011: - { - /* - Image columns. - */ - width=(size_t) datum; - break; - } - case 0x0100: - { - /* - Bits allocated. - */ - info.bits_allocated=(size_t) datum; - info.bytes_per_pixel=1; - if (datum > 8) - info.bytes_per_pixel=2; - info.depth=info.bits_allocated; - if ((info.depth == 0) || (info.depth > 32)) - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - info.max_value=(1UL << info.bits_allocated)-1; - image->depth=info.depth; - break; - } - case 0x0101: - { - /* - Bits stored. - */ - info.significant_bits=(size_t) datum; - info.bytes_per_pixel=1; - if (info.significant_bits > 8) - info.bytes_per_pixel=2; - info.depth=info.significant_bits; - if ((info.depth == 0) || (info.depth > 16)) - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - info.max_value=(1UL << info.significant_bits)-1; - info.mask=(size_t) GetQuantumRange(info.significant_bits); - image->depth=info.depth; - break; - } - case 0x0102: - { - /* - High bit. - */ - break; - } - case 0x0103: - { - /* - Pixel representation. - */ - info.signed_data=(size_t) datum; - break; - } - case 0x1050: - { - /* - Visible pixel range: center. - */ - if (data != (unsigned char *) NULL) - info.window_center=StringToDouble((char *) data, (char **) NULL); - break; - } - case 0x1051: - { - /* - Visible pixel range: width. - */ - if (data != (unsigned char *) NULL) - info.window_width=StringToDouble((char *) data, (char **) NULL); - break; - } - case 0x1052: - { - /* - Rescale intercept - */ - if (data != (unsigned char *) NULL) - info.rescale_intercept=StringToDouble((char *) data, - (char **) NULL); - break; - } - case 0x1053: - { - /* - Rescale slope - */ - if (data != (unsigned char *) NULL) - info.rescale_slope=StringToDouble((char *) data, (char **) NULL); - break; - } - case 0x1200: - case 0x3006: - { - /* - Populate graymap. - */ - if (data == (unsigned char *) NULL) + } + case 0x0006: + { + /* + Planar configuration. + */ + if (datum == 1) + image->interlace=PlaneInterlace; break; - colors=(size_t) (length/info.bytes_per_pixel); - datum=(int) colors; - if (graymap != (int *) NULL) - graymap=(int *) RelinquishMagickMemory(graymap); - graymap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), - sizeof(*graymap)); - if (graymap == (int *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - (void) memset(graymap,0,MagickMax(colors,65536)* - sizeof(*graymap)); - for (i=0; i < (ssize_t) colors; i++) - if (info.bytes_per_pixel == 1) - graymap[i]=(int) data[i]; - else - graymap[i]=(int) ((short *) data)[i]; - break; - } - case 0x1201: - { - unsigned short - index; - - /* - Populate redmap. - */ - if (data == (unsigned char *) NULL) + } + case 0x0008: + { + /* + Number of frames. + */ + if (data == (unsigned char *) NULL) + break; + number_scenes=StringToUnsignedLong((char *) data); break; - colors=(size_t) (length/2); - datum=(int) colors; - if (redmap != (int *) NULL) - redmap=(int *) RelinquishMagickMemory(redmap); - redmap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), - sizeof(*redmap)); - if (redmap == (int *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - (void) memset(redmap,0,MagickMax(colors,65536)* - sizeof(*redmap)); - p=data; - for (i=0; i < (ssize_t) colors; i++) + } + case 0x0010: { - if (image->endian == MSBEndian) - index=(unsigned short) ((*p << 8) | *(p+1)); - else - index=(unsigned short) (*p | (*(p+1) << 8)); - redmap[i]=(int) index; - p+=2; + /* + Image rows. + */ + height=(size_t) datum; + break; } - break; - } - case 0x1202: - { - unsigned short - index; - - /* - Populate greenmap. - */ - if (data == (unsigned char *) NULL) + case 0x0011: + { + /* + Image columns. + */ + width=(size_t) datum; break; - colors=(size_t) (length/2); - datum=(int) colors; - if (greenmap != (int *) NULL) - greenmap=(int *) RelinquishMagickMemory(greenmap); - greenmap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), - sizeof(*greenmap)); - if (greenmap == (int *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - (void) memset(greenmap,0,MagickMax(colors,65536)* - sizeof(*greenmap)); - p=data; - for (i=0; i < (ssize_t) colors; i++) + } + case 0x0100: { - if (image->endian == MSBEndian) - index=(unsigned short) ((*p << 8) | *(p+1)); - else - index=(unsigned short) (*p | (*(p+1) << 8)); - greenmap[i]=(int) index; - p+=2; + /* + Bits allocated. + */ + info.bits_allocated=(size_t) datum; + info.bytes_per_pixel=1; + if (datum > 8) + info.bytes_per_pixel=2; + info.depth=info.bits_allocated; + if ((info.depth == 0) || (info.depth > 32)) + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); + info.max_value=(1UL << info.bits_allocated)-1; + image->depth=info.depth; + break; } - break; - } - case 0x1203: - { - unsigned short - index; - - /* - Populate bluemap. - */ - if (data == (unsigned char *) NULL) + case 0x0101: + { + /* + Bits stored. + */ + info.significant_bits=(size_t) datum; + info.bytes_per_pixel=1; + if (info.significant_bits > 8) + info.bytes_per_pixel=2; + info.depth=info.significant_bits; + if ((info.depth == 0) || (info.depth > 16)) + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); + info.max_value=(1UL << info.significant_bits)-1; + info.mask=(size_t) GetQuantumRange(info.significant_bits); + image->depth=info.depth; break; - colors=(size_t) (length/2); - datum=(int) colors; - if (bluemap != (int *) NULL) - bluemap=(int *) RelinquishMagickMemory(bluemap); - bluemap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), - sizeof(*bluemap)); - if (bluemap == (int *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - (void) memset(bluemap,0,MagickMax(colors,65536)* - sizeof(*bluemap)); - p=data; - for (i=0; i < (ssize_t) colors; i++) + } + case 0x0102: { - if (image->endian == MSBEndian) - index=(unsigned short) ((*p << 8) | *(p+1)); - else - index=(unsigned short) (*p | (*(p+1) << 8)); - bluemap[i]=(int) index; - p+=2; + /* + High bit. + */ + break; } - break; - } - default: - break; - } - break; - } - case 0x2050: - { - switch (element) - { - case 0x0020: - { - if ((data != (unsigned char *) NULL) && - (strncmp((char *) data,"INVERSE",7) == 0)) - info.polarity=MagickTrue; - break; - } - default: - break; - } - break; - } - default: - break; - } - if (data != (unsigned char *) NULL) - { - char - *attribute; + case 0x0103: + { + /* + Pixel representation. + */ + info.signed_data=(size_t) datum; + break; + } + case 0x1050: + { + /* + Visible pixel range: center. + */ + if (data != (unsigned char *) NULL) + info.window_center=StringToDouble((char *) data,(char **) NULL); + break; + } + case 0x1051: + { + /* + Visible pixel range: width. + */ + if (data != (unsigned char *) NULL) + info.window_width=StringToDouble((char *) data,(char **) NULL); + break; + } + case 0x1052: + { + /* + Rescale intercept + */ + if (data != (unsigned char *) NULL) + info.rescale_intercept=StringToDouble((char *) data, + (char **) NULL); + break; + } + case 0x1053: + { + /* + Rescale slope + */ + if (data != (unsigned char *) NULL) + info.rescale_slope=StringToDouble((char *) data,(char **) NULL); + break; + } + case 0x1200: + case 0x3006: + { + /* + Populate graymap. + */ + if (data == (unsigned char *) NULL) + break; + colors=(size_t) (length/info.bytes_per_pixel); + datum=(int) colors; + if (graymap != (int *) NULL) + graymap=(int *) RelinquishMagickMemory(graymap); + graymap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), + sizeof(*graymap)); + if (graymap == (int *) NULL) + ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); + (void) memset(graymap,0,MagickMax(colors,65536)* + sizeof(*graymap)); + for (i=0; i < (ssize_t) colors; i++) + if (info.bytes_per_pixel == 1) + graymap[i]=(int) data[i]; + else + graymap[i]=(int) ((short *) data)[i]; + break; + } + case 0x1201: + { + unsigned short + index; - for (i=0; dicom_info[i].description != (char *) NULL; i++) - if ((group == dicom_info[i].group) && - (element == dicom_info[i].element)) - break; - if (dicom_info[i].description != (char *) NULL) - { - attribute=AcquireString("dcm:"); - (void) ConcatenateString(&attribute,dicom_info[i].description); - for (i=0; i < (ssize_t) MagickMax(length,4); i++) - if (isprint((int) data[i]) == MagickFalse) + /* + Populate redmap. + */ + if (data == (unsigned char *) NULL) break; - if ((i == (ssize_t) length) || (length > 4)) + colors=(size_t) (length/2); + datum=(int) colors; + if (redmap != (int *) NULL) + redmap=(int *) RelinquishMagickMemory(redmap); + redmap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), + sizeof(*redmap)); + if (redmap == (int *) NULL) + ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); + (void) memset(redmap,0,MagickMax(colors,65536)* + sizeof(*redmap)); + p=data; + for (i=0; i < (ssize_t) colors; i++) { - (void) SubstituteString(&attribute," ",""); - (void) SetImageProperty(image,attribute,(char *) data, - exception); + if (image->endian == MSBEndian) + index=(unsigned short) ((*p << 8) | *(p+1)); + else + index=(unsigned short) (*p | (*(p+1) << 8)); + redmap[i]=(int) index; + p+=2; } - attribute=DestroyString(attribute); - } - } - if (image_info->verbose != MagickFalse) - { - if (data == (unsigned char *) NULL) - (void) FormatLocaleFile(stdout,"%d\n",datum); - else - { - /* - Display group data. - */ - for (i=0; i < (ssize_t) MagickMax(length,4); i++) - if (isprint((int) data[i]) == MagickFalse) + break; + } + case 0x1202: + { + unsigned short + index; + + /* + Populate greenmap. + */ + if (data == (unsigned char *) NULL) break; - if ((i != (ssize_t) length) && (length <= 4)) + colors=(size_t) (length/2); + datum=(int) colors; + if (greenmap != (int *) NULL) + greenmap=(int *) RelinquishMagickMemory(greenmap); + greenmap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), + sizeof(*greenmap)); + if (greenmap == (int *) NULL) + ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); + (void) memset(greenmap,0,MagickMax(colors,65536)* + sizeof(*greenmap)); + p=data; + for (i=0; i < (ssize_t) colors; i++) { - ssize_t - j; - - datum=0; - for (j=(ssize_t) length-1; j >= 0; j--) - datum=(256*datum+data[j]); - (void) FormatLocaleFile(stdout,"%d",datum); + if (image->endian == MSBEndian) + index=(unsigned short) ((*p << 8) | *(p+1)); + else + index=(unsigned short) (*p | (*(p+1) << 8)); + greenmap[i]=(int) index; + p+=2; } - else - for (i=0; i < (ssize_t) length; i++) - if (isprint((int) data[i]) != MagickFalse) - (void) FormatLocaleFile(stdout,"%c",data[i]); + break; + } + case 0x1203: + { + unsigned short + index; + + /* + Populate bluemap. + */ + if (data == (unsigned char *) NULL) + break; + colors=(size_t) (length/2); + datum=(int) colors; + if (bluemap != (int *) NULL) + bluemap=(int *) RelinquishMagickMemory(bluemap); + bluemap=(int *) AcquireQuantumMemory(MagickMax(colors,65536), + sizeof(*bluemap)); + if (bluemap == (int *) NULL) + ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); + (void) memset(bluemap,0,MagickMax(colors,65536)* + sizeof(*bluemap)); + p=data; + for (i=0; i < (ssize_t) colors; i++) + { + if (image->endian == MSBEndian) + index=(unsigned short) ((*p << 8) | *(p+1)); else - (void) FormatLocaleFile(stdout,"%c",'.'); - (void) FormatLocaleFile(stdout,"\n"); + index=(unsigned short) (*p | (*(p+1) << 8)); + bluemap[i]=(int) index; + p+=2; + } + break; + } + default: + break; } + break; + } + case 0x2050: + { + switch (element) + { + case 0x0020: + { + if ((data != (unsigned char *) NULL) && + (strncmp((char *) data,"INVERSE",7) == 0)) + info.polarity=MagickTrue; + break; + } + default: + break; + } + break; + } + default: + break; } - if (data != (unsigned char *) NULL) - data=(unsigned char *) RelinquishMagickMemory(data); - if (EOFBlob(image) != MagickFalse) - { - ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", - image->filename); - break; - } - } - if ((width == 0) || (height == 0)) - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - image->columns=(size_t) width; - image->rows=(size_t) height; - if (info.signed_data == 0xffff) - info.signed_data=(size_t) (info.significant_bits == 16 ? 1 : 0); - if ((image->compression == JPEGCompression) || - (image->compression == JPEG2000Compression)) - { - Image - *images; - - ImageInfo - *read_info; + if (data != (unsigned char *) NULL) + { + char + *attribute; - int - c; + for (i=0; dicom_info[i].description != (char *) NULL; i++) + if ((group == dicom_info[i].group) && + (element == dicom_info[i].element)) + break; + if (dicom_info[i].description != (char *) NULL) + { + attribute=AcquireString("dcm:"); + (void) ConcatenateString(&attribute,dicom_info[i].description); + for (i=0; i < (ssize_t) MagickMax(length,4); i++) + if (isprint((int) data[i]) == MagickFalse) + break; + if ((i == (ssize_t) length) || (length > 4)) + { + (void) SubstituteString(&attribute," ",""); + (void) SetImageProperty(image,attribute,(char *) data, + exception); + } + attribute=DestroyString(attribute); + } + } + if (image_info->verbose != MagickFalse) + { + if (data == (unsigned char *) NULL) + (void) FormatLocaleFile(stdout,"%d\n",datum); + else + { + /* + Display group data. + */ + for (i=0; i < (ssize_t) MagickMax(length,4); i++) + if (isprint((int) data[i]) == MagickFalse) + break; + if ((i != (ssize_t) length) && (length <= 4)) + { + ssize_t + j; - /* - Read offset table. - */ - for (i=0; i < (ssize_t) stream_info->remaining; i++) - if (ReadBlobByte(image) == EOF) - break; - (void) (((ssize_t) ReadBlobLSBShort(image) << 16) | - ReadBlobLSBShort(image)); - length=(size_t) ReadBlobLSBLong(image); - if (length > GetBlobSize(image)) - ThrowDCMException(CorruptImageError,"InsufficientImageDataInFile"); - stream_info->offset_count=length >> 2; - if (stream_info->offset_count != 0) + datum=0; + for (j=(ssize_t) length-1; j >= 0; j--) + datum=(256*datum+data[j]); + (void) FormatLocaleFile(stdout,"%d",datum); + } + else + for (i=0; i < (ssize_t) length; i++) + if (isprint((int) data[i]) != MagickFalse) + (void) FormatLocaleFile(stdout,"%c",data[i]); + else + (void) FormatLocaleFile(stdout,"%c",'.'); + (void) FormatLocaleFile(stdout,"\n"); + } + } + if (data != (unsigned char *) NULL) + data=(unsigned char *) RelinquishMagickMemory(data); + if (EOFBlob(image) != MagickFalse) { - if (stream_info->offsets != (ssize_t *) NULL) - stream_info->offsets=(ssize_t *) RelinquishMagickMemory( - stream_info->offsets); - stream_info->offsets=(ssize_t *) AcquireQuantumMemory( - stream_info->offset_count,sizeof(*stream_info->offsets)); - if (stream_info->offsets == (ssize_t *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - for (i=0; i < (ssize_t) stream_info->offset_count; i++) - stream_info->offsets[i]=(ssize_t) ReadBlobLSBSignedLong(image); - offset=TellBlob(image); - for (i=0; i < (ssize_t) stream_info->offset_count; i++) - stream_info->offsets[i]+=offset; + ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", + image->filename); + break; } - /* - Handle non-native image formats. - */ - read_info=CloneImageInfo(image_info); - SetImageInfoBlob(read_info,(void *) NULL,0); - images=NewImageList(); - for (scene=0; scene < (ssize_t) number_scenes; scene++) + } + if ((group == 0xfffc) && (element == 0xfffc)) { - char - filename[MagickPathExtent]; - - const char - *property; - - FILE - *file; + Image + *last; + last=RemoveLastImageFromList(&image); + if (last != (Image *) NULL) + last=DestroyImage(last); + break; + } + if ((width == 0) || (height == 0)) + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); + image->columns=(size_t) width; + image->rows=(size_t) height; + if (info.signed_data == 0xffff) + info.signed_data=(size_t) (info.significant_bits == 16 ? 1 : 0); + if ((image->compression == JPEGCompression) || + (image->compression == JPEG2000Compression)) + { Image - *jpeg_image; + *images; - int - unique_file; + ImageInfo + *read_info; - unsigned int - tag; + int + c; - tag=((unsigned int) ReadBlobLSBShort(image) << 16) | - ReadBlobLSBShort(image); + /* + Read offset table. + */ + for (i=0; i < (ssize_t) stream_info->remaining; i++) + if (ReadBlobByte(image) == EOF) + break; + (void) (((ssize_t) ReadBlobLSBShort(image) << 16) | + ReadBlobLSBShort(image)); length=(size_t) ReadBlobLSBLong(image); - if (tag == 0xFFFEE0DD) - break; /* sequence delimiter tag */ - if (tag != 0xFFFEE000) - { - read_info=DestroyImageInfo(read_info); - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - } - file=(FILE *) NULL; - unique_file=AcquireUniqueFileResource(filename); - if (unique_file != -1) - file=fdopen(unique_file,"wb"); - if (file == (FILE *) NULL) + if (length > (size_t) GetBlobSize(image)) + ThrowDCMException(CorruptImageError,"InsufficientImageDataInFile"); + stream_info->offset_count=length >> 2; + if (stream_info->offset_count != 0) { - (void) RelinquishUniqueFileResource(filename); - ThrowFileException(exception,FileOpenError, - "UnableToCreateTemporaryFile",filename); - break; + if (stream_info->offsets != (ssize_t *) NULL) + stream_info->offsets=(ssize_t *) RelinquishMagickMemory( + stream_info->offsets); + stream_info->offsets=(ssize_t *) AcquireQuantumMemory( + stream_info->offset_count,sizeof(*stream_info->offsets)); + if (stream_info->offsets == (ssize_t *) NULL) + ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); + for (i=0; i < (ssize_t) stream_info->offset_count; i++) + stream_info->offsets[i]=(ssize_t) ReadBlobLSBSignedLong(image); + offset=TellBlob(image); + for (i=0; i < (ssize_t) stream_info->offset_count; i++) + stream_info->offsets[i]+=offset; } - for (c=EOF; length != 0; length--) + /* + Handle non-native image formats. + */ + read_info=CloneImageInfo(image_info); + SetImageInfoBlob(read_info,(void *) NULL,0); + images=NewImageList(); + for (scene=0; scene < (ssize_t) number_scenes; scene++) { - c=ReadBlobByte(image); - if (c == EOF) + char + filename[MagickPathExtent]; + + const char + *property; + + FILE + *file; + + Image + *jpeg_image; + + int + unique_file; + + unsigned int + tag; + + tag=((unsigned int) ReadBlobLSBShort(image) << 16) | + ReadBlobLSBShort(image); + length=(size_t) ReadBlobLSBLong(image); + if (tag == 0xFFFEE0DD) + break; /* sequence delimiter tag */ + if (tag != 0xFFFEE000) + { + read_info=DestroyImageInfo(read_info); + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); + } + file=(FILE *) NULL; + unique_file=AcquireUniqueFileResource(filename); + if (unique_file != -1) + file=fdopen(unique_file,"wb"); + if (file == (FILE *) NULL) { - ThrowFileException(exception,CorruptImageError, - "UnexpectedEndOfFile",image->filename); + (void) RelinquishUniqueFileResource(filename); + ThrowFileException(exception,FileOpenError, + "UnableToCreateTemporaryFile",filename); break; } - (void) fputc(c,file); - } - (void) fclose(file); - if (c == EOF) - break; - (void) FormatLocaleString(read_info->filename,MagickPathExtent, - "jpeg:%s",filename); - if (image->compression == JPEG2000Compression) - (void) FormatLocaleString(read_info->filename,MagickPathExtent, - "j2k:%s",filename); - jpeg_image=ReadImage(read_info,exception); - if (jpeg_image != (Image *) NULL) + for (c=EOF; length != 0; length--) { - ResetImagePropertyIterator(image); - property=GetNextImageProperty(image); - while (property != (const char *) NULL) + c=ReadBlobByte(image); + if (c == EOF) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + (void) fputc(c,file); + } + (void) fclose(file); + if (c == EOF) + break; + (void) FormatLocaleString(read_info->filename,MagickPathExtent, + "jpeg:%s",filename); + if (image->compression == JPEG2000Compression) + (void) FormatLocaleString(read_info->filename,MagickPathExtent, + "j2k:%s",filename); + jpeg_image=ReadImage(read_info,exception); + if (jpeg_image != (Image *) NULL) { - (void) SetImageProperty(jpeg_image,property, - GetImageProperty(image,property,exception),exception); + ResetImagePropertyIterator(image); property=GetNextImageProperty(image); + while (property != (const char *) NULL) + { + (void) SetImageProperty(jpeg_image,property, + GetImageProperty(image,property,exception),exception); + property=GetNextImageProperty(image); + } + AppendImageToList(&images,jpeg_image); } - AppendImageToList(&images,jpeg_image); - } - (void) RelinquishUniqueFileResource(filename); - } - read_info=DestroyImageInfo(read_info); - if (stream_info->offsets != (ssize_t *) NULL) - stream_info->offsets=(ssize_t *) - RelinquishMagickMemory(stream_info->offsets); - stream_info=(DCMStreamInfo *) RelinquishMagickMemory(stream_info); - if (info.scale != (Quantum *) NULL) - info.scale=(Quantum *) RelinquishMagickMemory(info.scale); - if (graymap != (int *) NULL) - graymap=(int *) RelinquishMagickMemory(graymap); - if (bluemap != (int *) NULL) - bluemap=(int *) RelinquishMagickMemory(bluemap); - if (greenmap != (int *) NULL) - greenmap=(int *) RelinquishMagickMemory(greenmap); - if (redmap != (int *) NULL) - redmap=(int *) RelinquishMagickMemory(redmap); - image=DestroyImage(image); - return(GetFirstImageInList(images)); - } - if (info.depth != (1UL*MAGICKCORE_QUANTUM_DEPTH)) - { - QuantumAny - range; - - /* - Compute pixel scaling table. - */ - length=(size_t) (GetQuantumRange(info.depth)+1); - if (length > GetBlobSize(image)) - ThrowDCMException(CorruptImageError,"InsufficientImageDataInFile"); - info.scale=(Quantum *) AcquireQuantumMemory(MagickMax(length,256), - sizeof(*info.scale)); - if (info.scale == (Quantum *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - (void) memset(info.scale,0,MagickMax(length,256)* - sizeof(*info.scale)); - range=GetQuantumRange(info.depth); - for (i=0; i <= (ssize_t) GetQuantumRange(info.depth); i++) - info.scale[i]=ScaleAnyToQuantum((size_t) i,range); - } - if (image->compression == RLECompression) - { - unsigned int - tag; - - /* - Read RLE offset table. - */ - for (i=0; i < (ssize_t) stream_info->remaining; i++) - { - int - c; - - c=ReadBlobByte(image); - if (c == EOF) - break; - } - tag=((unsigned int) ReadBlobLSBShort(image) << 16) | - ReadBlobLSBShort(image); - (void) tag; - length=(size_t) ReadBlobLSBLong(image); - if (length > GetBlobSize(image)) - ThrowDCMException(CorruptImageError,"InsufficientImageDataInFile"); - stream_info->offset_count=length >> 2; - if (stream_info->offset_count != 0) - { - stream_info->offsets=(ssize_t *) AcquireQuantumMemory( - stream_info->offset_count,sizeof(*stream_info->offsets)); - if (stream_info->offsets == (ssize_t *) NULL) - ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - for (i=0; i < (ssize_t) stream_info->offset_count; i++) - { - stream_info->offsets[i]=(ssize_t) ReadBlobLSBSignedLong(image); - if (EOFBlob(image) != MagickFalse) - break; - } - offset=TellBlob(image)+8; - for (i=0; i < (ssize_t) stream_info->offset_count; i++) - stream_info->offsets[i]+=offset; + (void) RelinquishUniqueFileResource(filename); } - } - for (scene=0; scene < (ssize_t) number_scenes; scene++) - { - if (image_info->ping != MagickFalse) - break; - image->columns=(size_t) width; - image->rows=(size_t) height; - image->depth=info.depth; - status=SetImageExtent(image,image->columns,image->rows,exception); - if (status == MagickFalse) - break; - image->colorspace=RGBColorspace; - (void) SetImageBackgroundColor(image,exception); - if ((image->colormap == (PixelInfo *) NULL) && - (info.samples_per_pixel == 1)) + read_info=DestroyImageInfo(read_info); + if (stream_info->offsets != (ssize_t *) NULL) + stream_info->offsets=(ssize_t *) + RelinquishMagickMemory(stream_info->offsets); + stream_info=(DCMStreamInfo *) RelinquishMagickMemory(stream_info); + if (info.scale != (Quantum *) NULL) + info.scale=(Quantum *) RelinquishMagickMemory(info.scale); + if (graymap != (int *) NULL) + graymap=(int *) RelinquishMagickMemory(graymap); + if (bluemap != (int *) NULL) + bluemap=(int *) RelinquishMagickMemory(bluemap); + if (greenmap != (int *) NULL) + greenmap=(int *) RelinquishMagickMemory(greenmap); + if (redmap != (int *) NULL) + redmap=(int *) RelinquishMagickMemory(redmap); + image=DestroyImage(image); + return(GetFirstImageInList(images)); + } + if (info.depth != (1UL*MAGICKCORE_QUANTUM_DEPTH)) { - int - index; - - size_t - one; + QuantumAny + range; - one=1; - if (colors == 0) - colors=one << info.depth; - if (AcquireImageColormap(image,colors,exception) == MagickFalse) + /* + Compute pixel scaling table. + */ + length=(size_t) (GetQuantumRange(info.depth)+1); + if (length > (size_t) GetBlobSize(image)) + ThrowDCMException(CorruptImageError,"InsufficientImageDataInFile"); + info.scale=(Quantum *) AcquireQuantumMemory(MagickMax(length,256), + sizeof(*info.scale)); + if (info.scale == (Quantum *) NULL) ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); - if (redmap != (int *) NULL) - for (i=0; i < (ssize_t) colors; i++) - { - index=redmap[i]; - if ((info.scale != (Quantum *) NULL) && (index >= 0) && - (index <= (int) info.max_value)) - index=(int) info.scale[index]; - image->colormap[i].red=(MagickRealType) index; - } - if (greenmap != (int *) NULL) - for (i=0; i < (ssize_t) colors; i++) - { - index=greenmap[i]; - if ((info.scale != (Quantum *) NULL) && (index >= 0) && - (index <= (int) info.max_value)) - index=(int) info.scale[index]; - image->colormap[i].green=(MagickRealType) index; - } - if (bluemap != (int *) NULL) - for (i=0; i < (ssize_t) colors; i++) - { - index=bluemap[i]; - if ((info.scale != (Quantum *) NULL) && (index >= 0) && - (index <= (int) info.max_value)) - index=(int) info.scale[index]; - image->colormap[i].blue=(MagickRealType) index; - } - if (graymap != (int *) NULL) - for (i=0; i < (ssize_t) colors; i++) - { - index=graymap[i]; - if ((info.scale != (Quantum *) NULL) && (index >= 0) && - (index <= (int) info.max_value)) - index=(int) info.scale[index]; - image->colormap[i].red=(MagickRealType) index; - image->colormap[i].green=(MagickRealType) index; - image->colormap[i].blue=(MagickRealType) index; - } + (void) memset(info.scale,0,MagickMax(length,256)* + sizeof(*info.scale)); + range=GetQuantumRange(info.depth); + for (i=0; i <= (ssize_t) GetQuantumRange(info.depth); i++) + info.scale[i]=ScaleAnyToQuantum((size_t) i,range); } if (image->compression == RLECompression) { @@ -4023,7 +3950,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception) tag; /* - Read RLE segment table. + Read RLE offset table. */ for (i=0; i < (ssize_t) stream_info->remaining; i++) { @@ -4036,154 +3963,279 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception) } tag=((unsigned int) ReadBlobLSBShort(image) << 16) | ReadBlobLSBShort(image); - stream_info->remaining=(size_t) ReadBlobLSBLong(image); - if ((tag != 0xFFFEE000) || (stream_info->remaining <= 64) || - (EOFBlob(image) != MagickFalse)) - { - if (stream_info->offsets != (ssize_t *) NULL) - stream_info->offsets=(ssize_t *) - RelinquishMagickMemory(stream_info->offsets); - ThrowDCMException(CorruptImageError,"ImproperImageHeader"); - } - stream_info->count=0; - stream_info->segment_count=ReadBlobLSBLong(image); - for (i=0; i < 15; i++) - stream_info->segments[i]=(ssize_t) ReadBlobLSBSignedLong(image); - stream_info->remaining-=64; - if (stream_info->segment_count > 1) + (void) tag; + length=(size_t) ReadBlobLSBLong(image); + if (length > (size_t) GetBlobSize(image)) + ThrowDCMException(CorruptImageError,"InsufficientImageDataInFile"); + stream_info->offset_count=length >> 2; + if (stream_info->offset_count != 0) { - info.bytes_per_pixel=1; - info.depth=8; - if (stream_info->offset_count > 0) - (void) SeekBlob(image,(MagickOffsetType) stream_info->offsets[0]+ - stream_info->segments[0],SEEK_SET); + stream_info->offsets=(ssize_t *) AcquireQuantumMemory( + stream_info->offset_count,sizeof(*stream_info->offsets)); + if (stream_info->offsets == (ssize_t *) NULL) + ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); + for (i=0; i < (ssize_t) stream_info->offset_count; i++) + { + stream_info->offsets[i]=(ssize_t) ReadBlobLSBSignedLong(image); + if (EOFBlob(image) != MagickFalse) + break; + } + offset=TellBlob(image)+8; + for (i=0; i < (ssize_t) stream_info->offset_count; i++) + stream_info->offsets[i]+=offset; } } - if ((info.samples_per_pixel > 1) && (image->interlace == PlaneInterlace)) - { - register ssize_t - x; - - register Quantum - *q; + for (scene=0; scene < (ssize_t) number_scenes; scene++) + { + if (image_info->ping != MagickFalse) + break; + image->columns=(size_t) width; + image->rows=(size_t) height; + image->depth=info.depth; + status=SetImageExtent(image,image->columns,image->rows,exception); + if (status == MagickFalse) + break; + image->colorspace=RGBColorspace; + (void) SetImageBackgroundColor(image,exception); + if ((image->colormap == (PixelInfo *) NULL) && + (info.samples_per_pixel == 1)) + { + int + index; - ssize_t - y; + size_t + one; - /* - Convert Planar RGB DCM Medical image to pixel packets. - */ - for (i=0; i < (ssize_t) info.samples_per_pixel; i++) + one=1; + if (colors == 0) + colors=one << info.depth; + if (AcquireImageColormap(image,colors,exception) == MagickFalse) + ThrowDCMException(ResourceLimitError,"MemoryAllocationFailed"); + if (redmap != (int *) NULL) + for (i=0; i < (ssize_t) colors; i++) + { + index=redmap[i]; + if ((info.scale != (Quantum *) NULL) && (index >= 0) && + (index <= (int) info.max_value)) + index=(int) info.scale[index]; + image->colormap[i].red=(MagickRealType) index; + } + if (greenmap != (int *) NULL) + for (i=0; i < (ssize_t) colors; i++) + { + index=greenmap[i]; + if ((info.scale != (Quantum *) NULL) && (index >= 0) && + (index <= (int) info.max_value)) + index=(int) info.scale[index]; + image->colormap[i].green=(MagickRealType) index; + } + if (bluemap != (int *) NULL) + for (i=0; i < (ssize_t) colors; i++) + { + index=bluemap[i]; + if ((info.scale != (Quantum *) NULL) && (index >= 0) && + (index <= (int) info.max_value)) + index=(int) info.scale[index]; + image->colormap[i].blue=(MagickRealType) index; + } + if (graymap != (int *) NULL) + for (i=0; i < (ssize_t) colors; i++) + { + index=graymap[i]; + if ((info.scale != (Quantum *) NULL) && (index >= 0) && + (index <= (int) info.max_value)) + index=(int) info.scale[index]; + image->colormap[i].red=(MagickRealType) index; + image->colormap[i].green=(MagickRealType) index; + image->colormap[i].blue=(MagickRealType) index; + } + } + if (image->compression == RLECompression) { - for (y=0; y < (ssize_t) image->rows; y++) + unsigned int + tag; + + /* + Read RLE segment table. + */ + for (i=0; i < (ssize_t) stream_info->remaining; i++) { - q=GetAuthenticPixels(image,0,y,image->columns,1,exception); - if (q == (Quantum *) NULL) + int + c; + + c=ReadBlobByte(image); + if (c == EOF) break; - for (x=0; x < (ssize_t) image->columns; x++) + } + tag=((unsigned int) ReadBlobLSBShort(image) << 16) | + ReadBlobLSBShort(image); + stream_info->remaining=(size_t) ReadBlobLSBLong(image); + if ((tag != 0xFFFEE000) || (stream_info->remaining <= 64) || + (EOFBlob(image) != MagickFalse)) + { + if (stream_info->offsets != (ssize_t *) NULL) + stream_info->offsets=(ssize_t *) + RelinquishMagickMemory(stream_info->offsets); + ThrowDCMException(CorruptImageError,"ImproperImageHeader"); + } + stream_info->count=0; + stream_info->segment_count=ReadBlobLSBLong(image); + for (i=0; i < 15; i++) + stream_info->segments[i]=(ssize_t) ReadBlobLSBSignedLong(image); + stream_info->remaining-=64; + if (stream_info->segment_count > 1) { - switch ((int) i) + info.bytes_per_pixel=1; + info.depth=8; + if (stream_info->offset_count > 0) + (void) SeekBlob(image,(MagickOffsetType) + stream_info->offsets[0]+stream_info->segments[0],SEEK_SET); + } + } + if ((info.samples_per_pixel > 1) && (image->interlace == PlaneInterlace)) + { + register ssize_t + x; + + register Quantum + *q; + + ssize_t + y; + + /* + Convert Planar RGB DCM Medical image to pixel packets. + */ + for (i=0; i < (ssize_t) info.samples_per_pixel; i++) + { + for (y=0; y < (ssize_t) image->rows; y++) + { + q=GetAuthenticPixels(image,0,y,image->columns,1,exception); + if (q == (Quantum *) NULL) + break; + for (x=0; x < (ssize_t) image->columns; x++) { - case 0: - { - SetPixelRed(image,ScaleCharToQuantum((unsigned char) - ReadDCMByte(stream_info,image)),q); - break; - } - case 1: + switch ((int) i) { - SetPixelGreen(image,ScaleCharToQuantum((unsigned char) - ReadDCMByte(stream_info,image)),q); - break; - } - case 2: - { - SetPixelBlue(image,ScaleCharToQuantum((unsigned char) - ReadDCMByte(stream_info,image)),q); - break; + case 0: + { + SetPixelRed(image,ScaleCharToQuantum((unsigned char) + ReadDCMByte(stream_info,image)),q); + break; + } + case 1: + { + SetPixelGreen(image,ScaleCharToQuantum((unsigned char) + ReadDCMByte(stream_info,image)),q); + break; + } + case 2: + { + SetPixelBlue(image,ScaleCharToQuantum((unsigned char) + ReadDCMByte(stream_info,image)),q); + break; + } + case 3: + { + SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) + ReadDCMByte(stream_info,image)),q); + break; + } + default: + break; } - case 3: + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + if (image->previous == (Image *) NULL) { - SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) - ReadDCMByte(stream_info,image)),q); - break; + status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) + y,image->rows); + if (status == MagickFalse) + break; } - default: - break; - } - q+=GetPixelChannels(image); } - if (SyncAuthenticPixels(image,exception) == MagickFalse) - break; - if (image->previous == (Image *) NULL) - { - status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) - break; - } } } - } - else - { - const char - *option; + else + { + const char + *option; - /* - Convert DCM Medical image to pixel packets. - */ - option=GetImageOption(image_info,"dcm:display-range"); - if (option != (const char *) NULL) - { - if (LocaleCompare(option,"reset") == 0) - info.window_width=0; - } - option=GetImageOption(image_info,"dcm:window"); - if (option != (char *) NULL) - { - GeometryInfo - geometry_info; + /* + Convert DCM Medical image to pixel packets. + */ + option=GetImageOption(image_info,"dcm:display-range"); + if (option != (const char *) NULL) + { + if (LocaleCompare(option,"reset") == 0) + info.window_width=0; + } + option=GetImageOption(image_info,"dcm:window"); + if (option != (char *) NULL) + { + GeometryInfo + geometry_info; - MagickStatusType - flags; + MagickStatusType + flags; - flags=ParseGeometry(option,&geometry_info); - if (flags & RhoValue) - info.window_center=geometry_info.rho; - if (flags & SigmaValue) - info.window_width=geometry_info.sigma; - info.rescale=MagickTrue; - } - option=GetImageOption(image_info,"dcm:rescale"); - if (option != (char *) NULL) - info.rescale=IsStringTrue(option); - if ((info.window_center != 0) && (info.window_width == 0)) - info.window_width=info.window_center; - status=ReadDCMPixels(image,&info,stream_info,MagickTrue,exception); - if ((status != MagickFalse) && (stream_info->segment_count > 1)) - { - if (stream_info->offset_count > 0) - (void) SeekBlob(image,(MagickOffsetType) stream_info->offsets[0]+ - stream_info->segments[1],SEEK_SET); - (void) ReadDCMPixels(image,&info,stream_info,MagickFalse,exception); - } - } - if (SetImageGray(image,exception) != MagickFalse) - (void) SetImageColorspace(image,GRAYColorspace,exception); - if (EOFBlob(image) != MagickFalse) - { - ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", - image->filename); - break; - } - /* - Proceed to next image. - */ - if (image_info->number_scenes != 0) - if (image->scene >= (image_info->scene+image_info->number_scenes-1)) - break; - if (scene < (ssize_t) (number_scenes-1)) + flags=ParseGeometry(option,&geometry_info); + if (flags & RhoValue) + info.window_center=geometry_info.rho; + if (flags & SigmaValue) + info.window_width=geometry_info.sigma; + info.rescale=MagickTrue; + } + option=GetImageOption(image_info,"dcm:rescale"); + if (option != (char *) NULL) + info.rescale=IsStringTrue(option); + if ((info.window_center != 0) && (info.window_width == 0)) + info.window_width=info.window_center; + status=ReadDCMPixels(image,&info,stream_info,MagickTrue,exception); + if ((status != MagickFalse) && (stream_info->segment_count > 1)) + { + if (stream_info->offset_count > 0) + (void) SeekBlob(image,(MagickOffsetType) + stream_info->offsets[0]+stream_info->segments[1],SEEK_SET); + (void) ReadDCMPixels(image,&info,stream_info,MagickFalse, + exception); + } + } + if (SetImageGray(image,exception) != MagickFalse) + (void) SetImageColorspace(image,GRAYColorspace,exception); + if (EOFBlob(image) != MagickFalse) + { + ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", + image->filename); + break; + } + /* + Proceed to next image. + */ + if (image_info->number_scenes != 0) + if (image->scene >= (image_info->scene+image_info->number_scenes-1)) + break; + if (scene < (ssize_t) (number_scenes-1)) + { + /* + Allocate next image structure. + */ + AcquireNextImage(image_info,image,exception); + if (GetNextImageInList(image) == (Image *) NULL) + { + image=DestroyImageList(image); + return((Image *) NULL); + } + image=SyncNextImageInList(image); + status=SetImageProgress(image,LoadImagesTag,TellBlob(image), + GetBlobSize(image)); + if (status == MagickFalse) + break; + } + } + if (TellBlob(image) < (MagickOffsetType) GetBlobSize(image)) { /* Allocate next image structure. @@ -4199,7 +4251,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception) GetBlobSize(image)); if (status == MagickFalse) break; - } + } } /* Free resources.