void ScImgDataLoader_GMagick::loadEmbeddedProfile(const QString& fn, int /*page*/) { initGraphicsMagick(); m_embeddedProfile.resize(0); m_profileComponents = 0; if (!QFile::exists(fn)) return; ExceptionInfo exception; GetExceptionInfo(&exception); ImageInfo *image_info = CloneImageInfo(0); strcpy(image_info->filename, fn.toUtf8().data()); image_info->units = PixelsPerInchResolution; Image *image = ReadImage(image_info, &exception); if (exception.severity != UndefinedException) CatchException(&exception); if (!image) { qCritical() << "Failed to read image" << fn; return; } size_t length = 0; const unsigned char *src = GetImageProfile(image, "ICM", &length); char *dest = m_embeddedProfile.data(); if (image->colorspace == CMYKColorspace) { m_profileComponents = 4; } else if (image->colorspace == RGBColorspace) { m_profileComponents = 3; } m_embeddedProfile.resize(length); memcpy(dest, src, length); }
static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { const char *value; CINInfo cin; const StringInfo *profile; MagickBooleanType status; MagickOffsetType offset; QuantumInfo *quantum_info; QuantumType quantum_type; register const Quantum *p; register ssize_t i; size_t length; ssize_t count, y; struct tm local_time; time_t seconds; unsigned char *pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); if (image->colorspace != LogColorspace) (void) TransformImageColorspace(image,LogColorspace,exception); /* Write image information. */ (void) ResetMagickMemory(&cin,0,sizeof(cin)); offset=0; cin.file.magic=0x802A5FD7UL; offset+=WriteBlobLong(image,(unsigned int) cin.file.magic); cin.file.image_offset=0x800; offset+=WriteBlobLong(image,(unsigned int) cin.file.image_offset); cin.file.generic_length=0x400; offset+=WriteBlobLong(image,(unsigned int) cin.file.generic_length); cin.file.industry_length=0x400; offset+=WriteBlobLong(image,(unsigned int) cin.file.industry_length); cin.file.user_length=0x00; profile=GetImageProfile(image,"dpx:user.data"); if (profile != (StringInfo *) NULL) { cin.file.user_length+=(size_t) GetStringInfoLength(profile); cin.file.user_length=(((cin.file.user_length+0x2000-1)/0x2000)*0x2000); } offset+=WriteBlobLong(image,(unsigned int) cin.file.user_length); cin.file.file_size=4*image->columns*image->rows+0x2000; offset+=WriteBlobLong(image,(unsigned int) cin.file.file_size); (void) CopyMagickString(cin.file.version,"V4.5",sizeof(cin.file.version)); offset+=WriteBlob(image,sizeof(cin.file.version),(unsigned char *) cin.file.version); value=GetCINProperty(image_info,image,"dpx:file.filename",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.file.filename,value,sizeof(cin.file.filename)); else (void) CopyMagickString(cin.file.filename,image->filename, sizeof(cin.file.filename)); offset+=WriteBlob(image,sizeof(cin.file.filename),(unsigned char *) cin.file.filename); seconds=time((time_t *) NULL); #if defined(MAGICKCORE_HAVE_LOCALTIME_R) (void) localtime_r(&seconds,&local_time); #else (void) memcpy(&local_time,localtime(&seconds),sizeof(local_time)); #endif (void) strftime(cin.file.create_date,sizeof(cin.file.create_date),"%Y:%m:%d", &local_time); offset+=WriteBlob(image,sizeof(cin.file.create_date),(unsigned char *) cin.file.create_date); (void) strftime(cin.file.create_time,sizeof(cin.file.create_time), "%H:%M:%S%Z",&local_time); offset+=WriteBlob(image,sizeof(cin.file.create_time),(unsigned char *) cin.file.create_time); offset+=WriteBlob(image,sizeof(cin.file.reserve),(unsigned char *) cin.file.reserve); cin.image.orientation=0x00; offset+=WriteBlobByte(image,cin.image.orientation); cin.image.number_channels=3; offset+=WriteBlobByte(image,cin.image.number_channels); offset+=WriteBlob(image,sizeof(cin.image.reserve1),(unsigned char *) cin.image.reserve1); for (i=0; i < 8; i++) { cin.image.channel[i].designator[0]=0; /* universal metric */ offset+=WriteBlobByte(image,cin.image.channel[0].designator[0]); cin.image.channel[i].designator[1]=(unsigned char) (i > 3 ? 0 : i+1); /* channel color */; offset+=WriteBlobByte(image,cin.image.channel[1].designator[0]); cin.image.channel[i].bits_per_pixel=(unsigned char) image->depth; offset+=WriteBlobByte(image,cin.image.channel[0].bits_per_pixel); offset+=WriteBlobByte(image,cin.image.channel[0].reserve); cin.image.channel[i].pixels_per_line=image->columns; offset+=WriteBlobLong(image,(unsigned int) cin.image.channel[0].pixels_per_line); cin.image.channel[i].lines_per_image=image->rows; offset+=WriteBlobLong(image,(unsigned int) cin.image.channel[0].lines_per_image); cin.image.channel[i].min_data=0; offset+=WriteBlobFloat(image,cin.image.channel[0].min_data); cin.image.channel[i].min_quantity=0.0; offset+=WriteBlobFloat(image,cin.image.channel[0].min_quantity); cin.image.channel[i].max_data=(float) ((MagickOffsetType) GetQuantumRange(image->depth)); offset+=WriteBlobFloat(image,cin.image.channel[0].max_data); cin.image.channel[i].max_quantity=2.048f; offset+=WriteBlobFloat(image,cin.image.channel[0].max_quantity); } offset+=WriteBlobFloat(image,image->chromaticity.white_point.x); offset+=WriteBlobFloat(image,image->chromaticity.white_point.y); offset+=WriteBlobFloat(image,image->chromaticity.red_primary.x); offset+=WriteBlobFloat(image,image->chromaticity.red_primary.y); offset+=WriteBlobFloat(image,image->chromaticity.green_primary.x); offset+=WriteBlobFloat(image,image->chromaticity.green_primary.y); offset+=WriteBlobFloat(image,image->chromaticity.blue_primary.x); offset+=WriteBlobFloat(image,image->chromaticity.blue_primary.y); value=GetCINProperty(image_info,image,"dpx:image.label",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.image.label,value,sizeof(cin.image.label)); offset+=WriteBlob(image,sizeof(cin.image.label),(unsigned char *) cin.image.label); offset+=WriteBlob(image,sizeof(cin.image.reserve),(unsigned char *) cin.image.reserve); /* Write data format information. */ cin.data_format.interleave=0; /* pixel interleave (rgbrgbr...) */ offset+=WriteBlobByte(image,cin.data_format.interleave); cin.data_format.packing=5; /* packing ssize_tword (32bit) boundaries */ offset+=WriteBlobByte(image,cin.data_format.packing); cin.data_format.sign=0; /* unsigned data */ offset+=WriteBlobByte(image,cin.data_format.sign); cin.data_format.sense=0; /* image sense: positive image */ offset+=WriteBlobByte(image,cin.data_format.sense); cin.data_format.line_pad=0; offset+=WriteBlobLong(image,(unsigned int) cin.data_format.line_pad); cin.data_format.channel_pad=0; offset+=WriteBlobLong(image,(unsigned int) cin.data_format.channel_pad); offset+=WriteBlob(image,sizeof(cin.data_format.reserve),(unsigned char *) cin.data_format.reserve); /* Write origination information. */ cin.origination.x_offset=0UL; value=GetCINProperty(image_info,image,"dpx:origination.x_offset",exception); if (value != (const char *) NULL) cin.origination.x_offset=(ssize_t) StringToLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.origination.x_offset); cin.origination.y_offset=0UL; value=GetCINProperty(image_info,image,"dpx:origination.y_offset",exception); if (value != (const char *) NULL) cin.origination.y_offset=(ssize_t) StringToLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.origination.y_offset); value=GetCINProperty(image_info,image,"dpx:origination.filename",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.filename,value, sizeof(cin.origination.filename)); else (void) CopyMagickString(cin.origination.filename,image->filename, sizeof(cin.origination.filename)); offset+=WriteBlob(image,sizeof(cin.origination.filename),(unsigned char *) cin.origination.filename); seconds=time((time_t *) NULL); (void) strftime(cin.origination.create_date, sizeof(cin.origination.create_date),"%Y:%m:%d",&local_time); offset+=WriteBlob(image,sizeof(cin.origination.create_date),(unsigned char *) cin.origination.create_date); (void) strftime(cin.origination.create_time, sizeof(cin.origination.create_time),"%H:%M:%S%Z",&local_time); offset+=WriteBlob(image,sizeof(cin.origination.create_time),(unsigned char *) cin.origination.create_time); value=GetCINProperty(image_info,image,"dpx:origination.device",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.device,value, sizeof(cin.origination.device)); offset+=WriteBlob(image,sizeof(cin.origination.device),(unsigned char *) cin.origination.device); value=GetCINProperty(image_info,image,"dpx:origination.model",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.model,value, sizeof(cin.origination.model)); offset+=WriteBlob(image,sizeof(cin.origination.model),(unsigned char *) cin.origination.model); value=GetCINProperty(image_info,image,"dpx:origination.serial",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.serial,value, sizeof(cin.origination.serial)); offset+=WriteBlob(image,sizeof(cin.origination.serial),(unsigned char *) cin.origination.serial); cin.origination.x_pitch=0.0f; value=GetCINProperty(image_info,image,"dpx:origination.x_pitch",exception); if (value != (const char *) NULL) cin.origination.x_pitch=StringToDouble(value,(char **) NULL); offset+=WriteBlobFloat(image,cin.origination.x_pitch); cin.origination.y_pitch=0.0f; value=GetCINProperty(image_info,image,"dpx:origination.y_pitch",exception); if (value != (const char *) NULL) cin.origination.y_pitch=StringToDouble(value,(char **) NULL); offset+=WriteBlobFloat(image,cin.origination.y_pitch); cin.origination.gamma=image->gamma; offset+=WriteBlobFloat(image,cin.origination.gamma); offset+=WriteBlob(image,sizeof(cin.origination.reserve),(unsigned char *) cin.origination.reserve); /* Image film information. */ cin.film.id=0; value=GetCINProperty(image_info,image,"dpx:film.id",exception); if (value != (const char *) NULL) cin.film.id=(char) StringToLong(value); offset+=WriteBlobByte(image,(unsigned char) cin.film.id); cin.film.type=0; value=GetCINProperty(image_info,image,"dpx:film.type",exception); if (value != (const char *) NULL) cin.film.type=(char) StringToLong(value); offset+=WriteBlobByte(image,(unsigned char) cin.film.type); cin.film.offset=0; value=GetCINProperty(image_info,image,"dpx:film.offset",exception); if (value != (const char *) NULL) cin.film.offset=(char) StringToLong(value); offset+=WriteBlobByte(image,(unsigned char) cin.film.offset); offset+=WriteBlobByte(image,(unsigned char) cin.film.reserve1); cin.film.prefix=0UL; value=GetCINProperty(image_info,image,"dpx:film.prefix",exception); if (value != (const char *) NULL) cin.film.prefix=StringToUnsignedLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.film.prefix); cin.film.count=0UL; value=GetCINProperty(image_info,image,"dpx:film.count",exception); if (value != (const char *) NULL) cin.film.count=StringToUnsignedLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.film.count); value=GetCINProperty(image_info,image,"dpx:film.format",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.film.format,value,sizeof(cin.film.format)); offset+=WriteBlob(image,sizeof(cin.film.format),(unsigned char *) cin.film.format); cin.film.frame_position=0UL; value=GetCINProperty(image_info,image,"dpx:film.frame_position",exception); if (value != (const char *) NULL) cin.film.frame_position=StringToUnsignedLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.film.frame_position); cin.film.frame_rate=0.0f; value=GetCINProperty(image_info,image,"dpx:film.frame_rate",exception); if (value != (const char *) NULL) cin.film.frame_rate=StringToDouble(value,(char **) NULL); offset+=WriteBlobFloat(image,cin.film.frame_rate); value=GetCINProperty(image_info,image,"dpx:film.frame_id",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.film.frame_id,value,sizeof(cin.film.frame_id)); offset+=WriteBlob(image,sizeof(cin.film.frame_id),(unsigned char *) cin.film.frame_id); value=GetCINProperty(image_info,image,"dpx:film.slate_info",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.film.slate_info,value, sizeof(cin.film.slate_info)); offset+=WriteBlob(image,sizeof(cin.film.slate_info),(unsigned char *) cin.film.slate_info); offset+=WriteBlob(image,sizeof(cin.film.reserve),(unsigned char *) cin.film.reserve); if (profile != (StringInfo *) NULL) offset+=WriteBlob(image,GetStringInfoLength(profile), GetStringInfoDatum(profile)); while (offset < (MagickOffsetType) cin.file.image_offset) offset+=WriteBlobByte(image,0x00); /* Convert pixel packets to CIN raster image. */ quantum_info=AcquireQuantumInfo(image_info,image); if (quantum_info == (QuantumInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); quantum_info->quantum=32; quantum_info->pack=MagickFalse; quantum_type=RGBQuantum; pixels=GetQuantumPixels(quantum_info); length=GetBytesPerRow(image->columns,3,image->depth,MagickTrue); if (0) { quantum_type=GrayQuantum; length=GetBytesPerRow(image->columns,1,image->depth,MagickTrue); } for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, quantum_type,pixels,exception); count=WriteBlob(image,length,pixels); if (count != (ssize_t) length) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } quantum_info=DestroyQuantumInfo(quantum_info); (void) CloseBlob(image); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e T H U M B N A I L I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteTHUMBNAILImage() extracts the EXIF thumbnail image and writes it. % % The format of the WriteTHUMBNAILImage method is: % % MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteTHUMBNAILImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { const char *property; const StringInfo *profile; Image *thumbnail_image; ImageInfo *write_info; MagickBooleanType status; register ssize_t i; size_t length; ssize_t offset; unsigned char magick[MaxTextExtent]; profile=GetImageProfile(image,"exif"); if (profile == (const StringInfo *) NULL) ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); property=GetImageProperty(image,"exif:JPEGInterchangeFormat",exception); if (property == (const char *) NULL) ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); offset=(ssize_t) StringToLong(property); property=GetImageProperty(image,"exif:JPEGInterchangeFormatLength",exception); if (property == (const char *) NULL) ThrowWriterException(CoderError,"ImageDoesNotHaveAThumbnail"); length=(size_t) StringToLong(property); (void) ResetMagickMemory(magick,0,sizeof(magick)); for (i=0; i < (ssize_t) length; i++) { magick[0]=magick[1]; magick[1]=magick[2]; magick[2]=GetStringInfoDatum(profile)[offset+i]; if (memcmp(magick,"\377\330\377",3) == 0) break; } thumbnail_image=BlobToImage(image_info,GetStringInfoDatum(profile)+offset+i-2, length,exception); if (thumbnail_image == (Image *) NULL) return(MagickFalse); (void) SetImageType(thumbnail_image,thumbnail_image->alpha_trait != BlendPixelTrait ? TrueColorType : TrueColorMatteType,exception); (void) CopyMagickString(thumbnail_image->filename,image->filename, MaxTextExtent); write_info=CloneImageInfo(image_info); (void) SetImageInfo(write_info,1,exception); if (LocaleCompare(write_info->magick,"THUMBNAIL") == 0) (void) FormatLocaleString(thumbnail_image->filename,MaxTextExtent, "miff:%s",write_info->filename); status=WriteImage(write_info,thumbnail_image,exception); thumbnail_image=DestroyImage(thumbnail_image); write_info=DestroyImageInfo(write_info); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadImage() reads an image or image sequence from a file or file handle. % The method returns a NULL if there is a memory shortage or if the image % cannot be read. On failure, a NULL image is returned and exception % describes the reason for the failure. % % The format of the ReadImage method is: % % Image *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: Read the image defined by the file or filename members of % this structure. % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *ReadImage(const ImageInfo *image_info, ExceptionInfo *exception) { char filename[MaxTextExtent], magick[MaxTextExtent], magick_filename[MaxTextExtent]; const char *value; const DelegateInfo *delegate_info; const MagickInfo *magick_info; ExceptionInfo *sans_exception; GeometryInfo geometry_info; Image *image, *next; ImageInfo *read_info; MagickStatusType flags, thread_support; PolicyDomain domain; PolicyRights rights; /* Determine image type from filename prefix or suffix (e.g. image.jpg). */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image_info->filename != (char *) NULL); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); read_info=CloneImageInfo(image_info); (void) CopyMagickString(magick_filename,read_info->filename,MaxTextExtent); (void) SetImageInfo(read_info,0,exception); (void) CopyMagickString(filename,read_info->filename,MaxTextExtent); (void) CopyMagickString(magick,read_info->magick,MaxTextExtent); domain=CoderPolicyDomain; rights=ReadPolicyRights; if (IsRightsAuthorized(domain,rights,read_info->magick) == MagickFalse) { errno=EPERM; (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, "NotAuthorized","`%s'",read_info->filename); return((Image *) NULL); } /* Call appropriate image reader based on image type. */ sans_exception=AcquireExceptionInfo(); magick_info=GetMagickInfo(read_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (magick_info != (const MagickInfo *) NULL) { if (GetMagickEndianSupport(magick_info) == MagickFalse) read_info->endian=UndefinedEndian; else if ((image_info->endian == UndefinedEndian) && (GetMagickRawSupport(magick_info) != MagickFalse)) { size_t lsb_first; lsb_first=1; read_info->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; } } if ((magick_info != (const MagickInfo *) NULL) && (GetMagickSeekableStream(magick_info) != MagickFalse)) { MagickBooleanType status; image=AcquireImage(read_info,exception); (void) CopyMagickString(image->filename,read_info->filename, MaxTextExtent); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { read_info=DestroyImageInfo(read_info); image=DestroyImage(image); return((Image *) NULL); } if (IsBlobSeekable(image) == MagickFalse) { /* Coder requires a seekable stream. */ *read_info->filename='\0'; status=ImageToFile(image,read_info->filename,exception); if (status == MagickFalse) { (void) CloseBlob(image); read_info=DestroyImageInfo(read_info); image=DestroyImage(image); return((Image *) NULL); } read_info->temporary=MagickTrue; } (void) CloseBlob(image); image=DestroyImage(image); } image=NewImageList(); if (constitute_semaphore == (SemaphoreInfo *) NULL) AcquireSemaphoreInfo(&constitute_semaphore); if ((magick_info != (const MagickInfo *) NULL) && (GetImageDecoder(magick_info) != (DecodeImageHandler *) NULL)) { thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & DecoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); image=GetImageDecoder(magick_info)(read_info,exception); if ((thread_support & DecoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } else { delegate_info=GetDelegateInfo(read_info->magick,(char *) NULL,exception); if (delegate_info == (const DelegateInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", read_info->filename); if (read_info->temporary != MagickFalse) (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } /* Let our decoding delegate process the image. */ image=AcquireImage(read_info,exception); if (image == (Image *) NULL) { read_info=DestroyImageInfo(read_info); return((Image *) NULL); } (void) CopyMagickString(image->filename,read_info->filename, MaxTextExtent); *read_info->filename='\0'; if (GetDelegateThreadSupport(delegate_info) == MagickFalse) LockSemaphoreInfo(constitute_semaphore); (void) InvokeDelegate(read_info,image,read_info->magick,(char *) NULL, exception); if (GetDelegateThreadSupport(delegate_info) == MagickFalse) UnlockSemaphoreInfo(constitute_semaphore); image=DestroyImageList(image); read_info->temporary=MagickTrue; (void) SetImageInfo(read_info,0,exception); magick_info=GetMagickInfo(read_info->magick,exception); if ((magick_info == (const MagickInfo *) NULL) || (GetImageDecoder(magick_info) == (DecodeImageHandler *) NULL)) { if (IsPathAccessible(read_info->filename) != MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", read_info->filename); else ThrowFileException(exception,FileOpenError,"UnableToOpenFile", read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & DecoderThreadSupport) == 0) LockSemaphoreInfo(constitute_semaphore); image=(Image *) (GetImageDecoder(magick_info))(read_info,exception); if ((thread_support & DecoderThreadSupport) == 0) UnlockSemaphoreInfo(constitute_semaphore); } if (read_info->temporary != MagickFalse) { (void) RelinquishUniqueFileResource(read_info->filename); read_info->temporary=MagickFalse; if (image != (Image *) NULL) (void) CopyMagickString(image->filename,filename,MaxTextExtent); } if (image == (Image *) NULL) { read_info=DestroyImageInfo(read_info); return(image); } if (exception->severity >= ErrorException) (void) LogMagickEvent(ExceptionEvent,GetMagickModule(), "Coder (%s) generated an image despite an error (%d), " "notify the developers",image->magick,exception->severity); if (IsBlobTemporary(image) != MagickFalse) (void) RelinquishUniqueFileResource(read_info->filename); if ((GetNextImageInList(image) != (Image *) NULL) && (IsSceneGeometry(read_info->scenes,MagickFalse) != MagickFalse)) { Image *clones; clones=CloneImages(image,read_info->scenes,exception); if (clones == (Image *) NULL) (void) ThrowMagickException(exception,GetMagickModule(),OptionError, "SubimageSpecificationReturnsNoImages","`%s'",read_info->filename); else { image=DestroyImageList(image); image=GetFirstImageInList(clones); } } if (GetBlobError(image) != MagickFalse) { ThrowFileException(exception,FileOpenError, "AnErrorHasOccurredReadingFromFile",read_info->filename); image=DestroyImageList(image); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } for (next=image; next != (Image *) NULL; next=GetNextImageInList(next)) { char magick_path[MaxTextExtent], *property, timestamp[MaxTextExtent]; const char *option; const StringInfo *profile; next->taint=MagickFalse; GetPathComponent(magick_filename,MagickPath,magick_path); if (*magick_path == '\0') (void) CopyMagickString(next->magick,magick,MaxTextExtent); (void) CopyMagickString(next->magick_filename,magick_filename, MaxTextExtent); if (IsBlobTemporary(image) != MagickFalse) (void) CopyMagickString(next->filename,filename,MaxTextExtent); if (next->magick_columns == 0) next->magick_columns=next->columns; if (next->magick_rows == 0) next->magick_rows=next->rows; value=GetImageProperty(next,"tiff:Orientation",exception); if (value == (char *) NULL) value=GetImageProperty(next,"exif:Orientation",exception); if (value != (char *) NULL) { next->orientation=(OrientationType) StringToLong(value); (void) DeleteImageProperty(next,"tiff:Orientation"); (void) DeleteImageProperty(next,"exif:Orientation"); } value=GetImageProperty(next,"exif:XResolution",exception); if (value != (char *) NULL) { geometry_info.rho=next->resolution.x; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->resolution.x=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:XResolution"); } value=GetImageProperty(next,"exif:YResolution",exception); if (value != (char *) NULL) { geometry_info.rho=next->resolution.y; geometry_info.sigma=1.0; flags=ParseGeometry(value,&geometry_info); if (geometry_info.sigma != 0) next->resolution.y=geometry_info.rho/geometry_info.sigma; (void) DeleteImageProperty(next,"exif:YResolution"); } value=GetImageProperty(next,"tiff:ResolutionUnit",exception); if (value == (char *) NULL) value=GetImageProperty(next,"exif:ResolutionUnit",exception); if (value != (char *) NULL) { next->units=(ResolutionType) (StringToLong(value)-1); (void) DeleteImageProperty(next,"exif:ResolutionUnit"); (void) DeleteImageProperty(next,"tiff:ResolutionUnit"); } if (next->page.width == 0) next->page.width=next->columns; if (next->page.height == 0) next->page.height=next->rows; option=GetImageOption(read_info,"caption"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"caption",property,exception); property=DestroyString(property); } option=GetImageOption(read_info,"comment"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"comment",property,exception); property=DestroyString(property); } option=GetImageOption(read_info,"label"); if (option != (const char *) NULL) { property=InterpretImageProperties(read_info,next,option,exception); (void) SetImageProperty(next,"label",property,exception); property=DestroyString(property); } if (LocaleCompare(next->magick,"TEXT") == 0) (void) ParseAbsoluteGeometry("0x0+0+0",&next->page); if ((read_info->extract != (char *) NULL) && (read_info->stream == (StreamHandler) NULL)) { RectangleInfo geometry; flags=ParseAbsoluteGeometry(read_info->extract,&geometry); if ((next->columns != geometry.width) || (next->rows != geometry.height)) { if (((flags & XValue) != 0) || ((flags & YValue) != 0)) { Image *crop_image; crop_image=CropImage(next,&geometry,exception); if (crop_image != (Image *) NULL) ReplaceImageInList(&next,crop_image); } else if (((flags & WidthValue) != 0) || ((flags & HeightValue) != 0)) { Image *size_image; flags=ParseRegionGeometry(next,read_info->extract,&geometry, exception); size_image=ResizeImage(next,geometry.width,geometry.height, next->filter,next->blur,exception); if (size_image != (Image *) NULL) ReplaceImageInList(&next,size_image); } } } profile=GetImageProfile(next,"icc"); if (profile == (const StringInfo *) NULL) profile=GetImageProfile(next,"icm"); profile=GetImageProfile(next,"iptc"); if (profile == (const StringInfo *) NULL) profile=GetImageProfile(next,"8bim"); (void) FormatMagickTime(GetBlobProperties(next)->st_mtime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:modify",timestamp,exception); (void) FormatMagickTime(GetBlobProperties(next)->st_ctime,MaxTextExtent, timestamp); (void) SetImageProperty(next,"date:create",timestamp,exception); option=GetImageOption(image_info,"delay"); if (option != (const char *) NULL) { GeometryInfo geometry_info; flags=ParseGeometry(option,&geometry_info); if ((flags & GreaterValue) != 0) { if (next->delay > (size_t) floor(geometry_info.rho+0.5)) next->delay=(size_t) floor(geometry_info.rho+0.5); } else if ((flags & LessValue) != 0) { if (next->delay < (size_t) floor(geometry_info.rho+0.5)) next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5); } else next->delay=(size_t) floor(geometry_info.rho+0.5); if ((flags & SigmaValue) != 0) next->ticks_per_second=(ssize_t) floor(geometry_info.sigma+0.5); } option=GetImageOption(image_info,"dispose"); if (option != (const char *) NULL) next->dispose=(DisposeType) ParseCommandOption(MagickDisposeOptions, MagickFalse,option); if (read_info->verbose != MagickFalse) (void) IdentifyImage(next,stderr,MagickFalse,exception); image=next; } read_info=DestroyImageInfo(read_info); return(GetFirstImageInList(image)); }
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; MagickBooleanType status; QuantumAny pixel, range[4]; register Quantum *q; register ssize_t i, x; size_t maximum_component_depth, number_components, x_step[4], y_step[4]; ssize_t components[4], y; /* 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); } /* 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"); } image->columns=jas_image_width(jp2_image); image->rows=jas_image_height(jp2_image); image->compression=JPEG2000Compression; switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))) { case JAS_CLRSPC_FAM_RGB: { SetImageColorspace(image,RGBColorspace,exception); 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->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_GRAY: { SetImageColorspace(image,GRAYColorspace,exception); 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: { SetImageColorspace(image,YCbCrColorspace,exception); 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->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_XYZ: { SetImageColorspace(image,XYZColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,0); components[1]=jas_image_getcmptbytype(jp2_image,1); components[2]=jas_image_getcmptbytype(jp2_image,2); 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->alpha_trait=BlendPixelTrait; number_components++; } break; } case JAS_CLRSPC_FAM_LAB: { SetImageColorspace(image,LabColorspace,exception); components[0]=jas_image_getcmptbytype(jp2_image,0); components[1]=jas_image_getcmptbytype(jp2_image,1); components[2]=jas_image_getcmptbytype(jp2_image,2); 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->alpha_trait=BlendPixelTrait; number_components++; } break; } default: { (void) jas_stream_close(jp2_stream); jas_image_destroy(jp2_image); ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported"); } } 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) || (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->alpha_trait=number_components > 3 ? BlendPixelTrait : UndefinedPixelTrait; 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 == (Quantum *) 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]); SetPixelGray(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); q+=GetPixelChannels(image); } break; } case 3: { /* RGB. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q); q+=GetPixelChannels(image); } break; } case 4: { /* RGBA. */ for (x=0; x < (ssize_t) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); SetPixelRed(image,ScaleAnyToQuantum((QuantumAny) pixel,range[0]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); SetPixelGreen(image,ScaleAnyToQuantum((QuantumAny) pixel,range[1]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); SetPixelBlue(image,ScaleAnyToQuantum((QuantumAny) pixel,range[2]),q); pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]); SetPixelAlpha(image,ScaleAnyToQuantum((QuantumAny) pixel,range[3]),q); q+=GetPixelChannels(image); } 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)) { jas_stream_memobj_t *blob; StringInfo *icc_profile, *profile; /* 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=BlobToStringInfo(blob->buf_,blob->len_); if (profile == (StringInfo *) NULL) ThrowReaderException(CorruptImageError,"MemoryAllocationFailed"); icc_profile=(StringInfo *) GetImageProfile(image,"icc"); if (icc_profile == (StringInfo *) NULL) (void) SetImageProfile(image,"icc",profile,exception); 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)); }
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; long components[4], y; MagickBooleanType status; QuantumAny pixel, *map[4], range; register long i, x; register PixelPacket *q; unsigned long 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 < (long) number_components; i++) { unsigned long height, width; width=(unsigned long) (jas_image_cmptwidth(jp2_image,components[i])* jas_image_cmpthstep(jp2_image,components[i])); height=(unsigned long) (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 < (long) 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 < (long) number_components; i++) { long j; map[i]=(QuantumAny *) AcquireQuantumMemory(MaxMap+1,sizeof(**map)); if (map[i] == (QuantumAny *) NULL) { for (--i; i >= 0; i--) map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]); for (i=0; i < (long) number_components; i++) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } range=GetQuantumRange((unsigned long) jas_image_cmptprec(jp2_image, components[i])); for (j=0; j <= (long) MaxMap; j++) map[i][j]=ScaleQuantumToMap(ScaleAnyToQuantum((QuantumAny) j,range)); } for (y=0; y < (long) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (i=0; i < (long) number_components; i++) (void) jas_image_readcmpt(jp2_image,(short) components[i],0, ((unsigned int) y)/y_step[i],((unsigned int) image->columns)/x_step[i], 1,pixels[i]); switch (number_components) { case 1: { /* Grayscale. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; q->green=q->red; q->blue=q->red; q++; } break; } case 3: { /* RGB. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) map[1][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) map[2][pixel]; q++; } break; } case 4: { /* RGBA. */ for (x=0; x < (long) image->columns; x++) { pixel=(QuantumAny) jas_matrix_getv(pixels[0],x/x_step[0]); q->red=(Quantum) map[0][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[1],x/x_step[1]); q->green=(Quantum) map[1][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[2],x/x_step[2]); q->blue=(Quantum) map[2][pixel]; pixel=(QuantumAny) jas_matrix_getv(pixels[3],x/x_step[3]); q->opacity=(Quantum) (QuantumRange-map[3][pixel]); q++; } break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,y,image->rows); if (status == MagickFalse) break; } for (i=0; i < (long) number_components; i++) map[i]=(QuantumAny *) RelinquishMagickMemory(map[i]); 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, %lu bytes",(unsigned long) 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 < (long) number_components; i++) jas_matrix_destroy(pixels[i]); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d C A C H E I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadMPCImage() reads an Magick Persistent Cache image file and returns % it. It allocates the memory necessary for the new Image structure and % returns a pointer to the new image. % % The format of the ReadMPCImage method is: % % Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception) % % Decompression code contributed by Kyle Shorter. % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception) { char cache_filename[MaxTextExtent], id[MaxTextExtent], keyword[MaxTextExtent], *options; const unsigned char *p; GeometryInfo geometry_info; Image *image; int c; LinkedListInfo *profiles; MagickBooleanType status; MagickOffsetType offset; MagickStatusType flags; register long i; size_t length; ssize_t count; StringInfo *profile; unsigned long depth, quantum_depth; /* 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); } (void) CopyMagickString(cache_filename,image->filename,MaxTextExtent); AppendImageFormat("cache",cache_filename); c=ReadBlobByte(image); if (c == EOF) { image=DestroyImage(image); return((Image *) NULL); } *id='\0'; (void) ResetMagickMemory(keyword,0,sizeof(keyword)); offset=0; do { /* Decode image header; header terminates one character beyond a ':'. */ profiles=(LinkedListInfo *) NULL; length=MaxTextExtent; options=AcquireString((char *) NULL); quantum_depth=MAGICKCORE_QUANTUM_DEPTH; image->depth=8; image->compression=NoCompression; while ((isgraph(c) != MagickFalse) && (c != (int) ':')) { register char *p; if (c == (int) '{') { char *comment; /* Read comment-- any text between { }. */ length=MaxTextExtent; comment=AcquireString((char *) NULL); for (p=comment; comment != (char *) NULL; p++) { c=ReadBlobByte(image); if ((c == EOF) || (c == (int) '}')) break; if ((size_t) (p-comment+1) >= length) { *p='\0'; length<<=1; comment=(char *) ResizeQuantumMemory(comment,length+ MaxTextExtent,sizeof(*comment)); if (comment == (char *) NULL) break; p=comment+strlen(comment); } *p=(char) c; } if (comment == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); *p='\0'; (void) SetImageProperty(image,"comment",comment); comment=DestroyString(comment); c=ReadBlobByte(image); } else if (isalnum(c) != MagickFalse) { /* Get the keyword. */ p=keyword; do { if (isspace((int) ((unsigned char) c)) != 0) break; if (c == (int) '=') break; if ((size_t) (p-keyword) < (MaxTextExtent-1)) *p++=(char) c; c=ReadBlobByte(image); } while (c != EOF); *p='\0'; p=options; while (isspace((int) ((unsigned char) c)) != 0) c=ReadBlobByte(image); if (c == (int) '=') { /* Get the keyword value. */ c=ReadBlobByte(image); while ((c != (int) '}') && (c != EOF)) { if ((size_t) (p-options+1) >= length) { *p='\0'; length<<=1; options=(char *) ResizeQuantumMemory(options,length+ MaxTextExtent,sizeof(*options)); if (options == (char *) NULL) break; p=options+strlen(options); } if (options == (char *) NULL) ThrowReaderException(ResourceLimitError, "MemoryAllocationFailed"); *p++=(char) c; c=ReadBlobByte(image); if (*options != '{') if (isspace((int) ((unsigned char) c)) != 0) break; } } *p='\0'; if (*options == '{') (void) CopyMagickString(options,options+1,MaxTextExtent); /* Assign a value to the specified keyword. */ switch (*keyword) { case 'b': case 'B': { if (LocaleCompare(keyword,"background-color") == 0) { (void) QueryColorDatabase(options,&image->background_color, exception); break; } if (LocaleCompare(keyword,"blue-primary") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.blue_primary.x=geometry_info.rho; image->chromaticity.blue_primary.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->chromaticity.blue_primary.y= image->chromaticity.blue_primary.x; break; } if (LocaleCompare(keyword,"border-color") == 0) { (void) QueryColorDatabase(options,&image->border_color, exception); break; } (void) SetImageProperty(image,keyword,options); break; } case 'c': case 'C': { if (LocaleCompare(keyword,"class") == 0) { long storage_class; storage_class=ParseMagickOption(MagickClassOptions, MagickFalse,options); if (storage_class < 0) break; image->storage_class=(ClassType) storage_class; break; } if (LocaleCompare(keyword,"colors") == 0) { image->colors=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"colorspace") == 0) { long colorspace; colorspace=ParseMagickOption(MagickColorspaceOptions, MagickFalse,options); if (colorspace < 0) break; image->colorspace=(ColorspaceType) colorspace; break; } if (LocaleCompare(keyword,"compression") == 0) { long compression; compression=ParseMagickOption(MagickCompressOptions, MagickFalse,options); if (compression < 0) break; image->compression=(CompressionType) compression; break; } if (LocaleCompare(keyword,"columns") == 0) { image->columns=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'd': case 'D': { if (LocaleCompare(keyword,"delay") == 0) { image->delay=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"depth") == 0) { image->depth=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"dispose") == 0) { long dispose; dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse, options); if (dispose < 0) break; image->dispose=(DisposeType) dispose; break; } (void) SetImageProperty(image,keyword,options); break; } case 'e': case 'E': { if (LocaleCompare(keyword,"endian") == 0) { long endian; endian=ParseMagickOption(MagickEndianOptions,MagickFalse, options); if (endian < 0) break; image->endian=(EndianType) endian; break; } if (LocaleCompare(keyword,"error") == 0) { image->error.mean_error_per_pixel=StringToDouble(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'g': case 'G': { if (LocaleCompare(keyword,"gamma") == 0) { image->gamma=StringToDouble(options); break; } if (LocaleCompare(keyword,"green-primary") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.green_primary.x=geometry_info.rho; image->chromaticity.green_primary.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->chromaticity.green_primary.y= image->chromaticity.green_primary.x; break; } (void) SetImageProperty(image,keyword,options); break; } case 'i': case 'I': { if (LocaleCompare(keyword,"id") == 0) { (void) CopyMagickString(id,options,MaxTextExtent); break; } if (LocaleCompare(keyword,"iterations") == 0) { image->iterations=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'm': case 'M': { if (LocaleCompare(keyword,"matte") == 0) { long matte; matte=ParseMagickOption(MagickBooleanOptions,MagickFalse, options); if (matte < 0) break; image->matte=(MagickBooleanType) matte; break; } if (LocaleCompare(keyword,"matte-color") == 0) { (void) QueryColorDatabase(options,&image->matte_color, exception); break; } if (LocaleCompare(keyword,"maximum-error") == 0) { image->error.normalized_maximum_error=StringToDouble(options); break; } if (LocaleCompare(keyword,"mean-error") == 0) { image->error.normalized_mean_error=StringToDouble(options); break; } if (LocaleCompare(keyword,"montage") == 0) { (void) CloneString(&image->montage,options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'o': case 'O': { if (LocaleCompare(keyword,"opaque") == 0) { long matte; matte=ParseMagickOption(MagickBooleanOptions,MagickFalse, options); if (matte < 0) break; image->matte=(MagickBooleanType) matte; break; } if (LocaleCompare(keyword,"orientation") == 0) { long orientation; orientation=ParseMagickOption(MagickOrientationOptions, MagickFalse,options); if (orientation < 0) break; image->orientation=(OrientationType) orientation; break; } (void) SetImageProperty(image,keyword,options); break; } case 'p': case 'P': { if (LocaleCompare(keyword,"page") == 0) { char *geometry; geometry=GetPageGeometry(options); (void) ParseAbsoluteGeometry(geometry,&image->page); geometry=DestroyString(geometry); break; } if ((LocaleNCompare(keyword,"profile:",8) == 0) || (LocaleNCompare(keyword,"profile-",8) == 0)) { if (profiles == (LinkedListInfo *) NULL) profiles=NewLinkedList(0); (void) AppendValueToLinkedList(profiles, AcquireString(keyword+8)); profile=AcquireStringInfo((size_t) StringToLong(options)); (void) SetImageProfile(image,keyword+8,profile); profile=DestroyStringInfo(profile); break; } (void) SetImageProperty(image,keyword,options); break; } case 'q': case 'Q': { if (LocaleCompare(keyword,"quality") == 0) { image->quality=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"quantum-depth") == 0) { quantum_depth=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'r': case 'R': { if (LocaleCompare(keyword,"red-primary") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.red_primary.x=geometry_info.rho; if ((flags & SigmaValue) != 0) image->chromaticity.red_primary.y=geometry_info.sigma; break; } if (LocaleCompare(keyword,"rendering-intent") == 0) { long rendering_intent; rendering_intent=ParseMagickOption(MagickIntentOptions, MagickFalse,options); if (rendering_intent < 0) break; image->rendering_intent=(RenderingIntent) rendering_intent; break; } if (LocaleCompare(keyword,"resolution") == 0) { flags=ParseGeometry(options,&geometry_info); image->x_resolution=geometry_info.rho; image->y_resolution=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->y_resolution=image->x_resolution; break; } if (LocaleCompare(keyword,"rows") == 0) { image->rows=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 's': case 'S': { if (LocaleCompare(keyword,"scene") == 0) { image->scene=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 't': case 'T': { if (LocaleCompare(keyword,"ticks-per-second") == 0) { image->ticks_per_second=(long) StringToLong(options); break; } if (LocaleCompare(keyword,"tile-offset") == 0) { char *geometry; geometry=GetPageGeometry(options); (void) ParseAbsoluteGeometry(geometry,&image->tile_offset); geometry=DestroyString(geometry); } if (LocaleCompare(keyword,"type") == 0) { long type; type=ParseMagickOption(MagickTypeOptions,MagickFalse, options); if (type < 0) break; image->type=(ImageType) type; break; } (void) SetImageProperty(image,keyword,options); break; } case 'u': case 'U': { if (LocaleCompare(keyword,"units") == 0) { long units; units=ParseMagickOption(MagickResolutionOptions,MagickFalse, options); if (units < 0) break; image->units=(ResolutionType) units; break; } (void) SetImageProperty(image,keyword,options); break; } case 'w': case 'W': { if (LocaleCompare(keyword,"white-point") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.white_point.x=geometry_info.rho; image->chromaticity.white_point.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->chromaticity.white_point.y= image->chromaticity.white_point.x; break; } (void) SetImageProperty(image,keyword,options); break; } default: { (void) SetImageProperty(image,keyword,options); break; } } } else c=ReadBlobByte(image); while (isspace((int) ((unsigned char) c)) != 0) c=ReadBlobByte(image); } options=DestroyString(options); (void) ReadBlobByte(image); /* Verify that required image information is defined. */ if ((LocaleCompare(id,"MagickCache") != 0) || (image->storage_class == UndefinedClass) || (image->compression == UndefinedCompression) || (image->columns == 0) || (image->rows == 0)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if (quantum_depth != MAGICKCORE_QUANTUM_DEPTH) ThrowReaderException(CacheError,"InconsistentPersistentCacheDepth"); if (image->montage != (char *) NULL) { register char *p; /* Image directory. */ length=MaxTextExtent; image->directory=AcquireString((char *) NULL); p=image->directory; do { *p='\0'; if ((strlen(image->directory)+MaxTextExtent) >= length) { /* Allocate more memory for the image directory. */ length<<=1; image->directory=(char *) ResizeQuantumMemory(image->directory, length+MaxTextExtent,sizeof(*image->directory)); if (image->directory == (char *) NULL) ThrowReaderException(CorruptImageError,"UnableToReadImageData"); p=image->directory+strlen(image->directory); } c=ReadBlobByte(image); *p++=(char) c; } while (c != (int) '\0'); } if (profiles != (LinkedListInfo *) NULL) { const char *name; const StringInfo *profile; register unsigned char *p; /* Read image profiles. */ ResetLinkedListIterator(profiles); name=(const char *) GetNextValueInLinkedList(profiles); while (name != (const char *) NULL) { profile=GetImageProfile(image,name); if (profile != (StringInfo *) NULL) { p=GetStringInfoDatum(profile); count=ReadBlob(image,GetStringInfoLength(profile),p); } name=(const char *) GetNextValueInLinkedList(profiles); } profiles=DestroyLinkedList(profiles,RelinquishMagickMemory); } depth=GetImageQuantumDepth(image,MagickFalse); if (image->storage_class == PseudoClass) { /* Create image colormap. */ if (AcquireImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if (image->colors != 0) { size_t packet_size; unsigned char *colormap; /* Read image colormap from file. */ packet_size=(size_t) (3UL*depth/8UL); colormap=(unsigned char *) AcquireQuantumMemory(image->colors, packet_size*sizeof(*colormap)); if (colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,packet_size*image->colors,colormap); if (count != (ssize_t) (packet_size*image->colors)) ThrowReaderException(CorruptImageError, "InsufficientImageDataInFile"); p=colormap; switch (depth) { default: ThrowReaderException(CorruptImageError, "ImageDepthNotSupported"); case 8: { unsigned char pixel; for (i=0; i < (long) image->colors; i++) { p=PushCharPixel(p,&pixel); image->colormap[i].red=ScaleCharToQuantum(pixel); p=PushCharPixel(p,&pixel); image->colormap[i].green=ScaleCharToQuantum(pixel); p=PushCharPixel(p,&pixel); image->colormap[i].blue=ScaleCharToQuantum(pixel); } break; } case 16: { unsigned short pixel; for (i=0; i < (long) image->colors; i++) { p=PushShortPixel(MSBEndian,p,&pixel); image->colormap[i].red=ScaleShortToQuantum(pixel); p=PushShortPixel(MSBEndian,p,&pixel); image->colormap[i].green=ScaleShortToQuantum(pixel); p=PushShortPixel(MSBEndian,p,&pixel); image->colormap[i].blue=ScaleShortToQuantum(pixel); } break; } case 32: { unsigned long pixel; for (i=0; i < (long) image->colors; i++) { p=PushLongPixel(MSBEndian,p,&pixel); image->colormap[i].red=ScaleLongToQuantum(pixel); p=PushLongPixel(MSBEndian,p,&pixel); image->colormap[i].green=ScaleLongToQuantum(pixel); p=PushLongPixel(MSBEndian,p,&pixel); image->colormap[i].blue=ScaleLongToQuantum(pixel); } break; } } colormap=(unsigned char *) RelinquishMagickMemory(colormap); } } if (EOFBlob(image) != MagickFalse) { ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); break; } if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Attach persistent pixel cache. */ status=PersistPixelCache(image,cache_filename,MagickTrue,&offset,exception); if (status == MagickFalse) ThrowReaderException(CacheError,"UnableToPersistPixelCache"); /* Proceed to next image. */ do { c=ReadBlobByte(image); } while ((isgraph(c) == MagickFalse) && (c != EOF)); if (c != EOF) { /* Allocate next image structure. */ AcquireNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=SetImageProgress(image,LoadImagesTag,TellBlob(image), GetBlobSize(image)); if (status == MagickFalse) break; } } while (c != EOF); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e M P C I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteMPCImage() writes an Magick Persistent Cache image to a file. % % The format of the WriteMPCImage method is: % % MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows: % % o image_info: the image info. % % o image: the image. % */ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent], cache_filename[MaxTextExtent]; const char *property, *value; MagickBooleanType status; MagickOffsetType offset, scene; register long i; unsigned long depth; /* Open persistent cache. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) CopyMagickString(cache_filename,image->filename,MaxTextExtent); AppendImageFormat("cache",cache_filename); scene=0; offset=0; do { /* Write persistent cache meta-information. */ depth=GetImageQuantumDepth(image,MagickTrue); if ((image->storage_class == PseudoClass) && (image->colors > (1UL << depth))) image->storage_class=DirectClass; (void) WriteBlobString(image,"id=MagickCache\n"); (void) FormatMagickString(buffer,MaxTextExtent,"quantum-depth=%d\n", MAGICKCORE_QUANTUM_DEPTH); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "class=%s colors=%lu matte=%s\n",MagickOptionToMnemonic( MagickClassOptions,image->storage_class),image->colors, MagickOptionToMnemonic(MagickBooleanOptions,(long) image->matte)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "columns=%lu rows=%lu depth=%lu\n",image->columns,image->rows, image->depth); (void) WriteBlobString(image,buffer); if (image->type != UndefinedType) { (void) FormatMagickString(buffer,MaxTextExtent,"type=%s\n", MagickOptionToMnemonic(MagickTypeOptions,image->type)); (void) WriteBlobString(image,buffer); } if (image->colorspace != UndefinedColorspace) { (void) FormatMagickString(buffer,MaxTextExtent,"colorspace=%s\n", MagickOptionToMnemonic(MagickColorspaceOptions,image->colorspace)); (void) WriteBlobString(image,buffer); } if (image->endian != UndefinedEndian) { (void) FormatMagickString(buffer,MaxTextExtent,"endian=%s\n", MagickOptionToMnemonic(MagickEndianOptions,image->endian)); (void) WriteBlobString(image,buffer); } if (image->compression != UndefinedCompression) { (void) FormatMagickString(buffer,MaxTextExtent, "compression=%s quality=%lu\n",MagickOptionToMnemonic( MagickCompressOptions,image->compression),image->quality); (void) WriteBlobString(image,buffer); } if (image->units != UndefinedResolution) { (void) FormatMagickString(buffer,MaxTextExtent,"units=%s\n", MagickOptionToMnemonic(MagickResolutionOptions,image->units)); (void) WriteBlobString(image,buffer); } if ((image->x_resolution != 0) || (image->y_resolution != 0)) { (void) FormatMagickString(buffer,MaxTextExtent, "resolution=%gx%g\n",image->x_resolution,image->y_resolution); (void) WriteBlobString(image,buffer); } if ((image->page.width != 0) || (image->page.height != 0)) { (void) FormatMagickString(buffer,MaxTextExtent,"page=%lux%lu%+ld%+ld\n", image->page.width,image->page.height,image->page.x,image->page.y); (void) WriteBlobString(image,buffer); } else if ((image->page.x != 0) || (image->page.y != 0)) { (void) FormatMagickString(buffer,MaxTextExtent,"page=%+ld%+ld\n", image->page.x,image->page.y); (void) WriteBlobString(image,buffer); } if ((image->page.x != 0) || (image->page.y != 0)) { (void) FormatMagickString(buffer,MaxTextExtent,"tile-offset=%+ld%+ld\n", image->tile_offset.x,image->tile_offset.y); (void) WriteBlobString(image,buffer); } if ((GetNextImageInList(image) != (Image *) NULL) || (GetPreviousImageInList(image) != (Image *) NULL)) { if (image->scene == 0) (void) FormatMagickString(buffer,MaxTextExtent, "iterations=%lu delay=%lu ticks-per-second=%lu\n", image->iterations,image->delay,image->ticks_per_second); else (void) FormatMagickString(buffer,MaxTextExtent, "scene=%lu iterations=%lu delay=%lu ticks-per-second=%lu\n", image->scene,image->iterations,image->delay, image->ticks_per_second); (void) WriteBlobString(image,buffer); } else { if (image->scene != 0) { (void) FormatMagickString(buffer,MaxTextExtent,"scene=%lu\n", image->scene); (void) WriteBlobString(image,buffer); } if (image->iterations != 0) { (void) FormatMagickString(buffer,MaxTextExtent,"iterations=%lu\n", image->iterations); (void) WriteBlobString(image,buffer); } if (image->delay != 0) { (void) FormatMagickString(buffer,MaxTextExtent,"delay=%lu\n", image->delay); (void) WriteBlobString(image,buffer); } if (image->ticks_per_second != UndefinedTicksPerSecond) { (void) FormatMagickString(buffer,MaxTextExtent, "ticks-per-second=%lu\n",image->ticks_per_second); (void) WriteBlobString(image,buffer); } } if (image->gravity != UndefinedGravity) { (void) FormatMagickString(buffer,MaxTextExtent,"gravity=%s\n", MagickOptionToMnemonic(MagickGravityOptions,image->gravity)); (void) WriteBlobString(image,buffer); } if (image->dispose != UndefinedDispose) { (void) FormatMagickString(buffer,MaxTextExtent,"dispose=%s\n", MagickOptionToMnemonic(MagickDisposeOptions,image->dispose)); (void) WriteBlobString(image,buffer); } if (image->rendering_intent != UndefinedIntent) { (void) FormatMagickString(buffer,MaxTextExtent, "rendering-intent=%s\n", MagickOptionToMnemonic(MagickIntentOptions,image->rendering_intent)); (void) WriteBlobString(image,buffer); } if (image->gamma != 0.0) { (void) FormatMagickString(buffer,MaxTextExtent,"gamma=%g\n", image->gamma); (void) WriteBlobString(image,buffer); } if (image->chromaticity.white_point.x != 0.0) { /* Note chomaticity points. */ (void) FormatMagickString(buffer,MaxTextExtent,"red-primary=" "%g,%g green-primary=%g,%g blue-primary=%g,%g\n", image->chromaticity.red_primary.x,image->chromaticity.red_primary.y, image->chromaticity.green_primary.x, image->chromaticity.green_primary.y, image->chromaticity.blue_primary.x, image->chromaticity.blue_primary.y); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "white-point=%g,%g\n",image->chromaticity.white_point.x, image->chromaticity.white_point.y); (void) WriteBlobString(image,buffer); } if (image->orientation != UndefinedOrientation) { (void) FormatMagickString(buffer,MaxTextExtent, "orientation=%s\n",MagickOptionToMnemonic(MagickOrientationOptions, image->orientation)); (void) WriteBlobString(image,buffer); } if (image->profiles != (void *) NULL) { const char *name; const StringInfo *profile; /* Generic profile. */ ResetImageProfileIterator(image); for (name=GetNextImageProfile(image); name != (const char *) NULL; ) { profile=GetImageProfile(image,name); if (profile != (StringInfo *) NULL) { (void) FormatMagickString(buffer,MaxTextExtent,"profile:%s=%lu\n", name,(unsigned long) GetStringInfoLength(profile)); (void) WriteBlobString(image,buffer); } name=GetNextImageProfile(image); } } if (image->montage != (char *) NULL) { (void) FormatMagickString(buffer,MaxTextExtent,"montage=%s\n", image->montage); (void) WriteBlobString(image,buffer); } ResetImagePropertyIterator(image); property=GetNextImageProperty(image); while (property != (const char *) NULL) { (void) FormatMagickString(buffer,MaxTextExtent,"%s=",property); (void) WriteBlobString(image,buffer); value=GetImageProperty(image,property); if (value != (const char *) NULL) { for (i=0; i < (long) strlen(value); i++) if (isspace((int) ((unsigned char) value[i])) != 0) break; if (i <= (long) strlen(value)) (void) WriteBlobByte(image,'{'); (void) WriteBlob(image,strlen(value),(unsigned char *) value); if (i <= (long) strlen(value)) (void) WriteBlobByte(image,'}'); } (void) WriteBlobByte(image,'\n'); property=GetNextImageProperty(image); } ResetImageArtifactIterator(image); (void) WriteBlobString(image,"\f\n:\032"); if (image->montage != (char *) NULL) { /* Write montage tile directory. */ if (image->directory != (char *) NULL) (void) WriteBlobString(image,image->directory); (void) WriteBlobByte(image,'\0'); } if (image->profiles != 0) { const char *name; const StringInfo *profile; /* Write image profiles. */ ResetImageProfileIterator(image); name=GetNextImageProfile(image); while (name != (const char *) NULL) { profile=GetImageProfile(image,name); (void) WriteBlob(image,GetStringInfoLength(profile), GetStringInfoDatum(profile)); name=GetNextImageProfile(image); } } if (image->storage_class == PseudoClass) { size_t packet_size; unsigned char *colormap, *q; /* Allocate colormap. */ packet_size=(size_t) (3UL*depth/8UL); colormap=(unsigned char *) AcquireQuantumMemory(image->colors, packet_size*sizeof(*colormap)); if (colormap == (unsigned char *) NULL) return(MagickFalse); /* Write colormap to file. */ q=colormap; for (i=0; i < (long) image->colors; i++) { switch (depth) { default: ThrowWriterException(CorruptImageError,"ImageDepthNotSupported"); case 32: { unsigned long pixel; pixel=ScaleQuantumToLong(image->colormap[i].red); q=PopLongPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToLong(image->colormap[i].green); q=PopLongPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToLong(image->colormap[i].blue); q=PopLongPixel(MSBEndian,pixel,q); } case 16: { unsigned short pixel; pixel=ScaleQuantumToShort(image->colormap[i].red); q=PopShortPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToShort(image->colormap[i].green); q=PopShortPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToShort(image->colormap[i].blue); q=PopShortPixel(MSBEndian,pixel,q); break; } case 8: { unsigned char pixel; pixel=(unsigned char) ScaleQuantumToChar(image->colormap[i].red); q=PopCharPixel(pixel,q); pixel=(unsigned char) ScaleQuantumToChar( image->colormap[i].green); q=PopCharPixel(pixel,q); pixel=(unsigned char) ScaleQuantumToChar(image->colormap[i].blue); q=PopCharPixel(pixel,q); break; } } } (void) WriteBlob(image,packet_size*image->colors,colormap); colormap=(unsigned char *) RelinquishMagickMemory(colormap); } /* Initialize persistent pixel cache. */ status=PersistPixelCache(image,cache_filename,MagickFalse,&offset, &image->exception); if (status == MagickFalse) ThrowWriterException(CacheError,"UnableToPersistPixelCache"); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(SaveImagesTag,scene, GetImageListLength(image),image->client_data); if (status == MagickFalse) break; } scene++; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % D e s c r i b e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DescribeImage() describes an image by printing its attributes to the file. % Attributes include the image width, height, size, and others. % % The format of the DescribeImage method is: % % void DescribeImage(Image *image,FILE *file,const MagickBool verbose) % % A description of each parameter follows: % % o image: The image. % % o file: The file, typically stdout. % % o verbose: A value other than zero prints more detailed information % about the image. Values greater than one enable counting the number of % colors in the image. % % */ MagickExport MagickPassFail DescribeImage(Image *image,FILE *file, const MagickBool verbose) { char color[MaxTextExtent], format[MaxTextExtent]; const unsigned char *profile; size_t profile_length; const ImageAttribute *attribute; const MagickInfo *magick_info; double elapsed_time, user_time; unsigned long columns, rows; magick_int64_t pixels_per_second; Image *p; long y; register long i, x; unsigned long count; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(file != (FILE *) NULL); elapsed_time=GetElapsedTime(&image->timer); user_time=GetUserTime(&image->timer); GetTimerInfo(&image->timer); if (!verbose) { /* Display summary info about the image. */ if (*image->magick_filename != '\0') if (LocaleCompare(image->magick_filename,image->filename) != 0) (void) fprintf(file,"%.1024s=>",image->magick_filename); if ((image->previous == (Image *) NULL) && (image->next == (Image *) NULL) && (image->scene == 0)) (void) fprintf(file,"%.1024s ",image->filename); else (void) fprintf(file,"%.1024s[%lu] ",image->filename,image->scene); (void) fprintf(file,"%.1024s ",image->magick); columns=image->columns; rows=image->rows; if ((image->magick_columns != 0) || (image->magick_rows != 0)) if ((image->magick_columns != image->columns) || (image->magick_rows != image->rows)) { columns=image->magick_columns; rows=image->magick_rows; (void) fprintf(file,"%lux%lu=>",image->magick_columns, image->magick_rows); } (void) fprintf(file,"%lux%lu%+ld%+ld ",image->columns,image->rows, image->page.x,image->page.y); if (image->storage_class == DirectClass) { (void) fprintf(file,"DirectClass "); if (image->total_colors != 0) { FormatSize(image->total_colors,format); (void) fprintf(file,"%.1024s ",format); } } else if (image->total_colors <= image->colors) (void) fprintf(file,"PseudoClass %uc ",image->colors); else { (void) fprintf(file,"PseudoClass %lu=>%uc ",image->total_colors, image->colors); (void) fprintf(file,"%ld/%.6f/%.6fe ", (long) image->error.mean_error_per_pixel, image->error.normalized_mean_error, image->error.normalized_maximum_error); } (void) fprintf(file,"%u-bit ",image->depth); if (GetBlobSize(image) != 0) { FormatSize(GetBlobSize(image),format); (void) fprintf(file,"%.1024s ",format); } (void) fprintf(file,"%0.3fu %ld:%02ld",user_time, (long) (elapsed_time/60.0), (long) ceil(fmod(elapsed_time,60.0))); /* Only display pixel read rate if the time accumulated is at least six times the timer's resolution (typically 0.01 on Unix). */ if (elapsed_time >= GetTimerResolution()*6) { pixels_per_second=(magick_int64_t) ((double) rows*columns/ elapsed_time); FormatSize(pixels_per_second,format); (void) fprintf(file," (%s pixels/s)",format); } (void) fprintf(file,"\n"); return (ferror(file) ? MagickFail : MagickPass); } /* Display verbose info about the image. */ (void) SignatureImage(image); if (verbose > 1) image->total_colors=GetNumberColors(image,(FILE *) NULL,&image->exception); (void) fprintf(file,"Image: %.1024s\n",image->filename); magick_info=GetMagickInfo(image->magick,&image->exception); if ((magick_info == (const MagickInfo *) NULL) || (*magick_info->description == '\0')) (void) fprintf(file," Format: %.1024s\n",image->magick); else (void) fprintf(file," Format: %.1024s (%.1024s)\n",image->magick, magick_info->description); (void) fprintf(file," Geometry: %lux%lu\n",image->columns,image->rows); if (image->storage_class == DirectClass) (void) fprintf(file," Class: DirectClass\n"); else (void) fprintf(file," Class: PseudoClass\n"); if ((image->magick_columns != 0) || (image->magick_rows != 0)) if ((image->magick_columns != image->columns) || (image->magick_rows != image->rows)) (void) fprintf(file," Base geometry: %lux%lu\n",image->magick_columns, image->magick_rows); (void) fprintf(file," Type: "); switch (GetImageType(image,&image->exception)) { case BilevelType: (void) fprintf(file,"bilevel"); break; case GrayscaleType: (void) fprintf(file,"grayscale"); break; case GrayscaleMatteType: (void) fprintf(file,"grayscale with transparency"); break; case PaletteType: (void) fprintf(file,"palette"); break; case PaletteMatteType: (void) fprintf(file,"palette with transparency"); break; case TrueColorType: (void) fprintf(file,"true color"); break; case TrueColorMatteType: (void) fprintf(file,"true color with transparency"); break; case ColorSeparationType: (void) fprintf(file,"color separated"); break; case ColorSeparationMatteType: (void) fprintf(file,"color separated with transparency"); break; default: (void) fprintf(file,"undefined"); break; } (void) fprintf(file,"\n"); (void) fprintf(file," Depth: %lu bits-per-pixel component\n", GetImageDepth(image,&image->exception)); (void) fprintf(file," Channel Depths:\n"); if (image->colorspace == CMYKColorspace) { (void) fprintf(file," Cyan: %u bits\n", GetImageChannelDepth(image,CyanChannel,&image->exception)); (void) fprintf(file," Magenta: %u bits\n", GetImageChannelDepth(image,MagentaChannel,&image->exception)); (void) fprintf(file," Yellow: %u bits\n", GetImageChannelDepth(image,YellowChannel,&image->exception)); (void) fprintf(file," Black: %u bits\n", GetImageChannelDepth(image,BlackChannel,&image->exception)); } else if ((IsGrayColorspace(image->colorspace)) || (image->is_grayscale == True)) { (void) fprintf(file," Gray: %u bits\n", GetImageChannelDepth(image,RedChannel,&image->exception)); } else { (void) fprintf(file," Red: %u bits\n", GetImageChannelDepth(image,RedChannel,&image->exception)); (void) fprintf(file," Green: %u bits\n", GetImageChannelDepth(image,GreenChannel,&image->exception)); (void) fprintf(file," Blue: %u bits\n", GetImageChannelDepth(image,BlueChannel,&image->exception)); } if (image->matte) (void) fprintf(file," Opacity: %u bits\n", GetImageChannelDepth(image,OpacityChannel,&image->exception)); (void) fprintf(file," Channel Statistics:\n"); { ImageStatistics statistics; (void) GetImageStatistics(image,&statistics,&image->exception); if (image->colorspace == CMYKColorspace) { (void) fprintf(file," Cyan:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.minimum, statistics.red.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.maximum, statistics.red.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.mean, statistics.red.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.standard_deviation, statistics.red.standard_deviation); (void) fprintf(file," Magenta:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.minimum, statistics.green.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.maximum, statistics.green.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.mean, statistics.green.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.standard_deviation, statistics.green.standard_deviation); (void) fprintf(file," Yellow:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.minimum, statistics.blue.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.maximum, statistics.blue.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.mean, statistics.blue.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.standard_deviation, statistics.blue.standard_deviation); (void) fprintf(file," Black:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.minimum, statistics.opacity.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.maximum, statistics.opacity.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.mean, statistics.opacity.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.standard_deviation, statistics.opacity.standard_deviation); /* if (image->matte) (void) fprintf(file," Opacity:\n"); */ } else if ((IsGrayColorspace(image->colorspace)) || (image->is_grayscale == True)) { (void) fprintf(file," Gray:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.minimum, statistics.red.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.maximum, statistics.red.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.mean, statistics.red.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.standard_deviation, statistics.red.standard_deviation); if (image->matte) { (void) fprintf(file," Opacity:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.minimum, statistics.opacity.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.maximum, statistics.opacity.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.mean, statistics.opacity.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.standard_deviation, statistics.opacity.standard_deviation); } } else { (void) fprintf(file," Red:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.minimum, statistics.red.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.maximum, statistics.red.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.mean, statistics.red.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.red.standard_deviation, statistics.red.standard_deviation); (void) fprintf(file," Green:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.minimum, statistics.green.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.maximum, statistics.green.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.mean, statistics.green.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.green.standard_deviation, statistics.green.standard_deviation); (void) fprintf(file," Blue:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.minimum, statistics.blue.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.maximum, statistics.blue.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.mean, statistics.blue.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.blue.standard_deviation, statistics.blue.standard_deviation); if (image->matte) { (void) fprintf(file," Opacity:\n"); (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.minimum, statistics.opacity.minimum); (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.maximum, statistics.opacity.maximum); (void) fprintf(file," Mean: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.mean, statistics.opacity.mean); (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n", MaxRGB*statistics.opacity.standard_deviation, statistics.opacity.standard_deviation); } } } x=0; p=(Image *) NULL; if ((image->matte && (strcmp(image->magick,"GIF") != 0)) || image->taint) { char tuple[MaxTextExtent]; register const PixelPacket *p; p=(PixelPacket *) NULL; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if (p->opacity == TransparentOpacity) break; p++; } if (x < (long) image->columns) break; } if ((x < (long) image->columns) || (y < (long) image->rows)) { GetColorTuple(p,image->depth,image->matte,False,tuple); (void) fprintf(file," Opacity: %.1024s\t",tuple); GetColorTuple(p,image->depth,image->matte,True,tuple); (void) fprintf(file," %.1024s\n",tuple); } } if (image->storage_class == DirectClass) { if (image->total_colors != 0) (void) fprintf(file," Colors: %lu\n",image->total_colors); } else { if (image->total_colors <= image->colors) (void) fprintf(file," Colors: %u\n",image->colors); else (void) fprintf(file," Colors: %lu=>%u\n",image->total_colors, image->colors); } if (image->storage_class == DirectClass) { if (image->total_colors < 1024) if (verbose > 1) (void) GetNumberColors(image,file,&image->exception); } else { char name[MaxTextExtent]; register PixelPacket *p; /* Display image colormap. */ p=image->colormap; for (i=0; i < (long) image->colors; i++) { char tuple[MaxTextExtent]; GetColorTuple(p,image->depth,image->matte,False,tuple); (void) fprintf(file," %lu: %.1024s",i,tuple); (void) fprintf(file,"\t"); (void) QueryColorname(image,p,SVGCompliance,name,&image->exception); (void) fprintf(file," %.1024s",name); (void) fprintf(file,"\n"); p++; } } if (image->error.mean_error_per_pixel != 0.0) (void) fprintf(file," Mean Exception Per Pixel: %ld\n", (long) image->error.mean_error_per_pixel); if (image->error.normalized_mean_error != 0.0) (void) fprintf(file," Normalized Mean Exception: %g\n", image->error.normalized_mean_error); if (image->error.normalized_maximum_error != 0.0) (void) fprintf(file," Normalized Maximum Exception: %gn", image->error.normalized_maximum_error); if (image->rendering_intent == SaturationIntent) (void) fprintf(file," Rendering-Intent: saturation\n"); else if (image->rendering_intent == PerceptualIntent) (void) fprintf(file," Rendering-Intent: perceptual\n"); else if (image->rendering_intent == AbsoluteIntent) (void) fprintf(file," Rendering-Intent: absolute\n"); else if (image->rendering_intent == RelativeIntent) (void) fprintf(file," Rendering-Intent: relative\n"); if (image->gamma != 0.0) (void) fprintf(file," Gamma: %g\n",image->gamma); if ((image->chromaticity.red_primary.x != 0.0) || (image->chromaticity.green_primary.x != 0.0) || (image->chromaticity.blue_primary.x != 0.0) || (image->chromaticity.white_point.x != 0.0)) { /* Display image chromaticity. */ (void) fprintf(file," Chromaticity:\n"); (void) fprintf(file," red primary: (%g,%g)\n", image->chromaticity.red_primary.x,image->chromaticity.red_primary.y); (void) fprintf(file," green primary: (%g,%g)\n", image->chromaticity.green_primary.x, image->chromaticity.green_primary.y); (void) fprintf(file," blue primary: (%g,%g)\n", image->chromaticity.blue_primary.x,image->chromaticity.blue_primary.y); (void) fprintf(file," white point: (%g,%g)\n", image->chromaticity.white_point.x,image->chromaticity.white_point.y); } if ((image->tile_info.width*image->tile_info.height) != 0) (void) fprintf(file," Tile geometry: %lux%lu%+ld%+ld\n", image->tile_info.width,image->tile_info.height,image->tile_info.x, image->tile_info.y); if ((image->x_resolution != 0.0) && (image->y_resolution != 0.0)) { /* Display image resolution. */ (void) fprintf(file," Resolution: %gx%g",image->x_resolution, image->y_resolution); if (image->units == UndefinedResolution) (void) fprintf(file," pixels\n"); else if (image->units == PixelsPerInchResolution) (void) fprintf(file," pixels/inch\n"); else if (image->units == PixelsPerCentimeterResolution) (void) fprintf(file," pixels/centimeter\n"); else (void) fprintf(file,"\n"); } FormatSize(GetBlobSize(image),format); (void) fprintf(file," Filesize: %.1024s\n",format); fprintf(file," Interlace: %s\n", InterlaceTypeToString(image->interlace == UndefinedInterlace ? NoInterlace : image->interlace)); (void) fprintf(file," Orientation: %s\n", OrientationTypeToString(image->orientation)); (void) QueryColorname(image,&image->background_color,SVGCompliance,color, &image->exception); (void) fprintf(file," Background Color: %.1024s\n",color); (void) QueryColorname(image,&image->border_color,SVGCompliance,color, &image->exception); (void) fprintf(file," Border Color: %.1024s\n",color); (void) QueryColorname(image,&image->matte_color,SVGCompliance,color, &image->exception); (void) fprintf(file," Matte Color: %.1024s\n",color); if ((image->page.width != 0) && (image->page.height != 0)) (void) fprintf(file," Page geometry: %lux%lu%+ld%+ld\n",image->page.width, image->page.height,image->page.x,image->page.y); (void) fprintf(file," Compose: %s\n", CompositeOperatorToString(image->compose)); (void) fprintf(file," Dispose: "); switch (image->dispose) { case UndefinedDispose: (void) fprintf(file,"Undefined\n"); break; case NoneDispose: (void) fprintf(file,"None\n"); break; case BackgroundDispose: (void) fprintf(file,"Background\n"); break; case PreviousDispose: (void) fprintf(file,"Previous\n"); break; default: (void) fprintf(file,"\n"); break; } if (image->delay != 0) (void) fprintf(file," Delay: %lu\n",image->delay); if (image->iterations != 1) (void) fprintf(file," Iterations: %lu\n",image->iterations); p=image; while (p->previous != (Image *) NULL) p=p->previous; for (count=1; p->next != (Image *) NULL; count++) p=p->next; if (count > 1) (void) fprintf(file," Scene: %lu of %lu\n",image->scene,count); else if (image->scene != 0) (void) fprintf(file," Scene: %lu\n",image->scene); (void) fprintf(file," Compression: %s\n", CompressionTypeToString(image->compression)); /* Display formatted image attributes. This must happen before we access any pseudo attributes like EXIF since doing so causes real attributes to be created and we would get duplicates in the output. */ attribute=GetImageAttribute(image,(char *) NULL); { for ( ; attribute != (const ImageAttribute *) NULL; attribute=attribute->next) { if (LocaleNCompare("EXIF",attribute->key,4) != 0) { (void) fprintf(file," %c", toupper((int)attribute->key[0])); if (strlen(attribute->key) > 1) (void) fprintf(file,"%.1024s",attribute->key+1); (void) fprintf(file,": "); (void) fprintf(file,"%s\n",attribute->value); } } } if((profile=GetImageProfile(image,"ICM",&profile_length)) != 0) (void) fprintf(file," Profile-color: %lu bytes\n",(unsigned long) profile_length); if((profile=GetImageProfile(image,"IPTC",&profile_length)) != 0) { char *tag, *text; size_t length; /* Describe IPTC data. */ (void) fprintf(file," Profile-iptc: %lu bytes\n",(unsigned long) profile_length); for (i=0; i < (long) profile_length; ) { if (profile[i] != 0x1c) { i++; continue; } i++; /* skip file separator */ i++; /* skip record number */ switch (profile[i]) { case 5: tag=(char *) "Image Name"; break; case 7: tag=(char *) "Edit Status"; break; case 10: tag=(char *) "Priority"; break; case 15: tag=(char *) "Category"; break; case 20: tag=(char *) "Supplemental Category"; break; case 22: tag=(char *) "Fixture Identifier"; break; case 25: tag=(char *) "Keyword"; break; case 30: tag=(char *) "Release Date"; break; case 35: tag=(char *) "Release Time"; break; case 40: tag=(char *) "Special Instructions"; break; case 45: tag=(char *) "Reference Service"; break; case 47: tag=(char *) "Reference Date"; break; case 50: tag=(char *) "Reference Number"; break; case 55: tag=(char *) "Created Date"; break; case 60: tag=(char *) "Created Time"; break; case 65: tag=(char *) "Originating Program"; break; case 70: tag=(char *) "Program Version"; break; case 75: tag=(char *) "Object Cycle"; break; case 80: tag=(char *) "Byline"; break; case 85: tag=(char *) "Byline Title"; break; case 90: tag=(char *) "City"; break; case 95: tag=(char *) "Province State"; break; case 100: tag=(char *) "Country Code"; break; case 101: tag=(char *) "Country"; break; case 103: tag=(char *) "Original Transmission Reference"; break; case 105: tag=(char *) "Headline"; break; case 110: tag=(char *) "Credit"; break; case 115: tag=(char *) "Source"; break; case 116: tag=(char *) "Copyright String"; break; case 120: tag=(char *) "Caption"; break; case 121: tag=(char *) "Local Caption"; break; case 122: tag=(char *) "Caption Writer"; break; case 200: tag=(char *) "Custom Field 1"; break; case 201: tag=(char *) "Custom Field 2"; break; case 202: tag=(char *) "Custom Field 3"; break; case 203: tag=(char *) "Custom Field 4"; break; case 204: tag=(char *) "Custom Field 5"; break; case 205: tag=(char *) "Custom Field 6"; break; case 206: tag=(char *) "Custom Field 7"; break; case 207: tag=(char *) "Custom Field 8"; break; case 208: tag=(char *) "Custom Field 9"; break; case 209: tag=(char *) "Custom Field 10"; break; case 210: tag=(char *) "Custom Field 11"; break; case 211: tag=(char *) "Custom Field 12"; break; case 212: tag=(char *) "Custom Field 13"; break; case 213: tag=(char *) "Custom Field 14"; break; case 214: tag=(char *) "Custom Field 15"; break; case 215: tag=(char *) "Custom Field 16"; break; case 216: tag=(char *) "Custom Field 17"; break; case 217: tag=(char *) "Custom Field 18"; break; case 218: tag=(char *) "Custom Field 19"; break; case 219: tag=(char *) "Custom Field 20"; break; default: tag=(char *) "unknown"; break; } i++; (void) fprintf(file," %.1024s:\n",tag); length=profile[i++] << 8; length|=profile[i++]; text=MagickAllocateMemory(char *,length+1); if (text != (char *) NULL) { char **textlist; register long j; (void) strncpy(text,(char *) profile+i,length); text[length]='\0'; textlist=StringToList(text); if (textlist != (char **) NULL) { for (j=0; textlist[j] != (char *) NULL; j++) { (void) fprintf(file," %s\n",textlist[j]); MagickFreeMemory(textlist[j]); } MagickFreeMemory(textlist); } MagickFreeMemory(text); } i+=length; } }