proclib/tools/tobmp.c

151 lines
4.0 KiB
C

/* ================================================================
Copyright (C) 2014 kts of kettek
This file is part of proclib. Some rights reserved. See ../src/COPYING.LESSER
================================================================ */
#include <ktkMap.h>
#include <ktk_parse.h>
#include <ktkProgram.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("usage: %s structures_file structure scale_multiplier [scale_multiplier_y]\n e.g., \"%s structs/smile.txt start 4\n would generate: smile.bmp at 4 times zoom\n", argv[0], argv[0]);
return 0;
}
int scale_x = 1;
int scale_y = 1;
if (argc >= 4) {
scale_x = atoi(argv[3]);
scale_y = scale_x;
}
if (argc >= 5) {
scale_y = atoi(argv[4]);
}
int a_e = strlen(argv[1]+1);
int a_i = a_e;
while(a_i > 0) {
if (argv[1][a_i] == '.') {
a_i--;
break;
}
a_i--;
}
a_e = a_i;
while(a_i > 0) {
if (argv[1][a_i] == '/') {
a_i++;
break;
}
a_i--;
}
int a_s = a_i;
int a_b = a_e - a_s + 1;
a_i = a_b;
char file_name[(5+a_b)*sizeof(char)];
memcpy(&file_name, argv[1]+a_s, a_b*sizeof(char));
file_name[a_i++] = '.';
file_name[a_i++] = 'b';
file_name[a_i++] = 'm';
file_name[a_i++] = 'p';
file_name[a_i++] = '\0';
ktk_randomizeSeed();
struct ktkProgram my_program = ktk_PROGRAM_DEFAULT;
struct ktkLive my_live = ktk_LIVE_DEFAULT;
struct ktkLive my_live_2 = ktk_LIVE_DEFAULT;
struct ktkMap my_map = ktk_MAP_DEFAULT;
my_map.flags |= ktk_MAP_RESIZE;
if (ktk_parseSFile(&my_program, argv[1]) == 1) {
printf("could open structures file \"%s\"!\n", argv[1]);
return 1;
}
ktk_buildStructure(&my_program, &my_live, ktk_getStructure(&my_program, argv[2]), &my_map);
ktk_linkStructures(&my_program, &my_live, &my_live_2, &my_map);
// *** begin BMP writing
FILE *file = fopen(file_name, "w");
if (file == NULL) {
printf("couldn't open \"%s\" for writing!", file_name);
return 1;
}
int w = my_map.w * scale_x;
int h = my_map.h * scale_y;
size_t pad_size = (4 - 3 * w % 4) % 4;
size_t size = w*h*3 + h*pad_size;
size_t total_size = size + (14*sizeof(unsigned char)) + (40*sizeof(unsigned char));
unsigned char header[14] = {
'B', 'M',
(unsigned char)total_size, (unsigned char)total_size>>8, (unsigned char)total_size>>16, (unsigned char)total_size>>24,
0, 0,
0, 0,
40+14, 0, 0, 0
};
unsigned char info[40] = {
40, 0, 0, 0,
(unsigned char)w, (unsigned char)(w>>8), (unsigned char)(w>>16), (unsigned char)(w>>24),
(unsigned char)h, (unsigned char)(h>>8), (unsigned char)(h>>16), (unsigned char)(h>>24),
1, 0,
24, 0,
0, 0, 0, 0,
(unsigned char)size, (unsigned char)(size>>8), (unsigned char)(size>>16), (unsigned char)(size>>24),
0x13, 0x0B, 0, 0,
0x13, 0x0B, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
fwrite(&header, sizeof(header), 1, file);
fwrite(&info, sizeof(info), 1, file);
unsigned char padding[3] = { 0, 0, 0 };
int x, y;
for (y = h; y > 0; y--) {
for (x = 0; x < w; x++) {
long color;
int c_x, c_y;
c_x = x / scale_x;
c_y = y / scale_y;
if (my_map.cell[c_x][c_y].flags & ktk_CELL_EMPTY) {
color = 128.0f;
} else {
color = lround(32.0f + my_map.cell[c_x][c_y].id_1 * 32.0f);
}
if (color < 0) color = 0;
if (color > 255) color = 255;
long red = 0, green = 0, blue = 0;
if ((color % 3) == 0) {
red = color;
blue = color/2;
green = color/4;
} else if ((color %3) == 1) {
green = color;
red = color/2;
blue = color/4;
} else {
blue = color;
green = color/2;
red = color/4;
}
unsigned char pixel[3];
pixel[0] = blue;
pixel[1] = green;
pixel[2] = red;
fwrite((char*)pixel, 3*sizeof(unsigned char), 1, file);
}
fwrite((char*)padding, pad_size, 1, file);
}
fclose(file);
ktk_deleteMap(&my_map);
ktk_freeProgram(&my_program);
return 0;
}