~ubuntu-branches/ubuntu/gutsy/amsn/gutsy

« back to all changes in this revision

Viewing changes to utils/TkCximage/src/CxImage/ximahist.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Theodore Karkoulis
  • Date: 2006-01-04 15:26:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060104152602-ipe1yg00rl3nlklv
Tags: 0.95-1
New Upstream Release (closes: #345052, #278575).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// xImaHist.cpp : histogram functions
 
2
/* 28/01/2004 v1.00 - www.xdp.it
 
3
 * CxImage version 5.99c 17/Oct/2004
 
4
 */
 
5
 
 
6
#include "ximage.h"
 
7
 
 
8
#if CXIMAGE_SUPPORT_DSP
 
9
 
 
10
////////////////////////////////////////////////////////////////////////////////
 
11
long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace)
 
12
{
 
13
        if (!pDib) return 0;
 
14
        RGBQUAD color;
 
15
 
 
16
        if (red) memset(red,0,256*sizeof(long));
 
17
        if (green) memset(green,0,256*sizeof(long));
 
18
        if (blue) memset(blue,0,256*sizeof(long));
 
19
        if (gray) memset(gray,0,256*sizeof(long));
 
20
 
 
21
        long xmin,xmax,ymin,ymax;
 
22
        if (pSelection){
 
23
                xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
 
24
                ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
 
25
        } else {
 
26
                xmin = ymin = 0;
 
27
                xmax = head.biWidth; ymax=head.biHeight;
 
28
        }
 
29
 
 
30
        for(long y=ymin; y<ymax; y++){
 
31
                for(long x=xmin; x<xmax; x++){
 
32
#if CXIMAGE_SUPPORT_SELECTION
 
33
                        if (SelectionIsInside(x,y))
 
34
#endif //CXIMAGE_SUPPORT_SELECTION
 
35
                        {
 
36
                                switch (colorspace){
 
37
                                case 1:
 
38
                                        color = HSLtoRGB(GetPixelColor(x,y));
 
39
                                        break;
 
40
                                case 2:
 
41
                                        color = YUVtoRGB(GetPixelColor(x,y));
 
42
                                        break;
 
43
                                case 3:
 
44
                                        color = YIQtoRGB(GetPixelColor(x,y));
 
45
                                        break;
 
46
                                case 4:
 
47
                                        color = XYZtoRGB(GetPixelColor(x,y));
 
48
                                        break;
 
49
                                default:
 
50
                                        color = GetPixelColor(x,y);
 
51
                                }
 
52
 
 
53
                                if (red) red[color.rgbRed]++;
 
54
                                if (green) green[color.rgbGreen]++;
 
55
                                if (blue) blue[color.rgbBlue]++;
 
56
                                if (gray) gray[(BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
 
57
                        }
 
58
                }
 
59
        }
 
60
 
 
61
        long n=0;
 
62
        for (int i=0; i<256; i++){
 
63
                if (red && red[i]>n) n=red[i];
 
64
                if (green && green[i]>n) n=green[i];
 
65
                if (blue && blue[i]>n) n=blue[i];
 
66
                if (gray && gray[i]>n) n=gray[i];
 
67
        }
 
68
 
 
69
        return n;
 
70
}
 
71
////////////////////////////////////////////////////////////////////////////////
 
72
/**
 
73
 * HistogramStretch
 
74
 * \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels.
 
75
 * \return true if everything is ok
 
76
 * \author [dave] and [nipper]
 
77
 */
 
78
bool CxImage::HistogramStretch(long method)
 
79
{
 
80
  if (!pDib) return false;
 
81
 
 
82
  if ((head.biBitCount==8) && IsGrayScale()){
 
83
        // get min/max info
 
84
        BYTE minc = 255, maxc = 0;
 
85
        BYTE gray;
 
86
        long y;
 
87
 
 
88
        double dbScaler = 50.0/head.biHeight;
 
89
 
 
90
        for (y=0; y<head.biHeight; y++)
 
91
        {
 
92
                info.nProgress = (long)(y*dbScaler);
 
93
                if (info.nEscape) break;
 
94
                for (long x=0; x<head.biWidth; x++)     {
 
95
                        gray = GetPixelIndex(x, y);
 
96
                        if (gray < minc)   minc = gray;
 
97
                        if (gray > maxc)   maxc = gray; 
 
98
                }
 
99
        }
 
100
 
 
101
        if (minc == 0 && maxc == 255) return true;
 
102
        
 
103
        // calculate LUT
 
104
        BYTE lut[256];
 
105
        BYTE range = maxc - minc;
 
106
        if (range != 0){
 
107
                for (long x = minc; x <= maxc; x++){
 
108
                        lut[x] = (BYTE)(255 * (x - minc) / range);
 
109
                }
 
110
        } else lut[minc] = minc;
 
111
 
 
112
        for (y=0; y<head.biHeight; y++) {
 
113
                if (info.nEscape) break;
 
114
                info.nProgress = (long)(50.0+y*dbScaler);
 
115
                for (long x=0; x<head.biWidth; x++)
 
116
                {
 
117
                        SetPixelIndex(x, y, lut[GetPixelIndex(x, y)]);
 
118
                }
 
119
        }
 
120
  } else {
 
121
        switch(method){
 
122
        case 1:
 
123
          { // <nipper>
 
124
                // get min/max info
 
125
                BYTE minc = 255, maxc = 0;
 
126
                RGBQUAD color;
 
127
                long y;
 
128
 
 
129
                for (y=0; y<head.biHeight; y++)
 
130
                {
 
131
                        if (info.nEscape) break;
 
132
 
 
133
                        for (long x=0; x<head.biWidth; x++)
 
134
                        {
 
135
                                color = GetPixelColor(x, y);
 
136
 
 
137
                                if (color.rgbRed < minc)   minc = color.rgbRed;
 
138
                                if (color.rgbBlue < minc)  minc = color.rgbBlue;
 
139
                                if (color.rgbGreen < minc) minc = color.rgbGreen;
 
140
 
 
141
                                if (color.rgbRed > maxc)   maxc = color.rgbRed; 
 
142
                                if (color.rgbBlue > maxc)  maxc = color.rgbBlue; 
 
143
                                if (color.rgbGreen > maxc) maxc = color.rgbGreen; 
 
144
                        }
 
145
                }
 
146
 
 
147
                if (minc == 0 && maxc == 255)
 
148
                        return true;
 
149
                
 
150
                // calculate LUT
 
151
                BYTE lut[256];
 
152
                BYTE range = maxc - minc;
 
153
 
 
154
                if (range != 0){
 
155
                        for (long x = minc; x <= maxc; x++){
 
156
                                lut[x] = (BYTE)(255 * (x - minc) / range);
 
157
                        }
 
158
                } else lut[minc] = minc;
 
159
 
 
160
                // normalize image
 
161
                double dbScaler = 100.0/head.biHeight;
 
162
 
 
163
                for (y=0; y<head.biHeight; y++) {
 
164
                        if (info.nEscape) break;
 
165
                        info.nProgress = (long)(y*dbScaler);
 
166
 
 
167
                        for (long x=0; x<head.biWidth; x++)
 
168
                        {
 
169
                                color = GetPixelColor(x, y);
 
170
 
 
171
                                color.rgbRed = lut[color.rgbRed];
 
172
                                color.rgbBlue = lut[color.rgbBlue];
 
173
                                color.rgbGreen = lut[color.rgbGreen];
 
174
 
 
175
                                SetPixelColor(x, y, color);
 
176
                        }
 
177
                }
 
178
          }
 
179
                break;
 
180
        case 2:
 
181
          { // <nipper>
 
182
                // get min/max info
 
183
                BYTE minR = 255, maxR = 0;
 
184
                BYTE minG = 255, maxG = 0;
 
185
                BYTE minB = 255, maxB = 0;
 
186
                RGBQUAD color;
 
187
                long y;
 
188
 
 
189
                for (y=0; y<head.biHeight; y++)
 
190
                {
 
191
                        if (info.nEscape) break;
 
192
 
 
193
                        for (long x=0; x<head.biWidth; x++)
 
194
                        {
 
195
                                color = GetPixelColor(x, y);
 
196
 
 
197
                                if (color.rgbRed < minR)   minR = color.rgbRed;
 
198
                                if (color.rgbBlue < minB)  minB = color.rgbBlue;
 
199
                                if (color.rgbGreen < minG) minG = color.rgbGreen;
 
200
 
 
201
                                if (color.rgbRed > maxR)   maxR = color.rgbRed; 
 
202
                                if (color.rgbBlue > maxB)  maxB = color.rgbBlue; 
 
203
                                if (color.rgbGreen > maxG) maxG = color.rgbGreen; 
 
204
                        }
 
205
                }
 
206
 
 
207
                if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
 
208
                        return true;
 
209
 
 
210
                // calculate LUT
 
211
                BYTE lutR[256];
 
212
                BYTE range = maxR - minR;
 
213
                if (range != 0) {
 
214
                        for (long x = minR; x <= maxR; x++){
 
215
                                lutR[x] = (BYTE)(255 * (x - minR) / range);
 
216
                        }
 
217
                } else lutR[minR] = minR;
 
218
 
 
219
                BYTE lutG[256];
 
220
                range = maxG - minG;
 
221
                if (range != 0) {
 
222
                        for (long x = minG; x <= maxG; x++){
 
223
                                lutG[x] = (BYTE)(255 * (x - minG) / range);
 
224
                        }
 
225
                } else lutG[minG] = minG;
 
226
                        
 
227
                BYTE lutB[256];
 
228
                range = maxB - minB;
 
229
                if (range != 0) {
 
230
                        for (long x = minB; x <= maxB; x++){
 
231
                                lutB[x] = (BYTE)(255 * (x - minB) / range);
 
232
                        }
 
233
                } else lutB[minB] = minB;
 
234
 
 
235
                // normalize image
 
236
                double dbScaler = 100.0/head.biHeight;
 
237
 
 
238
                for (y=0; y<head.biHeight; y++)
 
239
                {
 
240
                        info.nProgress = (long)(y*dbScaler);
 
241
                        if (info.nEscape) break;
 
242
 
 
243
                        for (long x=0; x<head.biWidth; x++)
 
244
                        {
 
245
                                color = GetPixelColor(x, y);
 
246
 
 
247
                                color.rgbRed = lutR[color.rgbRed];
 
248
                                color.rgbBlue = lutB[color.rgbBlue];
 
249
                                color.rgbGreen = lutG[color.rgbGreen];
 
250
 
 
251
                                SetPixelColor(x, y, color);
 
252
                        }
 
253
                }
 
254
          }
 
255
                break;
 
256
        default:
 
257
          { // <dave>
 
258
                // S = ( R - C ) ( B - A / D - C )
 
259
                double alimit = 0.0;
 
260
                double blimit = 255.0;
 
261
                double lowerc = 255.0;
 
262
                double upperd = 0.0;
 
263
                double tmpGray;
 
264
 
 
265
                RGBQUAD color;
 
266
                RGBQUAD yuvClr;
 
267
                double  stretcheds;
 
268
 
 
269
                if ( head.biClrUsed == 0 ){
 
270
                        long x, y, xmin, xmax, ymin, ymax;
 
271
                        xmin = ymin = 0;
 
272
                        xmax = head.biWidth; 
 
273
                        ymax = head.biHeight;
 
274
 
 
275
                        for( y = ymin; y < ymax; y++ ){
 
276
                                info.nProgress = (long)(50*y/ymax);
 
277
                                if (info.nEscape) break;
 
278
                                for( x = xmin; x < xmax; x++ ){
 
279
                                        color = GetPixelColor( x, y );
 
280
                                        tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
281
                                        if ( tmpGray < lowerc ) lowerc = tmpGray;
 
282
                                        if ( tmpGray > upperd ) upperd = tmpGray;
 
283
                                }
 
284
                        }
 
285
                        if (upperd==lowerc) return false;
 
286
                        
 
287
                        for( y = ymin; y < ymax; y++ ){
 
288
                                info.nProgress = (long)(50+50*y/ymax);
 
289
                                if (info.nEscape) break;
 
290
                                for( x = xmin; x < xmax; x++ ){
 
291
 
 
292
                                        color = GetPixelColor( x, y );
 
293
                                        yuvClr = RGBtoYUV(color);
 
294
 
 
295
                                        // Stretch Luminance
 
296
                                        tmpGray = (double)yuvClr.rgbRed;
 
297
                                        stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
 
298
                                        if ( stretcheds < 0.0 ) stretcheds = 0.0;
 
299
                                        else if ( stretcheds > 255.0 ) stretcheds = 255.0;
 
300
                                        yuvClr.rgbRed = (BYTE)stretcheds;
 
301
 
 
302
                                        color = YUVtoRGB(yuvClr);
 
303
                                        SetPixelColor( x, y, color );
 
304
                                }
 
305
                        }
 
306
                } else {
 
307
                        DWORD  j;
 
308
                        for( j = 0; j < head.biClrUsed; j++ ){
 
309
                                color = GetPaletteColor( (BYTE)j );
 
310
                                tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
311
                                if ( tmpGray < lowerc ) lowerc = tmpGray;
 
312
                                if ( tmpGray > upperd ) upperd = tmpGray;
 
313
                        }
 
314
                        if (upperd==lowerc) return false;
 
315
 
 
316
                        for( j = 0; j < head.biClrUsed; j++ ){
 
317
 
 
318
                                color = GetPaletteColor( (BYTE)j );
 
319
                                yuvClr = RGBtoYUV( color );
 
320
 
 
321
                                // Stretch Luminance
 
322
                                tmpGray = (double)yuvClr.rgbRed;
 
323
                                stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
 
324
                                if ( stretcheds < 0.0 ) stretcheds = 0.0;
 
325
                                else if ( stretcheds > 255.0 ) stretcheds = 255.0;
 
326
                                yuvClr.rgbRed = (BYTE)stretcheds;
 
327
 
 
328
                                color = YUVtoRGB(yuvClr);
 
329
                                SetPaletteColor( (BYTE)j, color );
 
330
                        }
 
331
                }
 
332
          }
 
333
        }
 
334
  }
 
335
  return true;
 
336
}
 
337
////////////////////////////////////////////////////////////////////////////////
 
338
// HistogramEqualize function by <dave> : dave(at)posortho(dot)com
 
339
bool CxImage::HistogramEqualize()
 
340
{
 
341
        if (!pDib) return false;
 
342
 
 
343
    int histogram[256];
 
344
        int map[256];
 
345
        int equalize_map[256];
 
346
    int x, y, i, j;
 
347
        RGBQUAD color;
 
348
        RGBQUAD yuvClr;
 
349
        unsigned int YVal, high, low;
 
350
 
 
351
        memset( &histogram, 0, sizeof(int) * 256 );
 
352
        memset( &map, 0, sizeof(int) * 256 );
 
353
        memset( &equalize_map, 0, sizeof(int) * 256 );
 
354
 
 
355
     // form histogram
 
356
        for(y=0; y < head.biHeight; y++){
 
357
                info.nProgress = (long)(50*y/head.biHeight);
 
358
                if (info.nEscape) break;
 
359
                for(x=0; x < head.biWidth; x++){
 
360
                        color = GetPixelColor( x, y );
 
361
                        YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
362
                        histogram[YVal]++;
 
363
                }
 
364
        }
 
365
 
 
366
        // integrate the histogram to get the equalization map.
 
367
        j = 0;
 
368
        for(i=0; i <= 255; i++){
 
369
                j += histogram[i];
 
370
                map[i] = j; 
 
371
        }
 
372
 
 
373
        // equalize
 
374
        low = map[0];
 
375
        high = map[255];
 
376
        if (low == high) return false;
 
377
        for( i = 0; i <= 255; i++ ){
 
378
                equalize_map[i] = (unsigned int)((((double)( map[i] - low ) ) * 255) / ( high - low ) );
 
379
        }
 
380
 
 
381
        // stretch the histogram
 
382
        if(head.biClrUsed == 0){ // No Palette
 
383
                for( y = 0; y < head.biHeight; y++ ){
 
384
                        info.nProgress = (long)(50+50*y/head.biHeight);
 
385
                        if (info.nEscape) break;
 
386
                        for( x = 0; x < head.biWidth; x++ ){
 
387
 
 
388
                                color = GetPixelColor( x, y );
 
389
                                yuvClr = RGBtoYUV(color);
 
390
 
 
391
                yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];
 
392
 
 
393
                                color = YUVtoRGB(yuvClr);
 
394
                                SetPixelColor( x, y, color );
 
395
                        }
 
396
                }
 
397
        } else { // Palette
 
398
                for( i = 0; i < (int)head.biClrUsed; i++ ){
 
399
 
 
400
                        color = GetPaletteColor((BYTE)i);
 
401
                        yuvClr = RGBtoYUV(color);
 
402
 
 
403
            yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];
 
404
 
 
405
                        color = YUVtoRGB(yuvClr);
 
406
                        SetPaletteColor( (BYTE)i, color );
 
407
                }
 
408
        }
 
409
        return true;
 
410
}
 
411
////////////////////////////////////////////////////////////////////////////////
 
412
// HistogramNormalize function by <dave> : dave(at)posortho(dot)com
 
413
bool CxImage::HistogramNormalize()
 
414
{
 
415
        if (!pDib) return false;
 
416
 
 
417
        int histogram[256];
 
418
        int threshold_intensity, intense;
 
419
        int x, y, i;
 
420
        unsigned int normalize_map[256];
 
421
        unsigned int high, low, YVal;
 
422
 
 
423
        RGBQUAD color;
 
424
        RGBQUAD yuvClr;
 
425
 
 
426
        memset( &histogram, 0, sizeof( int ) * 256 );
 
427
        memset( &normalize_map, 0, sizeof( unsigned int ) * 256 );
 
428
 
 
429
     // form histogram
 
430
        for(y=0; y < head.biHeight; y++){
 
431
                info.nProgress = (long)(50*y/head.biHeight);
 
432
                if (info.nEscape) break;
 
433
                for(x=0; x < head.biWidth; x++){
 
434
                        color = GetPixelColor( x, y );
 
435
                        YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
436
                        histogram[YVal]++;
 
437
                }
 
438
        }
 
439
 
 
440
        // find histogram boundaries by locating the 1 percent levels
 
441
        threshold_intensity = ( head.biWidth * head.biHeight) / 100;
 
442
 
 
443
        intense = 0;
 
444
        for( low = 0; low < 255; low++ ){
 
445
                intense += histogram[low];
 
446
                if( intense > threshold_intensity )     break;
 
447
        }
 
448
 
 
449
        intense = 0;
 
450
        for( high = 255; high != 0; high--){
 
451
                intense += histogram[ high ];
 
452
                if( intense > threshold_intensity ) break;
 
453
        }
 
454
 
 
455
        if ( low == high ){
 
456
                // Unreasonable contrast;  use zero threshold to determine boundaries.
 
457
                threshold_intensity = 0;
 
458
                intense = 0;
 
459
                for( low = 0; low < 255; low++){
 
460
                        intense += histogram[low];
 
461
                        if( intense > threshold_intensity )     break;
 
462
                }
 
463
                intense = 0;
 
464
                for( high = 255; high != 0; high-- ){
 
465
                        intense += histogram [high ];
 
466
                        if( intense > threshold_intensity )     break;
 
467
                }
 
468
        }
 
469
        if( low == high ) return false;  // zero span bound
 
470
 
 
471
        // Stretch the histogram to create the normalized image mapping.
 
472
        for(i = 0; i <= 255; i++){
 
473
                if ( i < (int) low ){
 
474
                        normalize_map[i] = 0;
 
475
                } else {
 
476
                        if(i > (int) high)
 
477
                                normalize_map[i] = 255;
 
478
                        else
 
479
                                normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low );
 
480
                }
 
481
        }
 
482
 
 
483
        // Normalize
 
484
        if( head.biClrUsed == 0 ){
 
485
                for( y = 0; y < head.biHeight; y++ ){
 
486
                        info.nProgress = (long)(50+50*y/head.biHeight);
 
487
                        if (info.nEscape) break;
 
488
                        for( x = 0; x < head.biWidth; x++ ){
 
489
 
 
490
                                color = GetPixelColor( x, y );
 
491
                                yuvClr = RGBtoYUV( color );
 
492
 
 
493
                yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];
 
494
 
 
495
                                color = YUVtoRGB( yuvClr );
 
496
                                SetPixelColor( x, y, color );
 
497
                        }
 
498
                }
 
499
        } else {
 
500
                for(i = 0; i < (int)head.biClrUsed; i++){
 
501
 
 
502
                        color = GetPaletteColor( (BYTE)i );
 
503
                        yuvClr = RGBtoYUV( color );
 
504
 
 
505
            yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];
 
506
 
 
507
                        color = YUVtoRGB( yuvClr );
 
508
                        SetPaletteColor( (BYTE)i, color );
 
509
                }
 
510
        }
 
511
        return true;
 
512
}
 
513
////////////////////////////////////////////////////////////////////////////////
 
514
// HistogramLog function by <dave> : dave(at)posortho(dot)com
 
515
bool CxImage::HistogramLog()
 
516
{
 
517
        if (!pDib) return false;
 
518
 
 
519
        //q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|);
 
520
    int x, y, i;
 
521
        RGBQUAD color;
 
522
        RGBQUAD yuvClr;
 
523
 
 
524
        unsigned int YVal, high = 1;
 
525
 
 
526
    // Find Highest Luminance Value in the Image
 
527
        if( head.biClrUsed == 0 ){ // No Palette
 
528
                for(y=0; y < head.biHeight; y++){
 
529
                        info.nProgress = (long)(50*y/head.biHeight);
 
530
                        if (info.nEscape) break;
 
531
                        for(x=0; x < head.biWidth; x++){
 
532
                                color = GetPixelColor( x, y );
 
533
                                YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
534
                                if (YVal > high ) high = YVal;
 
535
                        }
 
536
                }
 
537
        } else { // Palette
 
538
                for(i = 0; i < (int)head.biClrUsed; i++){
 
539
                        color = GetPaletteColor((BYTE)i);
 
540
                        YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
541
                        if (YVal > high ) high = YVal;
 
542
                }
 
543
        }
 
544
 
 
545
        // Logarithm Operator
 
546
        double k = 255.0 / ::log( 1.0 + (double)high );
 
547
        if( head.biClrUsed == 0 ){
 
548
                for( y = 0; y < head.biHeight; y++ ){
 
549
                        info.nProgress = (long)(50+50*y/head.biHeight);
 
550
                        if (info.nEscape) break;
 
551
                        for( x = 0; x < head.biWidth; x++ ){
 
552
 
 
553
                                color = GetPixelColor( x, y );
 
554
                                yuvClr = RGBtoYUV( color );
 
555
                
 
556
                                yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
 
557
 
 
558
                                color = YUVtoRGB( yuvClr );
 
559
                                SetPixelColor( x, y, color );
 
560
                        }
 
561
                }
 
562
        } else {
 
563
                for(i = 0; i < (int)head.biClrUsed; i++){
 
564
 
 
565
                        color = GetPaletteColor( (BYTE)i );
 
566
                        yuvClr = RGBtoYUV( color );
 
567
 
 
568
            yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
 
569
                        
 
570
                        color = YUVtoRGB( yuvClr );
 
571
                        SetPaletteColor( (BYTE)i, color );
 
572
                }
 
573
        }
 
574
 
 
575
        return true;
 
576
}
 
577
 
 
578
////////////////////////////////////////////////////////////////////////////////
 
579
// HistogramRoot function by <dave> : dave(at)posortho(dot)com
 
580
bool CxImage::HistogramRoot()
 
581
{
 
582
        if (!pDib) return false;
 
583
        //q(i,j) = sqrt(|p(i,j)|);
 
584
 
 
585
    int x, y, i;
 
586
        RGBQUAD color;
 
587
        RGBQUAD  yuvClr;
 
588
        double  dtmp;
 
589
        unsigned int YVal, high = 1;
 
590
 
 
591
     // Find Highest Luminance Value in the Image
 
592
        if( head.biClrUsed == 0 ){ // No Palette
 
593
                for(y=0; y < head.biHeight; y++){
 
594
                        info.nProgress = (long)(50*y/head.biHeight);
 
595
                        if (info.nEscape) break;
 
596
                        for(x=0; x < head.biWidth; x++){
 
597
                                color = GetPixelColor( x, y );
 
598
                                YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
599
                                if (YVal > high ) high = YVal;
 
600
                        }
 
601
                }
 
602
        } else { // Palette
 
603
                for(i = 0; i < (int)head.biClrUsed; i++){
 
604
                        color = GetPaletteColor((BYTE)i);
 
605
                        YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
 
606
                        if (YVal > high ) high = YVal;
 
607
                }
 
608
        }
 
609
 
 
610
        // Root Operator
 
611
        double k = 128.0 / ::log( 1.0 + (double)high );
 
612
        if( head.biClrUsed == 0 ){
 
613
                for( y = 0; y < head.biHeight; y++ ){
 
614
                        info.nProgress = (long)(50+50*y/head.biHeight);
 
615
                        if (info.nEscape) break;
 
616
                        for( x = 0; x < head.biWidth; x++ ){
 
617
 
 
618
                                color = GetPixelColor( x, y );
 
619
                                yuvClr = RGBtoYUV( color );
 
620
 
 
621
                                dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
 
622
                                if ( dtmp > 255.0 )     dtmp = 255.0;
 
623
                                if ( dtmp < 0 ) dtmp = 0;
 
624
                yuvClr.rgbRed = (BYTE)dtmp;
 
625
 
 
626
                                color = YUVtoRGB( yuvClr );
 
627
                                SetPixelColor( x, y, color );
 
628
                        }
 
629
                }
 
630
        } else {
 
631
                for(i = 0; i < (int)head.biClrUsed; i++){
 
632
 
 
633
                        color = GetPaletteColor( (BYTE)i );
 
634
                        yuvClr = RGBtoYUV( color );
 
635
 
 
636
                        dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
 
637
                        if ( dtmp > 255.0 )     dtmp = 255.0;
 
638
                        if ( dtmp < 0 ) dtmp = 0;
 
639
            yuvClr.rgbRed = (BYTE)dtmp;
 
640
 
 
641
                        color = YUVtoRGB( yuvClr );
 
642
                        SetPaletteColor( (BYTE)i, color );
 
643
                }
 
644
        }
 
645
 
 
646
        return true;
 
647
}
 
648
////////////////////////////////////////////////////////////////////////////////
 
649
#endif