Skip to content

Instantly share code, notes, and snippets.

@louisswarren

louisswarren/Makefile

Last active Aug 22, 2020
Embed
What would you like to do?
Tiny library for PPM output
#include <stdio.h>
#include <stdlib.h>
#include "problem.h"
int
main(void)
{
int width = 50;
int height = 20;
int i, j;
size_t psz;
struct problem *p;
if ((psz = problem_size(width, height)) == 0) {
fprintf(stderr, "Invalid image dimensions\n");
exit(1);
} else if ((p = calloc(1, psz)) == NULL) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
problem_init(p, width, height);
for (i = 4; i < 14; ++i) {
for (j = 0; j < 20; ++j)
problem_set(p, j, i, 0xFF00FF);
for (j = 20; j < 35; ++j)
problem_set(p, j, i, 0x00FFFF);
for (j = 35; j < 50; ++j)
problem_set(p, j, i, 0xFFFF00);
}
fwrite(p->raw, p->len, 1, stdout);
return 0;
}
.PHONY: test test-video
test-video: video
./video | mpv --no-correct-pts --fps=30 --scale=oversample -
test: output.png
sxiv $^
output.png: output.ppm
convert $< $@
output.ppm: example
./example > $@
example: example.c problem.o
$(CC) $(CFLAGS) -o $@ $^
video: video.c problem.o
$(CC) $(CFLAGS) -o $@ $^
problem.o: problem.c problem.h
$(CC) -c $(CFLAGS) -o $@ $<
.PHONY: clean
clean:
rm output.* example problem.o
#include <stdint.h>
#include <stdio.h>
#include "problem.h"
#define PPM_HDR_FMT_NONL "P6\n%d %d 255"
#define PPM_HDR_FMT (PPM_HDR_FMT_NONL "\n")
size_t
problem_size(long width, long height)
{
size_t header_len = sizeof(struct problem);
header_len += snprintf(NULL, 0, PPM_HDR_FMT, width, height);
if (width == SIZE_MAX)
return 0;
else if (height > (SIZE_MAX - header_len) / width / 3)
return 0;
return header_len + width * height * 3;
}
void
problem_init(struct problem *p, long width, long height)
{
long i;
p->width = width;
p->height = height;
/* Don't write out the null after the header in case the memory was
* already set (though this could be treated as misuse, I suppose). */
p->len = sprintf(p->raw, PPM_HDR_FMT_NONL, width, height);
p->raw[p->len++] = '\n';
p->image = p->raw + p->len;
p->len += 3 * width * height;
}
void
problem_set(struct problem *p, long x, long y, unsigned long colour)
{
p->image[3 * (p->width * y + x) + 0] = (colour >> 16) & 0xFF;
p->image[3 * (p->width * y + x) + 1] = (colour >> 8) & 0xFF;
p->image[3 * (p->width * y + x) + 2] = colour & 0xFF;
}
#include <stddef.h>
struct problem {
long width;
long height;
char *image;
size_t len;
char raw[];
};
size_t problem_size(long width, long height);
void problem_init(struct problem *p, long width, long height);
void problem_set(struct problem *p, long x, long y, unsigned long colour);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "problem.h"
void render(struct problem *p);
void render_ball(struct problem *p, float x, float y, float r, unsigned long c);
void
render(struct problem *p)
{
static int b = 0;
int i, j;
memset(p->image, 0x11, p->width * p->height * 3);
for (i = p->height / 4; i < p->height / 4 * 3; ++i) {
for (j = 0; j < p->width / 3; ++j)
problem_set(p, (j + b) % p->width, i, 0xFF00FF);
for (j = p->width / 3; j < p->width / 3 * 2; ++j)
problem_set(p, (j + b) % p->width, i, 0x00FFFF);
for (j = p->width / 3 * 2; j < p->width; ++j)
problem_set(p, (j + b) % p->width, i, 0xFFFF00);
}
render_ball(p, (320 + b) % p->width, (240 + b) % p->height, 25, 0xFF8822);
b += 10;
}
void
render_ball(struct problem *p, float x, float y, float r, unsigned long c)
{
int i, j;
int min_i = y - r < 0 ? 0 : y - r;
int min_j = x - r < 0 ? 0 : x - r;
int max_i = y + r + 1 <= p->height ? y + r + 1 : p->height;
int max_j = x + r + 1 <= p->width ? x + r + 1 : p->width;
for (i = min_i; i < max_i; ++i)
for (j = min_j; j < max_j; ++j)
if ((x - (float) j) * (x - (float) j) + (y - (float) i) * (y - (float) i) < r * r)
problem_set(p, j, i, c);
}
int
main(void)
{
int width = 640;
int height = 480;
size_t psz;
struct problem *p;
if ((psz = problem_size(width, height)) == 0) {
fprintf(stderr, "Invalid image dimensions\n");
exit(1);
} else if ((p = calloc(1, psz)) == NULL) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
problem_init(p, width, height);
do {
render(p);
} while (fwrite(p->raw, p->len, 1, stdout));
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "problem.h"
void render(struct problem *p);
void plot(struct problem *p, float x, float y, float r, unsigned long c);
void advance_colour(unsigned long *c);
void
render(struct problem *p)
{
static int j = 0;
static unsigned long c = 0;
int i, k;
double x, y;
float g = 0.01;
for (k = 0; k < 1.0 / g; ++k) {
x = 2 * M_PI * (g * k + j) / p->width * 4;
y = sin(x);
i = (1 - y) * p->height / 2;
i = i < 0 ? 0 : i;
i = i >= p->height ? p->height : i;
plot(p, j, i, 2, c);
advance_colour(&c);
if (c > 0xFFFFFF)
c = 0;
fprintf(stderr, "Colour: %d\t%d\t%d\n", c >> 32, (c >> 16) & 0xFF, (c >> 32) & 0xFF);
}
j = (j + 1) % p->width;
if (!j) {
memset(p->image, 0xFF, p->width * p->height * 3);
}
}
void
advance_colour(unsigned long *c)
{
if ((*c >> 32) % 2 == (*c >> 16) % 2) {
if (*c & 0xFF == 0xFF) {
if ((*c >> 16) & 0xFF == 0xFF)
*c += 0x10000;
else
*c += 0x100;
} else {
*c += 0x1;
}
} else {
if (*c & 0xFF == 0) {
if ((*c >> 16) & 0xFF == 0)
*c += 0x10000;
else
*c -= 0x100;
} else {
*c -= 0x1;
}
}
}
void
plot(struct problem *p, float x, float y, float r, unsigned long c)
{
int i, j;
int min_i = y - r < 0 ? 0 : y - r;
int min_j = x - r < 0 ? 0 : x - r;
int max_i = y + r + 1 <= p->height ? y + r + 1 : p->height;
int max_j = x + r + 1 <= p->width ? x + r + 1 : p->width;
for (i = min_i; i < max_i; ++i)
for (j = min_j; j < max_j; ++j)
if ((x - (float) j) * (x - (float) j) + (y - (float) i) * (y - (float) i) < r * r)
problem_set(p, j, i, c);
}
int
main(void)
{
int width = 640;
int height = 480;
int k;
size_t psz;
struct problem *p;
if ((psz = problem_size(width, height)) == 0) {
fprintf(stderr, "Invalid image dimensions\n");
exit(1);
} else if ((p = calloc(1, psz)) == NULL) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
problem_init(p, width, height);
memset(p->image, 0xFF, p->width * p->height * 3);
do {
for (k = 0; k < 10; ++k)
render(p);
} while (fwrite(p->raw, p->len, 1, stdout));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.