cleanup
This commit is contained in:
+15
-109
@@ -92,100 +92,6 @@ int _png_write(
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageData> _png_load(const char* file) {
|
||||
png_struct* png = png_create_read_struct(
|
||||
PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr
|
||||
);
|
||||
if (png == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
png_info* info = png_create_info_struct(png);
|
||||
if (info == nullptr) {
|
||||
png_destroy_read_struct(&png, (png_info**)nullptr, (png_info**)nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
png_info* end_info = png_create_info_struct(png);
|
||||
if (end_info == nullptr) {
|
||||
png_destroy_read_struct(&png, (png_info**)nullptr, (png_info**)nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png))) {
|
||||
png_destroy_read_struct(&png, &info, &end_info);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FILE* fp = nullptr;
|
||||
if ((fp = fopen(file, "rb")) == nullptr) {
|
||||
png_destroy_read_struct(&png, &info, &end_info);
|
||||
return nullptr;
|
||||
}
|
||||
png_init_io(png, fp);
|
||||
png_read_info(png, info);
|
||||
|
||||
int width = png_get_image_width(png, info);
|
||||
int height = png_get_image_height(png, info);
|
||||
png_byte color_type = png_get_color_type(png, info);
|
||||
int bit_depth = png_get_bit_depth(png, info);
|
||||
|
||||
if (bit_depth == 16) png_set_strip_16(png);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand_gray_1_2_4_to_8(png);
|
||||
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
|
||||
|
||||
// These color_type don't have an alpha channel then fill it with 0xff.
|
||||
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png);
|
||||
|
||||
png_read_update_info(png, info);
|
||||
|
||||
int row_bytes = png_get_rowbytes(png, info);
|
||||
// color_type = png_get_color_type(png, info);
|
||||
// png_get_color_type returns 2 (RGB) but raster always have alpha channel
|
||||
// due to PNG_FILLER_AFTER
|
||||
|
||||
color_type = 6;
|
||||
bit_depth = png_get_bit_depth(png, info);
|
||||
|
||||
auto image_data = std::make_unique<png_byte[]>(row_bytes * height);
|
||||
auto row_pointers = std::make_unique<png_byte*[]>(height);
|
||||
for (int i = 0; i < height; ++i) {
|
||||
row_pointers[height - 1 - i] = image_data.get() + i * row_bytes;
|
||||
}
|
||||
png_read_image(png, row_pointers.get());
|
||||
|
||||
ImageFormat format = ImageFormat::rgba8888;
|
||||
switch (color_type) {
|
||||
case PNG_COLOR_TYPE_RGBA:
|
||||
format = ImageFormat::rgba8888;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
format = ImageFormat::rgb888;
|
||||
break;
|
||||
default:
|
||||
logger.error() << "color type " << color_type
|
||||
<< " is not supported!";
|
||||
png_destroy_read_struct(&png, &info, &end_info);
|
||||
fclose(fp);
|
||||
return nullptr;
|
||||
}
|
||||
auto image = std::make_unique<ImageData>(
|
||||
format, width, height, std::move(image_data)
|
||||
);
|
||||
png_destroy_read_struct(&png, &info, &end_info);
|
||||
fclose(fp);
|
||||
return image;
|
||||
}
|
||||
|
||||
struct InMemoryReader {
|
||||
const ubyte* bytes;
|
||||
size_t size;
|
||||
@@ -205,8 +111,8 @@ static void read_in_memory(png_structp pngPtr, png_bytep dst, png_size_t toread)
|
||||
reader.offset += toread;
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageData> png::load_image_inmemory(const ubyte* bytes, size_t size) {
|
||||
if(!png_check_sig(bytes, size)) {
|
||||
std::unique_ptr<ImageData> png::load_image(const ubyte* bytes, size_t size) {
|
||||
if (!png_check_sig(bytes, size)) {
|
||||
throw std::runtime_error("invalid png signature");
|
||||
}
|
||||
png_structp pngPtr = nullptr;
|
||||
@@ -224,8 +130,6 @@ std::unique_ptr<ImageData> png::load_image_inmemory(const ubyte* bytes, size_t s
|
||||
InMemoryReader reader {bytes, size, 0};
|
||||
|
||||
png_set_read_fn(pngPtr, &reader, read_in_memory);
|
||||
// png_set_sig_bytes(png_ptr, kPngSignatureLength);
|
||||
|
||||
png_read_info(pngPtr, infoPtr);
|
||||
|
||||
png_uint_32 width = 0;
|
||||
@@ -300,22 +204,24 @@ std::unique_ptr<ImageData> png::load_image_inmemory(const ubyte* bytes, size_t s
|
||||
return image;
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageData> png::load_image(const std::string& filename) {
|
||||
auto bytes = files::read_bytes_buffer(fs::u8path(filename));
|
||||
auto image = load_image_inmemory(bytes.data(), bytes.size());
|
||||
if (image == nullptr) {
|
||||
throw std::runtime_error("could not load image " + filename);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
std::unique_ptr<Texture> png::load_texture(const std::string& filename) {
|
||||
auto image = load_image(filename);
|
||||
std::unique_ptr<Texture> png::load_texture(const ubyte* bytes, size_t size) {
|
||||
auto image = load_image(bytes, size);
|
||||
auto texture = GLTexture::from(image.get());
|
||||
texture->setNearestFilter();
|
||||
return texture;
|
||||
}
|
||||
|
||||
std::unique_ptr<Texture> png::load_texture(const std::string& filename) {
|
||||
auto bytes = files::read_bytes_buffer(fs::u8path(filename));
|
||||
try {
|
||||
return load_texture(bytes.data(), bytes.size());
|
||||
} catch (const std::runtime_error& err) {
|
||||
throw std::runtime_error(
|
||||
"could not to load " + filename + ": " + err.what()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void png::write_image(const std::string& filename, const ImageData* image) {
|
||||
_png_write(
|
||||
filename.c_str(),
|
||||
|
||||
Reference in New Issue
Block a user