Skip to content

Commit c25c793

Browse files
author
Zahl
committed
add png color extractor by Donkey Kong; tweaked the way some blocks are drawn; optimized the optimizer (about 40% faster)
1 parent 7893589 commit c25c793

13 files changed

+15
-3486
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ CFLAGS=-O2 -c -Wall -fomit-frame-pointer -pedantic -DWITHPNG -I/usr/local/includ
44
LDFLAGS=-O2 -lz -lpng -fomit-frame-pointer -L/usr/local/lib
55
DCFLAGS=-g -O0 -c -Wall -D_DEBUG -DWITHPNG -I/usr/local/include
66
DLDFLAGS=-g -O0 -lz -lpng -L/usr/local/lib
7-
SOURCES=main.cpp helper.cpp nbt.cpp draw.cpp colors.cpp worldloader.cpp filesystem.cpp globals.cpp draw_png.cpp
7+
SOURCES=main.cpp helper.cpp nbt.cpp draw.cpp colors.cpp worldloader.cpp filesystem.cpp globals.cpp draw_png.cpp extractcolors.cpp
88
OBJECTS=$(SOURCES:.cpp=.default.o)
99
OBJECTS_TURBO=$(SOURCES:.cpp=.turbo.o)
1010
DOBJECTS=$(SOURCES:.cpp=.debug.o)

colors.cpp

+1-176
Original file line numberDiff line numberDiff line change
@@ -1,176 +1 @@
1-
#include "colors.h"
2-
#include <cstring>
3-
#include <cstdio>
4-
#include <cstdlib>
5-
6-
#define SETCOLOR(col,r,g,b,a) do { \
7-
colors[col][BLUE] = colors[col][PBLUE] = b; \
8-
colors[col][GREEN] = colors[col][PGREEN] = g; \
9-
colors[col][RED] = colors[col][PRED] = r; \
10-
colors[col][ALPHA] = colors[col][PALPHA] = a; \
11-
colors[col][BRIGHTNESS] = (uint8_t)sqrt( \
12-
double(r * r) * .236 + \
13-
double(g * g) * .601 + \
14-
double(b * b) * .163); \
15-
} while (false)
16-
17-
#define SETCOLORNOISE(col,r,g,b,a,n) do { \
18-
colors[col][BLUE] = colors[col][PBLUE] = b; \
19-
colors[col][GREEN] = colors[col][PGREEN] = g; \
20-
colors[col][RED] = colors[col][PRED] = r; \
21-
colors[col][ALPHA] = colors[col][PALPHA] = a; \
22-
colors[col][NOISE] = n; \
23-
colors[col][BRIGHTNESS] = (uint8_t)sqrt( \
24-
double(r * r) * .236 + \
25-
double(g * g) * .601 + \
26-
double(b * b) * .163); \
27-
} while (false)
28-
29-
// See header for description
30-
uint8_t colors[256][16];
31-
32-
33-
void loadColors()
34-
{ // Colors are mostly the same as in Cartograph
35-
memset(colors, 0, sizeof colors);
36-
SETCOLOR(AIR, 255,255,255,0);
37-
SETCOLORNOISE(STONE, 128,128,128,255, 16);
38-
SETCOLORNOISE(GRASS, 117,176,73,255, 14);
39-
SETCOLORNOISE(DIRT, 134,96,67,255, 22);
40-
SETCOLORNOISE(COBBLESTONE, 115,115,115,255, 26);
41-
SETCOLORNOISE(WOOD, 157,128,79,255, 11);
42-
SETCOLOR(6, 120,120,120,0);
43-
SETCOLOR(7, 84,84,84,255);
44-
SETCOLOR(WATER, 38,92,225,128);
45-
SETCOLOR(STAT_WATER, 38,92,225,128);
46-
SETCOLOR(10, 255,90,0,255);
47-
SETCOLOR(11, 255,90,0,255);
48-
SETCOLORNOISE(SAND, 220,212,160,255, 14);
49-
SETCOLORNOISE(GRAVEL, 136,126,126,255, 24);
50-
SETCOLOR(14, 143,140,125,255);
51-
SETCOLOR(15, 136,130,127,255);
52-
SETCOLOR(16, 115,115,115,255);
53-
SETCOLOR(LOG, 102,81,51,255);
54-
SETCOLORNOISE(LEAVES, 64,168,40,180, 12);
55-
SETCOLOR(20, 255,255,255,64); //glass
56-
//SETCOLOR(21, 222,50,50,255);
57-
//SETCOLOR(22, 222,136,50,255);
58-
//SETCOLOR(23, 222,222,50,255);
59-
//SETCOLOR(24, 136,222,50,255);
60-
//SETCOLOR(25, 50,222,50,255);
61-
//SETCOLOR(26, 50,222,136,255);
62-
//SETCOLOR(27, 50,222,222,255);
63-
//SETCOLOR(28, 104,163,222,255);
64-
//SETCOLOR(29, 120,120,222,255);
65-
//SETCOLOR(30, 136,50,222,255);
66-
//SETCOLOR(31, 174,74,222,255);
67-
//SETCOLOR(32, 222,50,222,255);
68-
//SETCOLOR(33, 222,50,136,255);
69-
//SETCOLOR(34, 77,77,77,255);
70-
SETCOLOR(35, 222,222,222,255); //Color(143,143,143,255);
71-
//SETCOLOR(36, 222,222,222,255);
72-
SETCOLOR(FLOWERR, 255,0,0,254); // Not fully opaque to prevent culling on this one
73-
SETCOLOR(FLOWERY, 255,255,0,254); // Not fully opaque to prevent culling on this one
74-
SETCOLOR(MUSHROOMB, 128,100,0,254); // Not fully opaque to prevent culling on this one
75-
SETCOLOR(MUSHROOMR, 140,12,12,254); // Not fully opaque to prevent culling on this one
76-
SETCOLOR(41, 231,165,45,255);
77-
SETCOLOR(42, 191,191,191,255);
78-
SETCOLOR(DOUBLESTEP, 200,200,200,255);
79-
SETCOLOR(STEP, 200,200,200,254); // Not fully opaque to prevent culling on this one
80-
SETCOLOR(45, 170,86,62,255);
81-
SETCOLOR(46, 160,83,65,255);
82-
SETCOLOR(48, 115,115,115,255);
83-
SETCOLOR(49, 26,11,43,255);
84-
SETCOLOR(TORCH, 245,220,50,200);
85-
SETCOLOR(FIRE, 255,170,30,200);
86-
SETCOLOR(52, 245,220,50,255); // unnecessary afaik
87-
SETCOLOR(53, 157,128,79,255);
88-
SETCOLOR(54, 125,91,38,255);
89-
SETCOLOR(55, 245,220,50,255); // unnecessary afaik
90-
SETCOLOR(56, 129,140,143,255);
91-
SETCOLOR(57, 45,166,152,255);
92-
SETCOLOR(58, 114,88,56,255);
93-
SETCOLOR(59, 146,192,0,255);
94-
SETCOLOR(60, 95,58,30,255);
95-
SETCOLOR(61, 96,96,96,255);
96-
SETCOLOR(62, 96,96,96,255);
97-
SETCOLOR(63, 111,91,54,255);
98-
SETCOLOR(64, 136,109,67,255);
99-
SETCOLOR(65, 181,140,64,32);
100-
SETCOLOR(66, 150,134,102,180);
101-
SETCOLOR(67, 115,115,115,255);
102-
SETCOLOR(71, 191,191,191,255);
103-
SETCOLOR(73, 131,107,107,255);
104-
SETCOLOR(74, 131,107,107,255);
105-
SETCOLOR(REDTORCH_OFF, 181,100,44,254);
106-
SETCOLOR(REDTORCH_ON, 255,0,0,254);
107-
SETCOLOR(SNOW, 245,246,245,254); // Not fully opaque to prevent culling on this one
108-
SETCOLOR(79, 83,113,163,55);
109-
SETCOLOR(80, 250,250,250,255);
110-
SETCOLOR(81, 25,120,25,255);
111-
SETCOLOR(82, 151,157,169,255);
112-
SETCOLOR(83, 183,234,150,255);
113-
SETCOLOR(84, 100,67,50,255);
114-
SETCOLOR(FENCE, 137,112,65,225); // Not fully opaque to prevent culling on this one
115-
}
116-
117-
118-
bool loadColorsFromFile(const char* file)
119-
{
120-
FILE *f = fopen(file, "r");
121-
if (f == NULL) return false;
122-
while (!feof(f)) {
123-
char buffer[500];
124-
if (fgets(buffer, 500, f) == NULL) break;
125-
char *ptr = buffer;
126-
while (*ptr == ' ' || *ptr == '\t') ++ptr;
127-
if (*ptr == '\0' || *ptr == '#') continue; // This is a comment or empty line, skip
128-
int blockid = atoi(ptr);
129-
if (blockid < 1 || blockid > 255) {
130-
printf("Skipping invalid blockid %d in colors file\n", blockid);
131-
continue;
132-
}
133-
while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') ++ptr;
134-
uint8_t vals[5];
135-
bool valid = true;
136-
for (int i = 0; i < 5; ++i) {
137-
while (*ptr == ' ' || *ptr == '\t') ++ptr;
138-
if (*ptr == '\0') {
139-
printf("Too few arguments for block %d, ignoring line.\n", blockid);
140-
valid = false;
141-
break;
142-
}
143-
if (i == 0) vals[RED] = uint8_t(atoi(ptr));
144-
else if (i == 2) vals[BLUE] = uint8_t(atoi(ptr));
145-
else vals[i] = uint8_t(atoi(ptr));
146-
while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') ++ptr;
147-
}
148-
if (!valid) continue;
149-
memcpy(colors[blockid], vals, 5);
150-
colors[blockid][PRED] = colors[blockid][RED];
151-
colors[blockid][PGREEN] = colors[blockid][GREEN];
152-
colors[blockid][PBLUE] = colors[blockid][BLUE];
153-
colors[blockid][PALPHA] = colors[blockid][ALPHA];
154-
colors[blockid][BRIGHTNESS] = GETBRIGHTNESS(colors[blockid]);
155-
}
156-
fclose(f);
157-
return true;
158-
}
159-
160-
bool dumpColorsToFile(const char* file)
161-
{
162-
FILE *f = fopen(file, "w");
163-
if (f == NULL) return false;
164-
fprintf(f, "# For Block IDs see http://minecraftwiki.net/wiki/Data_values\n"
165-
"# Note that noise or alpha (or both) do not work for a few blocks like snow, torches, fences, steps, ...\n"
166-
"# Actually, you should leave alpha at <255 for those blocks to prevent black artifacts\n\n");
167-
for (size_t i = 1; i < 256; ++i) {
168-
uint8_t *c = colors[i];
169-
if (i % 15 == 1) {
170-
fprintf(f, "#ID R G B A Noise\n");
171-
}
172-
fprintf(f, "%3d %3d %3d %3d %3d %3d\n", int(i), int(c[2]), int(c[1]), int(c[0]), int(c[3]), int(c[4]));
173-
}
174-
fclose(f);
175-
return true;
176-
}
1+
#include "colors.h"#include "extractcolors.h"#include <cstring>#include <cstdio>#include <cstdlib>#include <png.h>#define SETCOLOR(col,r,g,b,a) do { \ colors[col][BLUE] = colors[col][PBLUE] = b; \ colors[col][GREEN] = colors[col][PGREEN] = g; \ colors[col][RED] = colors[col][PRED] = r; \ colors[col][ALPHA] = colors[col][PALPHA] = a; \ colors[col][BRIGHTNESS] = (uint8_t)sqrt( \ double(r * r) * .236 + \ double(g * g) * .601 + \ double(b * b) * .163); \ } while (false)#define SETCOLORNOISE(col,r,g,b,a,n) do { \ colors[col][BLUE] = colors[col][PBLUE] = b; \ colors[col][GREEN] = colors[col][PGREEN] = g; \ colors[col][RED] = colors[col][PRED] = r; \ colors[col][ALPHA] = colors[col][PALPHA] = a; \ colors[col][NOISE] = n; \ colors[col][BRIGHTNESS] = (uint8_t)sqrt( \ double(r * r) * .236 + \ double(g * g) * .601 + \ double(b * b) * .163); \ } while (false)// See header for descriptionuint8_t colors[256][16];void loadColors(){ // Colors are mostly the same as in Cartograph memset(colors, 0, sizeof colors); SETCOLOR(AIR, 255,255,255,0); SETCOLORNOISE(STONE, 128,128,128,255, 16); SETCOLORNOISE(GRASS, 117,176,73,255, 14); SETCOLORNOISE(DIRT, 134,96,67,255, 22); SETCOLORNOISE(COBBLESTONE, 115,115,115,255, 26); SETCOLORNOISE(WOOD, 157,128,79,255, 11); SETCOLOR(6, 120,120,120,0); SETCOLOR(7, 84,84,84,255); SETCOLOR(WATER, 38,92,225,41); SETCOLOR(STAT_WATER, 38,92,225,41); SETCOLOR(10, 255,90,0,255); SETCOLOR(11, 255,90,0,255); SETCOLORNOISE(SAND, 220,212,160,255, 14); SETCOLORNOISE(GRAVEL, 136,126,126,255, 24); SETCOLOR(14, 143,140,125,255); SETCOLOR(15, 136,130,127,255); SETCOLOR(16, 115,115,115,255); SETCOLOR(LOG, 102,81,51,255); SETCOLORNOISE(LEAVES, 64,168,40,180, 12); SETCOLOR(20, 255,255,255,64); //glass //SETCOLOR(21, 222,50,50,255); //SETCOLOR(22, 222,136,50,255); //SETCOLOR(23, 222,222,50,255); //SETCOLOR(24, 136,222,50,255); //SETCOLOR(25, 50,222,50,255); //SETCOLOR(26, 50,222,136,255); //SETCOLOR(27, 50,222,222,255); //SETCOLOR(28, 104,163,222,255); //SETCOLOR(29, 120,120,222,255); //SETCOLOR(30, 136,50,222,255); //SETCOLOR(31, 174,74,222,255); //SETCOLOR(32, 222,50,222,255); //SETCOLOR(33, 222,50,136,255); //SETCOLOR(34, 77,77,77,255); SETCOLOR(35, 222,222,222,255); //Color(143,143,143,255); //SETCOLOR(36, 222,222,222,255); SETCOLOR(FLOWERR, 255,0,0,254); // Not fully opaque to prevent culling on this one SETCOLOR(FLOWERY, 255,255,0,254); // Not fully opaque to prevent culling on this one SETCOLOR(MUSHROOMB, 128,100,0,254); // Not fully opaque to prevent culling on this one SETCOLOR(MUSHROOMR, 140,12,12,254); // Not fully opaque to prevent culling on this one SETCOLOR(41, 231,165,45,255); SETCOLOR(42, 191,191,191,255); SETCOLOR(DOUBLESTEP, 200,200,200,255); SETCOLOR(STEP, 200,200,200,254); // Not fully opaque to prevent culling on this one SETCOLOR(45, 170,86,62,255); SETCOLOR(46, 160,83,65,255); SETCOLOR(48, 115,115,115,255); SETCOLOR(49, 26,11,43,255); SETCOLOR(TORCH, 245,220,50,200); SETCOLOR(FIRE, 255,170,30,200); SETCOLOR(52, 245,220,50,255); // unnecessary afaik SETCOLOR(53, 157,128,79,255); SETCOLOR(54, 125,91,38,255); SETCOLOR(55, 245,220,50,255); // unnecessary afaik SETCOLOR(56, 129,140,143,255); SETCOLOR(57, 45,166,152,255); SETCOLOR(58, 114,88,56,255); SETCOLOR(59, 146,192,0,255); SETCOLOR(60, 95,58,30,255); SETCOLOR(61, 96,96,96,255); SETCOLOR(62, 96,96,96,255); SETCOLOR(63, 111,91,54,255); SETCOLOR(64, 136,109,67,255); SETCOLOR(65, 181,140,64,32); SETCOLOR(66, 150,134,102,180); SETCOLOR(67, 115,115,115,255); SETCOLOR(71, 191,191,191,255); SETCOLOR(73, 131,107,107,255); SETCOLOR(74, 131,107,107,255); SETCOLOR(REDTORCH_OFF, 181,100,44,254); SETCOLOR(REDTORCH_ON, 255,0,0,254); SETCOLOR(SNOW, 245,246,245,254); // Not fully opaque to prevent culling on this one SETCOLOR(79, 83,113,163,55); SETCOLOR(80, 250,250,250,255); SETCOLOR(81, 25,120,25,255); SETCOLOR(82, 151,157,169,255); SETCOLOR(83, 183,234,150,255); SETCOLOR(84, 100,67,50,255); SETCOLOR(FENCE, 137,112,65,225); // Not fully opaque to prevent culling on this one}bool loadColorsFromFile(const char *file){ FILE *f = fopen(file, "r"); if (f == NULL) { return false; } while (!feof(f)) { char buffer[500]; if (fgets(buffer, 500, f) == NULL) { break; } char *ptr = buffer; while (*ptr == ' ' || *ptr == '\t') { ++ptr; } if (*ptr == '\0' || *ptr == '#') { continue; // This is a comment or empty line, skip } int blockid = atoi(ptr); if (blockid < 1 || blockid > 255) { printf("Skipping invalid blockid %d in colors file\n", blockid); continue; } while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') { ++ptr; } uint8_t vals[5]; bool valid = true; for (int i = 0; i < 5; ++i) { while (*ptr == ' ' || *ptr == '\t') { ++ptr; } if (*ptr == '\0') { printf("Too few arguments for block %d, ignoring line.\n", blockid); valid = false; break; } if (i == 0) { vals[RED] = clamp(atoi(ptr)); } else if (i == 2) { vals[BLUE] = clamp(atoi(ptr)); } else { vals[i] = clamp(atoi(ptr)); } while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') { ++ptr; } } if (!valid) { continue; } memcpy(colors[blockid], vals, 5); colors[blockid][PRED] = colors[blockid][RED]; colors[blockid][PGREEN] = colors[blockid][GREEN]; colors[blockid][PBLUE] = colors[blockid][BLUE]; colors[blockid][PALPHA] = colors[blockid][ALPHA]; colors[blockid][BRIGHTNESS] = GETBRIGHTNESS(colors[blockid]); } fclose(f); return true;}bool dumpColorsToFile(const char *file){ FILE *f = fopen(file, "w"); if (f == NULL) { return false; } fprintf(f, "# For Block IDs see http://minecraftwiki.net/wiki/Data_values\n" "# Note that noise or alpha (or both) do not work for a few blocks like snow, torches, fences, steps, ...\n" "# Actually, if you see any block has an alpha value of 254 you should leave it that way to prevent black artifacts\n\n"); for (size_t i = 1; i < 256; ++i) { uint8_t *c = colors[i]; if (i % 15 == 1) { fprintf(f, "#ID R G B A Noise\n"); } fprintf(f, "%3d %3d %3d %3d %3d %3d\n", int(i), int(c[2]), int(c[1]), int(c[0]), int(c[3]), int(c[4])); } fclose(f); return true;}bool extractColors(const char* file){ // Open PNG file FILE* fh = fopen(file, "rb"); if (fh == NULL) return false; png_byte header[8]; // Check header if (fread(header, 1, 8, fh) != 8 || png_sig_cmp(header, 0, 8)) { // Not a PNG file fclose(fh); return false; } // Set up libpng to read file png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop pngInfo = NULL; if (pngPtr == NULL || setjmp(png_jmpbuf(pngPtr))) { png_destroy_read_struct(&pngPtr, &pngInfo, NULL); fclose(fh); return false; } pngInfo = png_create_info_struct(pngPtr); png_init_io(pngPtr, fh); png_set_sig_bytes(pngPtr, 8); png_read_info(pngPtr, pngInfo); png_uint_32 width, height; int bpc, type, interlace, comp, filter; // Check image format (square, RGBA) png_uint_32 ret = png_get_IHDR(pngPtr, pngInfo, &width, &height, &bpc, &type, &interlace, &comp, &filter); if (ret == 0 || width != height || (width / 8) * 8 != width || bpc != 8 || type != PNG_COLOR_TYPE_RGB_ALPHA) { png_destroy_read_struct(&pngPtr, &pngInfo, NULL); fclose(fh); } // Alloc mem uint8_t *imgData = new uint8_t[width * height * 4], **rows = new uint8_t*[height]; for (png_uint_32 i = 0; i < height; ++i) { rows[i] = imgData + i * width * 4; } png_read_image(pngPtr, rows); png_destroy_read_struct(&pngPtr, &pngInfo, NULL); for (int i = 0; i < 86; i++) { if (i == TORCH) continue; // Keep those yellow for now int r, g, b, a, n; // i i s g t u o l v n if (getTileRGBA(imgData, width / 16, i, r, g, b, a, n)) { const bool flag = (colors[i][ALPHA] == 254); if (i == FENCE) { r = clamp(r + 10); g = clamp(g + 10); b = clamp(b + 10); } SETCOLORNOISE(i, r, g, b, a, n); if (flag) colors[i][ALPHA] = colors[i][PALPHA] = 254; // If you don't like this, dump texture pack to txt file and modify that one } } delete[] rows; delete[] imgData; return true;}

colors.h

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// Byte order see below. Colors aligned to word boundaries for some speedup
1313
// Brightness is precalculated to speed up calculations later
1414
// Colors are stored twice since BMP and PNG need them in different order
15+
// Noise is supposed to look normal if -noise 10 is given
1516
extern uint8_t colors[256][16];
1617
#define BLUE 0
1718
#define GREEN 1
@@ -27,6 +28,7 @@ extern uint8_t colors[256][16];
2728
void loadColors();
2829
bool loadColorsFromFile(const char* file);
2930
bool dumpColorsToFile(const char* file);
31+
bool extractColors(const char* file);
3032

3133
#define AIR 0
3234
#define STONE 1

0 commit comments

Comments
 (0)