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

139 行
3.8 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; you can redistribute it and/or
  7. * modify it under the terms of the Do What The Fuck You Want To
  8. * Public License as published by Banlu Kemiyatorn. See
  9. * http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <limits.h>
  15. #include "config.h"
  16. #include "common.h"
  17. /* Our macros */
  18. #define FONTNAME "share/font_phpbb.png"
  19. static struct image *font = NULL;
  20. /* Main function */
  21. char *decode_phpbb(struct image *img)
  22. {
  23. char all[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
  24. char *result;
  25. struct image *tmp1, *tmp2, *tmp3;
  26. int x, y, i = 0;
  27. int r, g, b;
  28. int xmin, xmax, ymin, ymax, cur, offset = -1;
  29. int distmin, distx, disty, distch;
  30. if(!font)
  31. {
  32. font = image_load(FONTNAME);
  33. if(!font)
  34. {
  35. fprintf(stderr, "cannot load font %s\n", FONTNAME);
  36. exit(-1);
  37. }
  38. }
  39. /* phpBB captchas have 6 characters */
  40. result = malloc(7 * sizeof(char));
  41. strcpy(result, " ");
  42. tmp1 = filter_smooth(img);
  43. tmp2 = filter_equalize(tmp1, 128);
  44. tmp3 = image_new(img->width, img->height);
  45. for(x = 0; x < img->width; x++)
  46. for(y = 0; y < img->height; y++)
  47. {
  48. getpixel(tmp2, x, y, &r, &g, &b);
  49. if(r == 0 && offset == -1)
  50. offset = x;
  51. getpixel(img, x, y, &r, &g, &b);
  52. setpixel(tmp3, x, y, 255, g, 255);
  53. }
  54. for(cur = 0; cur < 6; cur++)
  55. {
  56. /* Try to find 1st letter */
  57. distmin = INT_MAX;
  58. for(i = 0; i < 35; i++)
  59. {
  60. int localmin = INT_MAX, localx, localy;
  61. xmin = i * 40;
  62. ymin = 0;
  63. xmax = i * 40 + 40;
  64. ymax = 40;
  65. for(y = 0; y < img->height - 40; y++)
  66. {
  67. x = offset - 3;
  68. if(cur == 0)
  69. x -= 10;
  70. if(x < 0)
  71. x = 0;
  72. for(; x < offset + 3; x++)
  73. {
  74. int z, t, dist;
  75. dist = 0;
  76. for(t = 0; t < ymax - ymin; t++)
  77. for(z = 0; z < xmax - xmin; z++)
  78. {
  79. int r2;
  80. getgray(font, xmin + z, ymin + t, &r);
  81. getgray(tmp2, x + z, y + t, &r2);
  82. if(r > r2)
  83. dist += r - r2;
  84. else
  85. dist += (r2 - r) * 3 / 4;
  86. }
  87. if(dist < localmin)
  88. {
  89. localmin = dist;
  90. localx = x;
  91. localy = y;
  92. }
  93. }
  94. }
  95. if(localmin < distmin)
  96. {
  97. distmin = localmin;
  98. distx = localx;
  99. disty = localy;
  100. distch = i;
  101. }
  102. }
  103. /* Print min glyph (debug) */
  104. xmin = distch * 40;
  105. ymin = 0;
  106. xmax = distch * 40 + 40;
  107. ymax = 40;
  108. for(y = 0; y < ymax - ymin; y++)
  109. for(x = 0; x < xmax - xmin; x++)
  110. {
  111. int r2;
  112. getpixel(font, xmin + x, ymin + y, &r2, &g, &b);
  113. if(r2 > 128) continue;
  114. getpixel(tmp3, distx + x, disty + y, &r, &g, &b);
  115. setpixel(tmp3, distx + x, disty + y, r2, g, b);
  116. }
  117. offset = distx + xmax - xmin;
  118. result[cur] = all[distch];
  119. }
  120. image_free(tmp1);
  121. image_free(tmp2);
  122. image_free(tmp3);
  123. return result;
  124. }