Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
GraphicsMagick.9821
GraphicsMagick-dcm.c-update-2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File GraphicsMagick-dcm.c-update-2.patch of Package GraphicsMagick.9821
Index: GraphicsMagick-1.3.25/coders/dcm.c =================================================================== --- GraphicsMagick-1.3.25.orig/coders/dcm.c 2018-06-13 20:15:45.674498775 +0200 +++ GraphicsMagick-1.3.25/coders/dcm.c 2018-06-13 20:16:37.039244592 +0200 @@ -1,5 +1,5 @@ /* -% Copyright (C) 2003-2017 GraphicsMagick Group +% Copyright (C) 2003-2018 GraphicsMagick Group % Copyright (C) 2002 ImageMagick Studio % Copyright 1991-1999 E. I. du Pont de Nemours and Company % @@ -183,7 +183,7 @@ typedef struct _DicomStream lower_lim; Quantum - *rescale_map; + *rescale_map; /* Allocated with dcm->max_value_in+1 entries */ #if defined(USE_GRAYMAP) unsigned short @@ -2851,6 +2851,7 @@ static MagickPassFail IsDCM(const unsign static MagickPassFail DCM_InitDCM(DicomStream *dcm,int verbose) { + (void) memset(dcm,0,sizeof(*dcm)); dcm->columns=0; dcm->rows=0; dcm->samples_per_pixel=1; @@ -2891,6 +2892,16 @@ static MagickPassFail DCM_InitDCM(DicomS return MagickPass; } +static void DCM_DestroyDCM(DicomStream *dcm) +{ + MagickFreeMemory(dcm->offset_arr); + MagickFreeMemory(dcm->data); +#if defined(USE_GRAYMAP) + MagickFreeMemory(dcm->graymap); +#endif + MagickFreeMemory(dcm->rescale_map); +} + /* Parse functions for DICOM elements */ @@ -3110,9 +3121,18 @@ static MagickPassFail funcDCM_BitsStored dcm->significant_bits=dcm->datum; dcm->bytes_per_pixel=1; + if ((dcm->significant_bits == 0U) || (dcm->significant_bits > 16U)) + { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "DICOM significant_bits = %u", + dcm->significant_bits); + ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename); + return MagickFail; + } if (dcm->significant_bits > 8) dcm->bytes_per_pixel=2; - dcm->max_value_in=(1 << dcm->significant_bits)-1; + dcm->max_value_in=MaxValueGivenBits(dcm->significant_bits); dcm->max_value_out=dcm->max_value_in; image->depth=Min(dcm->significant_bits,QuantumDepth); return MagickPass; @@ -3316,6 +3336,10 @@ static MagickPassFail funcDCM_Palette(Im return MagickFail; } + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Palette with %" MAGICK_SIZE_T_F "u entries...", + (MAGICK_SIZE_T) dcm->length); /* Initialize colormap (entries are always 16 bit) 1201/2/3 = red/green/blue palette @@ -3345,9 +3369,9 @@ static MagickPassFail funcDCM_Palette(Im for (i=0; i < (long) image->colors; i++) { if (dcm->msb_state == DCM_MSB_BIG) - index=(*p << 8) | *(p+1); + index=((unsigned short) *p << 8) | (unsigned short) *(p+1); else - index=*p | (*(p+1) << 8); + index=(unsigned short) *p | ((unsigned short) *(p+1) << 8); if (dcm->element == 0x1201) image->colormap[i].red=ScaleShortToQuantum(index); else if (dcm->element == 0x1202) @@ -3408,7 +3432,8 @@ static magick_uint8_t DCM_RLE_ReadByte(I static magick_uint16_t DCM_RLE_ReadShort(Image *image, DicomStream *dcm) { - return (DCM_RLE_ReadByte(image,dcm) << 4) | DCM_RLE_ReadByte(image,dcm); + return (((magick_uint16_t) DCM_RLE_ReadByte(image,dcm) << 4) | + (magick_uint16_t) DCM_RLE_ReadByte(image,dcm)); } static MagickPassFail DCM_ReadElement(Image *image, DicomStream *dcm,ExceptionInfo *exception) @@ -3760,20 +3785,38 @@ static MagickPassFail DCM_SetupRescaleMa Xw_min, Xw_max; - unsigned long + unsigned int i; if (dcm->rescaling == DCM_RS_NONE) return MagickPass; + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Set up rescale map for input range of %u" + " (%u entries)...", + dcm->max_value_in+1,MaxMap+1); + + /* + The rescale map must be limited to MaxMap+1 entries, which is 256 + or 65536, depending on QuantumDepth. Using a QuantumDepth less + than 16 for DICOM is a bad idea. + + The dcm->significant_bits value is limited to 16 (larger values + are outright rejected) so dcm->max_value_in and dcm->max_value_out + are limited to 65535. + */ + if (dcm->rescale_map == (Quantum *) NULL) { - dcm->rescale_map=MagickAllocateArray(Quantum *,dcm->max_value_in+1,sizeof(Quantum)); + size_t num_entries = Max(MaxMap+1,dcm->max_value_in+1); + dcm->rescale_map=MagickAllocateArray(Quantum *,num_entries,sizeof(Quantum)); if (dcm->rescale_map == NULL) { ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename); return MagickFail; } + (void) memset(dcm->rescale_map,0,num_entries*sizeof(Quantum)); } if (dcm->window_width == 0) @@ -3803,7 +3846,7 @@ static MagickPassFail DCM_SetupRescaleMa Xw_max = win_center - 0.5 + ((win_width-1)/2); for (i=0; i < (dcm->max_value_in+1); i++) { - if ((dcm->pixel_representation == 1) && (i >= (1U << (dcm->significant_bits-1)))) + if ((dcm->pixel_representation == 1) && (i >= MaxValueGivenBits(dcm->significant_bits))) Xr = -((dcm->max_value_in+1-i) * dcm->rescale_slope) + dcm->rescale_intercept; else Xr = (i * dcm->rescale_slope) + dcm->rescale_intercept; @@ -3815,8 +3858,9 @@ static MagickPassFail DCM_SetupRescaleMa dcm->rescale_map[i]=(Quantum)(((Xr-Xw_min)/(win_width-1))*dcm->max_value_out+0.5); } if (dcm->phot_interp == DCM_PI_MONOCHROME1) - for (i=0; i < (dcm->max_value_in+1); i++) + for (i=0; i <= dcm->max_value_in; i++) dcm->rescale_map[i]=dcm->max_value_out-dcm->rescale_map[i]; + return MagickPass; } @@ -3882,6 +3926,15 @@ void DCM_SetRescaling(DicomStream *dcm,i dcm->rescaling=DCM_RS_PRE; } +/* + FIXME: This code is totally broken since DCM_SetupRescaleMap + populates dcm->rescale_map and dcm->rescale_map has + dcm->max_value_in+1 entries, which has nothing to do with the number + of colormap entries or the range of MaxRGB. + + Disabling this whole function and code invoking it until someone + figures it out. +*/ static MagickPassFail DCM_PostRescaleImage(Image *image,DicomStream *dcm,unsigned long ScanLimits,ExceptionInfo *exception) { unsigned long @@ -3952,7 +4005,8 @@ static MagickPassFail DCM_PostRescaleIma } } - DCM_SetupRescaleMap(image,dcm,exception); + if (DCM_SetupRescaleMap(image,dcm,exception) == MagickFail) + return MagickFail; for (y=0; y < image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); @@ -3993,10 +4047,10 @@ static MagickPassFail DCM_PostRescaleIma static MagickPassFail DCM_ReadPaletteImage(Image *image,DicomStream *dcm,ExceptionInfo *exception) { - long + unsigned long y; - register long + register unsigned long x; register PixelPacket @@ -4013,13 +4067,17 @@ static MagickPassFail DCM_ReadPaletteIma byte=0; - for (y=0; y < (long) image->rows; y++) + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Reading Palette image..."); + + for (y=0; y < image->rows; y++) { q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) return MagickFail; indexes=AccessMutableIndexes(image); - for (x=0; x < (long) image->columns; x++) + for (x=0; x < image->columns; x++) { if (dcm->bytes_per_pixel == 1) { @@ -4075,6 +4133,8 @@ static MagickPassFail DCM_ReadPaletteIma index=(IndexPacket) (index); VerifyColormapIndex(image,index); indexes[x]=index; + *q=image->colormap[index]; + q++; } if (EOFBlob(image)) @@ -4097,16 +4157,16 @@ static MagickPassFail DCM_ReadPaletteIma static MagickPassFail DCM_ReadGrayscaleImage(Image *image,DicomStream *dcm,ExceptionInfo *exception) { - long + unsigned long y; - register long + register unsigned long x; register PixelPacket *q; -#if defined(GRAYSCALE_USES_PALETTE) +#if defined(GRAYSCALE_USES_PALETTE) /* not used */ register IndexPacket *indexes; #endif @@ -4117,18 +4177,29 @@ static MagickPassFail DCM_ReadGrayscaleI unsigned char byte; + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Reading Grayscale %lux%lu image...",image->columns,image->rows); + +#if !defined(GRAYSCALE_USES_PALETTE) + /* + If a palette was provided, the image may be in PseudoClass + */ + image->storage_class=DirectClass; +#endif + dcm->lower_lim = dcm->max_value_in; dcm->upper_lim = -(dcm->lower_lim); byte=0; - for (y=0; y < (long) image->rows; y++) + for (y=0; y < image->rows; y++) { - q=SetImagePixels(image,0,y,image->columns,1); + q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) return MagickFail; -#if defined(GRAYSCALE_USES_PALETTE) +#if defined(GRAYSCALE_USES_PALETTE) /* not used */ indexes=AccessMutableIndexes(image); #endif - for (x=0; x < (long) image->columns; x++) + for (x=0; x < image->columns; x++) { if (dcm->bytes_per_pixel == 1) { @@ -4181,17 +4252,21 @@ static MagickPassFail DCM_ReadGrayscaleI if ((int) l > dcm->upper_lim) dcm->upper_lim = l; } -#if defined(GRAYSCALE_USES_PALETTE) +#if defined(GRAYSCALE_USES_PALETTE) /* not used */ if (dcm->rescaling == DCM_RS_PRE) indexes[x]=dcm->rescale_map[index]; else indexes[x]=index; #else - if (dcm->rescaling == DCM_RS_PRE) - index=dcm->rescale_map[index]; + if ((dcm->rescaling == DCM_RS_PRE) && + (dcm->rescale_map != (Quantum *) NULL)) + { + index=dcm->rescale_map[index]; + } q->red=index; q->green=index; q->blue=index; + q->opacity=OpaqueOpacity; q++; #endif if (EOFBlob(image)) @@ -4200,7 +4275,7 @@ static MagickPassFail DCM_ReadGrayscaleI return MagickFail; } } - if (!SyncImagePixels(image)) + if (!SyncImagePixelsEx(image,exception)) return MagickFail; if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) @@ -4222,13 +4297,28 @@ static MagickPassFail DCM_ReadPlanarRGBI register PixelPacket *q; + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Reading Planar RGB %s compressed image with %u planes...", + (dcm->transfer_syntax == DCM_TS_RLE ? "RLE" : "not"), + dcm->samples_per_pixel); + /* + Force image to DirectClass since we are only updating DirectClass + representation. The image may be in PseudoClass if we were + previously provided with a Palette. + */ + image->storage_class=DirectClass; + for (plane=0; plane < dcm->samples_per_pixel; plane++) { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + " Plane %lu...",plane); for (y=0; y < image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) - return MagickFail; + return MagickFail; for (x=0; x < image->columns; x++) { @@ -4297,6 +4387,17 @@ static MagickPassFail DCM_ReadRGBImage(I green=0; blue=0; + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Reading RGB image..."); + + /* + Force image to DirectClass since we are only updating DirectClass + representation. The image may be in PseudoClass if we were + previously provided with a Palette. + */ + image->storage_class=DirectClass; + for (y=0; y < image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); @@ -4339,7 +4440,8 @@ static MagickPassFail DCM_ReadRGBImage(I red&=dcm->max_value_in; green&=dcm->max_value_in; blue&=dcm->max_value_in; - if (dcm->rescaling == DCM_RS_PRE) + if ((dcm->rescaling == DCM_RS_PRE) && + (dcm->rescale_map != (Quantum *) NULL)) { red=dcm->rescale_map[red]; green=dcm->rescale_map[green]; @@ -4349,6 +4451,7 @@ static MagickPassFail DCM_ReadRGBImage(I q->red=(Quantum) red; q->green=(Quantum) green; q->blue=(Quantum) blue; + q->opacity=OpaqueOpacity; q++; if (EOFBlob(image)) { @@ -4376,7 +4479,8 @@ static MagickPassFail DCM_ReadOffsetTabl length, i; - tag=(dcm->funcReadShort(image) << 16) | dcm->funcReadShort(image); + tag=((magick_uint32_t) dcm->funcReadShort(image) << 16) | + (magick_uint32_t) dcm->funcReadShort(image); length=dcm->funcReadLong(image); if (tag != 0xFFFEE000) return MagickFail; @@ -4476,7 +4580,8 @@ static MagickPassFail DCM_ReadNonNativeI /* Read fragment tag */ - tag=(dcm->funcReadShort(*image) << 16) | dcm->funcReadShort(*image); + tag=(((magick_uint32_t) dcm->funcReadShort(*image) << 16) | + (magick_uint32_t) dcm->funcReadShort(*image)); length=dcm->funcReadLong(*image); if (EOFBlob(*image)) { @@ -4561,7 +4666,7 @@ static MagickPassFail DCM_ReadNonNativeI dcm->bytes_per_pixel=1; if (dcm->significant_bits > 8) dcm->bytes_per_pixel=2; - dcm->max_value_in=(1 << dcm->significant_bits)-1; + dcm->max_value_in=MaxValueGivenBits(dcm->significant_bits); dcm->max_value_out=dcm->max_value_in; status=DCM_PostRescaleImage(next_image,dcm,True,exception); } @@ -4574,11 +4679,33 @@ static MagickPassFail DCM_ReadNonNativeI else AppendImageToList(&image_list,next_image); } + else if (next_image != (Image *) NULL) + { + DestroyImage(next_image); + next_image=(Image *) NULL; + } } (void) LiberateTemporaryFile(filename); + + if (status == MagickFail) + break; + } + if (EOFBlob(*image)) + { + status = MagickFail; + ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,(*image)->filename); + } + + if (status == MagickFail) + { + DestroyImageList(image_list); + image_list = (Image *) NULL; + } + else + { + DestroyImage(*image); + *image=image_list; } - DestroyImage(*image); - *image=image_list; return status; } @@ -4613,6 +4740,11 @@ static MagickPassFail DCM_ReadNonNativeI % % */ +#define ThrowDCMReaderException(code_,reason_,image_) \ + { \ + DCM_DestroyDCM(&dcm); \ + ThrowReaderException(code_,reason_,image_); \ +} static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception) { char @@ -4640,18 +4772,19 @@ static Image *ReadDCMImage(const ImageIn assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); + (void) DCM_InitDCM(&dcm,image_info->verbose); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFail) - ThrowReaderException(FileOpenError,UnableToOpenFile,image); + ThrowDCMReaderException(FileOpenError,UnableToOpenFile,image); /* Read DCM preamble */ if ((count=ReadBlob(image,128,(char *) magick)) != 128) - ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image); if ((count=ReadBlob(image,4,(char *) magick)) != 4) - ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image); if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "magick: \"%.4s\"",magick); @@ -4661,7 +4794,6 @@ static Image *ReadDCMImage(const ImageIn /* Loop to read DCM image header one element at a time */ - (void) DCM_InitDCM(&dcm,image_info->verbose); status=DCM_ReadElement(image,&dcm,exception); while ((status == MagickPass) && ((dcm.group != 0x7FE0) || (dcm.element != 0x0010))) { @@ -4689,31 +4821,44 @@ static Image *ReadDCMImage(const ImageIn Now process the image data */ if (status == MagickFail) - ; - else - if ((dcm.columns == 0) || (dcm.rows == 0)) - { - ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename); - status=MagickFail; - } - else if ((dcm.transfer_syntax != DCM_TS_IMPL_LITTLE) && - (dcm.transfer_syntax != DCM_TS_EXPL_LITTLE) && - (dcm.transfer_syntax != DCM_TS_EXPL_BIG) && - (dcm.transfer_syntax != DCM_TS_RLE)) - { - status=DCM_ReadNonNativeImages(&image,image_info,&dcm,exception); - dcm.number_scenes=0; - } - else if (dcm.rescaling != DCM_RS_POST) - { - status=DCM_SetupRescaleMap(image,&dcm,exception); - } + goto dcm_read_failure; + + if ((dcm.columns == 0) || (dcm.rows == 0)) + { + ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename); + status=MagickFail; + } + else if ((dcm.samples_per_pixel == 0) || (dcm.samples_per_pixel > 4)) + { + ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename); + status=MagickFail; + } + else if ((dcm.transfer_syntax != DCM_TS_IMPL_LITTLE) && + (dcm.transfer_syntax != DCM_TS_EXPL_LITTLE) && + (dcm.transfer_syntax != DCM_TS_EXPL_BIG) && + (dcm.transfer_syntax != DCM_TS_RLE)) + { + status=DCM_ReadNonNativeImages(&image,image_info,&dcm,exception); + dcm.number_scenes=0; + } + else if (dcm.rescaling != DCM_RS_POST) + { + status=DCM_SetupRescaleMap(image,&dcm,exception); + } + + if (status == MagickFail) + goto dcm_read_failure; if (dcm.transfer_syntax == DCM_TS_RLE) status=DCM_ReadOffsetTable(image,&dcm,exception); /* Loop to process all scenes in image */ - if (status == MagickFail) dcm.number_scenes = 0; + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "DICOM has %d scenes", dcm.number_scenes); + if (status == MagickFail) + goto dcm_read_failure; + for (scene=0; scene < (long) dcm.number_scenes; scene++) { if (dcm.transfer_syntax == DCM_TS_RLE) @@ -4729,14 +4874,15 @@ static Image *ReadDCMImage(const ImageIn SeekBlob(image,dcm.frag_bytes,SEEK_CUR); /* - Read fragment tag + Read fragment tag */ - tag=(dcm.funcReadShort(image) << 16) | dcm.funcReadShort(image); + tag=(((magick_uint32_t) dcm.funcReadShort(image)) << 16) | + (magick_uint32_t) dcm.funcReadShort(image); length=dcm.funcReadLong(image); if ((tag != 0xFFFEE000) || (length <= 64) || EOFBlob(image)) { status=MagickFail; - ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image); break; } @@ -4756,7 +4902,7 @@ static Image *ReadDCMImage(const ImageIn if (EOFBlob(image)) { status=MagickFail; - ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); + ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image); break; } if (dcm.rle_seg_ct > 1) @@ -4773,6 +4919,9 @@ static Image *ReadDCMImage(const ImageIn image->columns=dcm.columns; image->rows=dcm.rows; image->interlace=(dcm.interlace==1)?PlaneInterlace:NoInterlace; + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Scene[%d]: %lux%lu", scene, image->columns, image->rows); #if defined(GRAYSCALE_USES_PALETTE) if ((image->colormap == (PixelPacket *) NULL) && (dcm.samples_per_pixel == 1)) #else @@ -4787,7 +4936,7 @@ static Image *ReadDCMImage(const ImageIn break; if (CheckImagePixelLimits(image, exception) != MagickPass) - ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); + ThrowDCMReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); /* Process image according to type @@ -4813,15 +4962,23 @@ static Image *ReadDCMImage(const ImageIn ((dcm.phot_interp == DCM_PI_MONOCHROME1) || (dcm.phot_interp == DCM_PI_MONOCHROME2))) { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Normalizing image channels..."); NormalizeImage(image); } else - if (dcm.rescaling == DCM_RS_POST) - { - status = DCM_PostRescaleImage(image,&dcm,False,exception); - if (status != MagickPass) - break; - } + { + if (dcm.rescaling == DCM_RS_POST) + { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Rescaling image channels..."); + status = DCM_PostRescaleImage(image,&dcm,False,exception); + if (status != MagickPass) + break; + } + } /* Proceed to next image. @@ -4852,17 +5009,8 @@ static Image *ReadDCMImage(const ImageIn /* Free allocated resources */ - - if (dcm.offset_arr != NULL) - MagickFreeMemory(dcm.offset_arr); - if (dcm.data != NULL) - MagickFreeMemory(dcm.data); -#if defined(USE_GRAYMAP) - if (dcm.graymap != (unsigned short *) NULL) - MagickFreeMemory(dcm.graymap); -#endif - if (dcm.rescale_map != (Quantum *) NULL) - MagickFreeMemory(dcm.rescale_map); + dcm_read_failure: + DCM_DestroyDCM(&dcm); if (status == MagickPass) { /* It is possible to have success status yet have no image */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor