summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-07-24 15:17:51 +0200
committerkdx <kikoodx@paranoici.org>2023-07-24 15:17:51 +0200
commit4cd7ee8210aafaf927e381603e4995fb3b1e68d9 (patch)
treee3d7ba11d336aa735e35fa094e537eed22f60c06
parent4c1ecac3addae3d418a15ab5d8fe4848e9fad714 (diff)
downloadcatgy-4cd7ee8210aafaf927e381603e4995fb3b1e68d9.tar.gz
bit3 & blurge & gol
-rw-r--r--catgy.c111
1 files changed, 94 insertions, 17 deletions
diff --git a/catgy.c b/catgy.c
index f1cd128..2a5025e 100644
--- a/catgy.c
+++ b/catgy.c
@@ -1,6 +1,7 @@
#include <stdint.h>
#include <stdio.h>
#include <strings.h>
+#include <time.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
@@ -11,19 +12,32 @@ struct image {
uint8_t *data;
};
-static int process(char **argv);
+static int process(int argc, char **argv);
+static void bit3(struct image *img);
static void chaos1(struct image *img);
static void chaos3(struct image *img);
+static void blurge(struct image *img);
+static void gol(struct image *img);
int
main(int argc, char **argv) {
- if (argc != 3) {
- fprintf(stderr, "usage: %s filter image\n",
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s image [filters]\n",
argv[0]);
return 1;
}
- return process(argv);
+ srand(time(NULL));
+
+ return process(argc, argv);
+}
+
+static void
+bit3(struct image *img)
+{
+ /* deterministic threshold to 3-bit */
+ for (long i = 0; i < img->w * img->h * CHANS; i++)
+ img->data[i] = (img->data[i] > 0x7f) * 0xff;
}
static void
@@ -47,11 +61,67 @@ chaos3(struct image *img)
img->data[i] = (img->data[i] > (rand() & 0xff)) * 0xff;
}
+static void
+average(uint8_t dest[3], uint8_t src[9])
+{
+ for (int i = 0; i < 3; i++)
+ dest[i] = (src[i] + src[i + 3] + src[i + 6]) / 3;
+}
+
+static void
+blurge(struct image *img)
+{
+ for (int y = 0; y < img->h; y++)
+ for (int x = 1; x < img->w - 1; x++)
+ average(&img->data[x * 3 + y * img->w * 3],
+ &img->data[x * 3 - 3 + y * img->w * 3]);
+}
+
+static int
+neighbors(struct image *img, int x, int y, int o)
+{
+ const int stride = img->w * 3;
+ return (img->data[o + (x - 1) * 3 + (y ) * stride] != 0) +
+ (img->data[o + (x + 1) * 3 + (y ) * stride] != 0) +
+ (img->data[o + (x ) * 3 + (y - 1) * stride] != 0) +
+ (img->data[o + (x ) * 3 + (y + 1) * stride] != 0) +
+ (img->data[o + (x - 1) * 3 + (y - 1) * stride] != 0) +
+ (img->data[o + (x - 1) * 3 + (y + 1) * stride] != 0) +
+ (img->data[o + (x + 1) * 3 + (y - 1) * stride] != 0) +
+ (img->data[o + (x + 1) * 3 + (y + 1) * stride] != 0);
+}
+
+static void
+gol(struct image *img)
+{
+ uint8_t *copy = malloc(img->w * img->h * img->chans);
+ if (copy == NULL) {
+ perror("malloc");
+ return;
+ }
+ memcpy(copy, img->data, img->w * img->h * img->chans);
+
+ for (int y = 1; y < img->h - 1; y++) {
+ for (int x = 1; x < img->w - 1; x++) {
+ for (int o = 0; o < 3; o++) {
+ const int near = neighbors(img, x, y, o);
+ const int i = x * 3 + y * img->w * 3 + o;
+ if (near < 2 || near > 3)
+ copy[i] = 0;
+ else
+ copy[i] = 0xff;
+ }
+ }
+ }
+
+ memcpy(img->data, copy, img->w * img->h * img->chans);
+ free(copy);
+}
+
static int
-process(char **argv)
+process(int argc, char **argv)
{
- const char *filter = argv[1];
- const char *path = argv[2];
+ const char *path = argv[1];
/* read image */
struct image img;
@@ -78,23 +148,30 @@ process(char **argv)
const char *name;
void (*fun)(struct image *img);
} filters[] = {
+ { "bit3", bit3 },
{ "chaos1", chaos1 },
{ "chaos3", chaos3 },
+ { "blurge", blurge },
+ { "gol", gol },
};
int filtered = 0;
- for (size_t i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
- if (strcasecmp(filter, filters[i].name) == 0) {
- filters[i].fun(&img);
- filtered = 1;
- break;
+
+ for (int i = 2; i < argc; i++) {
+ const char *filter = argv[i];
+ for (size_t i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
+ if (strcasecmp(filter, filters[i].name) == 0) {
+ filters[i].fun(&img);
+ filtered = 1;
+ break;
+ }
}
- }
- if (!filtered) {
- fprintf(stderr, "error: unknown filter '%s'\n", filter);
- stbi_image_free(img.data);
- return 1;
+ if (!filtered) {
+ fprintf(stderr, "error: unknown filter '%s'\n", filter);
+ stbi_image_free(img.data);
+ return 1;
+ }
}
/* write PPM */