// 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