/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e V i r t u a l M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireVirtualMemory() allocates a pointer to a block of memory at least size % bytes suitably aligned for any use. % % The format of the AcquireVirtualMemory method is: % % MemoryInfo *AcquireVirtualMemory(const size_t count,const size_t quantum) % % A description of each parameter follows: % % o count: the number of quantum elements to allocate. % % o quantum: the number of bytes in each quantum. % */ MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count, const size_t quantum) { MemoryInfo *memory_info; size_t length; length=count*quantum; if ((count == 0) || (quantum != (length/count))) { errno=ENOMEM; return((MemoryInfo *) NULL); } memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, sizeof(*memory_info))); if (memory_info == (MemoryInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info)); memory_info->length=length; memory_info->signature=MagickSignature; if (AcquireMagickResource(MemoryResource,length) != MagickFalse) { memory_info->blob=AcquireAlignedMemory(1,length); if (memory_info->blob != NULL) memory_info->type=AlignedVirtualMemory; else RelinquishMagickResource(MemoryResource,length); } if ((memory_info->blob == NULL) && (AcquireMagickResource(MapResource,length) != MagickFalse)) { /* Heap memory failed, try anonymous memory mapping. */ memory_info->blob=MapBlob(-1,IOMode,0,length); if (memory_info->blob != NULL) memory_info->type=MapVirtualMemory; else RelinquishMagickResource(MapResource,length); } if (memory_info->blob == NULL) { int file; /* Anonymous memory mapping failed, try file-backed memory mapping. */ file=AcquireUniqueFileResource(memory_info->filename); if (file != -1) { if ((lseek(file,length-1,SEEK_SET) >= 0) && (write(file,"",1) == 1)) { memory_info->blob=MapBlob(file,IOMode,0,length); if (memory_info->blob != NULL) { memory_info->type=MapVirtualMemory; (void) AcquireMagickResource(MapResource,length); } } (void) close(file); } } if (memory_info->blob == NULL) { memory_info->blob=AcquireMagickMemory(length); if (memory_info->blob != NULL) memory_info->type=UnalignedVirtualMemory; } if (memory_info->blob == NULL) memory_info=RelinquishVirtualMemory(memory_info); return(memory_info); }
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) { const char *option; Image *image; int jp2_status; MagickBooleanType status; opj_codec_t *jp2_codec; opj_dparameters_t parameters; opj_image_t *jp2_image; opj_stream_t *jp2_stream; register ssize_t i; ssize_t y; unsigned char sans[4]; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Initialize JP2 codec. */ if (ReadBlob(image,4,sans) != 4) { image=DestroyImageList(image); return((Image *) NULL); } (void) SeekBlob(image,SEEK_SET,0); if (LocaleCompare(image_info->magick,"JPT") == 0) jp2_codec=opj_create_decompress(OPJ_CODEC_JPT); else if (IsJ2K(sans,4) != MagickFalse) jp2_codec=opj_create_decompress(OPJ_CODEC_J2K); else jp2_codec=opj_create_decompress(OPJ_CODEC_JP2); opj_set_warning_handler(jp2_codec,JP2WarningHandler,exception); opj_set_error_handler(jp2_codec,JP2ErrorHandler,exception); opj_set_default_decoder_parameters(¶meters); option=GetImageOption(image_info,"jp2:reduce-factor"); if (option != (const char *) NULL) parameters.cp_reduce=StringToInteger(option); option=GetImageOption(image_info,"jp2:quality-layers"); if (option != (const char *) NULL) parameters.cp_layer=StringToInteger(option); if (opj_setup_decoder(jp2_codec,¶meters) == 0) { opj_destroy_codec(jp2_codec); ThrowReaderException(DelegateError,"UnableToManageJP2Stream"); } jp2_stream=opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE,1); opj_stream_set_read_function(jp2_stream,JP2ReadHandler); opj_stream_set_write_function(jp2_stream,JP2WriteHandler); opj_stream_set_seek_function(jp2_stream,JP2SeekHandler); opj_stream_set_skip_function(jp2_stream,JP2SkipHandler); opj_stream_set_user_data(jp2_stream,image,NULL); opj_stream_set_user_data_length(jp2_stream,GetBlobSize(image)); if (opj_read_header(jp2_stream,jp2_codec,&jp2_image) == 0) { opj_stream_destroy(jp2_stream); opj_destroy_codec(jp2_codec); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } jp2_status=OPJ_TRUE; if (image->ping == MagickFalse) { if ((image->columns != 0) && (image->rows != 0)) /* Extract an area from the image. */ jp2_status=opj_set_decode_area(jp2_codec,jp2_image, (OPJ_INT32) image->extract_info.x,(OPJ_INT32) image->extract_info.y, (OPJ_INT32) (image->extract_info.x+(ssize_t) image->columns), (OPJ_INT32) (image->extract_info.y+(ssize_t) image->rows)); else jp2_status=opj_set_decode_area(jp2_codec,jp2_image,0,0, jp2_image->comps[0].w,jp2_image->comps[0].h); if (jp2_status == OPJ_FALSE) { opj_stream_destroy(jp2_stream); opj_destroy_codec(jp2_codec); opj_image_destroy(jp2_image); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } } if ((AcquireMagickResource(WidthResource,(size_t) jp2_image->comps[0].w) == MagickFalse) || (AcquireMagickResource(HeightResource,(size_t) jp2_image->comps[0].h) == MagickFalse)) { opj_stream_destroy(jp2_stream); opj_destroy_codec(jp2_codec); opj_image_destroy(jp2_image); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } if ((image_info->number_scenes != 0) && (image_info->scene != 0)) jp2_status=opj_get_decoded_tile(jp2_codec,jp2_stream,jp2_image, (unsigned int) image_info->scene-1); else if (image->ping == MagickFalse) { jp2_status=opj_decode(jp2_codec,jp2_stream,jp2_image); if (jp2_status != OPJ_FALSE) jp2_status=opj_end_decompress(jp2_codec,jp2_stream); } if (jp2_status == OPJ_FALSE) { opj_stream_destroy(jp2_stream); opj_destroy_codec(jp2_codec); opj_image_destroy(jp2_image); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } opj_stream_destroy(jp2_stream); for (i=0; i < (ssize_t) jp2_image->numcomps; i++) { if ((jp2_image->comps[0].dx == 0) || (jp2_image->comps[0].dy == 0) || (jp2_image->comps[0].prec != jp2_image->comps[i].prec) || (jp2_image->comps[0].sgnd != jp2_image->comps[i].sgnd) || ((image->ping == MagickFalse) && (jp2_image->comps[i].data == NULL))) { opj_destroy_codec(jp2_codec); opj_image_destroy(jp2_image); ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported") } }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e V i r t u a l M e m o r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireVirtualMemory() allocates a pointer to a block of memory at least size % bytes suitably aligned for any use. % % The format of the AcquireVirtualMemory method is: % % MemoryInfo *AcquireVirtualMemory(const size_t count,const size_t quantum) % % A description of each parameter follows: % % o count: the number of quantum elements to allocate. % % o quantum: the number of bytes in each quantum. % */ MagickExport MemoryInfo *AcquireVirtualMemory(const size_t count, const size_t quantum) { MemoryInfo *memory_info; size_t extent; if (CheckMemoryOverflow(count,quantum) != MagickFalse) return((MemoryInfo *) NULL); memory_info=(MemoryInfo *) MagickAssumeAligned(AcquireAlignedMemory(1, sizeof(*memory_info))); if (memory_info == (MemoryInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(memory_info,0,sizeof(*memory_info)); extent=count*quantum; memory_info->length=extent; memory_info->signature=MagickCoreSignature; if (AcquireMagickResource(MemoryResource,extent) != MagickFalse) { memory_info->blob=AcquireAlignedMemory(1,extent); if (memory_info->blob != NULL) { memory_info->type=AlignedVirtualMemory; return(memory_info); } } RelinquishMagickResource(MemoryResource,extent); if (AcquireMagickResource(MapResource,extent) != MagickFalse) { /* Heap memory failed, try anonymous memory mapping. */ memory_info->blob=MapBlob(-1,IOMode,0,extent); if (memory_info->blob != NULL) { memory_info->type=MapVirtualMemory; return(memory_info); } if (AcquireMagickResource(DiskResource,extent) != MagickFalse) { int file; /* Anonymous memory mapping failed, try file-backed memory mapping. If the MapResource request failed, there is no point in trying file-backed memory mapping. */ file=AcquireUniqueFileResource(memory_info->filename); if (file != -1) { if ((lseek(file,extent-1,SEEK_SET) == (extent-1)) && (write(file,"",1) == 1)) { memory_info->blob=MapBlob(file,IOMode,0,extent); if (memory_info->blob != NULL) { (void) close(file); memory_info->type=MapVirtualMemory; return(memory_info); } } /* File-backed memory mapping failed, delete the temporary file. */ (void) close(file); (void) RelinquishUniqueFileResource(memory_info->filename); *memory_info->filename = '\0'; } } RelinquishMagickResource(DiskResource,extent); } RelinquishMagickResource(MapResource,extent); if (memory_info->blob == NULL) { memory_info->blob=AcquireMagickMemory(extent); if (memory_info->blob != NULL) memory_info->type=UnalignedVirtualMemory; } if (memory_info->blob == NULL) memory_info=RelinquishVirtualMemory(memory_info); return(memory_info); }
MagickExport int AcquireUniqueFileResource(char *path) { #if !defined(O_NOFOLLOW) #define O_NOFOLLOW 0 #endif #if !defined(TMP_MAX) # define TMP_MAX 238328 #endif char *resource; int c, file; register char *p; register long i; unsigned char key[8]; assert(path != (char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); file=(-1); for (i=0; i < TMP_MAX; i++) { /* Get temporary pathname. */ (void) GetPathTemplate(path); #if defined(HAVE_MKSTEMP) file=mkstemp(path); if (file != -1) break; #endif GetRandomKey(key,8); p=path+strlen(path)-8; for (i=0; i < 8; i++) { c=(int) (key[i] & 0x1f); *p++=(char) (c > 9 ? c+(int) 'a'-10 : c+(int) '0'); } file=open(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,S_MODE); if ((file > 0) || (errno != EEXIST)) break; } (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path); if (file == -1) return(file); (void) AcquireMagickResource(FileResource,1); if (temporary_resources == (SplayTreeInfo *) NULL) temporary_resources=NewSplayTree(CompareSplayTreeString, RelinquishMagickMemory,DestroyTemporaryResources); resource=ConstantString(AcquireString(path)); (void) AddValueToSplayTree(temporary_resources,resource,resource); return(file); }