40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński/*
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * Some filters for Potrace in Inkscape
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński *
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * Authors:
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * Bob Jamison <rjamison@titan.com>
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * Stéphane Gimenez <dev@gim.name>
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński *
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * Copyright (C) 2004-2006 Authors
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński *
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * Released under GNU GPL, read the file 'COPYING' for more information
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński#include <cstdio>
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński#include <stdlib.h>
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński#include "imagemap-gdk.h"
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński#include "filterset.h"
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński#include "quantize.h"
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński/*#########################################################################
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński### G A U S S I A N (smoothing)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński#########################################################################*/
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński/**
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński *
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosińskistatic int gaussMatrix[] =
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński{
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński 2, 4, 5, 4, 2,
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński 4, 9, 12, 9, 4,
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński 5, 12, 15, 12, 5,
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński 4, 9, 12, 9, 4,
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński 2, 4, 5, 4, 2
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński};
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński/**
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński *
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof KosińskiGrayMap *grayMapGaussian(GrayMap *me)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński{
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int width = me->width;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int height = me->height;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int firstX = 2;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int lastX = width-3;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int firstY = 2;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int lastY = height-3;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński GrayMap *newGm = GrayMapCreate(width, height);
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński if (!newGm)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński return NULL;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński for (int y = 0 ; y<height ; y++)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński for (int x = 0 ; x<width ; x++)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński /* image boundaries */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński if (x<firstX || x>lastX || y<firstY || y>lastY)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński newGm->setPixel(newGm, x, y, me->getPixel(me, x, y));
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński continue;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński }
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński /* all other pixels */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int gaussIndex = 0;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński unsigned long sum = 0;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński for (int i= y-2 ; i<=y+2 ; i++)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński for (int j= x-2; j<=x+2 ; j++)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int weight = gaussMatrix[gaussIndex++];
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński sum += me->getPixel(me, j, i) * weight;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński }
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński }
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński sum /= 159;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński newGm->setPixel(newGm, x, y, sum);
d6519bf53baba32bd74436ad9c85f1fa2c6b6ae9Krzysztof Kosiński }
d6519bf53baba32bd74436ad9c85f1fa2c6b6ae9Krzysztof Kosiński }
d6519bf53baba32bd74436ad9c85f1fa2c6b6ae9Krzysztof Kosiński
d6519bf53baba32bd74436ad9c85f1fa2c6b6ae9Krzysztof Kosiński return newGm;
d6519bf53baba32bd74436ad9c85f1fa2c6b6ae9Krzysztof Kosiński}
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
a16a494f042310ee849a6f717ffea70846f1f22cKrzysztof Kosiński
a16a494f042310ee849a6f717ffea70846f1f22cKrzysztof Kosiński/**
a16a494f042310ee849a6f717ffea70846f1f22cKrzysztof Kosiński *
a16a494f042310ee849a6f717ffea70846f1f22cKrzysztof Kosiński */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof KosińskiRgbMap *rgbMapGaussian(RgbMap *me)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński{
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int width = me->width;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int height = me->height;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int firstX = 2;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int lastX = width-3;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int firstY = 2;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int lastY = height-3;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński RgbMap *newGm = RgbMapCreate(width, height);
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński if (!newGm)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński return NULL;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński for (int y = 0 ; y<height ; y++)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński for (int x = 0 ; x<width ; x++)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński /* image boundaries */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński if (x<firstX || x>lastX || y<firstY || y>lastY)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński {
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński newGm->setPixelRGB(newGm, x, y, me->getPixel(me, x, y));
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński continue;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński }
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński /* all other pixels */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int gaussIndex = 0;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int sumR = 0;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int sumG = 0;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński int sumB = 0;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński for (int i= y-2 ; i<=y+2 ; i++)
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński {
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński for (int j= x-2; j<=x+2 ; j++)
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński {
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński int weight = gaussMatrix[gaussIndex++];
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński RGB rgb = me->getPixel(me, j, i);
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński sumR += weight * (int)rgb.r;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński sumG += weight * (int)rgb.g;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński sumB += weight * (int)rgb.b;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński }
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński }
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński RGB rout;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński rout.r = ( sumR / 159 ) & 0xff;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński rout.g = ( sumG / 159 ) & 0xff;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński rout.b = ( sumB / 159 ) & 0xff;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński newGm->setPixelRGB(newGm, x, y, rout);
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński }
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński }
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński return newGm;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński}
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński/*#########################################################################
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński### C A N N Y E D G E D E T E C T I O N
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński#########################################################################*/
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosińskistatic int sobelX[] =
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński{
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński -1, 0, 1 ,
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński -2, 0, 2 ,
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński -1, 0, 1
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński};
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosińskistatic int sobelY[] =
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński{
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński 1, 2, 1 ,
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński 0, 0, 0 ,
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński -1, -2, -1
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński};
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński/**
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * Perform Sobel convolution on a GrayMap
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński */
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosińskistatic GrayMap *grayMapSobel(GrayMap *gm,
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński double dLowThreshold, double dHighThreshold)
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński{
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int width = gm->width;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int height = gm->height;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int firstX = 1;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int lastX = width-2;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int firstY = 1;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński int lastY = height-2;
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński GrayMap *newGm = GrayMapCreate(width, height);
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński if (!newGm)
return NULL;
for (int y = 0 ; y<height ; y++)
{
for (int x = 0 ; x<width ; x++)
{
unsigned long sum = 0;
/* image boundaries */
if (x<firstX || x>lastX || y<firstY || y>lastY)
{
sum = 0;
}
else
{
/* ### SOBEL FILTERING #### */
long sumX = 0;
long sumY = 0;
int sobelIndex = 0;
for (int i= y-1 ; i<=y+1 ; i++)
{
for (int j= x-1; j<=x+1 ; j++)
{
sumX += gm->getPixel(gm, j, i) *
sobelX[sobelIndex++];
}
}
sobelIndex = 0;
for (int i= y-1 ; i<=y+1 ; i++)
{
for (int j= x-1; j<=x+1 ; j++)
{
sumY += gm->getPixel(gm, j, i) *
sobelY[sobelIndex++];
}
}
/*### GET VALUE ### */
sum = abs(sumX) + abs(sumY);
if (sum > 765)
sum = 765;
#if 0
/*### GET ORIENTATION (slow, pedantic way) ### */
double orient = 0.0;
if (sumX==0)
{
if (sumY==0)
orient = 0.0;
else if (sumY<0)
{
sumY = -sumY;
orient = 90.0;
}
else
orient = 90.0;
}
else
{
orient = 57.295779515 * atan2( ((double)sumY),((double)sumX) );
if (orient < 0.0)
orient += 180.0;
}
/*### GET EDGE DIRECTION ### */
int edgeDirection = 0;
if (orient < 22.5)
edgeDirection = 0;
else if (orient < 67.5)
edgeDirection = 45;
else if (orient < 112.5)
edgeDirection = 90;
else if (orient < 157.5)
edgeDirection = 135;
#else
/*### GET EDGE DIRECTION (fast way) ### */
int edgeDirection = 0; /*x,y=0*/
if (sumX==0)
{
if (sumY!=0)
edgeDirection = 90;
}
else
{
/*long slope = sumY*1024/sumX;*/
long slope = (sumY << 10)/sumX;
if (slope > 2472 || slope< -2472) /*tan(67.5)*1024*/
edgeDirection = 90;
else if (slope > 414) /*tan(22.5)*1024*/
edgeDirection = 45;
else if (slope < -414) /*-tan(22.5)*1024*/
edgeDirection = 135;
}
#endif
/* printf("%ld %ld %f %d\n", sumX, sumY, orient, edgeDirection); */
/*### Get two adjacent pixels in edge direction ### */
unsigned long leftPixel;
unsigned long rightPixel;
if (edgeDirection == 0)
{
leftPixel = gm->getPixel(gm, x-1, y);
rightPixel = gm->getPixel(gm, x+1, y);
}
else if (edgeDirection == 45)
{
leftPixel = gm->getPixel(gm, x-1, y+1);
rightPixel = gm->getPixel(gm, x+1, y-1);
}
else if (edgeDirection == 90)
{
leftPixel = gm->getPixel(gm, x, y-1);
rightPixel = gm->getPixel(gm, x, y+1);
}
else /*135 */
{
leftPixel = gm->getPixel(gm, x-1, y-1);
rightPixel = gm->getPixel(gm, x+1, y+1);
}
/*### Compare current value to adjacent pixels ### */
/*### if less that either, suppress it ### */
if (sum < leftPixel || sum < rightPixel)
sum = 0;
else
{
unsigned long highThreshold =
(unsigned long)(dHighThreshold * 765.0);
unsigned long lowThreshold =
(unsigned long)(dLowThreshold * 765.0);
if (sum >= highThreshold)
sum = 765; /* EDGE. 3*255 this needs to be settable */
else if (sum < lowThreshold)
sum = 0; /* NONEDGE */
else
{
if ( gm->getPixel(gm, x-1, y-1)> highThreshold ||
gm->getPixel(gm, x , y-1)> highThreshold ||
gm->getPixel(gm, x+1, y-1)> highThreshold ||
gm->getPixel(gm, x-1, y )> highThreshold ||
gm->getPixel(gm, x+1, y )> highThreshold ||
gm->getPixel(gm, x-1, y+1)> highThreshold ||
gm->getPixel(gm, x , y+1)> highThreshold ||
gm->getPixel(gm, x+1, y+1)> highThreshold)
sum = 765; /* EDGE fix me too */
else
sum = 0; /* NONEDGE */
}
}
}/* else */
if (sum==0) /* invert light & dark */
sum = 765;
else
sum = 0;
newGm->setPixel(newGm, x, y, sum);
}/* for (x) */
}/* for (y) */
return newGm;
}
/**
*
*/
GrayMap *
grayMapCanny(GrayMap *gm, double lowThreshold, double highThreshold)
{
if (!gm)
return NULL;
GrayMap *cannyGm = grayMapSobel(gm, lowThreshold, highThreshold);
if (!cannyGm)
return NULL;
/*cannyGm->writePPM(cannyGm, "canny.ppm");*/
return cannyGm;
}
/*#########################################################################
### Q U A N T I Z A T I O N
#########################################################################*/
/**
* Experimental. Work on this later
*/
GrayMap *quantizeBand(RgbMap *rgbMap, int nrColors)
{
RgbMap *gaussMap = rgbMapGaussian(rgbMap);
//gaussMap->writePPM(gaussMap, "rgbgauss.ppm");
IndexedMap *qMap = rgbMapQuantize(gaussMap, nrColors);
//qMap->writePPM(qMap, "rgbquant.ppm");
gaussMap->destroy(gaussMap);
GrayMap *gm = GrayMapCreate(rgbMap->width, rgbMap->height);
// RGB is quantized. There should now be a small set of (R+G+B)
for (int y=0 ; y<qMap->height ; y++)
{
for (int x=0 ; x<qMap->width ; x++)
{
RGB rgb = qMap->getPixelValue(qMap, x, y);
int sum = rgb.r + rgb.g + rgb.b;
if (sum & 1)
sum = 765;
else
sum = 0;
// printf("%d %d %d : %d\n", rgb.r, rgb.g, rgb.b, index);
gm->setPixel(gm, x, y, sum);
}
}
qMap->destroy(qMap);
return gm;
}
/*#########################################################################
### E N D O F F I L E
#########################################################################*/