// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
// Implements the quick-and-dirty artistic halftoning algorithm.
// See readme.txt for a description.
//
// Author: Alejo Hausner (ahausner@truehaus.net) 2008.
#ifdef WIN32
#include
#endif
#include
#include
#include
#include
#include "Image.h"
using namespace std;
FILE *dbgfp = fopen("debug.dat","w");
class Pixel {
public:
int x, y, t;
void setPosition(int xx, int yy) {x = xx; y = yy;}
void setThreshold(int tt) {t = tt;}
Pixel& operator=(const Pixel& other) {
if (this != &other) {
x = other.x;
y = other.y;
t = other.t;
}
return *this;
}
};
int comparePixelsByThreshold( const void *arg1, const void *arg2 ) {
Pixel &pix1 = *(Pixel *) arg1;
Pixel &pix2 = *(Pixel *) arg2;
if (pix1.t < pix2.t)
return -1;
else if (pix1.t > pix2.t)
return +1;
else
return 0;
}
class PixelSubset {
public:
PixelSubset(int capacity) {
pixels = new Pixel[capacity];
size = 0;
}
void append(int x, int y) {
pixels[size++].setPosition(x,y);
}
void setThreshold(int i, int t) {
pixels[i].setThreshold(t);
}
Pixel operator[](int index) {
return pixels[index];
}
int getSize() { return size; }
void sort() {
qsort( (void *)pixels, (size_t)size, sizeof(Pixel),
comparePixelsByThreshold );
}
private:
Pixel *pixels;
int size;
};
int getGrayLevels(Image& motif, int *grays, int *grayCounts) {
for (int i=0; i<256; i++)
grayCounts[i] = 0;
int w = motif.getWidth();
int h = motif.getHeight();
byte **buf = motif.getBuf();
for (int y=0; yappend(x,y);
}
}
// for (int i=0; igetSize();
// for (int j=0; jgetSize();
for (int j=0; jsetThreshold(j,threshold);
}
}
}
void buildOutput(int nGrays, PixelSubset **S, Image& dither, Image& output) {
int w = dither.getWidth();
int h = dither.getHeight();
output.ensureSpace(w,h);
int nPixels = w*h;
int k=0;
byte **buf = output.getBuf();
for (int i=0; igetSize();
for (int j=0; jsort();
// fprintf(dbgfp,"After sorting subset %d:\n",i);
// int n = S[i]->getSize();
// for (int j=0; j