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

183 行
4.3 KiB

  1. /*
  2. * scode.c: decode scode captchas
  3. * $Id$
  4. *
  5. * Copyright: (c) 2004 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 "config.h"
  15. #include "common.h"
  16. static char find_glyph(struct image *img, int xmin, int xmax);
  17. /* Main function */
  18. char *decode_scode(struct image *img)
  19. {
  20. char *result;
  21. int stats[256];
  22. int x, y, i, incell = 0, cur = 0, xmin = 0;
  23. int r, g, b;
  24. struct image *tmp1;
  25. /* allocate enough place */
  26. result = malloc(1024 * sizeof(char));
  27. /* Detect background: first and last 3 lines */
  28. for(i = 0; i < 256; i++)
  29. stats[i] = 0;
  30. for(y = 0; y < 3; y++)
  31. for(x = 0; x < img->width; x++)
  32. {
  33. getpixel(img, x, y, &r, &g, &b);
  34. stats[r]++;
  35. getpixel(img, x, img->width - 1 - y, &r, &g, &b);
  36. stats[r]++;
  37. }
  38. /* Set non-background colours to 0 */
  39. tmp1 = image_new(img->width, img->height);
  40. for(y = 0; y < img->height; y++)
  41. for(x = 0; x < img->width; x++)
  42. {
  43. getpixel(img, x, y, &r, &g, &b);
  44. if(stats[r])
  45. setpixel(tmp1, x, y, 255, 255, 255);
  46. else
  47. setpixel(tmp1, x, y, 0, 0, 0);
  48. }
  49. /* Decode glyphs */
  50. for(x = 0; x < img->width; x++)
  51. {
  52. int found = 0;
  53. for(y = 0; y < img->height; y++)
  54. {
  55. getpixel(tmp1, x, y, &r, &g, &b);
  56. if(!r)
  57. {
  58. found = 1;
  59. break;
  60. }
  61. }
  62. if(found && !incell)
  63. {
  64. incell = 1;
  65. xmin = x;
  66. }
  67. else if(!found && incell)
  68. {
  69. incell = 0;
  70. /* Find glyph */
  71. result[cur++] = find_glyph(tmp1, xmin, x);
  72. }
  73. }
  74. image_free(tmp1);
  75. result[cur] = 0;
  76. return result;
  77. }
  78. static char find_glyph(struct image *img, int xmin, int xmax)
  79. {
  80. int ymin = -1, ymax = -1;
  81. int x, y, count = 0;
  82. int r, g, b;
  83. /* Compute vertical bounds of glyph */
  84. for(y = 0; y < img->height; y++)
  85. {
  86. int found = 0;
  87. for(x = xmin; x < xmax; x++)
  88. {
  89. getpixel(img, x, y, &r, &g, &b);
  90. if(!r)
  91. {
  92. found = 1;
  93. break;
  94. }
  95. }
  96. if(found)
  97. {
  98. if(ymin == -1)
  99. ymin = y;
  100. else
  101. ymax = y + 1;
  102. }
  103. }
  104. for(x = xmin; x < xmax; x++)
  105. {
  106. for(y = ymin; y < ymax; y++)
  107. {
  108. getpixel(img, x, y, &r, &g, &b);
  109. if(!r)
  110. count += 5 * (y - ymin) ^ 3 * (x - xmin);
  111. //count += y - ymin;
  112. }
  113. }
  114. switch(count)
  115. {
  116. /* Scode font */
  117. case 778: return '0';
  118. case 621: return '1';
  119. case 854: return '2';
  120. case 784: return '3';
  121. case 766: return '4';
  122. case 771: return '5';
  123. case 976: return '6';
  124. case 585: return '7';
  125. case 980: return '8';
  126. case 896: return '9';
  127. /* Small font */
  128. case 584: return '0';
  129. case 454: return '1';
  130. case 517: return '2';
  131. case 447: return '3';
  132. case 469: return '4';
  133. case 472: return '5';
  134. case 564: return '6';
  135. case 298: return '7';
  136. case 560: return '8';
  137. case 536: return '9';
  138. /* Thin font */
  139. case 438: return '0';
  140. case 405: return '1';
  141. case 485: return '2';
  142. case 486: return '3';
  143. case 413: return '4';
  144. case 509: return '5';
  145. case 582: return '6';
  146. case 242: return '7';
  147. case 579: return '8';
  148. case 440: return '9';
  149. #if 0
  150. case 162: return '0';
  151. case 131: return '1';
  152. case 150: return '2';
  153. case 139: return '3';
  154. case 155: return '4';
  155. case 159: return '5';
  156. case 181: return '6';
  157. case 90: return '7';
  158. case 180: return '8';
  159. case 170: return '9';
  160. #endif
  161. default:
  162. dprintf("don't know about checksum %i\n", count);
  163. return '?';
  164. }
  165. }