14 #ifndef TOOLS_USE_OUREX_PNG
17 #include <ourex_png.h>
23 inline bool is(
const std::string& a_file){
24 FILE* file = ::fopen(a_file.c_str(),
"rb");
25 if(!file)
return false;
27 size_t nitem = ::fread(header,1,8,file);
29 if(nitem!=8)
return false;
30 return ::png_sig_cmp(header,0,8)?
false:
true;
40 inline unsigned char*
read_FILE(FILE* a_file,
unsigned int& a_width,
unsigned int& a_height,
unsigned int& a_bpp) {
43 if(::fread(header,1,8,a_file)!=8) {
49 if(::png_sig_cmp(header,0,8)) {
57 ::png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
65 png_infop info_ptr = ::png_create_info_struct(png_ptr);
67 ::png_destroy_read_struct(&png_ptr,NULL,NULL);
74 if(::setjmp(png_jmpbuf(png_ptr))) {
75 ::png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
82 ::png_init_io(png_ptr,a_file);
83 ::png_set_sig_bytes(png_ptr,8);
85 ::png_read_info(png_ptr,info_ptr);
87 png_uint_32 width = ::png_get_image_width(png_ptr,info_ptr);
88 png_uint_32 height = ::png_get_image_height(png_ptr,info_ptr);
89 png_uint_32 rowbytes = ::png_get_rowbytes(png_ptr,info_ptr);
90 int bpp = width?rowbytes/width:0;
92 if((width<=0)||(height<=0)||(bpp<=0)) {
93 ::png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
106 ::png_read_update_info(png_ptr,info_ptr);
108 if(::setjmp(png_jmpbuf(png_ptr))) {
109 ::png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
116 unsigned char* buffer =
new unsigned char[rowbytes * height];
118 ::png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
125 {png_bytep* row_pointers =
new png_bytep[height];
126 png_byte* pos = buffer+rowbytes*(height-1);
127 for(png_uint_32 y=0;y<height;y++) {
128 row_pointers[y] = pos;
131 ::png_read_image(png_ptr,row_pointers);
132 delete [] row_pointers;}
134 ::png_read_end(png_ptr,info_ptr);
136 ::png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
145 inline unsigned char*
read(std::ostream& a_out,
const std::string& a_file,
unsigned int& a_width,
unsigned int& a_height,
unsigned int& a_bpp) {
147 FILE* file = fopen(a_file.c_str(),
"rb");
149 a_out <<
"tools::png::read :"
150 <<
" can't open file " <<
tools::sout(a_file) <<
"."
157 unsigned char* buffer =
read_FILE(file,a_width,a_height,a_bpp);
163 a_out <<
"tools::png::read :"
164 <<
" read_FILE " <<
tools::sout(a_file) <<
" failed."
173 const std::string& a_file,
174 unsigned int a_sx,
unsigned int a_sy,
175 unsigned int a_sw,
unsigned int a_sh,
176 unsigned int& a_rw,
unsigned int& a_rh,
177 unsigned int& a_rbpp) {
178 a_out <<
"tools::png::read_part :"
179 <<
" not yet implemented."
186 unsigned int w,h,bpp;
187 unsigned char* buffer =
read(a_out,a_file,w,h,bpp);
195 if((a_sx>=w)||(a_sy>=h)){
204 a_rw = tools::mn<unsigned int>(w-a_sx,a_sw);
205 a_rh = tools::mn<unsigned int>(h-a_sy,a_sh);
208 if(!a_rw||!a_rh||!a_rbpp){
216 unsigned char* rb =
new unsigned char[a_rw*a_rh*a_rbpp];
225 unsigned int rstride = a_rw * a_rbpp;
226 unsigned char* rpos = rb;
228 unsigned int stride = w * bpp;
229 unsigned char* pos = buffer+a_sy*stride+a_sx*bpp;
231 for(
unsigned int j=0;j<a_rh;j++,rpos+=rstride,pos+=stride) {
232 ::memcpy(rpos,pos,rstride);
240 inline bool write_FILE(FILE* a_file,
unsigned char* a_buffer,
unsigned int a_width,
unsigned int a_height,
unsigned int a_bpp) {
242 if((a_bpp!=3)&&(a_bpp!=4)) {
247 if(!(png_ptr = ::png_create_write_struct
248 (PNG_LIBPNG_VER_STRING,NULL,NULL,NULL)))
return false;
251 if(!(info_ptr = ::png_create_info_struct(png_ptr))){
252 ::png_destroy_write_struct(&png_ptr,NULL);
256 if(::setjmp(png_jmpbuf(png_ptr))) {
257 ::png_destroy_write_struct(&png_ptr,&info_ptr);
261 #ifndef Z_DEFAULT_COMPRESSION
262 #define Z_DEFAULT_COMPRESSION (-1)
265 ::png_init_io(png_ptr,a_file);
267 ::png_set_IHDR(png_ptr,info_ptr,a_width,a_height,8,
268 a_bpp==3?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_RGBA,
270 PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);
271 ::png_write_info(png_ptr,info_ptr);
273 for(
unsigned int row=0;row<a_height;row++){
274 unsigned char* pos = a_buffer+(a_height-1-row)*(a_width*a_bpp);
275 ::png_write_row(png_ptr,(png_bytep)pos);
278 ::png_write_end(png_ptr,info_ptr);
279 ::png_destroy_write_struct(&png_ptr,&info_ptr);
283 inline bool write(std::ostream& a_out,
284 const std::string& a_file,
285 unsigned char* a_buffer,
286 unsigned int a_width,
287 unsigned int a_height,
288 unsigned int a_bpp) {
289 FILE* file = ::fopen(a_file.c_str(),
"wb");
291 a_out <<
"tools::png::write :"
292 <<
" can't open file " <<
tools::sout(a_file) <<
"."
296 if(!
write_FILE(file,a_buffer,a_width,a_height,a_bpp)) {
298 a_out <<
"tools::png::write :"
299 <<
" can't write file " <<
tools::sout(a_file) <<
"."
307 inline bool infos_FILE(FILE* a_file,
unsigned int& a_width,
unsigned int& a_height,
unsigned int& a_bpp) {
310 if(::fread(header,1,8,a_file)!=8) {
316 if(::png_sig_cmp(header,0,8)) {
323 png_structp png_ptr =
324 ::png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
332 png_infop info_ptr = ::png_create_info_struct(png_ptr);
340 if(::setjmp(png_jmpbuf(png_ptr))) {
347 ::png_init_io(png_ptr,a_file);
348 ::png_set_sig_bytes(png_ptr,8);
349 ::png_read_info(png_ptr,info_ptr);
351 png_uint_32 width = ::png_get_image_width(png_ptr,info_ptr);
352 png_uint_32 height = ::png_get_image_height(png_ptr,info_ptr);
353 png_uint_32 rowbytes = ::png_get_rowbytes(png_ptr,info_ptr);
354 a_bpp = width?rowbytes/width:0;
356 ::png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
364 inline bool infos(std::ostream& a_out,
const std::string& a_file,
unsigned int& a_width,
unsigned int& a_height,
unsigned int& a_bpp) {
366 a_out <<
"tools::png::infos :"
367 <<
" file " << a_file <<
" is not png."
375 FILE* file = ::fopen(a_file.c_str(),
"rb");
377 a_out <<
"tools::png::infos :"
378 <<
" can't open " << a_file
386 unsigned int w,h,bpp;
392 a_out <<
"tools::png::infos :"
393 <<
" problem reading " << a_file
414 inline bool to_xpm(std::ostream& a_out,
const std::string& a_file,
const std::string& a_name,
bool a_verbose =
false) {
427 const std::vector<std::string>& a_files,
428 unsigned int a_cols,
unsigned int a_rows,
429 unsigned int a_bw,
unsigned int a_bh,
431 const std::string& a_file) {
432 unsigned int wa,ha,bppa;
435 (a_out,a_files,a_cols,a_rows,a_bw,a_bh,a_bc,
read,wa,ha,bppa);
437 a_out <<
"tools::png::concatenate :"
438 <<
" failed to concatenate all buffers."
444 FILE* file = ::fopen(a_file.c_str(),
"wb");
446 a_out <<
"tools::png::concatenate :"
447 <<
" can't open " << file <<
" for writing."
454 a_out <<
"tools::png::concatenate :"
455 <<
" can't write " << a_file <<
"."
471 virtual bool infos(std::ostream& a_out,
const std::string& a_file,
472 unsigned int& a_width,
unsigned int& a_height,
unsigned int& a_bpp)
const {
475 virtual unsigned char*
read(std::ostream& a_out,
const std::string& a_file,
476 unsigned int& a_width,
unsigned int& a_height,
unsigned int& a_bpp)
const {
479 virtual unsigned char*
read_part(std::ostream& a_out,
const std::string& a_file,
480 unsigned int a_sx,
unsigned int a_sy,
481 unsigned int a_sw,
unsigned int a_sh,
482 unsigned int& a_rw,
unsigned int& a_rh,
unsigned int& a_rbpp)
const {