/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % V a l i d a t e I m a g e F o r m a t s O n D i s k % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ValidateImageFormatsOnDisk() validates the ImageMagick image formats on disk % and returns the number of validation tests that passed and failed. % % The format of the ValidateImageFormatsOnDisk method is: % % unsigned long ValidateImageFormatsOnDisk(ImageInfo *image_info, % const char *reference_filename,const char *output_filename, % unsigned long *fail,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o reference_filename: the reference image filename. % % o output_filename: the output image filename. % % o fail: return the number of validation tests that pass. % % o exception: return any errors or warnings in this structure. % */ static unsigned long ValidateImageFormatsOnDisk(ImageInfo *image_info, const char *reference_filename,const char *output_filename, unsigned long *fail,ExceptionInfo *exception) { char size[MaxTextExtent]; const MagickInfo *magick_info; double distortion, fuzz; Image *difference_image, *reference_image, *reconstruct_image; MagickBooleanType status; register long i, j; unsigned long test; test=0; (void) fprintf(stdout,"validate image formats on disk:\n"); for (i=0; reference_formats[i].magick != (char *) NULL; i++) { magick_info=GetMagickInfo(reference_formats[i].magick,exception); if ((magick_info == (const MagickInfo *) NULL) || (magick_info->decoder == (DecodeImageHandler *) NULL) || (magick_info->encoder == (EncodeImageHandler *) NULL)) continue; for (j=0; reference_types[j].type != UndefinedType; j++) { /* Generate reference image. */ CatchException(exception); (void) fprintf(stdout," test %lu: %s/%s/%lu-bits",test++, reference_formats[i].magick,MagickOptionToMnemonic(MagickTypeOptions, reference_types[j].type),reference_types[j].depth); (void) CopyMagickString(image_info->filename,reference_filename, MaxTextExtent); reference_image=ReadImage(image_info,exception); if (reference_image == (Image *) NULL) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; continue; } /* Write reference image. */ (void) FormatMagickString(size,MaxTextExtent,"%lux%lu", reference_image->columns,reference_image->rows); (void) CloneString(&image_info->size,size); image_info->depth=reference_types[j].depth; (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s", reference_formats[i].magick,output_filename); status=SetImageType(reference_image,reference_types[j].type); InheritException(exception,&reference_image->exception); if (status == MagickFalse) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; reference_image=DestroyImage(reference_image); continue; } status=SetImageDepth(reference_image,reference_types[j].depth); InheritException(exception,&reference_image->exception); if (status == MagickFalse) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; reference_image=DestroyImage(reference_image); continue; } status=WriteImage(image_info,reference_image); InheritException(exception,&reference_image->exception); reference_image=DestroyImage(reference_image); if (status == MagickFalse) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; continue; } /* Read reference image. */ (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s", reference_formats[i].magick,output_filename); reference_image=ReadImage(image_info,exception); if (reference_image == (Image *) NULL) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; continue; } /* Write reference image. */ (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s", reference_formats[i].magick,output_filename); reference_image->depth=reference_types[j].depth; status=WriteImage(image_info,reference_image); InheritException(exception,&reference_image->exception); if (status == MagickFalse) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; reference_image=DestroyImage(reference_image); continue; } /* Read reconstruct image. */ (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s", reference_formats[i].magick,output_filename); reconstruct_image=ReadImage(image_info,exception); if (reconstruct_image == (Image *) NULL) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; reference_image=DestroyImage(reference_image); continue; } /* Compare reference to reconstruct image. */ fuzz=0.0; if (reference_formats[i].fuzz != 0.0) fuzz=reference_formats[i].fuzz; #if defined(MAGICKCORE_HDRI_SUPPORT) fuzz+=0.003; #endif if (reference_image->colorspace != RGBColorspace) fuzz+=0.3; fuzz+=MagickEpsilon; difference_image=CompareImageChannels(reference_image,reconstruct_image, AllChannels,MeanSquaredErrorMetric,&distortion,exception); reconstruct_image=DestroyImage(reconstruct_image); reference_image=DestroyImage(reference_image); if (difference_image == (Image *) NULL) { (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule()); (*fail)++; continue; } difference_image=DestroyImage(difference_image); if ((distortion/QuantumRange) > fuzz) { (void) fprintf(stdout,"... fail (with distortion %g).\n",distortion/ QuantumRange); (*fail)++; continue; } (void) fprintf(stdout,"... pass.\n"); } } (void) fprintf(stdout," summary: %lu subtests; %lu passed; %lu failed.\n", test,test-(*fail),*fail); return(test); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e H I S T O G R A M I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteHISTOGRAMImage writes an image to a file in Histogram format. % The image shows a histogram of the color (or gray) values in the image. The % image consists of three overlaid histograms: a red one for the red channel, % a green one for the green channel, and a blue one for the blue channel. The % image comment contains a list of unique pixel values and the number of times % each occurs in the image. % % This method is strongly based on a similar one written by % [email protected] which in turn is based on ppmhistmap of netpbm. % % The format of the WriteHISTOGRAMImage method is: % % unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o status: Method WriteHISTOGRAMImage return True if the image is written. % False is returned is there is a memory shortage or if the image file % fails to write. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o image: A pointer to an Image structure. % % */ static unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info, Image *image) { #define HistogramDensity "256x200" char filename[MaxTextExtent]; double scale; FILE *file; Image *histogram_image; long *blue, *green, maximum, *red; long y; RectangleInfo geometry; register const PixelPacket *p; register long x; register PixelPacket *q, *r; unsigned int status; unsigned long length; /* Allocate histogram image. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); (void) SetImageDepth(image,image->depth); SetGeometry(image,&geometry); if (image_info->density == (char *) NULL) (void) GetMagickGeometry(HistogramDensity,&geometry.x,&geometry.y, &geometry.width,&geometry.height); else (void) GetMagickGeometry(image_info->density,&geometry.x,&geometry.y, &geometry.width,&geometry.height); histogram_image=CloneImage(image,geometry.width,geometry.height,True, &image->exception); if (histogram_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); (void) SetImageType(histogram_image,TrueColorType); /* Allocate histogram count arrays. */ length=Max(ScaleQuantumToChar(MaxRGB)+1,histogram_image->columns); red=MagickAllocateMemory(long *,length*sizeof(long)); green=MagickAllocateMemory(long *,length*sizeof(long)); blue=MagickAllocateMemory(long *,length*sizeof(long)); if ((red == (long *) NULL) || (green == (long *) NULL) || (blue == (long *) NULL)) { DestroyImage(histogram_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image) }