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

Function ReadHeightmapPNG

src/heightmap.cpp:141–199  ·  view source on GitHub ↗

* Reads the heightmap and/or size of the heightmap from a PNG file. * If map == nullptr only the size of the PNG is read, otherwise a map * with greyscale pixels is allocated and assigned to *map. */

Source from the content-addressed store, hash-verified

139 * with greyscale pixels is allocated and assigned to *map.
140 */
141static bool ReadHeightmapPNG(std::string_view filename, uint *x, uint *y, std::vector<uint8_t> *map)
142{
143 png_structp png_ptr = nullptr;
144 png_infop info_ptr = nullptr;
145
146 auto fp = FioFOpenFile(filename, "rb", HEIGHTMAP_DIR);
147 if (!fp.has_value()) {
148 ShowErrorMessage(GetEncodedString(STR_ERROR_PNGMAP), GetEncodedString(STR_ERROR_PNGMAP_FILE_NOT_FOUND), WL_ERROR);
149 return false;
150 }
151
152 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
153 if (png_ptr == nullptr) {
154 ShowErrorMessage(GetEncodedString(STR_ERROR_PNGMAP), GetEncodedString(STR_ERROR_PNGMAP_MISC), WL_ERROR);
155 return false;
156 }
157
158 info_ptr = png_create_info_struct(png_ptr);
159 if (info_ptr == nullptr || setjmp(png_jmpbuf(png_ptr))) {
160 ShowErrorMessage(GetEncodedString(STR_ERROR_PNGMAP), GetEncodedString(STR_ERROR_PNGMAP_MISC), WL_ERROR);
161 png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
162 return false;
163 }
164
165 png_init_io(png_ptr, *fp);
166
167 /* Allocate memory and read image, without alpha or 16-bit samples
168 * (result is either 8-bit indexed/greyscale or 24-bit RGB) */
169 png_set_packing(png_ptr);
170 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_STRIP_16, nullptr);
171
172 /* Maps of wrong colour-depth are not used.
173 * (this should have been taken care of by stripping alpha and 16-bit samples on load) */
174 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)) {
175 ShowErrorMessage(GetEncodedString(STR_ERROR_PNGMAP), GetEncodedString(STR_ERROR_PNGMAP_IMAGE_TYPE), WL_ERROR);
176 png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
177 return false;
178 }
179
180 uint width = png_get_image_width(png_ptr, info_ptr);
181 uint height = png_get_image_height(png_ptr, info_ptr);
182
183 if (!IsValidHeightmapDimension(width, height)) {
184 ShowErrorMessage(GetEncodedString(STR_ERROR_PNGMAP), GetEncodedString(STR_ERROR_HEIGHTMAP_TOO_LARGE), WL_ERROR);
185 png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
186 return false;
187 }
188
189 if (map != nullptr) {
190 map->resize(static_cast<size_t>(width) * height);
191 ReadHeightmapPNGImageData(*map, png_ptr, info_ptr);
192 }
193
194 *x = width;
195 *y = height;
196
197 png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
198 return true;

Callers 1

ReadHeightMapFunction · 0.85

Calls 6

FioFOpenFileFunction · 0.85
ShowErrorMessageFunction · 0.85
resizeMethod · 0.80
GetEncodedStringFunction · 0.70

Tested by

no test coverage detected