/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t W i z a r d M a g i c k % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetWizardMagick() produces a unique signature useful for verifying that a % structure or file is in fact Wizard related. % % The format of the GetWizardMagick method is: % % StringInfo GetWizardMagick(const char *signature,const size_t length) % % A description of each parameter follows: % % o signature: Derive the magick from this signature. % % */ WizardExport StringInfo *GetWizardMagick(const unsigned char *signature, const size_t length) { HashInfo *hash_info; StringInfo *magick, *tag; hash_info=AcquireHashInfo(SHA2256Hash); InitializeHash(hash_info); tag=AcquireStringInfo(length); SetStringInfoDatum(tag,signature); UpdateHash(hash_info,tag); tag=DestroyStringInfo(tag); FinalizeHash(hash_info); magick=CloneStringInfo(GetHashDigest(hash_info)); hash_info=DestroyHashInfo(hash_info); return(magick); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t C o n f i g u r e O p t i o n s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetConfigureOptions() returns any Magick configuration options associated % with the specified filename. % % The format of the GetConfigureOptions method is: % % LinkedListInfo *GetConfigureOptions(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the configure file name. % % o exception: return any errors or warnings in this structure. % */ MagickExport LinkedListInfo *GetConfigureOptions(const char *filename, ExceptionInfo *exception) { char path[MaxTextExtent]; const char *element; LinkedListInfo *options, *paths; StringInfo *xml; assert(filename != (const char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); assert(exception != (ExceptionInfo *) NULL); (void) CopyMagickString(path,filename,MaxTextExtent); /* Load XML from configuration files to linked-list. */ options=NewLinkedList(0); paths=GetConfigurePaths(filename,exception); if (paths != (LinkedListInfo *) NULL) { ResetLinkedListIterator(paths); element=(const char *) GetNextValueInLinkedList(paths); while (element != (const char *) NULL) { (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename); (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Searching for configure file: \"%s\"",path); xml=ConfigureFileToStringInfo(path); if (xml != (StringInfo *) NULL) (void) AppendValueToLinkedList(options,xml); element=(const char *) GetNextValueInLinkedList(paths); } paths=DestroyLinkedList(paths,RelinquishMagickMemory); } #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (GetNumberOfElementsInLinkedList(options) == 0) { char *blob; blob=(char *) NTResourceToBlob(filename); if (blob != (char *) NULL) { xml=AcquireStringInfo(0); SetStringInfoLength(xml,strlen(blob)+1); SetStringInfoDatum(xml,(unsigned char *) blob); SetStringInfoPath(xml,filename); (void) AppendValueToLinkedList(options,xml); } } #endif if (GetNumberOfElementsInLinkedList(options) == 0) (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning, "UnableToOpenConfigureFile","`%s'",filename); ResetLinkedListIterator(options); return(options); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S i g n a t u r e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SignatureImage() computes a message digest from an image pixel stream with % an implementation of the NIST SHA-256 Message Digest algorithm. This % signature uniquely identifies the image and is convenient for determining % if an image has been modified or whether two images are identical. % % The format of the SignatureImage method is: % % MagickBooleanType SignatureImage(Image *image) % % A description of each parameter follows: % % o image: the image. % */ MagickExport MagickBooleanType SignatureImage(Image *image) { CacheView *image_view; char *hex_signature; ExceptionInfo *exception; QuantumInfo *quantum_info; QuantumType quantum_type; register const PixelPacket *p; SignatureInfo *signature_info; size_t length; ssize_t y; StringInfo *signature; unsigned char *pixels; /* Compute image digital signature. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image); if (quantum_info == (QuantumInfo *) NULL) ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", image->filename); quantum_type=RGBQuantum; if (image->matte != MagickFalse) quantum_type=RGBAQuantum; if (image->colorspace == CMYKColorspace) { quantum_type=CMYKQuantum; if (image->matte != MagickFalse) quantum_type=CMYKAQuantum; } signature_info=AcquireSignatureInfo(); signature=AcquireStringInfo(quantum_info->extent); pixels=GetQuantumPixels(quantum_info); exception=(&image->exception); image_view=AcquireCacheView(image); for (y=0; y < (ssize_t) image->rows; y++) { p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); if (p == (const PixelPacket *) NULL) break; length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type, pixels,&image->exception); SetStringInfoLength(signature,length); SetStringInfoDatum(signature,pixels); UpdateSignature(signature_info,signature); } image_view=DestroyCacheView(image_view); quantum_info=DestroyQuantumInfo(quantum_info); FinalizeSignature(signature_info); hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info)); (void) DeleteImageProperty(image,"signature"); (void) SetImageProperty(image,"signature",hex_signature); /* Free resources. */ hex_signature=DestroyString(hex_signature); signature=DestroyStringInfo(signature); signature_info=DestroySignatureInfo(signature_info); return(MagickTrue); }
static Image *ReadJP2Image(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; jas_cmprof_t *cm_profile; jas_iccprof_t *icc_profile; jas_image_t *jp2_image; jas_matrix_t *pixels[4]; jas_stream_t *jp2_stream; ssize_t components[4], y; MagickBooleanType status; QuantumAny pixel, range[4]; register ssize_t i, x; register PixelPacket *q; size_t maximum_component_depth, number_components, x_step[4], y_step[4]; /* 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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Initialize JPEG 2000 API. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowReaderException(DelegateError,"UnableToManageJP2Stream"); jp2_image=jas_image_decode(jp2_stream,-1,0); if (jp2_image == (jas_image_t *) NULL) { (void) jas_stream_close(jp2_stream); ThrowReaderException(DelegateError,"UnableToDecodeImageFile"); } switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_R); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_G); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_RGB_B); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,3); if (components[3] > 0) { image->matte=MagickTrue; number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_GRAY_Y); if (components[0] < 0) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=1; break; } case JAS_CLRSPC_FAM_YCBCR: { components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y); components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB); components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR); if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CorruptImageError,"MissingImageChannel"); } number_components=3; components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_UNKNOWN); if (components[3] > 0) { image->matte=MagickTrue; number_components++; } image->colorspace=YCbCrColorspace; break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported"); } } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); image->compression=JPEG2000Compression; for (i=0; i < (ssize_t) number_components; i++) { size_t height, width; width=(size_t) (jas_image_cmptwidth(jp2_image,components[i])* jas_image_cmpthstep(jp2_image,components[i])); height=(size_t) (jas_image_cmptheight(jp2_image,components[i])* jas_image_cmptvstep(jp2_image,components[i])); x_step[i]=(unsigned int) jas_image_cmpthstep(jp2_image,components[i]); y_step[i]=(unsigned int) jas_image_cmptvstep(jp2_image,components[i]); if ((width != image->columns) || (height != image->rows) || (jas_image_cmpttlx(jp2_image,components[i]) != 0) || (jas_image_cmpttly(jp2_image,components[i]) != 0) || (x_step[i] != 1) || (y_step[i] != 1) || (jas_image_cmptsgnd(jp2_image,components[i]) != MagickFalse)) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"IrregularChannelGeometryNotSupported"); } } /* Convert JPEG 2000 pixels. */ image->matte=number_components > 3 ? MagickTrue : MagickFalse; maximum_component_depth=0; for (i=0; i < (ssize_t) number_components; i++) { maximum_component_depth=(unsigned int) MagickMax((size_t) jas_image_cmptprec(jp2_image,components[i]),(size_t) maximum_component_depth); pixels[i]=jas_matrix_create(1,(int) (image->columns/x_step[i])); if (pixels[i] == (jas_matrix_t *) NULL) { for (--i; i >= 0; i--) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } } image->depth=maximum_component_depth; if (image_info->ping != MagickFalse) { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); return(GetFirstImageInList(image)); } for (i=0; i < (ssize_t) number_components; i++) range[i]=GetQuantumRange((size_t) jas_image_cmptprec(jp2_image, components[i])); for (y=0; y < (ssize_t) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (i=0; i < (ssize_t) number_components; i++) (void) jas_image_readcmpt(jp2_image,(short) components[i],0, (jas_image_coord_t) (y/y_step[i]),(jas_image_coord_t) (image->columns/ x_step[i]),1,pixels[i]); switch (number_components) { case 1: { /* Grayscale. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) ScaleAnyToQuantum((QuantumAny) pixel,range[0]); q->green=q->red; q->blue=q->red; q++; } break; } case 3: { /* RGB. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) ScaleAnyToQuantum((QuantumAny) pixel,range[0]); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) ScaleAnyToQuantum((QuantumAny) pixel,range[1]); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) ScaleAnyToQuantum((QuantumAny) pixel,range[2]); q++; } break; } case 4: { /* RGBA. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) ScaleAnyToQuantum((QuantumAny) pixel,range[0]); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) ScaleAnyToQuantum((QuantumAny) pixel,range[1]); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) ScaleAnyToQuantum((QuantumAny) pixel,range[2]); pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]); q->opacity=(Quantum) (QuantumRange- ScaleAnyToQuantum((QuantumAny) pixel,range[3])); q++; } break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } cm_profile=jas_image_cmprof(jp2_image); icc_profile=(jas_iccprof_t *) NULL; if (cm_profile != (jas_cmprof_t *) NULL) icc_profile=jas_iccprof_createfromcmprof(cm_profile); if (icc_profile != (jas_iccprof_t *) NULL) { jas_stream_t *icc_stream; icc_stream=jas_stream_memopen(NULL,0); if ((icc_stream != (jas_stream_t *) NULL) && (jas_iccprof_save(icc_profile,icc_stream) == 0) && (jas_stream_flush(icc_stream) == 0)) { StringInfo *icc_profile, *profile; jas_stream_memobj_t *blob; /* Extract the icc profile, handle errors without much noise. */ blob=(jas_stream_memobj_t *) icc_stream->obj_; if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Profile: ICC, %.20g bytes",(double) blob->len_); profile=AcquireStringInfo(blob->len_); SetStringInfoDatum(profile,blob->buf_); icc_profile=(StringInfo *) GetImageProfile(image,"icc"); if (icc_profile == (StringInfo *) NULL) (void) SetImageProfile(image,"icc",profile); else (void) ConcatenateStringInfo(icc_profile,profile); profile=DestroyStringInfo(profile); (void) jas_stream_close(icc_stream); } } (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); for (i=0; i < (ssize_t) number_components; i++) jas_matrix_destroy(pixels[i]); return(GetFirstImageInList(image)); }