00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include <utility>
00027 #include "Image.h"
00028 #include "SFCPath.h"
00029 #include "SFCPathFactory.h"
00030 #include "VG95.h"
00031 #include "VGSpec.h"
00032
00033 namespace halftoner
00034 {
00035
00036
00037
00038
00039
00040 VG95::VG95() throw()
00041 {
00042
00043 }
00044
00045
00046
00047
00048
00049
00050 VG95::~VG95()
00051 {
00052
00053 }
00054
00055
00056
00057
00058
00059
00060 Image* VG95::halftone(const Image& source, const HalftonerSpec* spec) throw (std::invalid_argument)
00061 {
00062
00063 const int width = source.getWidth();
00064 const int height = source.getHeight();
00065
00066 if (width != height)
00067 {
00068 string s("image is not square");
00069 throw std::invalid_argument(s);
00070 }
00071
00072
00073 const VGSpec* vgspec = dynamic_cast<const VGSpec*>(spec);
00074 int cluster = vgspec->getClusterSize();
00075 const SFCPathFactory::SizeMnemonic& mnemonic = vgspec->getMnemonic();
00076 SFCPath* curve = SFCPathFactory::getInstance(mnemonic);
00077
00078
00079 Image* out = new Image(width, height);
00080
00081 int accumulator = 0;
00082 int len = width * height;
00083 std::pair<int, int> maxblack; maxblack.first = 0; maxblack.second = 255;
00084 int grey;
00085 std::pair<int, int> p;
00086 int black;
00087 int step;
00088
00089 for (int i = 0; i < len; i += cluster)
00090 {
00091
00092 for (int n = 0; n < cluster; n++)
00093 {
00094 if (i + n < len)
00095 {
00096
00097 p = (*curve)[i + n];
00098
00099 grey = source.getColorAt(p.first, p.second);
00100
00101 accumulator += grey;
00102
00103 if (maxblack.second > grey)
00104 {
00105 maxblack.first = i + n;
00106 maxblack.second = grey;
00107 }
00108
00109 out->setColorAt(p.first, p.second, 1);
00110 }
00111 }
00112
00113 black = cluster;
00114 step = len - i;
00115 if (black > step) black = step;
00116 while (accumulator >= 255)
00117 {
00118 black--;
00119 accumulator -=255;
00120 }
00121
00122 if (black > 0)
00123 {
00124 p = (*curve)[maxblack.first];
00125 out->setColorAt(p.first, p.second, 0);
00126 black--;
00127 }
00128 int pos;
00129 for (int n = 1; i + n < len; n++)
00130 {
00131
00132 if (black == 0) break;
00133
00134 pos = maxblack.first - n;
00135 if (pos >= i)
00136 {
00137 p = (*curve)[pos];
00138 out->setColorAt(p.first, p.second, 0);
00139 black--;
00140 }
00141
00142 else
00143 {
00144 while (black > 0)
00145 {
00146 pos = maxblack.first + n; n++;
00147 p = (*curve)[pos];
00148 out->setColorAt(p.first, p.second, 0);
00149 black--;
00150 }
00151 break;
00152 }
00153
00154 if (black == 0) break;
00155
00156 pos = maxblack.first + n;
00157 if (pos < (i + cluster))
00158 {
00159 p = (*curve)[pos];
00160 out->setColorAt(p.first, p.second, 0);
00161 black--;
00162 }
00163
00164 else
00165 {
00166 while (black > 0)
00167 {
00168 n++; pos = maxblack.first - n;
00169 p = (*curve)[pos];
00170 out->setColorAt(p.first, p.second, 0);
00171 black--;
00172 }
00173 break;
00174 }
00175 }
00176
00177 maxblack.first = 0; maxblack.second = 255;
00178 }
00179 delete curve;
00180 return out;
00181 }
00182
00183 }