Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

ErrorDiffusionHalftoner.cxx

Go to the documentation of this file.
00001 /*
00002  * @(#)src/ErrorDiffusionHalftoner.cxx  1.0  2002-08-27 12:27
00003  *
00004  * Copyright (C)  2002  Daniel Léonard
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  */
00020 
00028 #include <algorithm>
00029 #include <string>
00030 #include "ErrorDiffusionHalftoner.h"
00031 #include "ErrorDiffusionSpec.h"
00032 #include "Image.h"
00033 
00034 namespace halftoner
00035 {
00036 
00037 //------------------------------------------
00038 // Class ErrorDiffusionHalftoner::PathStrategy
00039 //------------------------------------------
00040 
00041 //---------------------------
00042 // Constructor
00043 //---------------------------
00044 
00045    ErrorDiffusionHalftoner::PathStrategy::PathStrategy() throw()
00046    {
00047    // nothing
00048    }
00049 
00050 
00051 //---------------------------
00052 // Destructor
00053 //---------------------------
00054 
00055    ErrorDiffusionHalftoner::PathStrategy::~PathStrategy() throw()
00056    {
00057    // nothing
00058    }
00059 
00060 
00061 //------------------------------------------
00062 // Class ErrorDiffusionHalftoner::ScanlinePathStrategy
00063 //------------------------------------------
00064 
00065 //---------------------------
00066 // Overloaded operator
00067 //---------------------------
00068 
00069    Image* ErrorDiffusionHalftoner::ScanlinePathStrategy::operator()(ErrorDiffusionHalftoner& halftoner, const Image& source, int threshold) throw()
00070    {
00071       Image* result = halftoner.scanline(source, threshold);
00072       return result;
00073    }
00074 
00075 
00076 //------------------------------------------
00077 // Class ErrorDiffusionHalftoner::SerpentinePathStrategy
00078 //------------------------------------------
00079 
00080 //---------------------------
00081 // Overloaded operator
00082 //---------------------------
00083 
00084    Image* ErrorDiffusionHalftoner::SerpentinePathStrategy::operator()(ErrorDiffusionHalftoner& halftoner, const Image& source, int threshold) throw()
00085    {
00086       Image* result = halftoner.serpentine(source, threshold);
00087       return result;
00088    }
00089 
00090 
00091 //------------------------------------------
00092 // Class ErrorDiffusionHalftoner
00093 //------------------------------------------
00094 
00095 //---------------------------
00096 // Class variables
00097 //---------------------------
00098 
00099    ErrorDiffusionHalftoner::ScanlinePathStrategy   ErrorDiffusionHalftoner::scan_line_strategy;
00100    ErrorDiffusionHalftoner::SerpentinePathStrategy ErrorDiffusionHalftoner::serpentine_strategy;
00101 
00102    ErrorDiffusionHalftoner::PathStrategy& ErrorDiffusionHalftoner::SCANLINE   = ErrorDiffusionHalftoner::scan_line_strategy;
00103    ErrorDiffusionHalftoner::PathStrategy& ErrorDiffusionHalftoner::SERPENTINE = ErrorDiffusionHalftoner::serpentine_strategy;
00104 
00105 
00106 //---------------------------
00107 // Constructor
00108 //---------------------------
00109 
00110    ErrorDiffusionHalftoner::ErrorDiffusionHalftoner() throw()
00111    {
00112    // nothing
00113    }
00114 
00115 
00116 //---------------------------
00117 // Destructor
00118 //---------------------------
00119 
00120    ErrorDiffusionHalftoner::~ErrorDiffusionHalftoner() throw()
00121    {
00122    // nothing
00123    }
00124 
00125 
00126 //---------------------------
00127 // Implemented methods from Halftoner
00128 //---------------------------
00129 
00130    Image* ErrorDiffusionHalftoner::halftone(const Image& source, const HalftonerSpec* spec) throw (std::invalid_argument)
00131    {
00132    // check params
00133       if (0 == spec)
00134       {
00135          std::string message("HalftonerSpec* is 0");
00136          throw std::invalid_argument(message);
00137       }
00138 
00139    // cast the specs
00140       const ErrorDiffusionSpec* edspec = dynamic_cast<const ErrorDiffusionSpec*>(spec);
00141       if (0 == edspec)
00142       {
00143          std::string message("HalftonerSpec* is not an ErrorDiffusionSpec*");
00144          throw std::invalid_argument(message);
00145       }
00146 
00147    // extract the strategy
00148       ErrorDiffusionHalftoner::PathStrategy& strategy = edspec->getStrategy();
00149 
00150    // prepare variables for the strategy
00151       int threshold = edspec->getThreshold();
00152       ErrorDiffusionHalftoner& halftoner = *this;
00153 
00154    // call the strategy
00155       Image* result = strategy(halftoner, source, threshold);
00156       return result;
00157    }
00158 
00159 
00160 //---------------------------
00161 // Instance methods
00162 //---------------------------
00163 
00164    Image* ErrorDiffusionHalftoner::scanline(const Image& source, int threshold)
00165    {
00166    // extract image data
00167       const int width = source.getWidth();
00168       const int height = source.getHeight();
00169       const int len = width * height;
00170 
00171    // create representation of the image with higher precision
00172       float data[len];
00173 
00174       unsigned char* copy = source.getCopy();
00175       std::copy_n(copy, len, data);
00176       delete copy;
00177 
00178    // create new image
00179       Image* destination = new Image(width, height);
00180 
00181    //   int line[width];
00182       int offset = 0;
00183       for (int j = 0; j < height; j++)
00184       {
00185    //      int* pixel = line;
00186          for (int i = 0; i < width; i++, offset++/*, pixel++*/)
00187          {
00188    //         *pixel = this->halftoneToRight(data, i, j, offset, width, height, threshold);
00189             int bw = this->halftoneToRight(data, i, j, offset, width, height, threshold);
00190             destination->setColorAt(i, j, bw);
00191          }
00192    //      destination->setLine(j, line, width);
00193       }
00194 
00195       return destination;
00196    }
00197 
00198    Image* ErrorDiffusionHalftoner::serpentine(const Image& source, int threshold)
00199    {
00200    // extract image data
00201       const int width = source.getWidth();
00202       const int height = source.getHeight();
00203       const int len = width * height;
00204 
00205    // create representation of the image with higher precision
00206       float data[len];
00207 
00208       unsigned char* copy = source.getCopy();
00209       std::copy_n(copy, len, data);
00210       delete copy;
00211 
00212    // create new image
00213       Image* destination = new Image(width, height);
00214 
00215       int line[width];
00216       for (int j = 0; j < height; j++)
00217       {
00218       // adjust pos at the beginning of the jth line.
00219          int pos = Image::calculateOffset(0, j, width);
00220 
00221          int* pixel = line;
00222          for (int i = 0; i < width; i++, pos++, pixel++)
00223          {
00224             *pixel = this->halftoneToRight(data, i, j, pos, width, height, threshold);
00225          }
00226          destination->setLine(j, line, width);
00227 
00228          j++;
00229          if (j >= height)
00230          {
00231             break;
00232          }
00233 
00234       // adjust pos at the end of the jth line.
00235          pos = Image::calculateOffset(0, j + 1, width);
00236          pos--;
00237       // adjust pixel at the end of the line
00238          pixel = line + width - 1;
00239          for (int i = width - 1; i >= 0; i--, pos--, pixel--)
00240          {
00241             *pixel = this->halftoneToLeft(data, i, j, pos, width, height, threshold);
00242          }
00243          destination->setLine(j, line, width);
00244       }
00245 
00246       return destination;
00247    }
00248 
00249 }

Generated on Sat Sep 7 16:31:37 2002 for Halftoning Library by doxygen1.2.17