summaryrefslogtreecommitdiff
path: root/RGBImage.c
blob: 2fe37ba0972ba6ec88062e8eabdacbf70e059831 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "RGBImage.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

void
ARGB_set(ARGB* rgb, byte4 color) {
	rgb->a = (0xFF000000 & color) >> 24;
	rgb->r = (0x00FF0000 & color) >> 16;
	rgb->g = (0x0000FF00 & color) >> 8;
	rgb->b = (0x000000FF & color);
}

void
ARGB_merge(ARGB* bottom, ARGB top) {
	bottom->a = 255;
	double perc = top.a / 255.0;

	bottom->r = (bottom->r * (1.0 - perc)) + (top.r * perc);
	bottom->g = (bottom->g * (1.0 - perc)) + (top.g * perc);
	bottom->b = (bottom->b * (1.0 - perc)) + (top.b * perc);
}

RGBImage
RGBImage_new(u32 width, u32 height) {
	return (RGBImage){
		.width  = width,
		.height = height,
		.img    = malloc(sizeof(ARGB) * width * height)
	};
}

void
RGBImage_free(RGBImage img) {
	free(img.img);
}

void
RGBImage_delete(RGBImage* img) {
	RGBImage_free(*img);
	img->width = img->height = 0;
	img->img = NULL;
}

ARGB*
RGBImage_at(RGBImage img, int row, int col) {
	return img.img + (row % img.height) * img.width + col % img.width;
}

int
ppm6_write(FILE* f, RGBImage img) {
	fprintf(f, "P6\n%d %d\n255\n", img.width, img.height);
	size_t size = img.width * img.height;
	for (size_t i = 0; i < size; ++i) {
		fputc(img.img[i].r, f);
		fputc(img.img[i].g, f);
		fputc(img.img[i].b, f);
	}
	return fflush(f);
}

RGBImage
ppm_read(FILE* f) {
	u32 type, width, height, colors;
	fscanf(f, "P%d\n%d %d\n%d\n", &type, &width, &height, &colors);

	RGBImage img = RGBImage_new(width, height);
	ARGB* pixel = img.img;
	for (size_t i = img.width * img.height; i > 0; --i, ++pixel) {
		if (type == 3) {
			pixel->a = 0xFF;
			fscanf(f, "%d %d %d ", &pixel->r, &pixel->g, &pixel->b);
		}
	}
	return img;
}