2
% Copyright (C) 2003 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14
% H H IIIII SSSSS TTTTT OOO GGGG RRRR AAA M M %
15
% H H I SS T O O G R R A A MM MM %
16
% HHHHH I SSS T O O G GG RRRR AAAAA M M M %
17
% H H I SS T O O G G R R A A M M %
18
% H H IIIII SSSSS T OOO GGG R R A A M M %
21
% Write A Histogram Image. %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38
#include "magick/studio.h"
39
#include "magick/attribute.h"
40
#include "magick/blob.h"
41
#include "magick/cache.h"
42
#include "magick/color.h"
43
#include "magick/constitute.h"
44
#include "magick/magick.h"
45
#include "magick/monitor.h"
46
#include "magick/tempfile.h"
47
#include "magick/utility.h"
53
WriteHISTOGRAMImage(const ImageInfo *,Image *);
56
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60
% R e g i s t e r H I S T O G R A M I m a g e %
64
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66
% Method RegisterHISTOGRAMImage adds attributes for the Histogram image format
67
% to the list of supported formats. The attributes include the image format
68
% tag, a method to read and/or write the format, whether the format
69
% supports the saving of more than one frame to the same file or blob,
70
% whether the format supports native in-memory I/O, and a brief
71
% description of the format.
73
% The format of the RegisterHISTOGRAMImage method is:
75
% RegisterHISTOGRAMImage(void)
78
ModuleExport void RegisterHISTOGRAMImage(void)
83
entry=SetMagickInfo("HISTOGRAM");
84
entry->encoder=(EncoderHandler) WriteHISTOGRAMImage;
86
entry->description=AcquireString("Histogram of the image");
87
entry->module=AcquireString("HISTOGRAM");
88
(void) RegisterMagickInfo(entry);
92
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96
% U n r e g i s t e r H I S T O G R A M I m a g e %
100
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102
% Method UnregisterHISTOGRAMImage removes format registrations made by the
103
% HISTOGRAM module from the list of supported formats.
105
% The format of the UnregisterHISTOGRAMImage method is:
107
% UnregisterHISTOGRAMImage(void)
110
ModuleExport void UnregisterHISTOGRAMImage(void)
112
(void) UnregisterMagickInfo("HISTOGRAM");
116
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120
% W r i t e H I S T O G R A M I m a g e %
124
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126
% Method WriteHISTOGRAMImage writes an image to a file in Histogram format.
127
% The image shows a histogram of the color (or gray) values in the image. The
128
% image consists of three overlaid histograms: a red one for the red channel,
129
% a green one for the green channel, and a blue one for the blue channel. The
130
% image comment contains a list of unique pixel values and the number of times
131
% each occurs in the image.
133
% This method is strongly based on a similar one written by
134
% muquit@warm.semcor.com which in turn is based on ppmhistmap of netpbm.
136
% The format of the WriteHISTOGRAMImage method is:
138
% unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info,
141
% A description of each parameter follows.
143
% o status: Method WriteHISTOGRAMImage return True if the image is written.
144
% False is returned is there is a memory shortage or if the image file
147
% o image_info: Specifies a pointer to a ImageInfo structure.
149
% o image: A pointer to an Image structure.
153
static unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info,
156
#define HistogramDensity "256x200"
159
filename[MaxTextExtent];
182
register const PixelPacket
199
Allocate histogram image.
201
assert(image_info != (const ImageInfo *) NULL);
202
assert(image_info->signature == MagickSignature);
203
assert(image != (Image *) NULL);
204
assert(image->signature == MagickSignature);
205
SetImageDepth(image,image->depth);
206
SetGeometry(image,&geometry);
207
if (image_info->density == (char *) NULL)
208
(void) GetMagickGeometry(HistogramDensity,&geometry.x,&geometry.y,
209
&geometry.width,&geometry.height);
211
(void) GetMagickGeometry(image_info->density,&geometry.x,&geometry.y,
212
&geometry.width,&geometry.height);
213
histogram_image=CloneImage(image,geometry.width,geometry.height,True,
215
if (histogram_image == (Image *) NULL)
216
ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
217
SetImageType(histogram_image,TrueColorType);
219
Allocate histogram count arrays.
221
length=Max(ScaleQuantumToChar(MaxRGB)+1,histogram_image->columns);
222
red=MagickAllocateMemory(long *,length*sizeof(long));
223
green=MagickAllocateMemory(long *,length*sizeof(long));
224
blue=MagickAllocateMemory(long *,length*sizeof(long));
225
if ((red == (long *) NULL) || (green == (long *) NULL) ||
226
(blue == (long *) NULL))
228
DestroyImage(histogram_image);
229
ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image)
231
memset(red,0,length*sizeof(long));
232
memset(green,0,length*sizeof(long));
233
memset(blue,0,length*sizeof(long));
235
Initialize histogram count arrays.
237
for (y=0; y < (long) image->rows; y++)
239
p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
240
if (p == (const PixelPacket *) NULL)
242
for (x=0; x < (long) image->columns; x++)
244
red[ScaleQuantumToChar(p->red)]++;
245
green[ScaleQuantumToChar(p->green)]++;
246
blue[ScaleQuantumToChar(p->blue)]++;
251
for (x=0; x < (long) histogram_image->columns; x++)
253
if (maximum < red[x])
255
if (maximum < green[x])
257
if (maximum < blue[x])
260
scale=(double) histogram_image->rows/maximum;
262
Initialize histogram image.
264
(void) QueryColorDatabase("black",&histogram_image->background_color,
266
SetImage(histogram_image,OpaqueOpacity);
267
for (x=0; x < (long) histogram_image->columns; x++)
269
q=GetImagePixels(histogram_image,x,0,1,histogram_image->rows);
270
if (q == (PixelPacket *) NULL)
272
y=(long) (histogram_image->rows-(long) (scale*red[x]));
274
for ( ; y < (long) histogram_image->rows; y++)
279
y=(long) (histogram_image->rows-(long) (scale*green[x]));
281
for ( ; y < (long) histogram_image->rows; y++)
286
y=(long) (histogram_image->rows-(long) (scale*blue[x]));
288
for ( ; y < (long) histogram_image->rows; y++)
293
if (!SyncImagePixels(histogram_image))
295
if (QuantumTick(x,histogram_image->columns))
296
if (!MagickMonitor(SaveImageText,x,histogram_image->columns,&image->exception))
300
Free memory resources.
302
MagickFreeMemory(blue);
303
MagickFreeMemory(green);
304
MagickFreeMemory(red);
305
file=AcquireTemporaryFileStream(filename,BinaryFileIOMode);
306
if (file == (FILE *) NULL)
308
DestroyImage(histogram_image);
309
ThrowWriterTemporaryFileException(filename);
313
command[MaxTextExtent];
316
Add a histogram as an image comment.
318
(void) GetNumberColors(image,file,&image->exception);
320
FormatString(command,"@%.1024s",filename);
321
(void) SetImageAttribute(histogram_image,"comment",command);
322
LiberateTemporaryFile(filename);
325
Write Histogram image as MIFF.
327
(void) strncpy(filename,histogram_image->filename,MaxTextExtent-1);
328
(void) FormatString(histogram_image->filename,"miff:%.1024s",filename);
329
status=WriteImage(image_info,histogram_image);
330
DestroyImage(histogram_image);