Files
margen/src/generator.c
T
2025-09-24 15:37:50 +02:00

115 lines
3.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "args.h"
#include "bmp.h"
#include "config.h"
#include "rand.h"
#define BMP_COLOR_DEPTH 3
Parameters global_params;
float slope;
unsigned char color_depth;
unsigned int line_width;
unsigned char *last_line;
unsigned char *current_line;
unsigned char generate_pixel(unsigned char depth, unsigned char top_pixel,
unsigned char left_pixel) {
short k = rand_uchar(global_params.var[depth] + 1);
short v = (rand_uchar(2) == 0 ? k : -k) + (left_pixel)*slope +
(top_pixel) * (1.0 - slope);
return (unsigned char)(v < 0 ? 0 : (v > 255 ? (unsigned char)255 : v));
}
void generate_line() {
unsigned int i;
for (i = 0; i < line_width; i++) {
last_line[i] = current_line[i];
}
for (i = 0; i < line_width; i++) {
if (i < color_depth) {
current_line[i] = generate_pixel(i % color_depth, last_line[i],
global_params.start[i % color_depth]);
} else {
current_line[i] = generate_pixel(i % color_depth, last_line[i],
current_line[i - color_depth]);
}
}
}
void generate_bmp_line(unsigned short y, unsigned char *data_buffer,
unsigned int len) {
unsigned int i;
unsigned int x;
if (y % global_params.size == 0) {
generate_line();
}
for (i = 0; i < len; i++) {
x = i / (BMP_COLOR_DEPTH * global_params.size);
data_buffer[(global_params.rotation / 2) == 1 ? i : (len - i - 1)] =
current_line[x * color_depth + (i % color_depth)];
}
}
void debug_parameters(Parameters params) {
if (!params.quiet) {
printf(" output %s\n", params.file_path);
printf(" seed %ld\n", params.seed);
printf(" width %d\n", params.width);
printf(" height %d\n", params.height);
printf(" pixel %d\n", params.size);
printf(" slope %d\n", params.slope);
if (params.monochrome) {
printf(" color %u\n", params.start[0]);
printf(" var. %u\n", params.var[0]);
} else {
printf(" color %u,%u,%u\n", params.start[0], params.start[1],
params.start[2]);
printf(" var. %u,%u,%u\n", params.var[0], params.var[1],
params.var[2]);
}
printf(" rot. %d\n", params.rotation);
}
}
void init(Parameters params) {
global_params = params;
slope = ((float)params.slope) / 255.0;
color_depth = params.monochrome ? 1 : 3;
debug_parameters(params);
line_width = ((params.width / params.size) + 1) * color_depth;
last_line = (unsigned char *)malloc(line_width);
current_line = (unsigned char *)malloc(line_width);
unsigned int i = 0;
for (i = 0; i < line_width; i++) {
current_line[i] = params.start[i % color_depth];
}
set_seed(params.seed);
}
void clean() {
free(last_line);
free(current_line);
}
void print_time(Parameters params, clock_t start) {
if (!params.quiet) {
clock_t now = clock();
printf("time: %.3fs\n", (float)(now - start) / CLOCKS_PER_SEC);
}
}
void generate(Parameters params) {
if (!params.quiet) {
puts(PACKAGE " " VERSION);
}
clock_t start = clock();
init(params);
bmp_generate(params.width, params.height, BMP_COLOR_DEPTH,
params.rotation % 2 == 1, params.file_path, generate_bmp_line);
clean();
print_time(params, start);
}