34 #include "loaders/SILLYPNGImageLoader.h"
36 #ifndef SILLY_OPT_INLINE
38 #include "loaders/SILLYPNGImageLoader.icpp"
42 #include "loaders/SILLYPNGImageContext.h"
47 void PNG_read_function(png_structp png_ptr, png_bytep data, png_size_t length)
49 PNGImageContext* png =
reinterpret_cast<PNGImageContext*
>(png_get_io_ptr(png_ptr));
50 int readed = png->read(data, length);
51 if (readed != (
int)length)
53 png_error(png_ptr,
"PNG_read_function error");
57 void PNG_warning_function(png_structp png_ptr,
58 png_const_charp error)
63 void PNG_error_function(png_structp png_ptr,
64 png_const_charp error)
69 #if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
70 memcpy(buf, png_jmpbuf((png_ptr)),
sizeof(jmp_buf));
72 memcpy(buf, png_ptr->jmpbuf,
sizeof(jmp_buf));
78 PNGImageLoader::PNGImageLoader()
79 : ImageLoader(
"PNG Image Loader based on libpng")
82 PNGImageLoader::~PNGImageLoader()
96 png->d_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
97 if (png->d_png_ptr == 0)
102 png->d_info_ptr = png_create_info_struct(png->d_png_ptr);
103 if (png->d_info_ptr == 0)
108 if (setjmp(png_jmpbuf(png->d_png_ptr)))
113 png_set_error_fn(png->d_png_ptr, 0, PNG_error_function, PNG_warning_function);
114 png_set_read_fn(png->d_png_ptr, png, PNG_read_function);
120 int png_transform = PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_EXPAND;
122 png_read_png(png->d_png_ptr, png->d_info_ptr, png_transform, 0);
124 png->d_bit_depth = png_get_bit_depth(png->d_png_ptr, png->d_info_ptr);
125 png->d_num_channels = png_get_channels(png->d_png_ptr, png->d_info_ptr);
127 if (png->d_bit_depth == 8)
129 if (png->d_num_channels == 4)
131 formatSource = PF_RGBA;
133 else if (png->d_num_channels == 3)
135 formatSource = PF_RGB;
162 size_t width = png->getWidth();
163 size_t height = png->getHeight();
164 png_bytepp row_pointers = png_get_rows(png->d_png_ptr, png->d_info_ptr);
165 if (png->d_bit_depth == 8)
168 if (png->d_num_channels == 4)
170 for (
size_t j = 0 ; j < height ; ++j)
172 for(
size_t i = 0 ; i < width ; ++i)
174 size_t pixel_offset = 4 * i;
175 red = *(row_pointers[j] + pixel_offset);
176 green = *(row_pointers[j] + pixel_offset + 1);
177 blue = *(row_pointers[j] + pixel_offset + 2);
178 alpha = *(row_pointers[j] + pixel_offset + 3);
183 else if (png->d_num_channels == 3)
186 for (
size_t j = 0 ; j < height ; ++j)
188 for(
size_t i = 0 ; i < width ; ++i)
190 size_t pixel_offset = 3 * i;
191 red = *(row_pointers[j] + pixel_offset);
192 green = *(row_pointers[j] + pixel_offset + 1);
193 blue = *(row_pointers[j] + pixel_offset + 2);
200 if (origin == PO_BOTTOM_LEFT)