50 self->
read(data, length);
71 m_input.read((
char*)data, length *
sizeof(png_byte));
74const unsigned int claw::graphic::png::reader::s_rgba_pixel_size = 4;
104 std::istream::pos_type init_pos = f.tellg();
113 f.seekg(init_pos, std::ios_base::beg);
122void claw::graphic::png::reader::read_from_file(std::istream& f)
124 source_manager infile(f);
128 create_read_structures(png_ptr, info_ptr);
130 if(setjmp(png_jmpbuf(png_ptr)))
134 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
138 check_if_png(png_ptr, f);
140 png_set_read_fn(png_ptr, (
void*)&infile,
143 png_read_info(png_ptr, info_ptr);
145 png_set_strip_16(png_ptr);
146 png_set_expand_gray_1_2_4_to_8(png_ptr);
147 png_set_packing(png_ptr);
149 png_set_tRNS_to_alpha(png_ptr);
152 png_set_palette_to_rgb(png_ptr);
155 png_set_filler(png_ptr,
156 std::numeric_limits<rgba_pixel_8::component_type>::max(),
159 png_read_update_info(png_ptr, info_ptr);
161 read_image(png_ptr, info_ptr);
163 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
171void claw::graphic::png::reader::check_if_png(png_structp png_ptr,
172 std::istream& f)
const
176 const unsigned int bytes_to_check = 8;
177 png_byte buffer[bytes_to_check];
180 f.read((
char*)buffer, bytes_to_check *
sizeof(png_byte));
182 if((png_sig_cmp(buffer, (png_size_t)0, bytes_to_check) != 0) || !f)
185 png_set_sig_bytes(png_ptr, bytes_to_check);
193void claw::graphic::png::reader::read_image(png_structp png_ptr,
199 m_image.set_size(png_get_image_width(png_ptr, info_ptr),
200 png_get_image_height(png_ptr, info_ptr));
202 if(png_get_interlace_type(png_ptr, info_ptr) == PNG_INTERLACE_NONE)
203 read_sequential_image(png_ptr, info_ptr);
205 read_interlaced_image(png_ptr, info_ptr,
206 png_set_interlace_handling(png_ptr));
214void claw::graphic::png::reader::read_sequential_image(png_structp png_ptr,
221 = (png_bytep)png_malloc(png_ptr, s_rgba_pixel_size * m_image.width());
222 const png_byte color_type(png_get_color_type(png_ptr, info_ptr));
226 for(
unsigned int y = 0; y != m_image.height(); ++y)
228 png_read_row(png_ptr, data, NULL);
229 copy_pixel_line(color_type, data, y);
234 png_free(png_ptr, data);
238 png_free(png_ptr, data);
247void claw::graphic::png::reader::read_interlaced_image(png_structp png_ptr,
255 const unsigned int row_length = s_rgba_pixel_size * m_image.width();
257 = (png_bytepp)png_malloc(png_ptr,
sizeof(png_bytep) * m_image.height());
259 const png_byte color_type(png_get_color_type(png_ptr, info_ptr));
263 for(i = 0; i != m_image.height(); ++i)
265 data[i] = (png_bytep)png_malloc(png_ptr, row_length);
268 throw std::bad_alloc();
270 copy_pixel_line(color_type, data[i], i);
273 for(
unsigned int p = 0; p != passes; ++p)
274 png_read_rows(png_ptr, data, NULL, m_image.height());
276 for(
unsigned int y = 0; y != m_image.height(); ++y)
277 copy_pixel_line(color_type, data[y], y);
281 for(
unsigned int j = 0; j != i; ++j)
282 png_free(png_ptr, data[j]);
284 png_free(png_ptr, data);
288 for(i = 0; i != m_image.height(); ++i)
289 png_free(png_ptr, data[i]);
291 png_free(png_ptr, data);
300void claw::graphic::png::reader::copy_pixel_line(png_byte color_type,
307 if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
310 for(
unsigned int x = 0; x != m_image.width(); ++x, data += 2)
312 m_image[y][x].components.red = data[0];
313 m_image[y][x].components.green = data[0];
314 m_image[y][x].components.blue = data[0];
315 m_image[y][x].components.alpha = data[1];
319 for(
unsigned int x = 0; x != m_image.width();
320 ++x, data += s_rgba_pixel_size)
322 m_image[y][x].components.red = data[0];
323 m_image[y][x].components.green = data[1];
324 m_image[y][x].components.blue = data[2];
325 m_image[y][x].components.alpha = data[3];
334void claw::graphic::png::reader::create_read_structures(
335 png_structp& png_ptr, png_infop& info_ptr)
const
337 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
341 info_ptr = png_create_info_struct(png_ptr);
344 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
347 if(!png_ptr || !info_ptr)
Some assert macros to strengthen you code.
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.
image()
Constructor. Creates an image without datas.
void load(std::istream &f)
Load an image from a png file.
reader(image &img)
Constructor.
A simple class to use as exception with string message.
#define CLAW_EXCEPTION(m)
Create an exception and add the name of the current function to the message.
A class for png pictures.
void claw__graphic__png__source_manager__read(png_structp png_ptr, png_bytep data, png_size_t length)
Read data from the input stream.
Source manager that allow us to read from a std::istream.
void read(png_bytep data, png_size_t length)
Read data from the input stream.
source_manager(std::istream &is)
Constructor.