115 lines
3.3 KiB
C
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);
|
|
} |