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