MCPcopy Create free account
hub / github.com/OpenStarbound/OpenStarbound / readPng

Method readPng

source/core/StarImage.cpp:25–119  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

23}
24
25Image Image::readPng(IODevicePtr device) {
26 png_byte header[8]{};
27 device->readFull((char*)header, sizeof(header));
28
29 if (png_sig_cmp(header, 0, sizeof(header)))
30 throw ImageException(strf("File {} is not a png image!", device->deviceName()));
31
32 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
33 if (!png_ptr)
34 throw ImageException("Internal libPNG error");
35
36 // Use custom warning function to suppress cerr warnings
37 png_set_error_fn(png_ptr, (png_voidp)device.get(), logPngError, logPngWarning);
38
39 png_infop info_ptr = png_create_info_struct(png_ptr);
40 if (!info_ptr) {
41 png_destroy_read_struct(&png_ptr, nullptr, nullptr);
42 throw ImageException("Internal libPNG error");
43 }
44
45 png_infop end_info = png_create_info_struct(png_ptr);
46 if (!end_info) {
47 png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
48 throw ImageException("Internal libPNG error");
49 }
50
51 if (setjmp(png_jmpbuf(png_ptr))) {
52 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
53 throw ImageException("Internal error reading png.");
54 }
55
56 png_set_read_fn(png_ptr, device.get(), readPngData);
57
58 // Tell libPNG that we read some of the header.
59 png_set_sig_bytes(png_ptr, sizeof(header));
60
61 png_read_info(png_ptr, info_ptr);
62
63 png_uint_32 img_width = png_get_image_width(png_ptr, info_ptr);
64 png_uint_32 img_height = png_get_image_height(png_ptr, info_ptr);
65
66 png_uint_32 bitdepth = png_get_bit_depth(png_ptr, info_ptr);
67 png_uint_32 channels = png_get_channels(png_ptr, info_ptr);
68
69 // Color type. (RGB, RGBA, Luminance, luminance alpha... palette... etc)
70 png_uint_32 color_type = png_get_color_type(png_ptr, info_ptr);
71
72 if (color_type == PNG_COLOR_TYPE_PALETTE) {
73 png_set_palette_to_rgb(png_ptr);
74 channels = 3;
75 bitdepth = 8;
76 }
77
78 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
79 if (bitdepth < 8) {
80 png_set_expand_gray_1_2_4_to_8(png_ptr);
81 bitdepth = 8;
82 }

Callers

nothing calls this directly

Calls 5

strfFunction · 0.85
readFullMethod · 0.80
deviceNameMethod · 0.45
getMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected