45 ( png_structp png_ptr, png_bytep data, png_size_t length )
50 self->
read(data, length);
74 ( png_bytep data, png_size_t length )
76 m_input.read( (
char*)data, length *
sizeof(png_byte) );
83 const unsigned int claw::graphic::png::reader::s_rgba_pixel_size = 4;
118 std::istream::pos_type init_pos = f.tellg();
127 f.seekg( init_pos, std::ios_base::beg );
137 void claw::graphic::png::reader::read_from_file( std::istream& f )
143 create_read_structures(png_ptr, info_ptr);
145 if (setjmp(png_jmpbuf(png_ptr)))
149 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
153 check_if_png( png_ptr, f );
155 png_set_read_fn( png_ptr, (
void *)&infile,
158 png_read_info(png_ptr, info_ptr);
160 png_set_strip_16(png_ptr);
161 png_set_expand_gray_1_2_4_to_8(png_ptr);
162 png_set_packing(png_ptr);
164 png_set_tRNS_to_alpha(png_ptr);
167 png_set_palette_to_rgb(png_ptr);
170 png_set_filler( png_ptr,
171 std::numeric_limits<rgba_pixel_8::component_type>::max(),
174 png_read_update_info(png_ptr, info_ptr);
176 read_image( png_ptr, info_ptr );
178 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
187 void claw::graphic::png::reader::check_if_png
188 ( png_structp png_ptr, std::istream& f )
const 192 const unsigned int bytes_to_check = 8;
193 png_byte buffer[bytes_to_check];
196 f.read( (
char*)buffer, bytes_to_check *
sizeof(png_byte) );
198 if ( (png_sig_cmp(buffer, (png_size_t)0, bytes_to_check) != 0) || !f )
201 png_set_sig_bytes(png_ptr, bytes_to_check);
210 void claw::graphic::png::reader::read_image
211 ( png_structp png_ptr, png_infop info_ptr )
216 m_image.
set_size( png_get_image_width(png_ptr, info_ptr),
217 png_get_image_height(png_ptr, info_ptr) );
219 if ( png_get_interlace_type(png_ptr, info_ptr) == PNG_INTERLACE_NONE )
220 read_sequential_image(png_ptr, info_ptr);
222 read_interlaced_image( png_ptr, info_ptr,
223 png_set_interlace_handling(png_ptr) );
232 void claw::graphic::png::reader::read_sequential_image
233 ( png_structp png_ptr, png_infop info_ptr )
239 (png_bytep)png_malloc( png_ptr, s_rgba_pixel_size * m_image.
width() );
240 const png_byte color_type( png_get_color_type(png_ptr, info_ptr) );
244 for (
unsigned int y=0; y!=m_image.
height(); ++y)
246 png_read_row(png_ptr, data, NULL);
247 copy_pixel_line( color_type, data, y );
252 png_free(png_ptr, data);
256 png_free(png_ptr, data);
266 void claw::graphic::png::reader::read_interlaced_image
267 ( png_structp png_ptr, png_infop info_ptr,
unsigned int passes )
273 const unsigned int row_length = s_rgba_pixel_size * m_image.
width();
275 (png_bytepp)png_malloc( png_ptr,
sizeof(png_bytep) * m_image.
height() );
277 const png_byte color_type( png_get_color_type(png_ptr, info_ptr) );
281 for (i=0; i!=m_image.
height(); ++i)
283 data[i] = (png_bytep)png_malloc( png_ptr, row_length );
286 throw std::bad_alloc();
288 copy_pixel_line( color_type, data[i], i );
291 for (
unsigned int p=0; p!=passes; ++p)
292 png_read_rows( png_ptr, data, NULL, m_image.
height() );
294 for (
unsigned int y=0; y!=m_image.
height(); ++y)
295 copy_pixel_line( color_type, data[y], y );
299 for(
unsigned int j=0; j!=i; ++j)
300 png_free(png_ptr, data[j]);
302 png_free(png_ptr, data);
306 for(i=0; i!=m_image.
height(); ++i)
307 png_free(png_ptr, data[i]);
309 png_free(png_ptr, data);
320 claw::graphic::png::reader::copy_pixel_line
321 ( png_byte color_type, png_bytep data,
unsigned int y )
326 if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
328 for (
unsigned int x=0; x!=m_image.
width(); ++x, data += 2)
330 m_image[y][x].components.red = data[0];
331 m_image[y][x].components.green = data[0];
332 m_image[y][x].components.blue = data[0];
333 m_image[y][x].components.alpha = data[1];
337 for (
unsigned int x=0; x!=m_image.
width(); ++x, data+=s_rgba_pixel_size)
339 m_image[y][x].components.red = data[0];
340 m_image[y][x].components.green = data[1];
341 m_image[y][x].components.blue = data[2];
342 m_image[y][x].components.alpha = data[3];
352 void claw::graphic::png::reader::create_read_structures
353 ( png_structp& png_ptr, png_infop& info_ptr )
const 355 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
359 info_ptr = png_create_info_struct(png_ptr);
362 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
365 if (!png_ptr || !info_ptr)
void load(std::istream &f)
Load an image from a png file.
Source manager that allow us to read from a std::istream.
unsigned int height() const
Gets image's height.
A class for png pictures.
unsigned int width() const
Gets image's width.
void read(png_bytep data, png_size_t length)
Read data from the input stream.
reader(image &img)
Constructor.
A simple class to use as exception with string message.
source_manager(std::istream &is)
Constructor.
void claw__graphic__png__source_manager__read(png_structp png_ptr, png_bytep data, png_size_t length)
Read data from the input stream.
Some assert macros to strengthen you code.
A class to deal with images.
void set_size(unsigned int w, unsigned int h)
Set a new size to the image.
#define CLAW_EXCEPTION(m)
Create an exception and add the name of the current function to the message.
#define CLAW_PRECOND(b)
Abort the program if a precondition is not true.