version 0.3.14
[fms.git] / src / freenet / captcha / alternatecaptcha1.cpp
diff --git a/src/freenet/captcha/alternatecaptcha1.cpp b/src/freenet/captcha/alternatecaptcha1.cpp
new file mode 100644 (file)
index 0000000..07f4dde
--- /dev/null
@@ -0,0 +1,148 @@
+#include "../../../include/freenet/captcha/alternatecaptcha1.h"\r
+\r
+#include <Poco/Path.h>\r
+#include <Poco/DirectoryIterator.h>\r
+\r
+#include <cmath>\r
+\r
+#ifdef ALTERNATE_CAPTCHA\r
+\r
+bool AlternateCaptcha1::m_fontsloaded(false);\r
+std::vector<FreeImage::Font> AlternateCaptcha1::m_fonts;\r
+\r
+AlternateCaptcha1::AlternateCaptcha1()\r
+{\r
+       if(m_fontsloaded==false)\r
+       {\r
+               FreeImage_Initialise(true);\r
+               LoadFonts();\r
+               m_fontsloaded=true;\r
+       }\r
+}\r
+\r
+void AlternateCaptcha1::Generate()\r
+{\r
+       std::string puzzlestring=GenerateRandomString(5);\r
+       FreeImage::Bitmap tempchar(50,50,32);\r
+       tempchar.SetTransparent();\r
+       FreeImage::Bitmap bmp(110,50,32);\r
+       bmp.SetTransparent();\r
+\r
+       m_solution.clear();\r
+       m_puzzle.clear();\r
+\r
+       // draw the text\r
+       if(m_fonts.size()>0)\r
+       {\r
+               for(int i=0; i<puzzlestring.size(); i++)\r
+               {\r
+                       RGBQUAD black;\r
+                       black.rgbRed=0;\r
+                       black.rgbGreen=0;\r
+                       black.rgbBlue=0;\r
+                       int xoffset=(i*20)-(5+(rand()%5));\r
+                       int yoffset=(rand()%20)-10;\r
+                       int fontnum=rand()%m_fonts.size();\r
+                       FreeImage::Bitmap charbmp=m_fonts[fontnum].Char(puzzlestring[i]);\r
+\r
+                       tempchar.SetTransparent();\r
+                       tempchar.ClearTransparent();\r
+                       tempchar.BlitTrans(charbmp,25-(charbmp.Width()/2),25-(charbmp.Height()/2),0,0,charbmp.Width(),charbmp.Height());\r
+                       tempchar.Rotate((rand()%60)-30,0,0,25,25);\r
+\r
+                       bmp.BlitTrans(tempchar,xoffset,yoffset,0,0,50,50);\r
+               }\r
+       }\r
+\r
+       //place some random lines\r
+       RGBQUAD white;\r
+       white.rgbRed=255;\r
+       white.rgbGreen=255;\r
+       white.rgbBlue=255;\r
+       white.rgbReserved=255;\r
+       int numlines=(rand()%5)+10;\r
+       for(int i=0; i<numlines; i++)\r
+       {\r
+               // draw 4 short lines very close to each other\r
+               int x1[4];\r
+               int y1[4];\r
+               int x2[4];\r
+               int y2[4];\r
+\r
+               x1[0]=rand()%bmp.Width();\r
+               y1[0]=rand()%bmp.Height();\r
+               x2[0]=x1[0]+(rand()%40)-20;\r
+               y2[0]=y1[0]+(rand()%40)-20;\r
+\r
+               for(int i=1; i<4; i++)\r
+               {\r
+                       x1[i]=x1[i-1]+rand()%3-1;\r
+                       y1[i]=y1[i-1]+rand()%3-1;\r
+                       x2[i]=x2[i-1]+rand()%3-1;\r
+                       y2[i]=y2[i-1]+rand()%3-1;\r
+               }\r
+\r
+               for(int i=0; i<4; i++)\r
+               {\r
+                       bmp.Line(x1[i],y1[i],x2[i],y2[i],white);\r
+               }\r
+       }\r
+\r
+       int offset=rand()%10000;\r
+       for(int y=0; y<bmp.Height(); y++)\r
+       {\r
+               double shift=sin((double)(y+offset)/3.0);\r
+               bmp.HorizontalOffset(y,shift);\r
+       }\r
+\r
+       m_solution.clear();\r
+       m_solution.insert(m_solution.end(),puzzlestring.begin(),puzzlestring.end());\r
+       m_puzzle.clear();\r
+       bmp.SaveToMemory("bmp",m_puzzle);\r
+\r
+}\r
+\r
+const std::string AlternateCaptcha1::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 AlternateCaptcha1::GetPuzzle(std::vector<unsigned char> &puzzle)\r
+{\r
+       puzzle=m_puzzle;\r
+       return true;\r
+}\r
+\r
+const bool AlternateCaptcha1::GetSolution(std::vector<unsigned char> &solution)\r
+{\r
+       solution=m_solution;\r
+       return true;\r
+}\r
+\r
+void AlternateCaptcha1::LoadFonts()\r
+{\r
+       FreeImage::Bitmap bmp;\r
+       Poco::Path path("fonts");\r
+       Poco::DirectoryIterator di(path);\r
+       Poco::DirectoryIterator end;\r
+\r
+       while(di!=end)\r
+       {\r
+               if(di.name().find("bmp")!=std::string::npos)\r
+               {\r
+                       bmp.Load("bmp",di.path().toString());\r
+                       m_fonts.push_back(FreeImage::Font(bmp));\r
+               }\r
+               ++di;\r
+       }\r
+\r
+}\r
+\r
+#endif // ALTERNATE_CAPTCHA\r