| 187 | } |
| 188 | |
| 189 | static bool PNGCommonLoader(RGBA8Image* image, png_structp png_ptr, png_infop info_ptr, std::vector<u32>& new_data, |
| 190 | std::vector<png_bytep>& row_pointers) |
| 191 | { |
| 192 | png_read_info(png_ptr, info_ptr); |
| 193 | |
| 194 | const u32 width = png_get_image_width(png_ptr, info_ptr); |
| 195 | const u32 height = png_get_image_height(png_ptr, info_ptr); |
| 196 | const png_byte color_type = png_get_color_type(png_ptr, info_ptr); |
| 197 | const png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr); |
| 198 | |
| 199 | // Read any color_type into 8bit depth, RGBA format. |
| 200 | // See http://www.libpng.org/pub/png/libpng-manual.txt |
| 201 | |
| 202 | if (bit_depth == 16) |
| 203 | png_set_strip_16(png_ptr); |
| 204 | |
| 205 | if (color_type == PNG_COLOR_TYPE_PALETTE) |
| 206 | png_set_palette_to_rgb(png_ptr); |
| 207 | |
| 208 | // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth. |
| 209 | if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) |
| 210 | png_set_expand_gray_1_2_4_to_8(png_ptr); |
| 211 | |
| 212 | if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) |
| 213 | png_set_tRNS_to_alpha(png_ptr); |
| 214 | |
| 215 | // These color_type don't have an alpha channel then fill it with 0xff. |
| 216 | if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE) |
| 217 | png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER); |
| 218 | |
| 219 | if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
| 220 | png_set_gray_to_rgb(png_ptr); |
| 221 | |
| 222 | png_read_update_info(png_ptr, info_ptr); |
| 223 | |
| 224 | new_data.resize(width * height); |
| 225 | row_pointers.reserve(height); |
| 226 | for (u32 y = 0; y < height; y++) |
| 227 | row_pointers.push_back(reinterpret_cast<png_bytep>(new_data.data() + y * width)); |
| 228 | |
| 229 | png_read_image(png_ptr, row_pointers.data()); |
| 230 | image->SetPixels(width, height, std::move(new_data)); |
| 231 | return true; |
| 232 | } |
| 233 | |
| 234 | bool PNGFileLoader(RGBA8Image* image, const char* filename, std::FILE* fp) |
| 235 | { |