version 0.3.16
[fms.git] / src / freenet / captcha / alternatecaptcha1.cpp
1 #include "../../../include/freenet/captcha/alternatecaptcha1.h"\r
2 \r
3 #include <cmath>\r
4 \r
5 #ifdef ALTERNATE_CAPTCHA\r
6 \r
7 AlternateCaptcha1::AlternateCaptcha1()\r
8 {\r
9         AlternateCaptchaFonts fonts;\r
10         m_fonts=fonts.Fonts();\r
11 }\r
12 \r
13 void AlternateCaptcha1::Generate()\r
14 {\r
15         std::string puzzlestring=GenerateRandomString(5);\r
16         FreeImage::Bitmap tempchar(50,50,32);\r
17         tempchar.SetTransparent();\r
18         FreeImage::Bitmap bmp(110,50,32);\r
19         bmp.SetTransparent();\r
20 \r
21         m_solution.clear();\r
22         m_puzzle.clear();\r
23 \r
24         // draw the text\r
25         if(m_fonts.size()>0)\r
26         {\r
27                 for(int i=0; i<puzzlestring.size(); i++)\r
28                 {\r
29                         RGBQUAD black;\r
30                         black.rgbRed=0;\r
31                         black.rgbGreen=0;\r
32                         black.rgbBlue=0;\r
33                         int xoffset=(i*20)-(5+(rand()%5));\r
34                         int yoffset=(rand()%20)-10;\r
35                         int fontnum=rand()%m_fonts.size();\r
36                         FreeImage::Bitmap charbmp=m_fonts[fontnum].Char(puzzlestring[i]);\r
37 \r
38                         tempchar.SetTransparent();\r
39                         tempchar.ClearTransparent();\r
40                         tempchar.BlitTrans(charbmp,25-(charbmp.Width()/2),25-(charbmp.Height()/2),0,0,charbmp.Width(),charbmp.Height());\r
41                         tempchar.Rotate((rand()%60)-30,0,0,25,25);\r
42 \r
43                         bmp.BlitTrans(tempchar,xoffset,yoffset,0,0,50,50);\r
44                 }\r
45         }\r
46 \r
47         //place some random lines\r
48         RGBQUAD white;\r
49         white.rgbRed=255;\r
50         white.rgbGreen=255;\r
51         white.rgbBlue=255;\r
52         white.rgbReserved=255;\r
53         int numlines=(rand()%5)+10;\r
54         for(int i=0; i<numlines; i++)\r
55         {\r
56                 // draw 4 short lines very close to each other\r
57                 int x1[4];\r
58                 int y1[4];\r
59                 int x2[4];\r
60                 int y2[4];\r
61 \r
62                 x1[0]=rand()%bmp.Width();\r
63                 y1[0]=rand()%bmp.Height();\r
64                 x2[0]=x1[0]+(rand()%40)-20;\r
65                 y2[0]=y1[0]+(rand()%40)-20;\r
66 \r
67                 for(int i=1; i<4; i++)\r
68                 {\r
69                         x1[i]=x1[i-1]+rand()%3-1;\r
70                         y1[i]=y1[i-1]+rand()%3-1;\r
71                         x2[i]=x2[i-1]+rand()%3-1;\r
72                         y2[i]=y2[i-1]+rand()%3-1;\r
73                 }\r
74 \r
75                 for(int i=0; i<4; i++)\r
76                 {\r
77                         bmp.Line(x1[i],y1[i],x2[i],y2[i],white);\r
78                 }\r
79         }\r
80 \r
81         // make output a little wavy\r
82         int offset=rand()%10000;\r
83         for(int y=0; y<bmp.Height(); y++)\r
84         {\r
85                 double shift=sin((double)(y+offset)/3.0);\r
86                 bmp.HorizontalOffset(y,shift);\r
87         }\r
88 \r
89         m_solution.clear();\r
90         m_solution.insert(m_solution.end(),puzzlestring.begin(),puzzlestring.end());\r
91         m_puzzle.clear();\r
92         bmp.SaveToMemory("bmp",m_puzzle);\r
93 \r
94 }\r
95 \r
96 const std::string AlternateCaptcha1::GenerateRandomString(const int len)\r
97 {\r
98         // no l,1 O,0 because they look too much alike\r
99         static std::string chars="abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789@#";\r
100         std::string temp="";\r
101         for(int i=0; i<len; i++)\r
102         {\r
103                 temp+=chars[rand()%chars.size()];\r
104         }\r
105         return temp;\r
106 }\r
107 \r
108 const bool AlternateCaptcha1::GetPuzzle(std::vector<unsigned char> &puzzle)\r
109 {\r
110         puzzle=m_puzzle;\r
111         return true;\r
112 }\r
113 \r
114 const bool AlternateCaptcha1::GetSolution(std::vector<unsigned char> &solution)\r
115 {\r
116         solution=m_solution;\r
117         return true;\r
118 }\r
119 \r
120 #endif  // ALTERNATE_CAPTCHA\r