~ubuntu-branches/ubuntu/intrepid/graphicsmagick/intrepid

« back to all changes in this revision

Viewing changes to coders/histogram.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2006-05-06 16:28:08 UTC
  • Revision ID: james.westby@ubuntu.com-20060506162808-vt2ni3r5nytcszms
Tags: upstream-1.1.7
ImportĀ upstreamĀ versionĀ 1.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
% Copyright (C) 2003 GraphicsMagick Group
 
3
% Copyright (C) 2002 ImageMagick Studio
 
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
 
5
%
 
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.
 
9
%
 
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
11
%                                                                             %
 
12
%                                                                             %
 
13
%                                                                             %
 
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         %
 
19
%                                                                             %
 
20
%                                                                             %
 
21
%                          Write A Histogram Image.                           %
 
22
%                                                                             %
 
23
%                                                                             %
 
24
%                              Software Design                                %
 
25
%                                John Cristy                                  %
 
26
%                                 July 1992                                   %
 
27
%                                                                             %
 
28
%                                                                             %
 
29
%                                                                             %
 
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
31
%
 
32
%
 
33
*/
 
34
 
 
35
/*
 
36
  Include declarations.
 
37
*/
 
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"
 
48
 
 
49
/*
 
50
  Forward declarations.
 
51
*/
 
52
static unsigned int
 
53
  WriteHISTOGRAMImage(const ImageInfo *,Image *);
 
54
 
 
55
/*
 
56
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
57
%                                                                             %
 
58
%                                                                             %
 
59
%                                                                             %
 
60
%   R e g i s t e r H I S T O G R A M I m a g e                               %
 
61
%                                                                             %
 
62
%                                                                             %
 
63
%                                                                             %
 
64
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
65
%
 
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.
 
72
%
 
73
%  The format of the RegisterHISTOGRAMImage method is:
 
74
%
 
75
%      RegisterHISTOGRAMImage(void)
 
76
%
 
77
*/
 
78
ModuleExport void RegisterHISTOGRAMImage(void)
 
79
{
 
80
  MagickInfo
 
81
    *entry;
 
82
 
 
83
  entry=SetMagickInfo("HISTOGRAM");
 
84
  entry->encoder=(EncoderHandler) WriteHISTOGRAMImage;
 
85
  entry->adjoin=False;
 
86
  entry->description=AcquireString("Histogram of the image");
 
87
  entry->module=AcquireString("HISTOGRAM");
 
88
  (void) RegisterMagickInfo(entry);
 
89
}
 
90
 
 
91
/*
 
92
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
93
%                                                                             %
 
94
%                                                                             %
 
95
%                                                                             %
 
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                           %
 
97
%                                                                             %
 
98
%                                                                             %
 
99
%                                                                             %
 
100
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
101
%
 
102
%  Method UnregisterHISTOGRAMImage removes format registrations made by the
 
103
%  HISTOGRAM module from the list of supported formats.
 
104
%
 
105
%  The format of the UnregisterHISTOGRAMImage method is:
 
106
%
 
107
%      UnregisterHISTOGRAMImage(void)
 
108
%
 
109
*/
 
110
ModuleExport void UnregisterHISTOGRAMImage(void)
 
111
{
 
112
  (void) UnregisterMagickInfo("HISTOGRAM");
 
113
}
 
114
 
 
115
/*
 
116
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
117
%                                                                             %
 
118
%                                                                             %
 
119
%                                                                             %
 
120
%   W r i t e H I S T O G R A M I m a g e                                     %
 
121
%                                                                             %
 
122
%                                                                             %
 
123
%                                                                             %
 
124
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
125
%
 
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.
 
132
%
 
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.
 
135
%
 
136
%  The format of the WriteHISTOGRAMImage method is:
 
137
%
 
138
%      unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info,
 
139
%        Image *image)
 
140
%
 
141
%  A description of each parameter follows.
 
142
%
 
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
 
145
%      fails to write.
 
146
%
 
147
%    o image_info: Specifies a pointer to a ImageInfo structure.
 
148
%
 
149
%    o image:  A pointer to an Image structure.
 
150
%
 
151
%
 
152
*/
 
153
static unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info,
 
154
  Image *image)
 
155
{
 
156
#define HistogramDensity  "256x200"
 
157
 
 
158
  char
 
159
    filename[MaxTextExtent];
 
160
 
 
161
  double
 
162
    scale;
 
163
 
 
164
  FILE
 
165
    *file;
 
166
 
 
167
  Image
 
168
    *histogram_image;
 
169
 
 
170
  long
 
171
    *blue,
 
172
    *green,
 
173
    maximum,
 
174
    *red;
 
175
 
 
176
  long
 
177
    y;
 
178
 
 
179
  RectangleInfo
 
180
    geometry;
 
181
 
 
182
  register const PixelPacket
 
183
    *p;
 
184
 
 
185
  register long
 
186
    x;
 
187
 
 
188
  register PixelPacket
 
189
    *q,
 
190
    *r;
 
191
 
 
192
  unsigned int
 
193
    status;
 
194
 
 
195
  unsigned long
 
196
    length;
 
197
 
 
198
  /*
 
199
    Allocate histogram image.
 
200
  */
 
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);
 
210
  else
 
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,
 
214
    &image->exception);
 
215
  if (histogram_image == (Image *) NULL)
 
216
    ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
 
217
  SetImageType(histogram_image,TrueColorType);
 
218
  /*
 
219
    Allocate histogram count arrays.
 
220
  */
 
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))
 
227
    {
 
228
      DestroyImage(histogram_image);
 
229
      ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image)
 
230
    }
 
231
  memset(red,0,length*sizeof(long));
 
232
  memset(green,0,length*sizeof(long));
 
233
  memset(blue,0,length*sizeof(long));
 
234
  /*
 
235
    Initialize histogram count arrays.
 
236
  */
 
237
  for (y=0; y < (long) image->rows; y++)
 
238
  {
 
239
    p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
 
240
    if (p == (const PixelPacket *) NULL)
 
241
      break;
 
242
    for (x=0; x < (long) image->columns; x++)
 
243
    {
 
244
      red[ScaleQuantumToChar(p->red)]++;
 
245
      green[ScaleQuantumToChar(p->green)]++;
 
246
      blue[ScaleQuantumToChar(p->blue)]++;
 
247
      p++;
 
248
    }
 
249
  }
 
250
  maximum=0;
 
251
  for (x=0; x < (long) histogram_image->columns; x++)
 
252
  {
 
253
    if (maximum < red[x])
 
254
      maximum=red[x];
 
255
    if (maximum < green[x])
 
256
      maximum=green[x];
 
257
    if (maximum < blue[x])
 
258
      maximum=blue[x];
 
259
  }
 
260
  scale=(double) histogram_image->rows/maximum;
 
261
  /*
 
262
    Initialize histogram image.
 
263
  */
 
264
  (void) QueryColorDatabase("black",&histogram_image->background_color,
 
265
    &image->exception);
 
266
  SetImage(histogram_image,OpaqueOpacity);
 
267
  for (x=0; x < (long) histogram_image->columns; x++)
 
268
  {
 
269
    q=GetImagePixels(histogram_image,x,0,1,histogram_image->rows);
 
270
    if (q == (PixelPacket *) NULL)
 
271
      break;
 
272
    y=(long) (histogram_image->rows-(long) (scale*red[x]));
 
273
    r=q+y;
 
274
    for ( ; y < (long) histogram_image->rows; y++)
 
275
    {
 
276
      r->red=MaxRGB;
 
277
      r++;
 
278
    }
 
279
    y=(long) (histogram_image->rows-(long) (scale*green[x]));
 
280
    r=q+y;
 
281
    for ( ; y < (long) histogram_image->rows; y++)
 
282
    {
 
283
      r->green=MaxRGB;
 
284
      r++;
 
285
    }
 
286
    y=(long) (histogram_image->rows-(long) (scale*blue[x]));
 
287
    r=q+y;
 
288
    for ( ; y < (long) histogram_image->rows; y++)
 
289
    {
 
290
      r->blue=MaxRGB;
 
291
      r++;
 
292
    }
 
293
    if (!SyncImagePixels(histogram_image))
 
294
      break;
 
295
    if (QuantumTick(x,histogram_image->columns))
 
296
      if (!MagickMonitor(SaveImageText,x,histogram_image->columns,&image->exception))
 
297
        break;
 
298
  }
 
299
  /*
 
300
    Free memory resources.
 
301
  */
 
302
  MagickFreeMemory(blue);
 
303
  MagickFreeMemory(green);
 
304
  MagickFreeMemory(red);
 
305
  file=AcquireTemporaryFileStream(filename,BinaryFileIOMode);
 
306
  if (file == (FILE *) NULL)
 
307
    {
 
308
      DestroyImage(histogram_image);
 
309
      ThrowWriterTemporaryFileException(filename);
 
310
    }
 
311
    {
 
312
      char
 
313
        command[MaxTextExtent];
 
314
 
 
315
      /*
 
316
        Add a histogram as an image comment.
 
317
      */
 
318
      (void) GetNumberColors(image,file,&image->exception);
 
319
      (void) fclose(file);
 
320
      FormatString(command,"@%.1024s",filename);
 
321
      (void) SetImageAttribute(histogram_image,"comment",command);
 
322
      LiberateTemporaryFile(filename);
 
323
    }
 
324
  /*
 
325
    Write Histogram image as MIFF.
 
326
  */
 
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);
 
331
  return(status);
 
332
}