35 #include "loaders/SILLYPNGImageLoader.h"
37 #ifndef SILLY_OPT_INLINE
39 #include "loaders/SILLYPNGImageLoader.icpp"
43 #include "loaders/SILLYPNGImageContext.h"
48 void PNG_read_function(png_structp png_ptr, png_bytep data, png_size_t length)
50 PNGImageContext* png =
reinterpret_cast<PNGImageContext*
>(png_get_io_ptr(png_ptr));
51 int readed = png->read(data, length);
52 if (readed != (
int)length)
54 png_error(png_ptr,
"PNG_read_function error");
58 void PNG_warning_function(png_structp png_ptr,
59 png_const_charp error)
64 void PNG_error_function(png_structp png_ptr,
65 png_const_charp error)
70 #if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
71 memcpy(buf, png_jmpbuf((png_ptr)),
sizeof(jmp_buf));
73 memcpy(buf, png_ptr->jmpbuf,
sizeof(jmp_buf));
79 PNGImageLoader::PNGImageLoader()
80 : ImageLoader(
"PNG Image Loader based on libpng")
83 PNGImageLoader::~PNGImageLoader()
97 png->d_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
98 if (png->d_png_ptr == 0)
103 png->d_info_ptr = png_create_info_struct(png->d_png_ptr);
104 if (png->d_info_ptr == 0)
109 if (setjmp(png_jmpbuf(png->d_png_ptr)))
114 png_set_error_fn(png->d_png_ptr, 0, PNG_error_function, PNG_warning_function);
115 png_set_read_fn(png->d_png_ptr, png, PNG_read_function);
121 int png_transform = PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_EXPAND;
123 png_read_png(png->d_png_ptr, png->d_info_ptr, png_transform, 0);
125 png->d_bit_depth = png_get_bit_depth(png->d_png_ptr, png->d_info_ptr);
126 png->d_num_channels = png_get_channels(png->d_png_ptr, png->d_info_ptr);
128 if (png->d_bit_depth == 8)
130 if (png->d_num_channels == 4)
132 formatSource = PF_RGBA;
134 else if (png->d_num_channels == 3)
136 formatSource = PF_RGB;
163 size_t width = png->getWidth();
164 size_t height = png->getHeight();
165 png_bytepp row_pointers = png_get_rows(png->d_png_ptr, png->d_info_ptr);
166 if (png->d_bit_depth == 8)
169 if (png->d_num_channels == 4)
171 for (
size_t j = 0 ; j < height ; ++j)
173 for(
size_t i = 0 ; i < width ; ++i)
175 size_t pixel_offset = 4 * i;
176 red = *(row_pointers[j] + pixel_offset);
177 green = *(row_pointers[j] + pixel_offset + 1);
178 blue = *(row_pointers[j] + pixel_offset + 2);
179 alpha = *(row_pointers[j] + pixel_offset + 3);
184 else if (png->d_num_channels == 3)
187 for (
size_t j = 0 ; j < height ; ++j)
189 for(
size_t i = 0 ; i < width ; ++i)
191 size_t pixel_offset = 3 * i;
192 red = *(row_pointers[j] + pixel_offset);
193 green = *(row_pointers[j] + pixel_offset + 1);
194 blue = *(row_pointers[j] + pixel_offset + 2);
201 if (origin == PO_BOTTOM_LEFT)