MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / ReadHeightmapPNGImageData

Function ReadHeightmapPNGImageData

src/heightmap.cpp:82–134  ·  view source on GitHub ↗

* The PNG Heightmap loader. */

Source from the content-addressed store, hash-verified

80 * The PNG Heightmap loader.
81 */
82static void ReadHeightmapPNGImageData(std::span<uint8_t> map, png_structp png_ptr, png_infop info_ptr)
83{
84 uint x, y;
85 uint8_t gray_palette[256];
86 png_bytep *row_pointers = nullptr;
87 bool has_palette = png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE;
88 uint channels = png_get_channels(png_ptr, info_ptr);
89
90 /* Get palette and convert it to greyscale */
91 if (has_palette) {
92 int i;
93 int palette_size;
94 png_color *palette;
95 bool all_gray = true;
96
97 png_get_PLTE(png_ptr, info_ptr, &palette, &palette_size);
98 for (i = 0; i < palette_size && (palette_size != 16 || all_gray); i++) {
99 all_gray &= palette[i].red == palette[i].green && palette[i].red == palette[i].blue;
100 gray_palette[i] = RGBToGreyscale(palette[i].red, palette[i].green, palette[i].blue);
101 }
102
103 /**
104 * For a non-gray palette of size 16 we assume that
105 * the order of the palette determines the height;
106 * the first entry is the sea (level 0), the second one
107 * level 1, etc.
108 */
109 if (palette_size == 16 && !all_gray) {
110 for (i = 0; i < palette_size; i++) {
111 gray_palette[i] = 256 * i / palette_size;
112 }
113 }
114 }
115
116 row_pointers = png_get_rows(png_ptr, info_ptr);
117
118 /* Read the raw image data and convert in 8-bit greyscale */
119 for (x = 0; x < png_get_image_width(png_ptr, info_ptr); x++) {
120 for (y = 0; y < png_get_image_height(png_ptr, info_ptr); y++) {
121 uint8_t *pixel = &map[y * png_get_image_width(png_ptr, info_ptr) + x];
122 uint x_offset = x * channels;
123
124 if (has_palette) {
125 *pixel = gray_palette[row_pointers[y][x_offset]];
126 } else if (channels == 3) {
127 *pixel = RGBToGreyscale(row_pointers[y][x_offset + 0],
128 row_pointers[y][x_offset + 1], row_pointers[y][x_offset + 2]);
129 } else {
130 *pixel = row_pointers[y][x_offset];
131 }
132 }
133 }
134}
135
136/**
137 * Reads the heightmap and/or size of the heightmap from a PNG file.

Callers 1

ReadHeightmapPNGFunction · 0.85

Calls 1

RGBToGreyscaleFunction · 0.85

Tested by

no test coverage detected