From: cristy Date: Mon, 13 Aug 2012 16:03:09 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~5147 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2be7a37aa8f7f8c84489950241817f7db36fcf5;p=imagemagick --- diff --git a/coders/jnx.c b/coders/jnx.c index d0433633d..76a6de669 100644 --- a/coders/jnx.c +++ b/coders/jnx.c @@ -58,11 +58,51 @@ #include "MagickCore/module.h" #include "MagickCore/monitor.h" #include "MagickCore/monitor-private.h" +#include "MagickCore/property.h" #include "MagickCore/pixel-accessor.h" #include "MagickCore/quantum-private.h" #include "MagickCore/static.h" #include "MagickCore/string_.h" +typedef struct _JNXInfo +{ + unsigned int + version, + serial; + + PointInfo + northeast, + southwest; + + unsigned int + levels, + expire, + id, + crc, + signature; + + int + offset; + + unsigned int + order; +} JNXInfo; + +typedef struct _JNXLevelInfo +{ + unsigned int + count; + + int + offset; + + unsigned int + scale; + + char + copyright[MaxTextExtent]; +} JNXLevelInfo; + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @@ -91,7 +131,188 @@ */ static Image *ReadJNXImage(const ImageInfo *image_info,ExceptionInfo *exception) { - return((Image *) NULL); +#define JNXMaxLevels 20 + + Image + *image, + *images; + + JNXInfo + jnx_info; + + JNXLevelInfo + jnx_level_info[JNXMaxLevels]; + + MagickBooleanType + status; + + register ssize_t + i; + + /* + Open image file. + */ + assert(image_info != (const ImageInfo *) NULL); + assert(image_info->signature == MagickSignature); + if (image_info->debug != MagickFalse) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", + image_info->filename); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickSignature); + image=AcquireImage(image_info,exception); + status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); + if (status == MagickFalse) + { + image=DestroyImageList(image); + return((Image *) NULL); + } + /* + Read JNX header. + */ + (void) ResetMagickMemory(&jnx_info,0,sizeof(jnx_info)); + jnx_info.version=ReadBlobLSBLong(image); + if (jnx_info.version > 4) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + jnx_info.serial=ReadBlobLSBLong(image); + jnx_info.northeast.x=(double) ReadBlobLSBLong(image); + jnx_info.northeast.y=(double) ReadBlobLSBLong(image); + jnx_info.southwest.x=(double) ReadBlobLSBLong(image); + jnx_info.southwest.y=(double) ReadBlobLSBLong(image); + jnx_info.levels=ReadBlobLSBLong(image); + if (jnx_info.levels > JNXMaxLevels) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + jnx_info.expire=ReadBlobLSBLong(image); + jnx_info.id=ReadBlobLSBLong(image); + jnx_info.crc=ReadBlobLSBLong(image); + jnx_info.signature=ReadBlobLSBLong(image); + jnx_info.offset=ReadBlobLSBLong(image); + if (jnx_info.version > 3) + jnx_info.order=(int) ReadBlobLSBLong(image); + /* + Read JNX levels. + */ + (void) ResetMagickMemory(&jnx_level_info,0,sizeof(jnx_level_info)); + for (i=0; i < (ssize_t) jnx_info.levels; i++) + { + jnx_level_info[i].count=ReadBlobLSBLong(image); + jnx_level_info[i].offset=(int) ReadBlobLSBLong(image); + jnx_level_info[i].scale=(int) ReadBlobLSBLong(image); + if (jnx_info.version > 3) + { + int + c; + + register ssize_t + j; + + (void) ReadBlobLSBLong(image); + j=0; + while ((c=ReadBlobLSBShort(image)) != 0) + if (j < (MaxTextExtent-1)) + jnx_level_info[i].copyright[j++]=c; + jnx_level_info[i].copyright[j]='\0'; + } + } + /* + Read JNX tiles. + */ + images=NewImageList(); + for (i=0; i < (ssize_t) jnx_info.levels; i++) + { + register ssize_t + j; + + (void) SeekBlob(image,jnx_level_info[i].offset,SEEK_SET); + for (j=0; j < (ssize_t) jnx_level_info[i].count; j++) + { + Image + *tile_image; + + ImageInfo + *read_info; + + int + tile_offset; + + MagickOffsetType + offset; + + PointInfo + northeast, + southwest; + + ssize_t + count; + + unsigned char + *blob; + + unsigned int + tile_length; + + northeast.x=(double) ReadBlobLSBLong(image); + northeast.y=(double) ReadBlobLSBLong(image); + southwest.x=(double) ReadBlobLSBLong(image); + southwest.y=(double) ReadBlobLSBLong(image); + (void) ReadBlobLSBShort(image); /* width */ + (void) ReadBlobLSBShort(image); /* height */ + tile_length=ReadBlobLSBLong(image); + tile_offset=(int) ReadBlobLSBLong(image); + offset=TellBlob(image); + /* + Read a tile. + */ + blob=(unsigned char *) AcquireMagickMemory((tile_length+2)*sizeof(*blob)); + if (blob == (unsigned char *) NULL) + { + if (images != (Image *) NULL) + images=DestroyImageList(images); + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + } + (void) SeekBlob(image,tile_offset,SEEK_SET); + blob[0]=0xFF; + blob[1]=0xD8; + count=ReadBlob(image,tile_length,blob+2); + if (count != tile_length) + { + if (images != (Image *) NULL) + images=DestroyImageList(images); + blob=(unsigned char *) RelinquishMagickMemory(blob); + ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile"); + } + read_info=CloneImageInfo(image_info); + (void) CopyMagickString(read_info->magick,"JPEG",MaxTextExtent); + tile_image=BlobToImage(read_info,blob,tile_length+2,exception); + read_info=DestroyImageInfo(read_info); + blob=(unsigned char *) RelinquishMagickMemory(blob); + (void) SeekBlob(image,offset,SEEK_SET); + if (tile_image == (Image *) NULL) + continue; + if (*jnx_level_info[i].copyright != '\0') + (void) SetImageProperty(tile_image,"jnx:copyright", + jnx_level_info[i].copyright,exception); + (void) FormatImageProperty(tile_image,"jnx:northeast","%g,%g",northeast.x, + northeast.y); + (void) FormatImageProperty(tile_image,"jnx:southwest","%g,%g",southwest.x, + southwest.y); + AppendImageToList(&images,tile_image); + } + if (image->progress_monitor != (MagickProgressMonitor) NULL) + { + MagickBooleanType + proceed; + + proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType) i, + (MagickSizeType) jnx_info.levels); + if (proceed == MagickFalse) + status=MagickFalse; + } + } + (void) CloseBlob(image); + image=DestroyImage(image); + if (images == (Image *) NULL) + return((Image *) NULL); + return(GetFirstImageInList(images)); } /* @@ -124,6 +345,7 @@ ModuleExport size_t RegisterJNXImage(void) entry=SetMagickInfo("JNX"); entry->decoder=(DecodeImageHandler *) ReadJNXImage; entry->description=ConstantString("Garmin tile storage format"); + entry->seekable_stream=MagickTrue; entry->module=ConstantString("JNX"); (void) RegisterMagickInfo(entry); return(MagickImageCoderSignature);