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 "VG91.h"
00031 #include "VGSpec.h"
00032
00033 namespace halftoner
00034 {
00035
00036
00037
00038
00039
00040 VG91::VG91() throw()
00041 {
00042
00043 }
00044
00045
00046
00047
00048
00049
00050 VG91::~VG91()
00051 {
00052
00053 }
00054
00055
00056
00057
00058
00059
00060 Image* VG91::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
00074 const VGSpec* vgspec = dynamic_cast<const VGSpec*>(spec);
00075 int cluster = vgspec->getClusterSize();
00076 const SFCPathFactory::SizeMnemonic& mnemonic = vgspec->getMnemonic();
00077 SFCPath* curve = SFCPathFactory::getInstance(mnemonic);
00078
00079
00080 Image* out = new Image(width, height);
00081
00082
00083 int accumulator = 0;
00084 int len = width * height;
00085 std::pair<int, int> p;
00086
00087 for (int i = 0; i < len; i += cluster)
00088 {
00089
00090 for (int n = 0; n < cluster; n++)
00091 {
00092 if (i + n < len)
00093 {
00094 p = (*curve)[i + n];
00095 accumulator += source.getColorAt(p.first, p.second);
00096 }
00097 }
00098
00099 for (int n = 0; n < cluster; n++)
00100 {
00101 if (i + n < len)
00102 {
00103 p = (*curve)[i + n];
00104 if (accumulator >= 255)
00105 {
00106 accumulator -= 255;
00107 out->setColorAt(p.first, p.second, 1);
00108 }
00109 else
00110 {
00111 out->setColorAt(p.first, p.second, 0);
00112 }
00113 }
00114 }
00115 }
00116
00117 delete curve;
00118
00119 return out;
00120 }
00121
00122 }