From: Cristy Date: Fri, 21 Dec 2018 22:21:45 +0000 (-0500) Subject: The CUBE image format returns a HALD image (e.g. cube:Vibrant.cube[7]) X-Git-Tag: 7.0.8-20~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2547e20d46a1eda2049a02e5d990a16c3e403f0;p=imagemagick The CUBE image format returns a HALD image (e.g. cube:Vibrant.cube[7]) --- diff --git a/coders/cube.c b/coders/cube.c index 7727f7ab0..08b574f91 100644 --- a/coders/cube.c +++ b/coders/cube.c @@ -96,10 +96,24 @@ static Image *ReadCUBEImage(const ImageInfo *image_info, ExceptionInfo *exception) { +#define MapHALD(level,b,g,r) ((ssize_t) ((b)*(level)*(level)+(g)*(level)+(r))) + + typedef struct _CubePixel + { + float + r, + g, + b; + } CubePixel; + char - *cube_buffer, - token[MagickPathExtent], - value[MagickPathExtent]; + *buffer, + token[MagickPathExtent], + value[MagickPathExtent]; + + CubePixel + *cube, + *hald; Image *image; @@ -107,19 +121,21 @@ static Image *ReadCUBEImage(const ImageInfo *image_info, MagickBooleanType status; + MemoryInfo + *cube_info, + *hald_info; + register char *p; size_t - length; + cube_level, + hald_level; ssize_t - blue_rows, - green_columns, - red_columns; - - ssize_t - blue; + b, + i, + n; /* Create CUBE color lookup table image. @@ -138,105 +154,188 @@ static Image *ReadCUBEImage(const ImageInfo *image_info, image=DestroyImageList(image); return((Image *) NULL); } - length=MagickPathExtent; - cube_buffer=(char *) AcquireQuantumMemory((size_t) length, - sizeof(*cube_buffer)); - if (cube_buffer == (char *) NULL) - ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); - red_columns=0; - green_columns=0; - blue_rows=0; - *cube_buffer='\0'; - p=cube_buffer; + buffer=AcquireString(""); + cube_level=0; + cube_info=(MemoryInfo *) NULL; + cube=(CubePixel *) NULL; + n=0; + *buffer='\0'; + p=buffer; while (ReadBlobString(image,p) != (char *) NULL) { const char *q; - if ((*p == '#') && ((p == cube_buffer) || (*(p-1) == '\n'))) - continue; q=p; GetNextToken(q,&q,MagickPathExtent,token); + if ((*token == '#') || (*token == '\0')) + continue; GetNextToken(q,&q,MagickPathExtent,value); - if (LocaleCompare(token,"LUT_1D_SIZE") == 0) + if ((LocaleCompare(token,"LUT_1D_SIZE") == 0) || + (LocaleCompare(token,"LUT_3D_SIZE") == 0)) { - red_columns=(ssize_t) StringToLong(value); - if ((red_columns < 0) || (red_columns > 65535)) - { - cube_buffer=DestroyString(cube_buffer); - ThrowReaderException(CorruptImageError,"ImproperImageHeader"); - } - green_columns=1; - blue_rows=1; + cube_level=(size_t) StringToLong(value); + if ((cube_level < 2) || (cube_level > 65536)) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + if (cube_info != (MemoryInfo *) NULL) + cube_info=RelinquishVirtualMemory(cube_info); + cube_info=AcquireVirtualMemory(cube_level*cube_level,cube_level* + sizeof(*cube)); + if (cube_info == (MemoryInfo *) NULL) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + cube=(CubePixel *) GetVirtualMemoryBlob(cube_info); + (void) memset(cube,0,cube_level*cube_level*cube_level*sizeof(*cube)); } - if (LocaleCompare(token,"LUT_3D_SIZE") == 0) - { - red_columns=(ssize_t) StringToLong(value); - if ((red_columns < 0) || (red_columns > 256)) + else + if (LocaleCompare(token,"TITLE ") == 0) + (void) SetImageProperty(image,"title",value,exception); + else + if (cube_level != 0) { - cube_buffer=DestroyString(cube_buffer); - ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + char + *q; + + q=buffer; + cube[n].r=StringToDouble(q,&q); + cube[n].g=StringToDouble(q,&q); + cube[n].b=StringToDouble(q,&q); + n++; } - green_columns=red_columns; - blue_rows=red_columns; + else + if (('+' < *buffer) && (*buffer < ':')) + break; + } + buffer=DestroyString(buffer); + if (cube_level == 0) + { + cube_info=RelinquishVirtualMemory(cube_info); + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + } + /* + Create HALD image, interopolate from CUBE LUT. + */ + hald_level=image_info->scene; + if ((hald_level < 2) || (hald_level > 256)) + hald_level=8; + hald_info=AcquireVirtualMemory(hald_level*hald_level*hald_level, + hald_level*hald_level*hald_level*sizeof(*hald)); + if (hald_info == (MemoryInfo *) NULL) + { + cube_info=RelinquishVirtualMemory(cube_info); + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + } + hald=(CubePixel *) GetVirtualMemoryBlob(hald_info); + (void) memset(hald,0,hald_level*hald_level*hald_level*sizeof(*hald)); + n=0; + for (b=0; b < (ssize_t) (hald_level*hald_level); b++) + { + register ssize_t + g; + + for (g=0; g < (ssize_t) (hald_level*hald_level); g++) + { + register ssize_t + r; + + for (r=0; r < (ssize_t) (hald_level*hald_level); r++) + { + CubePixel + index, + next, + offset, + scale; + + offset.r=(PerceptibleReciprocal((double) (hald_level*hald_level)-1.0)* + r)*(cube_level-1.0); + index.r=floor(offset.r); + scale.r=offset.r-index.r; + next.r=index.r+1; + if ((size_t) index.r == (cube_level-1)) + next.r=index.r; + offset.g=(PerceptibleReciprocal(((double) hald_level*hald_level)-1.0)* + g)*(cube_level-1.0); + index.g=floor(offset.g); + scale.g=offset.g-index.g; + next.g=index.g+1; + if ((size_t) index.g == (cube_level-1)) + next.g=index.g; + offset.b=(PerceptibleReciprocal(((double) hald_level*hald_level)-1.0)* + b)*(cube_level-1.0); + index.b=floor(offset.b); + scale.b=offset.b-index.b; + next.b=index.b+1; + if ((size_t) index.b == (cube_level-1)) + next.b=index.b; + hald[n].r=cube[MapHALD(cube_level,index.b,index.g,index.r)].r+scale.r*( + cube[MapHALD(cube_level,index.b,index.g,next.r)].r- + cube[MapHALD(cube_level,index.b,index.g,index.r)].r); + hald[n].g=cube[MapHALD(cube_level,index.b,index.g,index.r)].g+scale.g*( + cube[MapHALD(cube_level,index.b,next.g,index.r)].g- + cube[MapHALD(cube_level,index.b,index.g,index.r)].g); + hald[n].b=cube[MapHALD(cube_level,index.b,index.g,index.r)].b+scale.b*( + cube[MapHALD(cube_level,next.b,index.g,index.r)].b- + cube[MapHALD(cube_level,index.b,index.g,index.r)].b); + n++; } - if (LocaleCompare(token,"TITLE ") == 0) - (void) SetImageProperty(image,"title",value,exception); - if (('+' < *p) && (*p < ':')) - break; + } } + cube_info=RelinquishVirtualMemory(cube_info); + /* + Write HALD image. + */ status=MagickTrue; - image->columns=(size_t) (red_columns*green_columns); - image->rows=(size_t) (blue_rows); + image->columns=(size_t) (hald_level*hald_level*hald_level); + image->rows=(size_t) (hald_level*hald_level*hald_level); status=SetImageExtent(image,image->columns,image->rows,exception); if (status == MagickFalse) { - cube_buffer=DestroyString(cube_buffer); + hald_info=RelinquishVirtualMemory(hald_info); return(DestroyImageList(image)); } - for (blue=0; blue < blue_rows; blue++) + n=0; + for (b=0; b < (ssize_t) (hald_level*hald_level); b++) { - ssize_t - green, - red; - - register Quantum - *magick_restrict q; + register ssize_t + g; if (status == MagickFalse) continue; - q=QueueAuthenticPixels(image,0,blue,(size_t) red_columns*green_columns,1, - exception); - if (q == (Quantum *) NULL) - { - status=MagickFalse; - continue; - } - for (green=0; green < green_columns; green++) + for (g=0; g < (ssize_t) (hald_level*hald_level); g++) { - for (red=0; red < red_columns; red++) + register ssize_t + r; + + for (r=0; r < (ssize_t) (hald_level*hald_level); r++) { - char - *p; + register Quantum + *magick_restrict q; - p=cube_buffer; - SetPixelRed(image,ClampToQuantum(QuantumRange*StringToDouble(p,&p)), - q); - SetPixelGreen(image,ClampToQuantum(QuantumRange*StringToDouble(p,&p)), - q); - SetPixelBlue(image,ClampToQuantum(QuantumRange*StringToDouble(p,&p)), - q); + ssize_t + x, + y; + + x=(g % hald_level)*(hald_level*hald_level)+r; + y=(b*hald_level)+((g/hald_level) % (hald_level*hald_level)); + q=QueueAuthenticPixels(image,x,y,1,1,exception); + if (q == (Quantum *) NULL) + { + status=MagickFalse; + continue; + } + SetPixelRed(image,ClampToQuantum(QuantumRange*hald[n].r),q); + SetPixelGreen(image,ClampToQuantum(QuantumRange*hald[n].g),q); + SetPixelBlue(image,ClampToQuantum(QuantumRange*hald[n].b),q); SetPixelAlpha(image,OpaqueAlpha,q); - q+=GetPixelChannels(image); - while (ReadBlobString(image,cube_buffer) != (char *) NULL) - if (('+' < *cube_buffer) && (*cube_buffer < ':')) - break; + if (SyncAuthenticPixels(image,exception) == MagickFalse) + status=MagickFalse; + n++; } } - if (SyncAuthenticPixels(image,exception) == MagickFalse) - status=MagickFalse; } - cube_buffer=DestroyString(cube_buffer); + hald_info=RelinquishVirtualMemory(hald_info); + if (image_info->scene != 0) + for (i=0; i < (ssize_t) image_info->scene; i++) + AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); return(GetFirstImageInList(image)); } diff --git a/coders/hald.c b/coders/hald.c index 20091f6d0..ab4a303d1 100644 --- a/coders/hald.c +++ b/coders/hald.c @@ -103,6 +103,7 @@ static Image *ReadHALDImage(const ImageInfo *image_info, level; ssize_t + i, y; /* @@ -119,7 +120,9 @@ static Image *ReadHALDImage(const ImageInfo *image_info, level=0; if (*image_info->filename != '\0') level=StringToUnsignedLong(image_info->filename); - if (level < 2) + if (image_info->scene != 0) + level=image_info->scene; + if ((level < 2) || (level > 256)) level=8; status=MagickTrue; cube_size=level*level; @@ -162,6 +165,9 @@ static Image *ReadHALDImage(const ImageInfo *image_info, if (SyncAuthenticPixels(image,exception) == MagickFalse) status=MagickFalse; } + if (image_info->scene != 0) + for (i=0; i < (ssize_t) image_info->scene; i++) + AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); return(GetFirstImageInList(image)); } diff --git a/coders/jpeg.c b/coders/jpeg.c index f55b4e643..5647140e2 100644 --- a/coders/jpeg.c +++ b/coders/jpeg.c @@ -1381,15 +1381,15 @@ static Image *ReadJPEGImage(const ImageInfo *image_info, if (jpeg_info.arith_code == TRUE) (void) SetImageProperty(image,"jpeg:coding","arithmetic",exception); #endif + if ((dct_method == (const char *) NULL) && (image->quality > 0) && + (image->quality <= 90)) + jpeg_info.dct_method=JDCT_IFAST; if (image_info->ping != MagickFalse) { jpeg_destroy_decompress(&jpeg_info); (void) CloseBlob(image); return(GetFirstImageInList(image)); } - if ((dct_method == (const char *) NULL) && (image->quality > 0) && - (image->quality <= 90)) - jpeg_info.dct_method=JDCT_IFAST; status=SetImageExtent(image,image->columns,image->rows,exception); if (status == MagickFalse) { diff --git a/coders/pcd.c b/coders/pcd.c index e51073232..8eb8ac652 100644 --- a/coders/pcd.c +++ b/coders/pcd.c @@ -873,15 +873,9 @@ static Image *ReadPCDImage(const ImageInfo *image_info,ExceptionInfo *exception) image->colorspace=YCCColorspace; if (LocaleCompare(image_info->magick,"PCDS") == 0) (void) SetImageColorspace(image,sRGBColorspace,exception); - if ((image_info->number_scenes != 0) && (image_info->scene != 0)) - { - AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); - AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); - AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); + if (image_info->scene != 0) + for (i=0; i < (ssize_t) image_info->scene; i++) AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); - AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); - AppendImageToList(&image,CloneImage(image,0,0,MagickTrue,exception)); - } return(GetFirstImageInList(image)); }