1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
#include <iostream>
#include <cmath>
#include <gdk/gdkpixbuf.h>
#include "support/debug.h"
#include "histogram.h"
using namespace std;
struct Hist_Shades
{
int r;
int g;
int b;
};
// Fixme - no reason why we couldn't create these on the fly from a
// DeviceNColorants.
static Hist_Shades Hist_RGBShades[]=
{
{255,255,255}, // None
{255,64,64}, // Red
{64,255,64}, // Green
{96,144,0}, // Red + Green
{64,64,255}, // Blue
{96,0,144}, // Red + Blue
{0,96,144}, // Green + Blue
{64,64,96}, // Red + Green + Blue
{128,128,128}, // As above but with Alpha
{128,32,32}, // ...
{32,128,32},
{48,72,0},
{32,32,128},
{48,0,72},
{0,48,72},
{32,32,48},
};
static Hist_Shades Hist_CMYKShades[]=
{
{255,255,255}, // None
{64,255,255}, // Cyan
{255,64,255}, // Magenta
{96,96,255}, // Cyan + Magenta
{255,255,64}, // Yellow
{96,255,96}, // Cyan + Yellow
{255,96,96}, // Magenta + Yellow
{128,128,64}, // Cyan + Magenta + Yellow
{128,128,128}, // As above but with Black
{32,128,128}, // ...
{128,32,128},
{48,48,128},
{128,128,32},
{48,128,48},
{128,48,48},
{72,72,48}
};
// DrawHistogram() - renders a GdkPixbuf from a histogram.
GdkPixbuf *PPHistogram::DrawHistogram(int width,int height)
{
Hist_Shades *shades;
switch(GetType())
{
case IS_TYPE_RGB:
case IS_TYPE_RGBA:
Debug[TRACE] << "Drawing histogram for RGB Image" << endl;
shades=Hist_RGBShades;
break;
case IS_TYPE_CMYK:
Debug[TRACE] << "Drawing histogram for CMYK Image" << endl;
shades=Hist_CMYKShades;
break;
default:
throw "Unknown histogram type";
break;
}
int channels=GetChannelCount();
GdkPixbuf *pb=gdk_pixbuf_new(GDK_COLORSPACE_RGB,FALSE,8,width,height);
if(pb)
{
int rowstride=gdk_pixbuf_get_rowstride(pb);
unsigned char *pixels=gdk_pixbuf_get_pixels(pb);
double max=GetMax();
for(int x=0;x<width;++x)
{
int bucket=(x*IS_HISTOGRAM_BUCKETS)/width;
for(int y=0;y<height;++y)
{
int bit=1;
int ci=0;
for(int c=0;c<channels;++c)
{
double t=(*this)[c][bucket];
t/=max;
t=sqrt(t);
if((height-y)<(255.0*t))
ci|=bit;
bit<<=1;
}
int pi=3*x+y*rowstride;
pixels[pi]=shades[ci].r;
pixels[pi+1]=shades[ci].g;
pixels[pi+2]=shades[ci].b;
}
}
}
return(pb);
}
|