您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

136 行
3.9 KiB

  1. /*
  2. * phpbb.c: decode phpBB captchas
  3. * $Id$
  4. *
  5. * Copyright: (c) 2005 Sam Hocevar <sam@zoy.org>
  6. * This program is free software. It comes without any warranty, to
  7. * the extent permitted by applicable law. You can redistribute it
  8. * and/or modify it under the terms of the Do What The Fuck You Want
  9. * To Public License, Version 2, as published by Sam Hocevar. See
  10. * http://sam.zoy.org/wtfpl/COPYING for more details.
  11. */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <limits.h>
  16. #include "config.h"
  17. #include "common.h"
  18. /* Main function */
  19. char *decode_phpbb(struct image *img)
  20. {
  21. static struct font *font = NULL;
  22. char *result;
  23. struct image *tmp1, *tmp2;
  24. int x, y, i = 0;
  25. int r, g, b;
  26. int xmin, xmax, ymin, ymax, cur, offset = -1;
  27. int distmin, distx, disty, distch;
  28. if(!font)
  29. {
  30. font = font_load_fixed("font_phpbb.png",
  31. "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789");
  32. if(!font)
  33. exit(-1);
  34. }
  35. /* phpBB captchas have 6 characters */
  36. result = malloc(7 * sizeof(char));
  37. strcpy(result, " ");
  38. tmp1 = image_dup(img);
  39. tmp2 = image_new(img->width, img->height);
  40. filter_smooth(tmp1);
  41. filter_threshold(tmp1, 128);
  42. for(x = 0; x < img->width; x++)
  43. for(y = 0; y < img->height; y++)
  44. {
  45. getpixel(tmp1, x, y, &r, &g, &b);
  46. if(r == 0 && offset == -1)
  47. offset = x;
  48. getpixel(img, x, y, &r, &g, &b);
  49. setpixel(tmp2, x, y, 255, g, 255);
  50. }
  51. for(cur = 0; cur < 6; cur++)
  52. {
  53. /* Try to find 1st letter */
  54. distmin = INT_MAX;
  55. for(i = 0; i < font->size; i++)
  56. {
  57. int localmin = INT_MAX, localx, localy;
  58. xmin = font->glyphs[i].xmin;
  59. ymin = font->glyphs[i].ymin;
  60. xmax = font->glyphs[i].xmax;
  61. ymax = font->glyphs[i].ymax;
  62. for(y = 0; y < img->height - (ymax - ymin); y++)
  63. {
  64. x = offset - 3;
  65. if(cur == 0)
  66. x -= 10;
  67. if(x < 0)
  68. x = 0;
  69. for(; x < offset + 3; x++)
  70. {
  71. int z, t, dist;
  72. dist = 0;
  73. for(t = 0; t < ymax - ymin; t++)
  74. for(z = 0; z < xmax - xmin; z++)
  75. {
  76. int r2;
  77. getgray(font->img, xmin + z, ymin + t, &r);
  78. getgray(tmp1, x + z, y + t, &r2);
  79. if(r > r2)
  80. dist += r - r2;
  81. else
  82. dist += (r2 - r) * 3 / 4;
  83. }
  84. if(dist < localmin)
  85. {
  86. localmin = dist;
  87. localx = x;
  88. localy = y;
  89. }
  90. }
  91. }
  92. if(localmin < distmin)
  93. {
  94. distmin = localmin;
  95. distx = localx;
  96. disty = localy;
  97. distch = i;
  98. }
  99. }
  100. /* Print min glyph (debug) */
  101. xmin = font->glyphs[distch].xmin;
  102. ymin = font->glyphs[distch].ymin;
  103. xmax = font->glyphs[distch].xmax;
  104. ymax = font->glyphs[distch].ymax;
  105. for(y = 0; y < ymax - ymin; y++)
  106. for(x = 0; x < xmax - xmin; x++)
  107. {
  108. int r2;
  109. getpixel(font->img, xmin + x, ymin + y, &r2, &g, &b);
  110. if(r2 > 128)
  111. continue;
  112. getpixel(tmp2, distx + x, disty + y, &r, &g, &b);
  113. setpixel(tmp2, distx + x, disty + y, r2, g, b);
  114. }
  115. offset = distx + xmax - xmin;
  116. result[cur] = font->glyphs[distch].c;
  117. }
  118. image_free(tmp1);
  119. image_free(tmp2);
  120. return result;
  121. }