version 0.3.16
[fms.git] / src / freenet / captcha / alternatecaptcha2.cpp
diff --git a/src/freenet/captcha/alternatecaptcha2.cpp b/src/freenet/captcha/alternatecaptcha2.cpp
new file mode 100644 (file)
index 0000000..08cbdd6
--- /dev/null
@@ -0,0 +1,117 @@
+#include "../../../include/freenet/captcha/alternatecaptcha2.h"\r
+\r
+#include <Poco/Path.h>\r
+#include <Poco/DirectoryIterator.h>\r
+\r
+#include <cmath>\r
+#include <vector>\r
+\r
+#ifdef ALTERNATE_CAPTCHA\r
+\r
+AlternateCaptcha2::AlternateCaptcha2()\r
+{\r
+       AlternateCaptchaFonts fonts;\r
+       m_fonts=fonts.Fonts();\r
+}\r
+\r
+void AlternateCaptcha2::Generate()\r
+{\r
+       std::string puzzlestring=GenerateRandomString(6);\r
+       std::vector<int> fontnums(puzzlestring.size(),0);\r
+       \r
+       m_solution.clear();\r
+       m_puzzle.clear();\r
+       \r
+       FreeImage::Bitmap bigbmp(300,300,32);\r
+       bigbmp.SetTransparent();\r
+\r
+       // get total width of text\r
+       int textwidth=0;\r
+       for(int i=0; i<puzzlestring.size(); i++)\r
+       {\r
+               fontnums[i]=rand()%m_fonts.size();\r
+               textwidth+=m_fonts[fontnums[i]].Char(puzzlestring[i]).Width();\r
+       }\r
+\r
+       RGBQUAD white;\r
+       white.rgbRed=255;\r
+       white.rgbGreen=255;\r
+       white.rgbBlue=255;\r
+       white.rgbReserved=255;\r
+       int numlines=(rand()%3)+2;\r
+       for(int i=0; i<numlines; i++)\r
+       {\r
+               int x1=rand()%150;\r
+               int y1=(rand()%100)+100;\r
+               int x2=(rand()%150)+150;\r
+               int y2=(rand()%100)+100;\r
+               bigbmp.Line(x1,y1,x2,y2,white);\r
+               bigbmp.Line(x1+1,y1,x2+1,y2,white);\r
+       }\r
+       \r
+       // draw the text on the bigbmp centered\r
+       int currentx=150-(textwidth/2);\r
+       for(int i=0; i<puzzlestring.size(); i++)\r
+       {\r
+               FreeImage::Bitmap charbmp=m_fonts[fontnums[i]].Char(puzzlestring[i]);\r
+               bigbmp.BlitTrans(charbmp,currentx,150-(charbmp.Height()/2),0,0,charbmp.Width(),charbmp.Height());\r
+               currentx+=m_fonts[fontnums[i]].Char(puzzlestring[i]).Width();//+1;\r
+       }\r
+       \r
+       // rotate and skew the big bitmap a few times\r
+       int lastrot=0;\r
+       int thisrot=0;\r
+       int numrots=(rand()%4)+4;\r
+       for(int i=0; i<numrots; i++)\r
+       {\r
+               thisrot=((rand()%180)-90);\r
+               bigbmp.Rotate(-lastrot+thisrot,0,0,150,150);\r
+               int offset=rand()%10000;\r
+               float freq=3.0+(float(rand()%7000)/1000.0);\r
+               float amp=1.0+(float(rand()%1000)/500.0);\r
+               for(int y=0; y<bigbmp.Height(); y++)\r
+               {\r
+                       double shift=sin((double)(y+offset)/freq)*amp;\r
+                       bigbmp.HorizontalOffset(y,shift);\r
+               }\r
+               lastrot=thisrot;\r
+       }\r
+\r
+       // rotate the big bitmap back to (almost) horizontal\r
+       bigbmp.Rotate(-lastrot+((rand()%10)-5),0,0,150,150);\r
+\r
+       // grab the center of the big bitmap as the final bitmap\r
+       FreeImage::Bitmap bmp(110,50,32);\r
+       bmp.SetTransparent();\r
+       bmp.Blit(bigbmp,0,0,95,125,110,50,255);\r
+\r
+       m_solution.insert(m_solution.end(),puzzlestring.begin(),puzzlestring.end());\r
+       bmp.SaveToMemory("bmp",m_puzzle);\r
+\r
+}\r
+\r
+const std::string AlternateCaptcha2::GenerateRandomString(const int len)\r
+{\r
+       // no l,1 O,0 because they look too much alike\r
+       static std::string chars="abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789@#";\r
+       std::string temp="";\r
+       for(int i=0; i<len; i++)\r
+       {\r
+               temp+=chars[rand()%chars.size()];\r
+       }\r
+       return temp;\r
+}\r
+\r
+const bool AlternateCaptcha2::GetPuzzle(std::vector<unsigned char> &puzzle)\r
+{\r
+       puzzle=m_puzzle;\r
+       return true;\r
+}\r
+\r
+const bool AlternateCaptcha2::GetSolution(std::vector<unsigned char> &solution)\r
+{\r
+       solution=m_solution;\r
+       return true;\r
+}\r
+\r
+#endif // ALTERNATE_CAPTCHA\r