HTMLify

filter.c
Views: 1 | Author: abh
#include "string.h"
#include "filter.h"


// filters

Image *grayscale(const Image *image) {
    Image *filtered = image_new(image->width, image->height);
    Pixel *op, *fp;
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            op = image_get_pixel(image, x, y);
            fp = image_get_pixel(filtered, x, y);
            unsigned char v = (op->r + op->g + op->b)/3;
            fp->r = v;
            fp->g = v;
            fp->b = v;
        }
    }
    return filtered;
}

Image *negative(const Image *image) {
    Image *filtered = image_new(image->width, image->height);
    Pixel *op, *fp;
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            op = image_get_pixel(image, x, y);
            fp = image_get_pixel(filtered, x, y);
            fp->r = 255 - op->r;
            fp->g = 255 - op->g;
            fp->b = 255 - op->b;
        }
    }
    return filtered;
}

Image *add(const Image *image1, const Image *image2) {
    int width = image1->width > image2->width ? image1->width : image2->width;
    int height = image1->height > image2->height ? image1->height : image2->height;
    Image *addition = image_new(width, height);
    Pixel *ap, *p1, *p2;
    for (int y=0; y<addition->height; y++) {
        for (int x=0; x<addition->width; x++) {
            ap = image_get_pixel(addition, x, y);
            p1 = image_get_pixel(image1, x, y);
            p2 = image_get_pixel(image2, x, y);
            ap->r = p1->r + p2->r;
            ap->g = p1->g + p2->g;
            ap->b = p1->b + p2->b;
        }
    }
    return addition;
}

Image *blur(const Image *image) {
    Image *filtered = image_new(image->width, image->height);
    Pixel *fp, *op;
    int i, j, sr, sg, sb;
    Pixel *n;
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            fp = image_get_pixel(filtered, x, y);
            op = image_get_pixel(image, x, y);
            sr = 0, sg = 0, sb = 0;
            for (i=-1; i<2; i++) {
                for (j=-1; j<2; j++) {
                    n = image_get_pixel(image, x+i, y+j);
                    if (x+i<0 || x+i>=image->width || y+j<0 || y+j>image->height) {
                        n = op;
                    }
                    sr += n->r;
                    sg += n->g;
                    sb += n->b;
                }
            }
            fp->r = sr/9;
            fp->g = sg/9;
            fp->b = sb/9;
        }
    }
    return filtered;
}

Image *sepia(const Image *image) {
    Image *filtered = image_new(image->width, image->height);
    Pixel *op, *fp;
    int r, g, b;
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            op = image_get_pixel(image, x, y);
            fp = image_get_pixel(filtered, x, y);
            r = (op->r * 0.393 + op->g * 0.769 + op->b * 0.189);
            g = (op->r * 0.349 + op->g * 0.686 + op->b * 0.168);
            b = (op->r * 0.272 + op->g * 0.534 + op->b * 0.131);
            if (r > 255) r = 255;
            if (g > 255) g = 255;
            if (b > 255) b = 255;
            fp->r = r;
            fp->g = g;
            fp->b = b;
        }
    }
    return filtered;
}

Image *glitch(const Image *image) {
    Image *glitched = image_new(image->width, image->height);
    Pixel *rp, *gp, *bp, *fp;
    int
        glitch_percent = 5,
        glitch_x = glitched->width * glitch_percent / 100,
        glitch_y = glitched->height * glitch_percent / 100
    ;
    for (int y=0; y<glitched->height; y++) {
        for (int x=0; x<glitched->width; x++) {
            fp = image_get_pixel(glitched, x, y);
            rp = image_get_pixel(image, x+glitch_x, y+glitch_y);
            gp = image_get_pixel(image, x, y);
            bp = image_get_pixel(image, x-glitch_x, y-glitch_y);
            fp->r = rp->r;
            fp->g = gp->g;
            fp->b = bp->b;
        }
    }
    return glitched;
}

Image *flip_v(const Image *image) {
    Image *flipped = image_new(image->width, image->height);
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            image_set_pixel(flipped, x, y, image_get_pixel(image, x, image->height - 1 - y));
        }
    }
    return flipped;
}

Image *flip_h(const Image *image) {
    Image *flipped = image_new(image->width, image->height);
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            image_set_pixel(flipped, x, y, image_get_pixel(image, image->width - x - 1, y));
        }
    }
    return flipped;
}

Image *mirror_v(const Image *image) {
    Image *mirrored = image_new(image->width, image->height);
    Pixel *p;
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width/2+1; x++) {
            p = image_get_pixel(image, x, y);
            image_set_pixel(mirrored, x, y, p);
            image_set_pixel(mirrored, mirrored->width-1-x, y, p);
        }
    }
    return mirrored;
}

Image *mirror_h(const Image *image) {
    Image *mirrored = image_new(image->width, image->height);
    Pixel *p;
    for (int y=0; y<image->height/2+1; y++) {
        for (int x=0; x<image->width; x++) {
            p = image_get_pixel(image, x, y);
            image_set_pixel(mirrored, x, y, p);
            image_set_pixel(mirrored, x, mirrored->height-1-y, p);
        }
    }
    return mirrored;
}

Image *pixled(const Image *image) {
    Image *pixeled = image_new(image->width, image->height);
    Pixel *p;
    int rs, gs, bs, i, j, ss = 3;
    for (int y=0; y<image->height/2+1; y++) {
        for (int x=0; x<image->width; x++) {
        }
    }
    return pixeled;
}

Image *rotate_l(const Image *image) {
    Image *rotated = image_new(image->height, image->width);
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            image_set_pixel(rotated, y, image->width-x-1, image_get_pixel(image, x, y));
        }
    }
    return rotated;
}

Image *rotate_r(const Image *image) {
    Image *rotated = image_new(image->height, image->width);
    for (int y=0; y<image->height; y++) {
        for (int x=0; x<image->width; x++) {
            image_set_pixel(rotated, image->height-y-1, x, image_get_pixel(image, x, y));
        }
    }
    return rotated;
}

Image *concat_r(const Image *image1, const Image *image2) {
    Image *merged = image_new(image1->width + image2->width, image1->height);
    for (int y=0; y<merged->height; y++) {
        for (int x=0; x<merged->width; x++) {
            if (x<image1->width)
                image_set_pixel(merged, x, y, image_get_pixel(image1, x, y));
            else
                image_set_pixel(merged, x, y, image_get_pixel(image2, x-image1->width, y));
        }
    }
    return merged;
}

Image *concat_l(const Image *image1, const Image *image2) {
    return concat_r(image2, image1);
}

Image *concat_b(const Image *image1, const Image *image2) {
    Image *merged = image_new(image1->width, image1->height + image2->width);
    for (int y=0; y<merged->height; y++) {
        for (int x=0; x<merged->width; x++) {
            if (y<image1->height)
                image_set_pixel(merged, x, y, image_get_pixel(image1, x, y));
            else
                image_set_pixel(merged, x, y, image_get_pixel(image2, x, y-image1->height));
        }
    }
    return merged;
}

Image *concat_t(const Image *image1, const Image *image2) {
    return concat_b(image2, image1);
}

Image *transpose(const Image *image) {
    Image *t = image_new(image->height, image->width);
    for (int y=0; y<t->height; y++) {
        for (int x=0; x<t->width; x++) {
            image_set_pixel(t, x, y, image_get_pixel(image, y, x));
        }
    }
    return t;
}

Image *posterize(const Image *image) {
    Image *p = image_new(image->width, image->height);
    Pixel *pp, *op;
    for (int y=0; y<p->height; y++) {
        for (int x=0; x<p->width; x++) {
            op = image_get_pixel(image, x, y);
            pp = image_get_pixel(p, x, y);
            pp->r = (op->r/16)*16;
            pp->g = (op->g/16)*16;
            pp->b = (op->b/16)*16;
        }
    }
    return p;
}

Image *half(const Image *image) {
    Image *half = image_new(image->width / 2, image->height / 2);
    for (int y=0; y<half->height; y++) {
        for (int x=0; x<half->width; x++) {
            image_set_pixel(half, x, y, image_get_pixel(image, x*2, y*2));
        }
    }
    return half;
}

// accicability

#define _filter_count 21
const int filter_count = _filter_count;
Filter filters[_filter_count] = {
    { .name = "grayscale",  .argc = 1, grayscale,   NULL,       }, // 1
    { .name = "negative",   .argc = 1, negative,    NULL,       }, // 2
    { .name = "invert",     .argc = 1, negative,    NULL,       }, // 2
    { .name = "add",        .argc = 2, NULL,        add,        }, // 3
    { .name = "merge",      .argc = 2, NULL,        add,        }, // 3
    { .name = "blur",       .argc = 1, blur,        NULL,       }, // 4
    { .name = "sepia",      .argc = 1, sepia,       NULL,       }, // 4
    { .name = "glitch",     .argc = 1, glitch,      NULL,       }, // 5
    { .name = "flip-v",     .argc = 1, flip_v,      NULL,       }, // 6
    { .name = "flip-h",     .argc = 1, flip_h,      NULL,       }, // 6
    { .name = "mirror-v",   .argc = 1, mirror_v,    NULL,       }, // 7
    { .name = "mirror-h",   .argc = 1, mirror_h,    NULL,       }, // 7
    { .name = "rotate-l",   .argc = 1, rotate_l,    NULL,       }, // 8
    { .name = "rotate-r",   .argc = 1, rotate_r,    NULL,       }, // 8
    { .name = "concat-l",   .argc = 2, NULL,        concat_l,   }, // 9
    { .name = "concat-r",   .argc = 2, NULL,        concat_r,   }, // 9
    { .name = "concat-t",   .argc = 2, NULL,        concat_t,   }, // 9
    { .name = "concat-b",   .argc = 2, NULL,        concat_b,   }, // 9
    { .name = "transpose",  .argc = 1, transpose,   NULL,       }, // 10
    { .name = "posterize",  .argc = 1, posterize,   NULL,       }, // 10
    { .name = "half",       .argc = 1, half,        NULL,       }, // 11
};

Filter *filter_by_name(const char *name) {
    for (int i=0; i<filter_count; i++)
        if (strcmp(filters[i].name, name) == 0)
            return &filters[i];
    return NULL;
}

Comments