13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6787c09caeeb16217a92190b802477636aebd55bdcristy% H H IIIII SSSSS TTTTT OOO GGGG RRRR AAA M M % 7787c09caeeb16217a92190b802477636aebd55bdcristy% H H I SS T O O G R R A A MM MM % 8787c09caeeb16217a92190b802477636aebd55bdcristy% HHHHH I SSS T O O G GG RRRR AAAAA M M M % 9787c09caeeb16217a92190b802477636aebd55bdcristy% H H I SS T O O G G R R A A M M % 10787c09caeeb16217a92190b802477636aebd55bdcristy% H H IIIII SSSSS T OOO GGG R R A A M M % 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 13787c09caeeb16217a92190b802477636aebd55bdcristy% Write A Histogram Image. % 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Software Design % 16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy% Cristy % 17787c09caeeb16217a92190b802477636aebd55bdcristy% July 1992 % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% dedicated to making software imaging solutions freely available. % 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% You may not use this file except in compliance with the License. You may % 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% obtain a copy of the License at % 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.imagemagick.org/script/license.php % 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Unless required by applicable law or agreed to in writing, software % 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% distributed under the License is distributed on an "AS IS" BASIS, % 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% See the License for the specific language governing permissions and % 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% limitations under the License. % 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Include declarations. 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h" 4376ce6e193e5a305875173a744bbd59d27ddb3148cristy#include "MagickCore/artifact.h" 444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h" 454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h" 464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h" 474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h" 484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h" 494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h" 514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h" 534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/histogram.h" 544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h" 604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 6176ce6e193e5a305875173a744bbd59d27ddb3148cristy#include "MagickCore/property.h" 624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h" 634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h" 644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h" 654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h" 664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h" 68e40005d4b3d35ab5844d139731543174539453cfcristy#include "MagickCore/token.h" 694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h" 703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Forward declarations. 733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 74787c09caeeb16217a92190b802477636aebd55bdcristystatic MagickBooleanType 751e178e70fb3c956f9fc1e30c3ba863e882666465cristy WriteHISTOGRAMImage(const ImageInfo *,Image *,ExceptionInfo *); 763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 82787c09caeeb16217a92190b802477636aebd55bdcristy% R e g i s t e r H I S T O G R A M I m a g e % 833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 88787c09caeeb16217a92190b802477636aebd55bdcristy% RegisterHISTOGRAMImage() adds attributes for the Histogram image format 89787c09caeeb16217a92190b802477636aebd55bdcristy% to the list of supported formats. The attributes include the image format 90787c09caeeb16217a92190b802477636aebd55bdcristy% tag, a method to read and/or write the format, whether the format 91787c09caeeb16217a92190b802477636aebd55bdcristy% supports the saving of more than one frame to the same file or blob, 92787c09caeeb16217a92190b802477636aebd55bdcristy% whether the format supports native in-memory I/O, and a brief 93787c09caeeb16217a92190b802477636aebd55bdcristy% description of the format. 941bd4a3a6b7cc5505da6698c4e61423a091d9d79fcristy% 95787c09caeeb16217a92190b802477636aebd55bdcristy% The format of the RegisterHISTOGRAMImage method is: 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 97bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% size_t RegisterHISTOGRAMImage(void) 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 100bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterHISTOGRAMImage(void) 1011bd4a3a6b7cc5505da6698c4e61423a091d9d79fcristy{ 102787c09caeeb16217a92190b802477636aebd55bdcristy MagickInfo 103787c09caeeb16217a92190b802477636aebd55bdcristy *entry; 104787c09caeeb16217a92190b802477636aebd55bdcristy 10506b627a07ff44e1ff93ef1288c9f428066ded10ddirk entry=AcquireMagickInfo("HISTOGRAM","HISTOGRAM","Histogram of the image"); 106787c09caeeb16217a92190b802477636aebd55bdcristy entry->encoder=(EncodeImageHandler *) WriteHISTOGRAMImage; 10708e9a113db499034abb5ad8d59b42f8eca3c641cdirk entry->flags^=CoderAdjoinFlag; 108009d739511cb808de2f5899fe7e06be7350838e9cristy entry->format_type=ImplicitFormatType; 109787c09caeeb16217a92190b802477636aebd55bdcristy (void) RegisterMagickInfo(entry); 110787c09caeeb16217a92190b802477636aebd55bdcristy return(MagickImageCoderSignature); 1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 118787c09caeeb16217a92190b802477636aebd55bdcristy% U n r e g i s t e r H I S T O G R A M I m a g e % 1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 124787c09caeeb16217a92190b802477636aebd55bdcristy% UnregisterHISTOGRAMImage() removes format registrations made by the 125787c09caeeb16217a92190b802477636aebd55bdcristy% HISTOGRAM module from the list of supported formats. 1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 127787c09caeeb16217a92190b802477636aebd55bdcristy% The format of the UnregisterHISTOGRAMImage method is: 1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 129787c09caeeb16217a92190b802477636aebd55bdcristy% UnregisterHISTOGRAMImage(void) 1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 132787c09caeeb16217a92190b802477636aebd55bdcristyModuleExport void UnregisterHISTOGRAMImage(void) 1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 134787c09caeeb16217a92190b802477636aebd55bdcristy (void) UnregisterMagickInfo("HISTOGRAM"); 1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 142787c09caeeb16217a92190b802477636aebd55bdcristy% W r i t e H I S T O G R A M I m a g e % 1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 148787c09caeeb16217a92190b802477636aebd55bdcristy% WriteHISTOGRAMImage() writes an image to a file in Histogram format. 149787c09caeeb16217a92190b802477636aebd55bdcristy% The image shows a histogram of the color (or gray) values in the image. The 150787c09caeeb16217a92190b802477636aebd55bdcristy% image consists of three overlaid histograms: a red one for the red channel, 151787c09caeeb16217a92190b802477636aebd55bdcristy% a green one for the green channel, and a blue one for the blue channel. The 152787c09caeeb16217a92190b802477636aebd55bdcristy% image comment contains a list of unique pixel values and the number of times 153787c09caeeb16217a92190b802477636aebd55bdcristy% each occurs in the image. 1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 155787c09caeeb16217a92190b802477636aebd55bdcristy% This method is strongly based on a similar one written by 156787c09caeeb16217a92190b802477636aebd55bdcristy% muquit@warm.semcor.com which in turn is based on ppmhistmap of netpbm. 1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 158787c09caeeb16217a92190b802477636aebd55bdcristy% The format of the WriteHISTOGRAMImage method is: 1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 160787c09caeeb16217a92190b802477636aebd55bdcristy% MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, 1611e178e70fb3c956f9fc1e30c3ba863e882666465cristy% Image *image,ExceptionInfo *exception) 1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows. 1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 165787c09caeeb16217a92190b802477636aebd55bdcristy% o image_info: the image info. 1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 167787c09caeeb16217a92190b802477636aebd55bdcristy% o image: The image. 1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1691e178e70fb3c956f9fc1e30c3ba863e882666465cristy% o exception: return any errors or warnings in this structure. 1701e178e70fb3c956f9fc1e30c3ba863e882666465cristy% 1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 172787c09caeeb16217a92190b802477636aebd55bdcristystatic MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, 1731e178e70fb3c956f9fc1e30c3ba863e882666465cristy Image *image,ExceptionInfo *exception) 174787c09caeeb16217a92190b802477636aebd55bdcristy{ 17531ac0f02045e4e34f2353d9a746b4b912987dc96cristy#define HistogramDensity "256x200" 1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 177787c09caeeb16217a92190b802477636aebd55bdcristy char 178151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy filename[MagickPathExtent]; 1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1806db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy const char 1816db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy *option; 1826db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy 183787c09caeeb16217a92190b802477636aebd55bdcristy Image 184787c09caeeb16217a92190b802477636aebd55bdcristy *histogram_image; 1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 186787c09caeeb16217a92190b802477636aebd55bdcristy ImageInfo 187787c09caeeb16217a92190b802477636aebd55bdcristy *write_info; 1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 189787c09caeeb16217a92190b802477636aebd55bdcristy MagickBooleanType 190787c09caeeb16217a92190b802477636aebd55bdcristy status; 191787c09caeeb16217a92190b802477636aebd55bdcristy 1924c08aed51c5899665ade97263692328eea4af106cristy PixelInfo 193787c09caeeb16217a92190b802477636aebd55bdcristy *histogram; 1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 195a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 196787c09caeeb16217a92190b802477636aebd55bdcristy maximum, 197787c09caeeb16217a92190b802477636aebd55bdcristy scale; 198787c09caeeb16217a92190b802477636aebd55bdcristy 199787c09caeeb16217a92190b802477636aebd55bdcristy RectangleInfo 200787c09caeeb16217a92190b802477636aebd55bdcristy geometry; 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2024c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2054c08aed51c5899665ade97263692328eea4af106cristy register Quantum 206787c09caeeb16217a92190b802477636aebd55bdcristy *q, 207787c09caeeb16217a92190b802477636aebd55bdcristy *r; 2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20931ac0f02045e4e34f2353d9a746b4b912987dc96cristy register ssize_t 21031ac0f02045e4e34f2353d9a746b4b912987dc96cristy x; 21131ac0f02045e4e34f2353d9a746b4b912987dc96cristy 212787c09caeeb16217a92190b802477636aebd55bdcristy size_t 213787c09caeeb16217a92190b802477636aebd55bdcristy length; 2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 21531ac0f02045e4e34f2353d9a746b4b912987dc96cristy ssize_t 21631ac0f02045e4e34f2353d9a746b4b912987dc96cristy y; 21731ac0f02045e4e34f2353d9a746b4b912987dc96cristy 218787c09caeeb16217a92190b802477636aebd55bdcristy /* 219787c09caeeb16217a92190b802477636aebd55bdcristy Allocate histogram image. 220787c09caeeb16217a92190b802477636aebd55bdcristy */ 221787c09caeeb16217a92190b802477636aebd55bdcristy assert(image_info != (const ImageInfo *) NULL); 222e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image_info->signature == MagickCoreSignature); 2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 224e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 226787c09caeeb16217a92190b802477636aebd55bdcristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 227787c09caeeb16217a92190b802477636aebd55bdcristy image_info->filename); 228787c09caeeb16217a92190b802477636aebd55bdcristy SetGeometry(image,&geometry); 229787c09caeeb16217a92190b802477636aebd55bdcristy if (image_info->density == (char *) NULL) 230787c09caeeb16217a92190b802477636aebd55bdcristy (void) ParseAbsoluteGeometry(HistogramDensity,&geometry); 231787c09caeeb16217a92190b802477636aebd55bdcristy else 232787c09caeeb16217a92190b802477636aebd55bdcristy (void) ParseAbsoluteGeometry(image_info->density,&geometry); 233787c09caeeb16217a92190b802477636aebd55bdcristy histogram_image=CloneImage(image,geometry.width,geometry.height,MagickTrue, 2341e178e70fb3c956f9fc1e30c3ba863e882666465cristy exception); 235787c09caeeb16217a92190b802477636aebd55bdcristy if (histogram_image == (Image *) NULL) 236787c09caeeb16217a92190b802477636aebd55bdcristy ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 2371e178e70fb3c956f9fc1e30c3ba863e882666465cristy (void) SetImageStorageClass(histogram_image,DirectClass,exception); 2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 239787c09caeeb16217a92190b802477636aebd55bdcristy Allocate histogram count arrays. 2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 2416e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy length=MagickMax((size_t) ScaleQuantumToChar(QuantumRange)+1UL, 242787c09caeeb16217a92190b802477636aebd55bdcristy histogram_image->columns); 2430553bd5babdbdf65b95f91ed401c98fead17ab54cristy histogram=(PixelInfo *) AcquireQuantumMemory(length,sizeof(*histogram)); 2444c08aed51c5899665ade97263692328eea4af106cristy if (histogram == (PixelInfo *) NULL) 2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 246787c09caeeb16217a92190b802477636aebd55bdcristy histogram_image=DestroyImage(histogram_image); 247787c09caeeb16217a92190b802477636aebd55bdcristy ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 249787c09caeeb16217a92190b802477636aebd55bdcristy /* 250787c09caeeb16217a92190b802477636aebd55bdcristy Initialize histogram count arrays. 251787c09caeeb16217a92190b802477636aebd55bdcristy */ 252787c09caeeb16217a92190b802477636aebd55bdcristy (void) ResetMagickMemory(histogram,0,length*sizeof(*histogram)); 253bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2551e178e70fb3c956f9fc1e30c3ba863e882666465cristy p=GetVirtualPixels(image,0,y,image->columns,1,exception); 2564c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 258bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 260ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 2614c08aed51c5899665ade97263692328eea4af106cristy histogram[ScaleQuantumToChar(GetPixelRed(image,p))].red++; 262ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 2634c08aed51c5899665ade97263692328eea4af106cristy histogram[ScaleQuantumToChar(GetPixelGreen(image,p))].green++; 264ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 2654c08aed51c5899665ade97263692328eea4af106cristy histogram[ScaleQuantumToChar(GetPixelBlue(image,p))].blue++; 266ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy p+=GetPixelChannels(image); 2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 269787c09caeeb16217a92190b802477636aebd55bdcristy maximum=histogram[0].red; 270bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) histogram_image->columns; x++) 271787c09caeeb16217a92190b802477636aebd55bdcristy { 272ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) && 2732b9582a27910c7baaeb04b7e969638328fa70095cristy (maximum < histogram[x].red)) 274787c09caeeb16217a92190b802477636aebd55bdcristy maximum=histogram[x].red; 275ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) && 2762b9582a27910c7baaeb04b7e969638328fa70095cristy (maximum < histogram[x].green)) 277787c09caeeb16217a92190b802477636aebd55bdcristy maximum=histogram[x].green; 278ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) && 2792b9582a27910c7baaeb04b7e969638328fa70095cristy (maximum < histogram[x].blue)) 280787c09caeeb16217a92190b802477636aebd55bdcristy maximum=histogram[x].blue; 281787c09caeeb16217a92190b802477636aebd55bdcristy } 282e6133492f32b99b69eb298622d92e5eb11fd98fbcristy scale=0.0; 283e6133492f32b99b69eb298622d92e5eb11fd98fbcristy if (fabs(maximum) >= MagickEpsilon) 284e6133492f32b99b69eb298622d92e5eb11fd98fbcristy scale=(double) histogram_image->rows/maximum; 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 286787c09caeeb16217a92190b802477636aebd55bdcristy Initialize histogram image. 2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 288fad60c95ffc2ea3de9e5f0eaaeaaa3d008289683cristy (void) QueryColorCompliance("#000000",AllCompliance, 2899950d57e1124b73f684fb5946e206994cefda628cristy &histogram_image->background_color,exception); 290ea1a8aa04a9fe1500104284407c1cc06d20da699cristy (void) SetImageBackgroundColor(histogram_image,exception); 291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) histogram_image->columns; x++) 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 293fad60c95ffc2ea3de9e5f0eaaeaaa3d008289683cristy q=GetAuthenticPixels(histogram_image,x,0,1,histogram_image->rows,exception); 294acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy if (q == (Quantum *) NULL) 2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 296ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) 2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 298bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].red-0.5); 2996db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy r=q+y*GetPixelChannels(histogram_image); 300bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for ( ; y < (ssize_t) histogram_image->rows; y++) 3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3024c08aed51c5899665ade97263692328eea4af106cristy SetPixelRed(histogram_image,QuantumRange,r); 3036db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy r+=GetPixelChannels(histogram_image); 3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 306ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) 3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].green-0.5); 3096db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy r=q+y*GetPixelChannels(histogram_image); 310bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for ( ; y < (ssize_t) histogram_image->rows; y++) 311787c09caeeb16217a92190b802477636aebd55bdcristy { 3124c08aed51c5899665ade97263692328eea4af106cristy SetPixelGreen(histogram_image,QuantumRange,r); 3136db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy r+=GetPixelChannels(histogram_image); 314787c09caeeb16217a92190b802477636aebd55bdcristy } 3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 316ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) 3171bd4a3a6b7cc5505da6698c4e61423a091d9d79fcristy { 318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].blue-0.5); 3196db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy r=q+y*GetPixelChannels(histogram_image); 320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for ( ; y < (ssize_t) histogram_image->rows; y++) 321787c09caeeb16217a92190b802477636aebd55bdcristy { 3224c08aed51c5899665ade97263692328eea4af106cristy SetPixelBlue(histogram_image,QuantumRange,r); 3236db52da8af55ddc52b33fa84df8ddcc58bf1d0c1cristy r+=GetPixelChannels(histogram_image); 324787c09caeeb16217a92190b802477636aebd55bdcristy } 3251bd4a3a6b7cc5505da6698c4e61423a091d9d79fcristy } 326787c09caeeb16217a92190b802477636aebd55bdcristy if (SyncAuthenticPixels(histogram_image,exception) == MagickFalse) 327787c09caeeb16217a92190b802477636aebd55bdcristy break; 328787c09caeeb16217a92190b802477636aebd55bdcristy status=SetImageProgress(image,SaveImageTag,y,histogram_image->rows); 329787c09caeeb16217a92190b802477636aebd55bdcristy if (status == MagickFalse) 330787c09caeeb16217a92190b802477636aebd55bdcristy break; 3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3324c08aed51c5899665ade97263692328eea4af106cristy histogram=(PixelInfo *) RelinquishMagickMemory(histogram); 333092ec8d083fedaedfb7792995e7ea42164553cffcristy option=GetImageOption(image_info,"histogram:unique-colors"); 334d5f40a91c013256a09b3e3c66cb6ea036ab44b95cristy if ((option == (const char *) NULL) || (IsStringTrue(option) != MagickFalse)) 3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 336787c09caeeb16217a92190b802477636aebd55bdcristy FILE 337787c09caeeb16217a92190b802477636aebd55bdcristy *file; 3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 339787c09caeeb16217a92190b802477636aebd55bdcristy int 340787c09caeeb16217a92190b802477636aebd55bdcristy unique_file; 3411bd4a3a6b7cc5505da6698c4e61423a091d9d79fcristy 342787c09caeeb16217a92190b802477636aebd55bdcristy /* 343787c09caeeb16217a92190b802477636aebd55bdcristy Add a unique colors as an image comment. 344787c09caeeb16217a92190b802477636aebd55bdcristy */ 345787c09caeeb16217a92190b802477636aebd55bdcristy file=(FILE *) NULL; 346787c09caeeb16217a92190b802477636aebd55bdcristy unique_file=AcquireUniqueFileResource(filename); 347787c09caeeb16217a92190b802477636aebd55bdcristy if (unique_file != -1) 348787c09caeeb16217a92190b802477636aebd55bdcristy file=fdopen(unique_file,"wb"); 349787c09caeeb16217a92190b802477636aebd55bdcristy if ((unique_file != -1) && (file != (FILE *) NULL)) 3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 351787c09caeeb16217a92190b802477636aebd55bdcristy char 352787c09caeeb16217a92190b802477636aebd55bdcristy *property; 3531bd4a3a6b7cc5505da6698c4e61423a091d9d79fcristy 3541e178e70fb3c956f9fc1e30c3ba863e882666465cristy (void) GetNumberColors(image,file,exception); 355787c09caeeb16217a92190b802477636aebd55bdcristy (void) fclose(file); 3561e178e70fb3c956f9fc1e30c3ba863e882666465cristy property=FileToString(filename,~0UL,exception); 357787c09caeeb16217a92190b802477636aebd55bdcristy if (property != (char *) NULL) 358787c09caeeb16217a92190b802477636aebd55bdcristy { 359d15e65928aec551b7388c2863de3e3e628e2e0ddcristy (void) SetImageProperty(histogram_image,"comment",property, 360d15e65928aec551b7388c2863de3e3e628e2e0ddcristy exception); 361787c09caeeb16217a92190b802477636aebd55bdcristy property=DestroyString(property); 362787c09caeeb16217a92190b802477636aebd55bdcristy } 3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 364787c09caeeb16217a92190b802477636aebd55bdcristy (void) RelinquishUniqueFileResource(filename); 3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 366787c09caeeb16217a92190b802477636aebd55bdcristy /* 367787c09caeeb16217a92190b802477636aebd55bdcristy Write Histogram image. 368787c09caeeb16217a92190b802477636aebd55bdcristy */ 369787c09caeeb16217a92190b802477636aebd55bdcristy (void) CopyMagickString(histogram_image->filename,image_info->filename, 370151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy MagickPathExtent); 371787c09caeeb16217a92190b802477636aebd55bdcristy write_info=CloneImageInfo(image_info); 372e6fb02dc1886ecc7669872eb4144730b42b871b7Cristy *write_info->magick='\0'; 3731e178e70fb3c956f9fc1e30c3ba863e882666465cristy (void) SetImageInfo(write_info,1,exception); 37460f21f2ac2609b04da3830e79673846568078737Cristy if ((*write_info->magick == '\0') || 37560f21f2ac2609b04da3830e79673846568078737Cristy (LocaleCompare(write_info->magick,"HISTOGRAM") == 0)) 376e6fb02dc1886ecc7669872eb4144730b42b871b7Cristy (void) FormatLocaleString(histogram_image->filename,MagickPathExtent, 377e6fb02dc1886ecc7669872eb4144730b42b871b7Cristy "miff:%s",write_info->filename); 378bc3d31cb071e1a8b1ce2dead3e124f215b2938e1Cristy histogram_image->blob=DetachBlob(histogram_image->blob); 379bc3d31cb071e1a8b1ce2dead3e124f215b2938e1Cristy histogram_image->blob=CloneBlobInfo(image->blob); 3801e178e70fb3c956f9fc1e30c3ba863e882666465cristy status=WriteImage(write_info,histogram_image,exception); 381bc3d31cb071e1a8b1ce2dead3e124f215b2938e1Cristy image->blob=DetachBlob(image->blob); 382bc3d31cb071e1a8b1ce2dead3e124f215b2938e1Cristy image->blob=CloneBlobInfo(histogram_image->blob); 383787c09caeeb16217a92190b802477636aebd55bdcristy histogram_image=DestroyImage(histogram_image); 384787c09caeeb16217a92190b802477636aebd55bdcristy write_info=DestroyImageInfo(write_info); 385787c09caeeb16217a92190b802477636aebd55bdcristy return(status); 3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 387