21 #include "table/strings.h"
35 static const uint MAX_HEIGHTMAP_SIZE_PIXELS = 256 << 20;
41 static_assert(MAX_HEIGHTMAP_SIZE_PIXELS < UINT32_MAX / 8);
54 return (uint64)width * height <= MAX_HEIGHTMAP_SIZE_PIXELS &&
67 return ((red * 19595) + (green * 38470) + (blue * 7471)) / 65536;
81 byte gray_palette[256];
82 png_bytep *row_pointers =
nullptr;
83 bool has_palette = png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE;
84 uint channels = png_get_channels(png_ptr, info_ptr);
93 png_get_PLTE(png_ptr, info_ptr, &palette, &palette_size);
94 for (i = 0; i < palette_size && (palette_size != 16 || all_gray); i++) {
95 all_gray &= palette[i].red == palette[i].green && palette[i].red == palette[i].blue;
96 gray_palette[i] =
RGBToGrayscale(palette[i].red, palette[i].green, palette[i].blue);
105 if (palette_size == 16 && !all_gray) {
106 for (i = 0; i < palette_size; i++) {
107 gray_palette[i] = 256 * i / palette_size;
112 row_pointers = png_get_rows(png_ptr, info_ptr);
115 for (x = 0; x < png_get_image_width(png_ptr, info_ptr); x++) {
116 for (y = 0; y < png_get_image_height(png_ptr, info_ptr); y++) {
117 byte *pixel = &map[y * png_get_image_width(png_ptr, info_ptr) + x];
118 uint x_offset = x * channels;
121 *pixel = gray_palette[row_pointers[y][x_offset]];
122 }
else if (channels == 3) {
124 row_pointers[y][x_offset + 1], row_pointers[y][x_offset + 2]);
126 *pixel = row_pointers[y][x_offset];
140 png_structp png_ptr =
nullptr;
141 png_infop info_ptr =
nullptr;
149 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
nullptr,
nullptr,
nullptr);
150 if (png_ptr ==
nullptr) {
156 info_ptr = png_create_info_struct(png_ptr);
157 if (info_ptr ==
nullptr || setjmp(png_jmpbuf(png_ptr))) {
160 png_destroy_read_struct(&png_ptr, &info_ptr,
nullptr);
164 png_init_io(png_ptr, fp);
168 png_set_packing(png_ptr);
169 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_STRIP_16,
nullptr);
173 if ((png_get_channels(png_ptr, info_ptr) != 1) && (png_get_channels(png_ptr, info_ptr) != 3) && (png_get_bit_depth(png_ptr, info_ptr) != 8)) {
176 png_destroy_read_struct(&png_ptr, &info_ptr,
nullptr);
180 uint width = png_get_image_width(png_ptr, info_ptr);
181 uint height = png_get_image_height(png_ptr, info_ptr);
186 png_destroy_read_struct(&png_ptr, &info_ptr,
nullptr);
190 if (map !=
nullptr) {
191 *map = MallocT<byte>(width * height);
199 png_destroy_read_struct(&png_ptr, &info_ptr,
nullptr);
212 byte gray_palette[256];
214 if (data->palette !=
nullptr) {
216 bool all_gray =
true;
220 all_gray &= data->palette[i].r == data->palette[i].g && data->palette[i].r == data->palette[i].b;
221 gray_palette[i] =
RGBToGrayscale(data->palette[i].r, data->palette[i].g, data->palette[i].b);
241 gray_palette[1] = 16;
246 for (y = 0; y < info->
height; y++) {
247 byte *pixel = &map[y * info->
width];
248 byte *bitmap = &data->bitmap[y * info->
width * (info->
bpp == 24 ? 3 : 1)];
250 for (x = 0; x < info->
width; x++) {
251 if (info->
bpp != 24) {
252 *pixel++ = gray_palette[*bitmap++];
274 memset(&data, 0,
sizeof(data));
282 BmpInitializeBuffer(&buffer, f);
284 if (!BmpReadHeader(&buffer, &info, &data)) {
287 BmpDestroyData(&data);
294 BmpDestroyData(&data);
298 if (map !=
nullptr) {
299 if (!BmpReadBitmap(&buffer, &info, &data)) {
302 BmpDestroyData(&data);
310 BmpDestroyData(&data);
329 const uint num_div = 16384;
335 uint row_pad = 0, col_pad = 0;
337 uint img_row, img_col;
342 default: NOT_REACHED();
353 if ((img_width * num_div) / img_height > ((width * num_div) / height)) {
355 img_scale = (width * num_div) / img_width;
356 row_pad = (1 + height - ((img_height * img_scale) / num_div)) / 2;
359 img_scale = (height * num_div) / img_height;
360 col_pad = (1 + width - ((img_width * img_scale) / num_div)) / 2;
369 for (row = 0; row < height; row++) {
370 for (col = 0; col < width; col++) {
372 default: NOT_REACHED();
385 img_row = (((row - row_pad) * num_div) / img_scale);
387 default: NOT_REACHED();
389 img_col = (((width - 1 - col - col_pad) * num_div) / img_scale);
392 img_col = (((col - col_pad) * num_div) / img_scale);
396 assert(img_row < img_height);
397 assert(img_col < img_width);
399 uint heightmap_height = map[img_row * img_width + img_col];
401 if (heightmap_height > 0) {
433 for (row = 0; (uint)row < height; row++) {
434 for (col = 0; (uint)col < width; col++) {
455 for (row = height - 1; row >= 0; row--) {
456 for (col = width - 1; col >= 0; col--) {
458 if ((uint)col != width - 1) {
463 if ((uint)row != height - 1) {
547 for (uint row = edge_distance; row <
MapSizeY() - edge_distance; row++) {
548 for (uint col = edge_distance; col <
MapSizeX() - edge_distance; col++) {