Example #1
0
/* Main function */
char *decode_authimage(struct image *img)
{
    static struct font *font = NULL;
    char *result;
    struct image *tmp;
    int x, y, r, g, b, i;

    if(!font)
    {
        font = font_load_fixed(DECODER, "font.png",
                               "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        if(!font)
            exit(-1);
    }

    /* authimage captchas have 6 characters */
    result = malloc(7 * sizeof(char));
    memset(result, '\0', 7);

    /* double the captcha size for better accuracy in the rotation */
    tmp = image_dup(img);
    filter_scale(tmp, 2.0);
    getpixel(tmp, 0, 0, &r, &g, &b);
    filter_threshold(tmp, r * 3 / 4);
    filter_smooth(tmp);
    filter_threshold(tmp, 220);

    for(i = 0; i < 6; i++)
    {
        int mindiff = INT_MAX, minch = -1, ch;
        for(ch = 0; ch < font->size; ch++)
        {
            int diff = 0;
            for(y = 0; y < 7; y++)
            {
                for(x = 0; x < 5; x++)
                {
                    int newx, newy, r2;
                    newx = 35.0 + (x + 6 * i) * 218.0 / 34.0 + y * 5.0 / 6.0 + 0.5;
                    newy = 33.0 - (x + 6 * i) * 18.0 / 34.0 + y * 42.0 / 6.0 + 0.5;
                    getpixel(tmp, newx, newy, &r, &g, &b);
                    getpixel(font->img, x + 6 * ch, y, &r2, &g, &b);
                    diff += (r - r2) * (r - r2);
                }
            }
            if(diff < mindiff)
            {
                mindiff = diff;
                minch = ch;
            }
        }
        result[i] = font->glyphs[minch].c;
    }

    image_free(tmp);

    return result;
}
Example #2
0
/* Main function */
char *decode_vbulletin(struct image *img)
{
    static struct font *font = NULL;
    char *result;
    struct image *tmp;
    int limits[6] = { 26, 53, 80, 107, 134, 160 };
    int x, y, r, g, b, i, j;

    if(!font)
    {
        font = font_load_fixed(DECODER, "font.png",
                               "2346789ABCDEFGHJKLMNPRTWXYZ");
        if(!font)
            exit(-1);
    }

    /* vBulletin captchas have 6 characters */
    result = malloc(7 * sizeof(char));
    strcpy(result, "      ");

    /* half the captchas are inverse video; we set them back to normal */
    tmp = image_dup(img);
    getpixel(tmp, 0, 0, &r, &g, &b);
    if(r < 50)
        filter_threshold(tmp, 128);
    else
        filter_threshold(tmp, -128);

    /* Remove garbage around the cells */
    for(x = 0; x < tmp->width; x++)
    {
        for(y = 0; y < 15; y++)
            setpixel(tmp, x, y, 255, 255, 255);
        for(y = 45; y < tmp->height; y++)
            setpixel(tmp, x, y, 255, 255, 255);
    }

    for(x = 0; x < tmp->width; x++)
    {
        for(i = 0; i < 6; i++)
            if(x == limits[i])
                break;
        if(i == 6)
            for(y = 15; y < 45; y++)
                setpixel(tmp, x, y, 255, 255, 255);
        else
            x += 11;
    }

    filter_black_stuff(tmp);
    filter_black_stuff(tmp);

    /* Fill letters in gray */
    for(x = 26; x < 172; x++)
    {
        getpixel(tmp, x, 15, &r, &g, &b);
        if(r == 0)
            filter_flood_fill(tmp, x, 15, 127, 0, 255);
    }

    /* Find remaining black parts and remove them */
    for(x = 26; x < 172; x++)
        for(y = 15; y < 45; y++)
        {
            getpixel(tmp, x, y, &r, &g, &b);
            if(r == 0)
                filter_flood_fill(tmp, x, y, 255, 255, 255);
        }

    /* Fill letters in black */
    for(x = 26; x < 172; x++)
    {
        getpixel(tmp, x, 44, &r, &g, &b);
        if(r == 127)
            filter_flood_fill(tmp, x, 44, 0, 0, 0);
    }

    /* Find remaining gray parts and remove them */
    for(x = 26; x < 172; x++)
        for(y = 15; y < 45; y++)
        {
            getpixel(tmp, x, y, &r, &g, &b);
            if(r == 127)
                filter_flood_fill(tmp, x, y, 255, 255, 255);
        }

    /* Guess all glyphs */
    for(i = 0; i < 6; i++)
    {
        int mindist = INT_MAX, min = -1;
        for(j = 0; j < font->size; j++)
        {
            int dist = 0;
            for(y = 0; y < 30; y++)
                for(x = 0; x < 11; x++)
                {
                    int r2, g2, b2;
                    getpixel(font->img, 12 * j + x, y, &r, &g, &b);
                    getpixel(tmp, limits[i] + x, 15 + y, &r2, &g2, &b2);
                    dist += (r - r2) * (r - r2);
                }
            if(dist < mindist)
            {
                mindist = dist;
                min = j;
            }
        }
        result[i] = font->glyphs[min].c;
    }

    image_free(tmp);

    return result;
}
Example #3
0
/* Main function */
char *decode_linuxfr(struct image *img)
{
    static struct font *font = NULL;
    char *result;
    struct image *tmp;
    int x, y, r, g, b, i, j, c;
    int *stats;

    if(!font)
    {
        font = font_load_fixed(DECODER, "font.png",
                               "abcdefghijklmnopqrstuvwxyz"
                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                               "0123456789");
        if(!font)
            exit(-1);
    }

    /* linuxfr captchas have 7 characters */
    result = malloc(8 * sizeof(char));
    memset(result, '\0', 8);

    stats = malloc(img->height * sizeof(int));

    tmp = image_dup(img);
    filter_threshold(tmp, 150);

    for(y = 0; y < tmp->height; y++)
    {
        int count = 0;
        for(x = 0; x < tmp->width; x++)
        {
            getpixel(tmp, x, y, &r, &g, &b);
            if(r == 0)
                count++;
        }
        stats[y] = count;
    }

    /* Find 7 consecutive lines that have at least 14 pixels; they're
     * baseline candidates */
    for(y = 0; y < tmp->height - 11; y++)
    {
        int ycan = 1;
        for(j = 3; j < 10; j++)
        {
            if(stats[y + j] < 14)
            {
                ycan = 0;
                y = y + j - 3;
                break;
            }
        }
        if(!ycan)
            continue;

        /* Find 7 consecutive cells that have at least 2 pixels on
         * each line; they're base column candidates */
        for(x = 0; x < tmp->width - 9 * 7 + 1; x++)
        {
            int goodx = 1;
            for(c = 0; c < 7 && goodx; c++)
            {
                for(j = 3; j < 10; j++)
                {
                    int count = 0;
                    for(i = 0; i < 8; i++)
                    {
                        getpixel(tmp, x + c * 9 + i, y + j, &r, &g, &b);
                        if(r == 0)
                        {
                            count++;
                            if(count == 2)
                                break;
                        }
                    }
                    if(count < 2)
                    {
                        goodx = 0;
                        break;
                    }
                }
            }
            if(!goodx)
                continue;

            /* Now we have an (x,y) candidate - try to fit 7 characters */
            for(c = 0; c < 7 && goodx; c++)
            {
                int r2, g2, b2, ch;
                int minerror = INT_MAX;
                for(ch = 0; ch < font->size; ch++)
                {
                    int error = 0, goodch = 1;
                    for(j = 0; j < 12 && goodch; j++)
                        for(i = 0; i < 8; i++)
                        {
                            getpixel(tmp, x + c * 9 + i, y + j, &r, &g, &b);
                            getpixel(font->img, ch * 9 + i, j, &r2, &g2, &b2);
                            /* Only die if font is black and image is white */
                            if(r > r2)
                            {
                                goodch = 0;
                                break;
                            }
                            else if(r < r2)
                                error++;
                        }
                    if(goodch && error < minerror)
                    {
                        minerror = error;
                        result[c] = font->glyphs[ch].c;
                        result[c+1] = '\0';
                    }
                }
                if(minerror == INT_MAX)
                    goodx = 0;
            }
            /* Wow, that was a good guess! Exit this loop */
            if(goodx)
                break;
        }
    }

    image_free(tmp);
    free(stats);

    if(strlen(result) != 7)
    {
        free(result);
        return NULL;
    }

    return result;
}