Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/Halftoning.cpp view on Meta::CPAN
// NB : The predefined dither matrices are the same as matrices used in
// the Netpbm package (http://netpbm.sourceforge.net) and are defined in Ulichney's book.
// See also : The newsprint web site at http://www.cl.cam.ac.uk/~and1000/newsprint/
// for more technical info on this dithering technique
//
static FIBITMAP* OrderedClusteredDot(FIBITMAP *dib, int order) {
// Order-3 clustered dithering matrix.
int cluster3[] = {
9,11,10, 8, 6, 7,
12,17,16, 5, 0, 1,
13,14,15, 4, 3, 2,
8, 6, 7, 9,11,10,
5, 0, 1,12,17,16,
4, 3, 2,13,14,15
};
// Order-4 clustered dithering matrix.
int cluster4[] = {
18,20,19,16,13,11,12,15,
27,28,29,22, 4, 3, 2, 9,
26,31,30,21, 5, 0, 1,10,
23,25,24,17, 8, 6, 7,14,
13,11,12,15,18,20,19,16,
4, 3, 2, 9,27,28,29,22,
5, 0, 1,10,26,31,30,21,
8, 6, 7,14,23,25,24,17
};
// Order-8 clustered dithering matrix.
int cluster8[] = {
64, 69, 77, 87, 86, 76, 68, 67, 63, 58, 50, 40, 41, 51, 59, 60,
70, 94,100,109,108, 99, 93, 75, 57, 33, 27, 18, 19, 28, 34, 52,
78,101,114,116,115,112, 98, 83, 49, 26, 13, 11, 12, 15, 29, 44,
88,110,123,124,125,118,107, 85, 39, 17, 4, 3, 2, 9, 20, 42,
89,111,122,127,126,117,106, 84, 38, 16, 5, 0, 1, 10, 21, 43,
79,102,119,121,120,113, 97, 82, 48, 25, 8, 6, 7, 14, 30, 45,
71, 95,103,104,105, 96, 92, 74, 56, 32, 24, 23, 22, 31, 35, 53,
65, 72, 80, 90, 91, 81, 73, 66, 62, 55, 47, 37, 36, 46, 54, 61,
63, 58, 50, 40, 41, 51, 59, 60, 64, 69, 77, 87, 86, 76, 68, 67,
57, 33, 27, 18, 19, 28, 34, 52, 70, 94,100,109,108, 99, 93, 75,
49, 26, 13, 11, 12, 15, 29, 44, 78,101,114,116,115,112, 98, 83,
39, 17, 4, 3, 2, 9, 20, 42, 88,110,123,124,125,118,107, 85,
38, 16, 5, 0, 1, 10, 21, 43, 89,111,122,127,126,117,106, 84,
48, 25, 8, 6, 7, 14, 30, 45, 79,102,119,121,120,113, 97, 82,
56, 32, 24, 23, 22, 31, 35, 53, 71, 95,103,104,105, 96, 92, 74,
62, 55, 47, 37, 36, 46, 54, 61, 65, 72, 80, 90, 91, 81, 73, 66
};
int x, y, pixel;
int width, height;
BYTE *bits, *new_bits;
FIBITMAP *new_dib = NULL;
// allocate a 8-bit DIB
width = FreeImage_GetWidth(dib);
height = FreeImage_GetHeight(dib);
new_dib = FreeImage_Allocate(width, height, 8);
if(NULL == new_dib) return NULL;
// select the dithering matrix
int *matrix = NULL;
switch(order) {
case 3:
matrix = &cluster3[0];
break;
case 4:
matrix = &cluster4[0];
break;
case 8:
matrix = &cluster8[0];
break;
default:
return NULL;
}
// scale the dithering matrix
int l = 2 * order;
int scale = 256 / (l * order);
for(y = 0; y < l; y++) {
for(x = 0; x < l; x++) {
matrix[y*l + x] *= scale;
}
}
// perform the dithering
for(y = 0; y < height; y++) {
// scan left to right
bits = FreeImage_GetScanLine(dib, y);
new_bits = FreeImage_GetScanLine(new_dib, y);
for(x = 0; x < width; x++) {
pixel = bits[x];
if(pixel >= matrix[(y % l) + l * (x % l)]) {
new_bits[x] = WHITE;
} else {
new_bits[x] = BLACK;
}
}
}
return new_dib;
}
// ==========================================================
// Halftoning function
//
FIBITMAP * DLL_CALLCONV
FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm) {
FIBITMAP *input = NULL, *dib8 = NULL;
if(!FreeImage_HasPixels(dib)) return NULL;
const unsigned bpp = FreeImage_GetBPP(dib);
if(bpp == 1) {
// Just clone the dib and adjust the palette if needed
FIBITMAP *new_dib = FreeImage_Clone(dib);
if(NULL == new_dib) return NULL;
if(FreeImage_GetColorType(new_dib) == FIC_PALETTE) {
// Build a monochrome palette
( run in 1.347 second using v1.01-cache-2.11-cpan-d7f47b0818f )