aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c117
-rw-r--r--src/ppm.c2
2 files changed, 113 insertions, 6 deletions
diff --git a/src/main.c b/src/main.c
index 242e464..0182328 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,16 +1,123 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include "ppm.h"
+static Image image_convolution(Image input, float kernel[9]);
+static void split_rgb(Image input, uint8_t *r, uint8_t *g, uint8_t *b);
+static void merge_rgb(Image *out, uint8_t *r, uint8_t *g, uint8_t *b);
+static uint8_t kernel_op(uint8_t *data, float kernel[9], int i, int j, int w, int h);
+
+Image
+image_convolution(Image input, float kernel[9])
+{
+ Image out;
+ out.width = input.width;
+ out.height = input.height;
+ out.pixel_bits = input.pixel_bits;
+
+ size_t n_pixels = out.width * out.height * 3;
+
+ out.data = calloc(n_pixels, sizeof(uint8_t));
+
+ if (out.data == NULL) {
+ perror("image_convolution() Error");
+ exit(1);
+ }
+
+ uint8_t *r, *g, *b;
+ r = calloc(input.width * input.height, sizeof(uint8_t));
+ g = calloc(input.width * input.height, sizeof(uint8_t));
+ b = calloc(input.width * input.height, sizeof(uint8_t));
+ split_rgb(input, r, g, b);
+
+ int i, j, index;
+ for (i = 0; i < input.height; i++) {
+ for (j = 0; j < input.width; j++) {
+ index = i * input.width + j;
+ r[index] = kernel_op(r, kernel, i, j, input.width, input.height);
+ g[index] = kernel_op(g, kernel, i, j, input.width, input.height);
+ b[index] = kernel_op(b, kernel, i, j, input.width, input.height);
+ }
+ }
+
+ merge_rgb(&out, r, g, b);
+ free(r);
+ free(g);
+ free(b);
+ return out;
+}
+
+void
+merge_rgb(Image *out, uint8_t *r, uint8_t *g, uint8_t *b)
+{
+ int i;
+ for (i = 0; i < out->width * out->height; i++) {
+ out->data[3 * i] = r[i];
+ out->data[3 * i + 1] = g[i];
+ out->data[3 * i + 2] = b[i];
+ }
+}
+
+uint8_t
+kernel_op(uint8_t *data, float kernel[9], int i, int j, int w, int h)
+{
+ float kernel_value = 0;
+ int ki, kj, img_index, index_i, index_j, index_k;
+ for (ki = 0; ki < 3; ki++) {
+ for (kj = 0; kj < 3; kj++) {
+ index_i = i + ki - 1; //height
+ index_j = j + kj - 1; //width
+ index_k = 3 * ki + kj;
+
+ if (index_i < 0
+ || index_i >= h
+ || index_j < 0
+ || index_j >= w)
+ kernel_value += data[i * w + j] * kernel[index_k];
+ else {
+ img_index = index_i * w + index_j;
+ kernel_value += data[img_index] * kernel[index_k];
+ }
+
+ kernel_value = (kernel_value > 255) ? 255: kernel_value;
+ kernel_value = (kernel_value < 0) ? 0: kernel_value;
+ }
+ }
+ return (uint8_t)kernel_value;
+}
+
+void
+split_rgb(Image input, uint8_t *r, uint8_t *g, uint8_t *b)
+{
+
+ if (!r || !g || !b) {
+ perror("rgb_split() Error");
+ exit(1);
+ }
+
+ int i;
+ for (i = 0; i < input.width * input.height; i++) {
+ r[i] = input.data[3 * i];
+ g[i] = input.data[3 * i + 1];
+ b[i] = input.data[3 * i + 2];
+ }
+
+}
+
int main(int argc, char *argv[])
{
Image img;
- ppm_read("images/boxes_1.ppm", &img);
+ float kernel[9] = {
+ -1, -1, -1,
+ -1, 8, -1,
+ -1, -1, -1,
+ };
- printf("width: %d\n", img.width);
- printf("height: %d\n", img.height);
- printf("bits: %d\n", img.pixel_bits);
- printf("data[2]: %d\n", img.data[2]);
+ //for (int i = 0; i < 9; i++) kernel[i] /= 16;
+ ppm_read("images/synth_1.ppm", &img);
+ Image out_img = image_convolution(img, kernel);
+ ppm_write("out.ppm", &out_img);
return 0;
}
diff --git a/src/ppm.c b/src/ppm.c
index f96e950..aded7cd 100644
--- a/src/ppm.c
+++ b/src/ppm.c
@@ -13,7 +13,7 @@ ppm_write(const char *file, Image *img)
exit(1);
}
- size_t n_pixels;
+ size_t n_pixels = img->width * img->height * 3;
fprintf(fp, "P6\n%d %d\n%d\n", img->width, img->height, img->pixel_bits);
fwrite(img->data, n_pixels, sizeof(uint8_t), fp);
Feel free to download, copy and edit any repo