26 : m_PngPtr(0), m_InfoPtr(0), m_nWidth(0), m_nHeight(0), m_pRowPointers(0)
29 FILE *stream = fopen(filename,
"rb");
32 klog(LOG_ALERT,
"PNG file failed to open");
38 if (fread(buf, 1, 4, stream) != 4)
40 klog(LOG_ALERT,
"PNG file failed to read ident");
44 if (png_sig_cmp(reinterpret_cast<png_byte *>(buf), 0, 4) != 0)
46 klog(LOG_ALERT,
"PNG file failed IDENT check");
51 m_PngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
55 klog(LOG_ALERT,
"PNG file failed to initialise");
60 m_InfoPtr = png_create_info_struct(m_PngPtr);
63 klog(LOG_ALERT,
"PNG info failed to initialise");
64 png_destroy_read_struct(&m_PngPtr, NULL, NULL);
69 png_init_io(m_PngPtr, stream);
71 png_set_sig_bytes(m_PngPtr, 4);
73 png_set_palette_to_rgb(m_PngPtr);
77 PNG_TRANSFORM_STRIP_16 |
78 PNG_TRANSFORM_STRIP_ALPHA |
79 PNG_TRANSFORM_PACKING,
80 reinterpret_cast<void *>(0));
82 m_pRowPointers = png_get_rows(m_PngPtr, m_InfoPtr);
85 int bit_depth, color_type, interlace_type, compression_type, filter_method;
88 m_PngPtr, m_InfoPtr, &w, &h, &bit_depth, &color_type, &interlace_type,
89 &compression_type, &filter_method);
96 klog(LOG_ALERT,
"PNG - invalid bit depth");
99 if (color_type != PNG_COLOR_TYPE_RGB)
101 klog(LOG_ALERT,
"PNG - invalid colour type: %d", color_type);
105 m_pBitmap = (uint32_t *) malloc(4 * w * h);
107 for (y = 0; y < m_nHeight; ++y)
109 png_byte *row = m_pRowPointers[y];
110 for (x = 0; x < m_nWidth; ++x)
112 png_byte *ptr = &(row[x * 3]);
113 m_pBitmap[(y * m_nWidth) + x] =
114 (ptr[0] << 16) | (ptr[1] << 8) | (ptr[2]);
118 png_destroy_read_struct(&m_PngPtr, &m_InfoPtr, NULL);
122 klog(LOG_INFO,
"PNG loaded %zd %zd", m_nWidth, m_nHeight);
129 void Png::render(cairo_t *cr,
size_t x,
size_t y,
size_t width,
size_t height)
131 cairo_surface_t *surface = cairo_image_surface_create_for_data(
132 (uint8_t *) m_pBitmap, CAIRO_FORMAT_RGB24, m_nWidth, m_nHeight,
136 cairo_identity_matrix(cr);
137 cairo_translate(cr, x, y);
138 cairo_scale(cr, width / (
double) m_nWidth, height / (
double) m_nHeight);
139 cairo_set_source_surface(cr, surface, 0, 0);
143 cairo_surface_destroy(surface);
146 void Png::renderPartial(
147 cairo_t *cr,
size_t atX,
size_t atY,
size_t innerX,
size_t innerY,
148 size_t partialWidth,
size_t partialHeight,
size_t scaleWidth,
151 cairo_surface_t *surface = cairo_image_surface_create_for_data(
152 (uint8_t *) m_pBitmap, CAIRO_FORMAT_RGB24, m_nWidth, m_nHeight,
157 cairo_rectangle(cr, atX, atY, partialWidth, partialHeight);
161 cairo_identity_matrix(cr);
163 cr, scaleWidth / (
double) m_nWidth, scaleHeight / (
double) m_nHeight);
164 cairo_translate(cr, innerX, innerY);
165 cairo_set_source_surface(cr, surface, 0, 0);
169 cairo_surface_destroy(surface);
Png(const char *filename)