Blame | Last modification | View Log | RSS feed
.TH LIBPNG 3 "October 15, 1999".SH NAMElibpng \- Portable Network Graphics (PNG) Reference Library 1.0.5 - October 15, 1999.SH SYNOPSIS\fI\fB\fB#include <png.h>\fP\fI\fB\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP\fI\fB\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP\fI\fB\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP\fI\fB\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP\fI\fB\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP\fI\fB\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP\fI\fB\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP\fI\fB\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP\fI\fB\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP\fI\fB\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP\fI\fB\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP\fI\fB\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP\fI\fB\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP\fI\fB\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP\fI\fB\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP\fI\fB\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP\fI\fB\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP\fI\fB\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP\fI\fB\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP\fI\fB\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP\fI\fB\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP\fI\fB\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP\fI\fB\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP\fI\fB\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP\fI\fB\fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr)\fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP\fI\fB\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP\fI\fB\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP\fI\fB\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP\fI\fB\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP\fI\fB\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP\fI\fB\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP\fI\fB\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP\fI\fB\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP\fI\fB\fBvoid png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP\fI\fB\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP\fI\fB\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP\fI\fB\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP\fI\fB\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP\fI\fB\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP\fI\fB\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP\fI\fB\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP\fI\fB\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP\fI\fB\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP\fI\fB\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP\fI\fB\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP\fI\fB\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP\fI\fB\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP\fI\fB\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP\fI\fB\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP\fI\fB\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP\fI\fB\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP\fI\fB\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP\fI\fB\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP\fI\fB\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP\fI\fB\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP\fI\fB\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP\fI\fB\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP\fI\fB\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP\fI\fB\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP\fI\fB\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP\fI\fB\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP\fI\fB\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP\fI\fB\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP\fI\fB\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP\fI\fB\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP\fI\fB\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP\fI\fB\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP\fI\fB\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP\fI\fB\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fIerror_action\fP\fB);\fP\fI\fB\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP\fI\fB\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP\fI\fB\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP\fI\fB\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP\fI\fB\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP\fI\fB\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP\fI\fB\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP\fI\fB\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP\fI\fB\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP\fI\fB\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP\fI\fB\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP\fI\fB\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP\fI\fB\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP\fI\fB\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP\fI\fB\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP\fI\fB\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP\fI\fB\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP\fI\fB\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_write_destroy_info (png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP\fI\fB\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP\fI\fB\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP\fI\fB\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP\fI\fB\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP\fI\fB.SH DESCRIPTIONThe.I libpnglibrary supports encoding, decoding, and various manipulations ofthe Portable Network Graphics (PNG) format image files. It uses the.IR zlib(3)compression library.Following is a copy of the libpng.txt file that accompanies libpng..SH LIBPNG.TXTlibpng.txt - A description on how to use and modify libpnglibpng version 1.0.5 - October 15, 1999Updated and distributed by Glenn Randers-Pehrson<randeg@alum.rpi.edu>Copyright (c) 1998, 1999 Glenn Randers-PehrsonFor conditions of distribution and use, see copyrightnotice in png.h.based on:libpng 1.0 beta 6 version 0.96 May 28, 1997Updated and distributed by Andreas DilgerCopyright (c) 1996, 1997 Andreas Dilgerlibpng 1.0 beta 2 - version 0.88 January 26, 1996For conditions of distribution and use, see copyrightnotice in png.h. Copyright (c) 1995, 1996 Guy EricSchalnat, Group 42, Inc.Updated/rewritten per request in the libpng FAQCopyright (c) 1995 Frank J. T. WojcikDecember 18, 1995 && January 20, 1996*.SH I. IntroductionThis file describes how to use and modify the PNG reference library(known as libpng) for your own use. There are five sections to thisfile: introduction, structures, reading, writing, and modification andconfiguration notes for various special platforms. In addition to thisfile, example.c is a good starting point for using the library, asit is heavily commented and should include everything most peoplewill need. We assume that libpng is already installed; see theINSTALL file for instructions on how to install libpng.Libpng was written as a companion to the PNG specification, as a wayof reducing the amount of time and effort it takes to support the PNGfile format in application programs.The PNG-1.2 specification is available at <http://www.cdrom.com/png>.The PNG-1.0 specification is availableas RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as aW3C Recommendation <http://www.w3.org/TR/REC.png.html>. Someadditional chunks are described in the special-purpose public chunksdocuments at <ftp://ftp.uu.net/graphics/png/documents/>.Other informationabout PNG, and the latest version of libpng, can be found at the PNG homepage, <http://www.cdrom.com/pub/png/>.Most users will not have to modify the library significantly; advancedusers may want to modify it more. All attempts were made to make it ascomplete as possible, while keeping the code easy to understand.Currently, this library only supports C. Support for other languagesis being considered.Libpng has been designed to handle multiple sessions at one time,to be easily modifiable, to be portable to the vast majority ofmachines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easyto use. The ultimate goal of libpng is to promote the acceptance ofthe PNG file format in whatever way possible. While there is stillwork to be done (see the TODO file), libpng should cover themajority of the needs of its users.Libpng uses zlib for its compression and decompression of PNG files.Further information about zlib, and the latest version of zlib, canbe found at the zlib home page, <http://www.cdrom.com/pub/infozip/zlib/>.The zlib compression utility is a general purpose utility that isuseful for more than PNG files, and can be used without libpng.See the documentation delivered with zlib for more details.You can usually find the source files for the zlib utility wherever youfind the libpng source files.Libpng is thread safe, provided the threads are using differentinstances of the structures. Each thread should have its ownpng_struct and png_info instances, and thus its own image.Libpng does not protect itself against two threads using thesame instance of a structure..SH II. StructuresThere are two main structures that are important to libpng, png_structand png_info. The first, png_struct, is an internal structure thatwill not, for the most part, be used by a user except as the firstvariable passed to every libpng function call.The png_info structure is designed to provide information about thePNG file. At one time, the fields of png_info were intended to bedirectly accessible to the user. However, this tended to cause problemswith applications using dynamically loaded libraries, and as a resulta set of interface functions for png_info was developed. The fieldsof png_info are still available for older applications, but it issuggested that applications use the new interfaces if at all possible.The png.h header file is an invaluable reference for programming with libpng.And while I'm on the topic, make sure you include the libpng header file:#include <png.h>.SH III. ReadingReading PNG files:We'll now walk you through the possible functions to call when readingin a PNG file, briefly explaining the syntax and purpose of each one.See example.c and png.h for more detail. While Progressive readingis covered in the next section, you will still need some of thefunctions discussed in this section to read a PNG file.You will want to do the I/O initialization(*) before you get into libpng,so if it doesn't work, you don't have much to undo. Of course, youwill also want to insure that you are, in fact, dealing with a PNGfile. Libpng provides a simple check to see if a file is a PNG file.To use it, pass in the first 1 to 8 bytes of the file, and it willreturn true or false (1 or 0) depending on whether the bytes could bepart of a PNG file. Of course, the more bytes you pass in, thegreater the accuracy of the prediction.If you are intending to keep the file pointer open for use in libpng,you must ensure you don't read more than 8 bytes from the beginningof the file, and you also have to make a call to png_set_sig_bytes_read()with the number of bytes you read from the beginning. Libpng willthen only check the bytes (if any) that your program didn't read.(*): If you are not using the standard I/O functions, you will needto replace them with custom functions. See the discussion underCustomizing libpng.FILE *fp = fopen(file_name, "rb");if (!fp){return;}fread(header, 1, number, fp);is_png = !png_sig_cmp(header, 0, number);if (!is_png){return;}Next, png_struct and png_info need to be allocated and initialized. Inorder to ensure that the size of these structures is correct even with adynamically linked libpng, there are functions to initialize andallocate the structures. We also pass the library version, optionalpointers to error handling functions, and a pointer to a data struct foruse by the error functions, if necessary (the pointer and functions canbe NULL if the default error handlers are to be used). See the sectionon Changes to Libpng below regarding the old initialization functions.png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,user_error_fn, user_warning_fn);if (!png_ptr)return;png_infop info_ptr = png_create_info_struct(png_ptr);if (!info_ptr){png_destroy_read_struct(&png_ptr,(png_infopp)NULL, (png_infopp)NULL);return;}png_infop end_info = png_create_info_struct(png_ptr);if (!end_info){png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL);return;}If you want to use your own memory allocation routines,define PNG_USER_MEM_SUPPORTED and usepng_create_read_struct_2() instead of png_create_read_struct():png_structp png_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,user_error_fn, user_warning_fn, (png_voidp)user_mem_ptr, user_malloc_fn, user_free_fn);The error handling routines passed to png_create_read_struct()and the memory alloc/free routines passed to png_create_struct_2()are only necessary if you are not using the libpng supplied errorhandling and memory alloc/free functions.When libpng encounters an error, it expects to longjmp backto your routine. Therefore, you will need to call setjmp and passyour png_ptr->jmpbuf. If you read the file from differentroutines, you will need to update the jmpbuf field every time you entera new routine that will call a png_ function.See your documentation of setjmp/longjmp for your compiler for morehandling in the Customizing Libpng section below for more information onthe libpng error handling. If an error occurs, and libpng longjmp'sback to your setjmp, you will want to call png_destroy_read_struct() tofree any memory.if (setjmp(png_ptr->jmpbuf)){png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);fclose(fp);return;}Now you need to set up the input code. The default for libpng is touse the C function fread(). If you use this, you will need to pass avalid FILE * in the function png_init_io(). Be sure that the file isopened in binary mode. If you wish to handle reading data in anotherway, you need not call the png_init_io() function, but you must thenimplement the libpng I/O methods discussed in the Customizing Libpngsection below.png_init_io(png_ptr, fp);If you had previously opened the file and read any of the signature fromthe beginning in order to see if this was a PNG file, you need to letlibpng know that there are some bytes missing from the start of the file.png_set_sig_bytes(png_ptr, number);At this point, you can set up a callback function that will becalled after each row has been read, which you can use to controla progress meter or the like. It's demonstrated in pngtest.c.You must supply a functionvoid read_row_callback(png_ptr, png_uint_32 row, int pass);{/* put your code here */}(You can give it another name that you like instead of "read_row_callback")To inform libpng about your function, usepng_set_read_status_fn(png_ptr, read_row_callback);In PNG files, the alpha channel in an image is the level of opacity.If you need the alpha channel in an image to be the level of transparencyinstead of opacity, you can invert the alpha channel (or the tRNS chunkdata) after it's read, so that 0 is fully opaque and 255 (in 8-bit orpaletted images) or 65535 (in 16-bit images) is fully transparent, withpng_set_invert_alpha(png_ptr);This has to appear here rather than later with the other transformationsbecause the tRNS chunk data must be modified in the case of paletted images.If your image is not a paletted image, the tRNS data (which in such casesrepresents a single color to be rendered as transparent) won't be changed.Finally, you can write your own transformation function if none ofthe existing ones meets your needs. This is done by setting a callbackwithpng_set_read_user_transform_fn(png_ptr,read_transform_fn);You must supply the functionvoid read_transform_fn(png_ptr ptr, row_info_ptrrow_info, png_bytep data)See pngtest.c for a working example. Your function will be calledafter all of the other transformations have been processed.You can also set up a pointer to a user structure for use by yourcallback function, and you can inform libpng that your transformfunction will change the number of channels or bit depth with thefunctionpng_set_user_transform_info(png_ptr, user_ptr,user_depth, user_channels);You can retrieve the pointer via the functionpng_get_user_transform_ptr(). For example:voidp read_user_transform_ptr =png_get_user_transform_ptr(png_ptr);You are now ready to read all the file information up to the actualimage data. You do this with a call to png_read_info().png_read_info(png_ptr, info_ptr);Functions are used to get the information from the info_ptr:png_get_IHDR(png_ptr, info_ptr, &width, &height,&bit_depth, &color_type, &interlace_type,&compression_type, &filter_type);width - holds the width of the imagein pixels (up to 2^31).height - holds the height of the imagein pixels (up to 2^31).bit_depth - holds the bit depth of one of theimage channels. (valid values are1, 2, 4, 8, 16 and depend also onthe color_type. See alsosignificant bits (sBIT) below).color_type - describes which color/alpha channelsare present.PNG_COLOR_TYPE_GRAY(bit depths 1, 2, 4, 8, 16)PNG_COLOR_TYPE_GRAY_ALPHA(bit depths 8, 16)PNG_COLOR_TYPE_PALETTE(bit depths 1, 2, 4, 8)PNG_COLOR_TYPE_RGB(bit_depths 8, 16)PNG_COLOR_TYPE_RGB_ALPHA(bit_depths 8, 16)PNG_COLOR_MASK_PALETTEPNG_COLOR_MASK_COLORPNG_COLOR_MASK_ALPHAfilter_type - (must be PNG_FILTER_TYPE_BASEfor PNG 1.0)compression_type - (must be PNG_COMPRESSION_TYPE_BASEfor PNG 1.0)interlace_type - (PNG_INTERLACE_NONE orPNG_INTERLACE_ADAM7)Any or all of interlace_type, compression_type, offilter_type can beNULL if you are not interested in their values.channels = png_get_channels(png_ptr, info_ptr);channels - number of channels of info for thecolor type (valid values are 1 (GRAY,PALETTE), 2 (GRAY_ALPHA), 3 (RGB),4 (RGB_ALPHA or RGB + filler byte))rowbytes = png_get_rowbytes(png_ptr, info_ptr);rowbytes - number of bytes needed to hold a rowsignature = png_get_signature(png_ptr, info_ptr);signature - holds the signature read from thefile (if any). The data is kept inthe same offset it would be if thewhole signature were read (i.e. if anapplication had already read in 4bytes of signature before startinglibpng, the remaining 4 bytes wouldbe in signature[4] through signature[7](see png_set_sig_bytes())).width = png_get_image_width(png_ptr,info_ptr);height = png_get_image_height(png_ptr,info_ptr);bit_depth = png_get_bit_depth(png_ptr,info_ptr);color_type = png_get_color_type(png_ptr,info_ptr);filter_type = png_get_filter_type(png_ptr,info_ptr);compression_type = png_get_compression_type(png_ptr,info_ptr);interlace_type = png_get_interlace_type(png_ptr,info_ptr);These are also important, but their validity depends on whether the chunkhas been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) andpng_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if thedata has been read, or zero if it is missing. The parameters to thepng_get_<chunk> are set directly if they are simple data types, or a pointerinto the info_ptr is returned for any complex types.png_get_PLTE(png_ptr, info_ptr, &palette,&num_palette);palette - the palette for the file(array of png_color)num_palette - number of entries in the palettepng_get_gAMA(png_ptr, info_ptr, &gamma);gamma - the gamma the file is writtenat (PNG_INFO_gAMA)png_get_sRGB(png_ptr, info_ptr, &srgb_intent);srgb_intent - the rendering intent (PNG_INFO_sRGB)The presence of the sRGB chunkmeans that the pixel data is in thesRGB color space. This chunk alsoimplies specific values of gAMA andcHRM.png_get_sBIT(png_ptr, info_ptr, &sig_bit);sig_bit - the number of significant bits for(PNG_INFO_sBIT) each of the gray,red, green, and blue channels,whichever are appropriate for thegiven color type (png_color_16)png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,&trans_values);trans - array of transparent entries forpalette (PNG_INFO_tRNS)trans_values - transparent pixel for non-palettedimages (PNG_INFO_tRNS)num_trans - number of transparent entries(PNG_INFO_tRNS)png_get_hIST(png_ptr, info_ptr, &hist);(PNG_INFO_hIST)hist - histogram of palette (array ofpng_color_16)png_get_tIME(png_ptr, info_ptr, &mod_time);mod_time - time image was last modified(PNG_VALID_tIME)png_get_bKGD(png_ptr, info_ptr, &background);background - background color (PNG_VALID_bKGD)num_text = png_get_text(png_ptr, info_ptr, &text_ptr);text_ptr - array of png_text holding imagecommentstext_ptr[i]->key - keyword for comment.text_ptr[i]->text - text comments for currentkeyword.text_ptr[i]->compression - type of compression usedon "text" PNG_TEXT_COMPRESSION_NONEor PNG_TEXT_COMPRESSION_zTXtnum_text - number of commentspng_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,&unit_type);offset_x - positive offset from the left edgeof the screenoffset_y - positive offset from the top edgeof the screenunit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETERpng_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,&unit_type);res_x - pixels/unit physical resolution inx directionres_y - pixels/unit physical resolution inx directionunit_type - PNG_RESOLUTION_UNKNOWN,PNG_RESOLUTION_METERThe data from the pHYs chunk can be retrieved in several convenientforms:res_x = png_get_x_pixels_per_meter(png_ptr,info_ptr)res_y = png_get_y_pixels_per_meter(png_ptr,info_ptr)res_x_and_y = png_get_pixels_per_meter(png_ptr,info_ptr)aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,info_ptr)(Each of these returns 0 [signifying "unknown"] ifthe data is not present or if res_x is 0;res_x_and_y is 0 if res_x != res_y)For more information, see the png_info definition in png.h and thePNG specification for chunk contents. Be careful with trustingrowbytes, as some of the transformations could increase the spaceneeded to hold a row (expand, filler, gray_to_rgb, etc.).See png_read_update_info(), below.A quick word about text_ptr and num_text. PNG stores comments inkeyword/text pairs, one pair per chunk, with no limit on the numberof text chunks, and a 2^31 byte limit on their size. While there aresuggested keywords, there is no requirement to restrict the use to thesestrings. It is strongly suggested that keywords and text be sensibleto humans (that's the point), so don't use abbreviations. Non-printingsymbols are not allowed. See the PNG specification for more details.There is also no requirement to have text after the keyword.Keywords should be limited to 79 Latin-1 characters without leading ortrailing spaces, but non-consecutive spaces are allowed within thekeyword. It is possible to have the same keyword any number of times.The text_ptr is an array of png_text structures, each holding pointerto a keyword and a pointer to a text string. Only the text string maybe null. The keyword/text pairs are put into the array in the orderthat they are received. However, some or all of the text chunks may beafter the image, so, to make sure you have read all the text chunks,don't mess with these until after you read the stuff after the image.This will be mentioned again below in the discussion that goes withpng_read_end().After you've read the header information, you can set up the libraryto handle any special transformations of the image data. The variousways to transform the data will be described in the order that theyshould occur. This is important, as some of these change the colortype and/or bit depth of the data, and some others only work oncertain color types and bit depths. Even though each transformationchecks to see if it has data that it can do something with, you shouldmake sure to only enable a transformation if it will be valid for thedata. For example, don't swap red and blue on grayscale data.The colors used for the background and transparency values should besupplied in the same format/depth as the current image data. Theyare stored in the same format/depth as the image data in a bKGD or tRNSchunk, so this is what libpng expects for this data. The colors aretransformed to keep in sync with the image data when an applicationcalls the png_read_update_info() routine (see below).Data will be decoded into the supplied row buffers packed into bytesunless the library has been told to transform it into another format.For example, 4 bit/pixel paletted or grayscale data will be returned2 pixels/byte with the leftmost pixel in the high-order bits of thebyte, unless png_set_packing() is called. 8-bit RGB data will be storedin RGB RGB RGB format unless png_set_filler() is called to insert fillerbytes, either before or after each RGB triplet. 16-bit RGB data willbe returned RRGGBB RRGGBB, with the most significant byte of the colorvalue first, unless png_set_strip_16() is called to transform it toregular RGB RGB triplets, or png_set_filler() is called to insertfiller bytes, either before or after each RRGGBB triplet. Similarly,8-bit or 16-bit grayscale data can be modified with png_set_filler()or png_set_strip_16().The following code transforms grayscale images of less than 8 to 8 bits,changes paletted images to RGB, and adds a full alpha channel if there istransparency information in a tRNS chunk. This is most useful ongrayscale images with bit depths of 2 or 4 or if there is a multiple-imageviewing application that wishes to treat all images in the same way.if (color_type == PNG_COLOR_TYPE_PALETTE &&bit_depth <= 8) png_set_palette_to_rgb(png_ptr);if (color_type == PNG_COLOR_TYPE_GRAY &&bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);if (png_get_valid(png_ptr, info_ptr,PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);These three functions are actually aliases for png_set_expand(), addedin libpng version 1.0.4, with the function names expanded to improve codereadability. In some future version they may actually do differentthings.PNG can have files with 16 bits per channel. If you only can handle8 bits per channel, this will strip the pixels down to 8 bit.if (bit_depth == 16)png_set_strip_16(png_ptr);The png_set_background() function tells libpng to composite imageswith alpha or simple transparency against the supplied backgroundcolor. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),you may use this color, or supply another color more suitable forthe current display (e.g., the background color from a web page). Youneed to tell libpng whether the color is in the gamma space of thedisplay (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or onethat is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don'tknow why anyone would use this, but it's here).If, for some reason, you don't need the alpha channel on an image,and you want to remove it rather than combining it with the background(but the image author certainly had in mind that you *would* combineit with the background, so that's what you should probably do):if (color_type & PNG_COLOR_MASK_ALPHA)png_set_strip_alpha(png_ptr);PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small asthey can, resulting in, for example, 8 pixels per byte for 1 bitfiles. This code expands to 1 pixel per byte without changing thevalues of the pixels:if (bit_depth < 8)png_set_packing(png_ptr);PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixelsstored in a PNG image have been "scaled" or "shifted" up to the nexthigher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to8 bits/sample in the range [0, 255]). However, it is also possible toconvert the PNG pixel data back to the original bit depth of the image.This call reduces the pixels back down to the original bit depth:png_color_16p sig_bit;if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))png_set_shift(png_ptr, sig_bit);PNG files store 3-color pixels in red, green, blue order. This codechanges the storage of the pixels to blue, green, red:if (color_type == PNG_COLOR_TYPE_RGB ||color_type == PNG_COLOR_TYPE_RGB_ALPHA)png_set_bgr(png_ptr);PNG files store RGB pixels packed into 3 bytes. This code expands theminto 4 bytes for windowing systems that need them in this format:if (bit_depth == 8 && color_type ==PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr,filler, PNG_FILLER_BEFORE);where "filler" is the 8 or 16-bit number to fill with, and the location iseither PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whetheryou want the filler before the RGB or after. This transformationdoes not affect images that already have full alpha channels.If you are reading an image with an alpha channel, and you need thedata as ARGB instead of the normal PNG format RGBA:if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)png_set_swap_alpha(png_ptr);For some uses, you may want a grayscale image to be represented asRGB. This code will do that conversion:if (color_type == PNG_COLOR_TYPE_GRAY ||color_type == PNG_COLOR_TYPE_GRAY_ALPHA)png_set_gray_to_rgb(png_ptr);Conversely, you can convert an RGB or RGBA image to grayscale or grayscalewith alpha. This is intended for conversion of images that really aregray (red == green == blue), so the function simply strips out the redand blue channels, leaving the green channel in the gray position.if (color_type == PNG_COLOR_TYPE_RGB ||color_type == PNG_COLOR_TYPE_RGB_ALPHA)png_set_rgb_to_gray(png_ptr, error_action,double red_weight, double green_weight);error_action = 1: silently do the conversionerror_action = 2: issue a warning if the originalimage has any pixel wherered != green or red != blueerror_action = 3: issue an error and abort theconversion if the originalimage has any pixel wherered != green or red != bluered_weight: weight of red component(NULL -> default 54/256)green_weight: weight of green component(NULL -> default 183/256)If you have set error_action = 1 or 2, you canlater check whether the image really was gray, after processingthe image rows, with the png_get_rgb_to_gray_status(png_ptr) function.It will return a png_byte that is zero if the image was gray or1 if there were any non-gray pixels. bKGD and sBIT datawill be silently converted to grayscale, using the green channeldata, regardless of the error_action setting.With 0.0<=red_weight+green_weight<=1.0,the normalized graylevel is computed:int rw = red_weight * 256;int gw = green_weight * 256;int bw = 256 - (rw + gw);gray = (rw*red + gw*green + bw*blue)/256;The default values approximate those recommended in the CharlesPoynton's Color FAQ, <http://www.inforamp.net/~poynton/>Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.netY = 0.212671 * R + 0.715160 * G + 0.072169 * BLibpng approximates this withY = 0.211 * R + 0.715 * G + 0.074 * Bwhich can be expressed with integers asY = (54 * R + 183 * G + 19 * B)/256The calculation is done in a linear colorspace, if the image gammais known.If you have a grayscale and you are using png_set_expand_depth() orpng_set_expand() to change toa higher bit-depth, you must either supply the background color as a grayvalue at the original file bit-depth (need_expand = 1) or else supply thebackground color as an RGB triplet at the final, expanded bit depth(need_expand = 0). Similarly, if you are reading a paletted image, youmust either supply the background color as a palette index (need_expand = 1)or as an RGB triplet that may or may not be in the palette (need_expand = 0).png_color_16 my_background;png_color_16p image_background;if (png_get_bKGD(png_ptr, info_ptr, &image_background))png_set_background(png_ptr, image_background,PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);elsepng_set_background(png_ptr, &my_background,PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);To properly display PNG images on any kind of system, the application needsto know what the display gamma is. Ideally, the user will know this, andthe application will allow them to set it. One method of allowing the userto set the display gamma separately for each system is to check for aSCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully becorrectly set.Note that display_gamma is the overall gamma correction required to producepleasing results, which depends on the lighting conditions in the surroundingenvironment. In a dim or brightly lit room, no compensation other thanthe physical gamma exponent of the monitor is needed, while in a dark rooma slightly smaller exponent is better.double gamma, screen_gamma;if (/* We have a user-defined screengamma value */){screen_gamma = user_defined_screen_gamma;}/* One way that applications can share the samescreen gamma value */else if ((gamma_str = getenv("SCREEN_GAMMA"))!= NULL){screen_gamma = (double)atof(gamma_str);}/* If we don't have another value */else{screen_gamma = 2.2; /* A good guess for aPC monitor in a bright office or a dim room */screen_gamma = 2.0; /* A good guess for aPC monitor in a dark room */screen_gamma = 1.7 or 1.0; /* A goodguess for Mac systems */}The png_set_gamma() function handles gamma transformations of the data.Pass both the file gamma and the current screen_gamma. If the file doesnot have a gamma value, you can pass one anyway if you have an idea whatit is (usually 0.45455 is a good guess for GIF images on PCs). Notethat file gammas are inverted from screen gammas. See the discussionson gamma in the PNG specification for an excellent description of whatgamma is, and why all applications should support it. It is stronglyrecommended that PNG viewers support gamma correction.if (png_get_gAMA(png_ptr, info_ptr, &gamma))png_set_gamma(png_ptr, screen_gamma, gamma);elsepng_set_gamma(png_ptr, screen_gamma, 0.45455);If you need to reduce an RGB file to a paletted file, or if a palettedfile has more entries then will fit on your screen, png_set_dither()will do that. Note that this is a simple match dither that merelyfinds the closest color available. This should work fairly well withoptimized palettes, and fairly badly with linear color cubes. If youpass a palette that is larger then maximum_colors, the file willreduce the number of colors in the palette so it will fit intomaximum_colors. If there is a histogram, it will use it to makemore intelligent choices when reducing the palette. If there is nohistogram, it may not do as good a job.if (color_type & PNG_COLOR_MASK_COLOR){if (png_get_valid(png_ptr, info_ptr,PNG_INFO_PLTE)){png_color_16p histogram;png_get_hIST(png_ptr, info_ptr,&histogram);png_set_dither(png_ptr, palette, num_palette,max_screen_colors, histogram, 1);}else{png_color std_color_cube[MAX_SCREEN_COLORS] ={ ... colors ... };png_set_dither(png_ptr, std_color_cube,MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,NULL,0);}}PNG files describe monochrome as black being zero and white being one.The following code will reverse this (make black be one and white bezero):if (bit_depth == 1 && color_type == PNG_COLOR_GRAY)png_set_invert_mono(png_ptr);PNG files store 16 bit pixels in network byte order (big-endian,ie. most significant bits first). This code changes the storage to theother way (little-endian, i.e. least significant bits first, theway PCs store them):if (bit_depth == 16)png_set_swap(png_ptr);If you are using packed-pixel images (1, 2, or 4 bits/pixel), and youneed to change the order the pixels are packed into bytes, you can use:if (bit_depth < 8)png_set_packswap(png_ptr);The last thing to handle is interlacing; this is covered in detail below,but you must call the function here if you want libpng to handle expansionof the interlaced image.number_of_passes = png_set_interlace_handling(png_ptr);After setting the transformations, libpng can update your png_infostructure to reflect any transformations you've requested with thiscall. This is most useful to update the info structure's rowbytesfield so you can use it to allocate your image memory. This functionwill also update your palette with the correct screen_gamma andbackground if these have been given with the calls above.png_read_update_info(png_ptr, info_ptr);After you call png_read_update_info(), you can allocate anymemory you need to hold the image. The row data is simplyraw byte data for all forms of images. As the actual allocationvaries among applications, no example will be given. If youare allocating one large chunk, you will need to build anarray of pointers to each row, as it will be needed for someof the functions below.After you've allocated memory, you can read the image data.The simplest way to do this is in one function call. If you areallocating enough memory to hold the whole image, you can justcall png_read_image() and libpng will read in all the image dataand put it in the memory area supplied. You will need to pass inan array of pointers to each row.This function automatically handles interlacing, so you don't needto call png_set_interlace_handling() or call this function multipletimes, or any of that other stuff necessary with png_read_rows().png_read_image(png_ptr, row_pointers);where row_pointers is:png_bytep row_pointers[height];You can point to void or char or whatever you use for pixels.If you don't want to read in the whole image at once, you canuse png_read_rows() instead. If there is no interlacing (checkinterlace_type == PNG_INTERLACE_NONE), this is simple:png_read_rows(png_ptr, row_pointers, NULL,number_of_rows);where row_pointers is the same as in the png_read_image() call.If you are doing this just one row at a time, you can do this withrow_pointers:png_bytep row_pointers = row;png_read_row(png_ptr, &row_pointers, NULL);If the file is interlaced (info_ptr->interlace_type != 0), things getsomewhat harder. The only current (PNG Specification version 1.2)interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)is a somewhat complicated 2D interlace scheme, known as Adam7, thatbreaks down an image into seven smaller images of varying size, basedon an 8x8 grid.libpng can fill out those images or it can give them to you "as is".If you want them filled out, there are two ways to do that. The onementioned in the PNG specification is to expand each pixel to coverthose pixels that have not been read yet (the "rectangle" method).This results in a blocky image for the first pass, which graduallysmooths out as more pixels are read. The other method is the "sparkle"method, where pixels are drawn only in their final locations, with therest of the image remaining whatever colors they were initialized tobefore the start of the read. The first method usually looks better,but tends to be slower, as there are more pixels to put in the rows.If you don't want libpng to handle the interlacing details, just callpng_read_rows() seven times to read in all seven images. Each of theimages is a valid image by itself, or they can all be combined on an8x8 grid to form a single image (although if you intend to combine themyou would be far better off using the libpng interlace handling).The first pass will return an image 1/8 as wide as the entire image(every 8th column starting in column 0) and 1/8 as high as the original(every 8th row starting in row 0), the second will be 1/8 as wide(starting in column 4) and 1/8 as high (also starting in row 0). Thethird pass will be 1/4 as wide (every 4th pixel starting in column 0) and1/8 as high (every 8th row starting in row 4), and the fourth pass willbe 1/4 as wide and 1/4 as high (every 4th column starting in column 2,and every 4th row starting in row 0). The fifth pass will return animage 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),while the sixth pass will be 1/2 as wide and 1/2 as high as the original(starting in column 1 and row 0). The seventh and final pass will be aswide as the original, and 1/2 as high, containing all of the oddnumbered scanlines. Phew!If you want libpng to expand the images, call this before callingpng_start_read_image() or png_read_update_info():if (interlace_type == PNG_INTERLACE_ADAM7)number_of_passes= png_set_interlace_handling(png_ptr);This will return the number of passes needed. Currently, thisis seven, but may change if another interlace type is added.This function can be called even if the file is not interlaced,where it will return one pass.If you are not going to display the image after each pass, but aregoing to wait until the entire image is read in, use the sparkleeffect. This effect is faster and the end result of either methodis exactly the same. If you are planning on displaying the imageafter each pass, the "rectangle" effect is generally considered thebetter looking one.If you only want the "sparkle" effect, just call png_read_rows() asnormal, with the third parameter NULL. Make sure you make pass overthe image number_of_passes times, and you don't change the data in therows between calls. You can change the locations of the data, justnot the data. Each pass only writes the pixels appropriate for thatpass, and assumes the data from previous passes is still valid.png_read_rows(png_ptr, row_pointers, NULL,number_of_rows);If you only want the first effect (the rectangles), do the same asbefore except pass the row buffer in the third parameter, and leavethe second parameter NULL.png_read_rows(png_ptr, NULL, row_pointers,number_of_rows);After you are finished reading the image, you can finish readingthe file. If you are interested in comments or time, which may bestored either before or after the image data, you should pass theseparate png_info struct if you want to keep the comments frombefore and after the image separate. If you are not interested, youcan pass NULL.png_read_end(png_ptr, end_info);When you are done, you can free all memory allocated by libpng like this:png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);For a more compact example of reading a PNG image, see the file example.c.Reading PNG files progressively:The progressive reader is slightly different then the non-progressivereader. Instead of calling png_read_info(), png_read_rows(), andpng_read_end(), you make one call to png_process_data(), which callscallbacks when it has the info, a row, or the end of the image. Youset up these callbacks with png_set_progressive_read_fn(). You don'thave to worry about the input/output functions of libpng, as you aregiving the library the data directly in png_process_data(). I willassume that you have read the section on reading PNG files above,so I will only highlight the differences (although I will showall of the code).png_structp png_ptr;png_infop info_ptr;/* An example code fragment of how you wouldinitialize the progressive reader in yourapplication. */intinitialize_png_reader(){png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,user_error_fn, user_warning_fn);if (!png_ptr)return -1;info_ptr = png_create_info_struct(png_ptr);if (!info_ptr){png_destroy_read_struct(&png_ptr, (png_infopp)NULL,(png_infopp)NULL);return -1;}if (setjmp(png_ptr->jmpbuf)){png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL);return -1;}/* This one's new. You can provide functionsto be called when the header info is valid,when each row is completed, and when the imageis finished. If you aren't using all functions,you can specify NULL parameters. Even when allthree functions are NULL, you need to callpng_set_progressive_read_fn(). You can useany struct as the user_ptr (cast to a void pointerfor the function call), and retrieve the pointerfrom inside the callbacks using the functionpng_get_progressive_ptr(png_ptr);which will return a void pointer, which you haveto cast appropriately.*/png_set_progressive_read_fn(png_ptr, (void *)user_ptr,info_callback, row_callback, end_callback);return 0;}/* A code fragment that you call as you receive blocksof data */intprocess_data(png_bytep buffer, png_uint_32 length){if (setjmp(png_ptr->jmpbuf)){png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL);return -1;}/* This one's new also. Simply give it a chunkof data from the file stream (in order, ofcourse). On machines with segmented memorymodels machines, don't give it any more than64K. The library seems to run fine with sizesof 4K. Although you can give it much less ifnecessary (I assume you can give it chunks of1 byte, I haven't tried less then 256 bytesyet). When this function returns, you maywant to display any rows that were generatedin the row callback if you don't already doso there.*/png_process_data(png_ptr, info_ptr, buffer, length);return 0;}/* This function is called (as set bypng_set_progressive_read_fn() above) when enough datahas been supplied so all of the header has beenread.*/voidinfo_callback(png_structp png_ptr, png_infop info){/* Do any setup here, including setting any ofthe transformations mentioned in the ReadingPNG files section. For now, you _must_ calleither png_start_read_image() orpng_read_update_info() after all thetransformations are set (even if you don't setany). You may start getting rows beforepng_process_data() returns, so this is yourlast chance to prepare for that.*/}/* This function is called when each row of imagedata is complete */voidrow_callback(png_structp png_ptr, png_bytep new_row,png_uint_32 row_num, int pass){/* If the image is interlaced, and you turnedon the interlace handler, this function willbe called for every row in every pass. Someof these rows will not be changed from theprevious pass. When the row is not changed,the new_row variable will be NULL. The rowsand passes are called in order, so you don'treally need the row_num and pass, but I'msupplying them because it may make your lifeeasier.For the non-NULL rows of interlaced images,you must call png_progressive_combine_row()passing in the row and the old row. You cancall this function for NULL rows (it will justreturn) and for non-interlaced images (it justdoes the memcpy for you) if it will make thecode easier. Thus, you can just do this forall cases:*/png_progressive_combine_row(png_ptr, old_row,new_row);/* where old_row is what was displayed forpreviously for the row. Note that the firstpass (pass == 0, really) will completely coverthe old row, so the rows do not have to beinitialized. After the first pass (and onlyfor interlaced images), you will have to passthe current row, and the function will combinethe old row and the new row.*/}voidend_callback(png_structp png_ptr, png_infop info){/* This function is called after the whole imagehas been read, including any chunks after theimage (up to and including the IEND). Youwill usually have the same info chunk as youhad in the header, although some data may havebeen added to the comments and time fields.Most people won't do much here, perhaps settinga flag that marks the image as finished.*/}.SH IV. WritingMuch of this is very similar to reading. However, everything ofimportance is repeated here, so you won't have to constantly lookback up in the reading section to understand writing.You will want to do the I/O initialization before you get into libpng,so if it doesn't work, you don't have anything to undo. If you are notusing the standard I/O functions, you will need to replace them withcustom writing functions. See the discussion under Customizing libpng.FILE *fp = fopen(file_name, "wb");if (!fp){return;}Next, png_struct and png_info need to be allocated and initialized.As these can be both relatively large, you may not want to store theseon the stack, unless you have stack space to spare. Of course, youwill want to check if they return NULL. If you are also reading,you won't want to name your read structure and your write structureboth "png_ptr"; you can call them anything you like, such as"read_ptr" and "write_ptr". Look at pngtest.c, for example.png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,user_error_fn, user_warning_fn);if (!png_ptr)return;png_infop info_ptr = png_create_info_struct(png_ptr);if (!info_ptr){png_destroy_write_struct(&png_ptr,(png_infopp)NULL);return;}If you want to use your own memory allocation routines,define PNG_USER_MEM_SUPPORTED and usepng_create_write_struct_2() instead of png_create_read_struct():png_structp png_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,user_error_fn, user_warning_fn, (png_voidp)user_mem_ptr, user_malloc_fn, user_free_fn);After you have these structures, you will need to set up theerror handling. When libpng encounters an error, it expects tolongjmp() back to your routine. Therefore, you will need to callsetjmp() and pass the png_ptr->jmpbuf. If youwrite the file from different routines, you will need to updatethe jmpbuf field every time you enter a new routine that willcall a png_ function. See your documentation of setjmp/longjmpfor your compiler for more information on setjmp/longjmp. Seethe discussion on libpng error handling in the Customizing Libpngsection below for more information on the libpng error handling.if (setjmp(png_ptr->jmpbuf)){png_destroy_write_struct(&png_ptr, &info_ptr);fclose(fp);return;}...return;Now you need to set up the output code. The default for libpng is touse the C function fwrite(). If you use this, you will need to pass avalid FILE * in the function png_init_io(). Be sure that the file isopened in binary mode. Again, if you wish to handle writing data inanother way, see the discussion on libpng I/O handling in the CustomizingLibpng section below.png_init_io(png_ptr, fp);At this point, you can set up a callback function that will becalled after each row has been written, which you can use to controla progress meter or the like. It's demonstrated in pngtest.c.You must supply a functionvoid write_row_callback(png_ptr, png_uint_32 row, int pass);{/* put your code here */}(You can give it another name that you like instead of "write_row_callback")To inform libpng about your function, usepng_set_write_status_fn(png_ptr, write_row_callback);You now have the option of modifying how the compression library willrun. The following functions are mainly for testing, but may be usefulin some cases, like if you need to write PNG files extremely fast andare willing to give up some compression, or if you want to get themaximum possible compression at the expense of slower writing. If youhave no special needs in this area, let the library do what it wants bynot calling this function at all, as it has been tuned to deliver a goodspeed/compression ratio. The second parameter to png_set_filter() isthe filter method, for which the only valid value is '0' (as of theJuly 1999 PNG specification, version 1.2). The third parameter is aflag that indicates which filter type(s) are to be tested for eachscanline. See the Compression Library for details on the specific filtertypes./* turn on or off filtering, and/or choosespecific filters */png_set_filter(png_ptr, 0,PNG_FILTER_NONE | PNG_FILTER_SUB |PNG_FILTER_PAETH);The png_set_compression_???() functions interface to the zlib compressionlibrary, and should mostly be ignored unless you really know what you aredoing. The only generally useful call is png_set_compression_level()which changes how much time zlib spends on trying to compress the imagedata. See the Compression Library for details on the compression levels./* set the zlib compression level */png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);/* set other zlib parameters */png_set_compression_mem_level(png_ptr, 8);png_set_compression_strategy(png_ptr,Z_DEFAULT_STRATEGY);png_set_compression_window_bits(png_ptr, 15);png_set_compression_method(png_ptr, 8);You now need to fill in the png_info structure with all the data youwish to write before the actual image. Note that the only thing youare allowed to write after the image is the text chunks and the timechunk (as of PNG Specification 1.2, anyway). See png_write_end() andthe latest PNG specification for more information on that. If youwish to write them before the image, fill them in now, and flag thatdata as being valid. If you want to wait until after the data, don'tfill them until png_write_end(). For all the fields in png_info andtheir data types, see png.h. For explanations of what the fieldscontain, see the PNG specification.Some of the more important parts of the png_info are:png_set_IHDR(png_ptr, info_ptr, width, height,bit_depth, color_type, interlace_type,compression_type, filter_type)width - holds the width of the imagein pixels (up to 2^31).height - holds the height of the imagein pixels (up to 2^31).bit_depth - holds the bit depth of one of theimage channels.(valid values are 1, 2, 4, 8, 16and depend also on thecolor_type. See also significantbits (sBIT) below).color_type - describes which color/alphachannels are present.PNG_COLOR_TYPE_GRAY(bit depths 1, 2, 4, 8, 16)PNG_COLOR_TYPE_GRAY_ALPHA(bit depths 8, 16)PNG_COLOR_TYPE_PALETTE(bit depths 1, 2, 4, 8)PNG_COLOR_TYPE_RGB(bit_depths 8, 16)PNG_COLOR_TYPE_RGB_ALPHA(bit_depths 8, 16)PNG_COLOR_MASK_PALETTEPNG_COLOR_MASK_COLORPNG_COLOR_MASK_ALPHAinterlace_type - PNG_INTERLACE_NONE orPNG_INTERLACE_ADAM7compression_type - (must bePNG_COMPRESSION_TYPE_DEFAULT)filter_type - (must be PNG_FILTER_TYPE_DEFAULT)png_set_PLTE(png_ptr, info_ptr, palette,num_palette);palette - the palette for the file(array of png_color)num_palette - number of entries in the palettepng_set_gAMA(png_ptr, info_ptr, gamma);gamma - the gamma the image was createdat (PNG_INFO_gAMA)png_set_sRGB(png_ptr, info_ptr, srgb_intent);srgb_intent - the rendering intent(PNG_INFO_sRGB) The presence ofthe sRGB chunk means that the pixeldata is in the sRGB color space.This chunk also implies specificvalues of gAMA and cHRM. Renderingintent is the CSS-1 property thathas been defined by the InternationalColor Consortium(http://www.color.org).It can be one ofPNG_SRGB_INTENT_SATURATION,PNG_SRGB_INTENT_PERCEPTUAL,PNG_SRGB_INTENT_ABSOLUTE, orPNG_SRGB_INTENT_RELATIVE.png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,srgb_intent);srgb_intent - the rendering intent(PNG_INFO_sRGB) The presence of thesRGB chunk means that the pixeldata is in the sRGB color space.This function also causes gAMA andcHRM chunks with the specific valuesthat are consistent with sRGB to bewritten.png_set_sBIT(png_ptr, info_ptr, sig_bit);sig_bit - the number of significant bits for(PNG_INFO_sBIT) each of the gray, red,green, and blue channels, whichever areappropriate for the given color type(png_color_16)png_set_tRNS(png_ptr, info_ptr, trans, num_trans,trans_values);trans - array of transparent entries forpalette (PNG_INFO_tRNS)trans_values - transparent pixel for non-palettedimages (PNG_INFO_tRNS)num_trans - number of transparent entries(PNG_INFO_tRNS)png_set_hIST(png_ptr, info_ptr, hist);(PNG_INFO_hIST)hist - histogram of palette (array ofpng_color_16)png_set_tIME(png_ptr, info_ptr, mod_time);mod_time - time image was last modified(PNG_VALID_tIME)png_set_bKGD(png_ptr, info_ptr, background);background - background color (PNG_VALID_bKGD)png_set_text(png_ptr, info_ptr, text_ptr, num_text);text_ptr - array of png_text holding imagecommentstext_ptr[i]->key - keyword for comment.text_ptr[i]->text - text comments for currentkeyword.text_ptr[i]->compression - type of compression usedon "text" PNG_TEXT_COMPRESSION_NONE orPNG_TEXT_COMPRESSION_zTXtnum_text - number of comments in text_ptrpng_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,unit_type);offset_x - positive offset from the leftedge of the screenoffset_y - positive offset from the topedge of the screenunit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETERpng_set_pHYs(png_ptr, info_ptr, res_x, res_y,unit_type);res_x - pixels/unit physical resolutionin x directionres_y - pixels/unit physical resolutionin y directionunit_type - PNG_RESOLUTION_UNKNOWN,PNG_RESOLUTION_METERIn PNG files, the alpha channel in an image is the level of opacity.If your data is supplied as a level of transparency, you can invert thealpha channel before you write it, so that 0 is fully transparent and 255(in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque,withpng_set_invert_alpha(png_ptr);This must appear here instead of later with the other transformationsbecause in the case of paletted images the tRNS chunk data has tobe inverted before the tRNS chunk is written. If your image is not apaletted image, the tRNS data (which in such cases represents a singlecolor to be rendered as transparent) won't be changed.A quick word about text and num_text. text is an array of png_textstructures. num_text is the number of valid structures in the array.If you want, you can use max_text to hold the size of the array, butlibpng ignores it for writing (it does use it for reading). Eachpng_text structure holds a keyword-text value, and a compression type.The compression types have the same valid numbers as the compressiontypes of the image data. Currently, the only valid number is zero.However, you can store text either compressed or uncompressed, unlikeimages, which always have to be compressed. So if you don't want thetext compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.Until text gets around 1000 bytes, it is not worth compressing it.After the text has been written out to the file, the compression typeis set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,so that it isn't written out again at the end (in case you are callingpng_write_end() with the same struct.The keywords that are given in the PNG Specification are:Title Short (one line) title orcaption for imageAuthor Name of image's creatorDescription Description of image (possibly long)Copyright Copyright noticeCreation Time Time of original image creation(usually RFC 1123 format, see below)Software Software used to create the imageDisclaimer Legal disclaimerWarning Warning of nature of contentSource Device used to create the imageComment Miscellaneous comment; conversionfrom other image formatThe keyword-text pairs work like this. Keywords should be shortsimple descriptions of what the comment is about. Some typicalkeywords are found in the PNG specification, as is some recommendationson keywords. You can repeat keywords in a file. You can even writesome text before the image and some after. For example, you may wantto put a description of the image before the image, but leave thedisclaimer until after, so viewers working over modem connectionsdon't have to wait for the disclaimer to go over the modem beforethey start seeing the image. Finally, keywords should be fullwords, not abbreviations. Keywords and text are in the ISO 8859-1(Latin-1) character set (a superset of regular ASCII) and can notcontain NUL characters, and should not contain control or otherunprintable characters. To make the comments widely readable, stickwith basic ASCII, and avoid machine specific character set extensionslike the IBM-PC character set. The keyword must be present, butyou can leave off the text string on non-compressed pairs.Compressed pairs must have a text string, as only the text stringis compressed anyway, so the compression would be meaningless.PNG supports modification time via the png_time structure. Twoconversion routines are proved, png_convert_from_time_t() fortime_t and png_convert_from_struct_tm() for struct tm. Thetime_t routine uses gmtime(). You don't have to use either ofthese, but if you wish to fill in the png_time structure directly,you should provide the time in universal time (GMT) if possibleinstead of your local time. Note that the year number is the fullyear (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), andthat months start with 1.If you want to store the time of the original image creation, you shoulduse a plain tEXt chunk with the "Creation Time" keyword. This isnecessary because the "creation time" of a PNG image is somewhat vague,depending on whether you mean the PNG file, the time the image wascreated in a non-PNG format, a still photo from which the image wasscanned, or possibly the subject matter itself. In order to facilitatemachine-readable dates, it is recommended that the "Creation Time"tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),although this isn't a requirement. Unlike the tIME chunk, the"Creation Time" tEXt chunk is not expected to be automatically changedby the software. To facilitate the use of RFC 1123 dates, a functionpng_convert_to_rfc1123(png_timep) is provided to convert from PNGtime to an RFC 1123 format string.You are now ready to write all the file information up to the actualimage data. You do this with a call to png_write_info().png_write_info(png_ptr, info_ptr);After you've written the file information, you can set up the libraryto handle any special transformations of the image data. The variousways to transform the data will be described in the order that theyshould occur. This is important, as some of these change the colortype and/or bit depth of the data, and some others only work oncertain color types and bit depths. Even though each transformationchecks to see if it has data that it can do something with, you shouldmake sure to only enable a transformation if it will be valid for thedata. For example, don't swap red and blue on grayscale data.PNG files store RGB pixels packed into 3 or 6 bytes. This code tellsthe library to expand the input data to 4 or 8 bytes per pixel(or expand 1 or 2-byte grayscale data to 2 or 4 bytes per pixel).png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);where the 0 is the value that will be put in the 4th byte, and thelocation is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, dependingupon whether the filler byte is stored XRGB or RGBX.PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small asthey can, resulting in, for example, 8 pixels per byte for 1 bit files.If the data is supplied at 1 pixel per byte, use this code, which willcorrectly pack the pixels into a single byte:png_set_packing(png_ptr);PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If yourdata is of another bit depth, you can write an sBIT chunk into thefile so that decoders can get the original data if desired./* Set the true bit depth of the image data */if (color_type & PNG_COLOR_MASK_COLOR){sig_bit.red = true_bit_depth;sig_bit.green = true_bit_depth;sig_bit.blue = true_bit_depth;}else{sig_bit.gray = true_bit_depth;}if (color_type & PNG_COLOR_MASK_ALPHA){sig_bit.alpha = true_bit_depth;}png_set_sBIT(png_ptr, info_ptr, &sig_bit);If the data is stored in the row buffer in a bit depth other thanone supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),this will scale the values to appear to be the correct bit depth asis required by PNG.png_set_shift(png_ptr, &sig_bit);PNG files store 16 bit pixels in network byte order (big-endian,ie. most significant bits first). This code would be used if they aresupplied the other way (little-endian, i.e. least significant bitsfirst, the way PCs store them):if (bit_depth > 8)png_set_swap(png_ptr);If you are using packed-pixel images (1, 2, or 4 bits/pixel), and youneed to change the order the pixels are packed into bytes, you can use:if (bit_depth < 8)png_set_packswap(png_ptr);PNG files store 3 color pixels in red, green, blue order. This codewould be used if they are supplied as blue, green, red:png_set_bgr(png_ptr);PNG files describe monochrome as black being zero and white beingone. This code would be used if the pixels are supplied with this reversed(black being one and white being zero):png_set_invert_mono(png_ptr);Finally, you can write your own transformation function if none ofthe existing ones meets your needs. This is done by setting a callbackwithpng_set_write_user_transform_fn(png_ptr,write_transform_fn);You must supply the functionvoid write_transform_fn(png_ptr ptr, row_info_ptrrow_info, png_bytep data)See pngtest.c for a working example. Your function will be calledbefore any of the other transformations are processed.You can also set up a pointer to a user structure for use by yourcallback function.png_set_user_transform_info(png_ptr, user_ptr, 0, 0);The user_channels and user_depth parameters of this function are ignoredwhen writing; you can set them to zero as shown.You can retrieve the pointer via the functionpng_get_user_transform_ptr(). For example:voidp write_user_transform_ptr =png_get_user_transform_ptr(png_ptr);It is possible to have libpng flush any pending output, either manually,or automatically after a certain number of lines have been written. Toflush the output stream a single time call:png_write_flush(png_ptr);and to have libpng flush the output stream periodically after a certainnumber of scanlines have been written, call:png_set_flush(png_ptr, nrows);Note that the distance between rows is from the last time png_write_flush()was called, or the first row of the image if it has never been called.So if you write 50 lines, and then png_set_flush 25, it will flush theoutput on the next scanline, and every 25 lines thereafter, unlesspng_write_flush() is called before 25 more lines have been written.If nrows is too small (less than about 10 lines for a 640 pixel wideRGB image) the image compression may decrease noticeably (although thismay be acceptable for real-time applications). Infrequent flushing willonly degrade the compression performance by a few percent over imagesthat do not use flushing.That's it for the transformations. Now you can write the image data.The simplest way to do this is in one function call. If have thewhole image in memory, you can just call png_write_image() and libpngwill write the image. You will need to pass in an array of pointers toeach row. This function automatically handles interlacing, so you don'tneed to call png_set_interlace_handling() or call this function multipletimes, or any of that other stuff necessary with png_write_rows().png_write_image(png_ptr, row_pointers);where row_pointers is:png_byte *row_pointers[height];You can point to void or char or whatever you use for pixels.If you don't want to write the whole image at once, you canuse png_write_rows() instead. If the file is not interlaced,this is simple:png_write_rows(png_ptr, row_pointers,number_of_rows);row_pointers is the same as in the png_write_image() call.If you are just writing one row at a time, you can do this withrow_pointers:png_bytep row_pointer = row;png_write_row(png_ptr, &row_pointer);When the file is interlaced, things can get a good deal morecomplicated. The only currently (as of August 1999 -- PNG Specificationversion 1.2, dated July 1999) defined interlacing scheme for PNG filesis the "Adam7" interlace scheme, that breaks down animage into seven smaller images of varying size. libpng will buildthese images for you, or you can do them yourself. If you want tobuild them yourself, see the PNG specification for details of whichpixels to write when.If you don't want libpng to handle the interlacing details, justuse png_set_interlace_handling() and call png_write_rows() thecorrect number of times to write all seven sub-images.If you want libpng to build the sub-images, call this before you startwriting any rows:number_of_passes =png_set_interlace_handling(png_ptr);This will return the number of passes needed. Currently, thisis seven, but may change if another interlace type is added.Then write the complete image number_of_passes times.png_write_rows(png_ptr, row_pointers,number_of_rows);As some of these rows are not used, and thus return immediately,you may want to read about interlacing in the PNG specification,and only update the rows that are actually used.After you are finished writing the image, you should finish writingthe file. If you are interested in writing comments or time, you shouldpass an appropriately filled png_info pointer. If you are not interested,you can pass NULL.png_write_end(png_ptr, info_ptr);When you are done, you can free all memory used by libpng like this:png_destroy_write_struct(&png_ptr, &info_ptr);You must free any data you allocated for info_ptr, such as comments,palette, or histogram, before the call to png_destroy_write_struct();For a more compact example of writing a PNG image, see the file example.c..SH V. Modifying/Customizing libpng:There are two issues here. The first is changing how libpng doesstandard things like memory allocation, input/output, and error handling.The second deals with more complicated things like adding new chunks,adding new transformations, and generally changing how libpng works.All of the memory allocation, input/output, and error handling in libpnggoes through callbacks that are user settable. The default routines arein pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively. To changethese functions, call the appropriate png_set_???_fn() function.Memory allocation is done through the functions png_large_malloc(),png_malloc(), png_realloc(), png_large_free(), and png_free(). Thesecurrently just call the standard C functions. The large functions musthandle exactly 64K, but they don't have to handle more than that. Ifyour pointers can't access more then 64K at a time, you will want to setMAXSEG_64K in zlib.h. Since it is unlikely that the method of handlingmemory allocation on a platform will change between applications, thesefunctions must be modified in the library at compile time.Input/Output in libpng is done through png_read() and png_write(),which currently just call fread() and fwrite(). The FILE * is stored inpng_struct and is initialized via png_init_io(). If you wish to changethe method of I/O, the library supplies callbacks that you can setthrough the function png_set_read_fn() and png_set_write_fn() at runtime, instead of calling the png_init_io() function.These functionsalso provide a void pointer that can be retrieved via the functionpng_get_io_ptr(). For example:png_set_read_fn(png_structp read_ptr,voidp read_io_ptr, png_rw_ptr read_data_fn)png_set_write_fn(png_structp write_ptr,voidp write_io_ptr, png_rw_ptr write_data_fn,png_flush_ptr output_flush_fn);voidp read_io_ptr = png_get_io_ptr(read_ptr);voidp write_io_ptr = png_get_io_ptr(write_ptr);The replacement I/O functions should have prototypes as follows:void user_read_data(png_structp png_ptr,png_bytep data, png_uint_32 length);void user_write_data(png_structp png_ptr,png_bytep data, png_uint_32 length);void user_flush_data(png_structp png_ptr);Supplying NULL for the read, write, or flush functions sets them backto using the default C stream functions. It is an error to read froma write stream, and vice versa.Error handling in libpng is done through png_error() and png_warning().Errors handled through png_error() are fatal, meaning that png_error()should never return to its caller. Currently, this is handled viasetjmp() and longjmp(), but you could change this to do things likeexit() if you should wish. On non-fatal errors, png_warning() is calledto print a warning message, and then control returns to the calling code.By default png_error() and png_warning() print a message on stderr viafprintf() unless the library is compiled with PNG_NO_STDIO defined. Ifyou wish to change the behavior of the error functions, you will need toset up your own message callbacks. These functions are normally suppliedat the time that the png_struct is created. It is also possible to changethese functions after png_create_???_struct() has been called by calling:png_set_error_fn(png_structp png_ptr,png_voidp error_ptr, png_error_ptr error_fn,png_error_ptr warning_fn);png_voidp error_ptr = png_get_error_ptr(png_ptr);If NULL is supplied for either error_fn or warning_fn, then the libpngdefault function will be used, calling fprintf() and/or longjmp() if aproblem is encountered. The replacement error functions should haveparameters as follows:void user_error_fn(png_structp png_ptr,png_const_charp error_msg);void user_warning_fn(png_structp png_ptr,png_const_charp warning_msg);The motivation behind using setjmp() and longjmp() is the C++ throw andcatch exception handling methods. This makes the code much easier to write,as there is no need to check every return code of every function call.However, there are some uncertainties about the status of local variablesafter a longjmp, so the user may want to be careful about doing anything aftersetjmp returns non-zero besides returning itself. Consult your compilerdocumentation for more details.If you need to read or write custom chunks, you will need to get deeperinto the libpng code, as a mechanism has not yet been supplied for usercallbacks with custom chunks. First, read the PNG specification, and havea first level of understanding of how it works. Pay particular attentionto the sections that describe chunk names, and look at how other chunkswere designed, so you can do things similarly. Second, check out thesections of libpng that read and write chunks. Try to find a chunk thatis similar to yours and copy off of it. More details can be found in thecomments inside the code. A way of handling unknown chunks in a genericmethod, potentially via callback functions, would be best.If you wish to write your own transformation for the data, look throughthe part of the code that does the transformations, and check out some ofthe simpler ones to get an idea of how they work. Try to find a similartransformation to the one you want to add and copy off of it. More detailscan be found in the comments inside the code itself.Configuring for 16 bit platforms:You may need to change the png_large_malloc() and png_large_free()routines in pngmem.c, as these are required to allocate 64K, althoughthere is already support for many of the common DOS compilers. Also,you will want to look into zconf.h to tell zlib (and thus libpng) thatit cannot allocate more then 64K at a time. Even if you can, the memorywon't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K.Configuring for DOS:For DOS users who only have access to the lower 640K, you willhave to limit zlib's memory usage via a png_set_compression_mem_level()call. See zlib.h or zconf.h in the zlib library for more information.Configuring for Medium Model:Libpng's support for medium model has been tested on most of the popularcompilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD getsdefined, and FAR gets defined to far in pngconf.h, and you should beall set. Everything in the library (except for zlib's structure) isexpecting far data. You must use the typedefs with the p or pp onthe end for pointers (or at least look at them and be careful). Makenote that the row's of data are defined as png_bytepp, which is anunsigned char far * far *.Configuring for gui/windowing platforms:You will need to write new error and warning functions that use the GUIinterface, as described previously, and set them to be the error andwarning functions at the time that png_create_???_struct() is called,in order to have them available during the structure initialization.They can be changed later via png_set_error_fn(). On some compilers,you may also have to change the memory allocators (png_malloc, etc.).Configuring for compiler xxx:All includes for libpng are in pngconf.h. If you need to add/change/deletean include, this is the place to do it. The includes that are notneeded outside libpng are protected by the PNG_INTERNAL definition,which is only defined for those routines inside libpng itself. Thefiles in libpng proper only include png.h, which includes pngconf.h.Configuring zlib:There are special functions to configure the compression. Perhaps themost useful one changes the compression level, which currently usesinput compression values in the range 0 - 9. The library normallyuses the default compression level (Z_DEFAULT_COMPRESSION = 6). Testshave shown that for a large majority of images, compression values inthe range 3-6 compress nearly as well as higher levels, and do so muchfaster. For online applications it may be desirable to have maximum speed(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can alsospecify no compression (Z_NO_COMPRESSION = 0), but this would createfiles larger than just storing the raw bitmap. You can specify thecompression level by calling:png_set_compression_level(png_ptr, level);Another useful one is to reduce the memory level used by the library.The memory level defaults to 8, but it can be lowered if you areshort on memory (running DOS, for example, where you only have 640K).png_set_compression_mem_level(png_ptr, level);The other functions are for configuring zlib. They are not recommendedfor normal use and may result in writing an invalid PNG file. Seezlib.h for more information on what these mean.png_set_compression_strategy(png_ptr,strategy);png_set_compression_window_bits(png_ptr,window_bits);png_set_compression_method(png_ptr, method);Controlling row filtering:If you want to control whether libpng uses filtering or not, whichfilters are used, and how it goes about picking row filters, youcan call one of these functions. The selection and configurationof row filters can have a significant impact on the size andencoding speed and a somewhat lesser impact on the decoding speedof an image. Filtering is enabled by default for RGB and grayscaleimages (with and without alpha), but not for paletted images norfor any images with bit depths less than 8 bits/pixel.The 'method' parameter sets the main filtering method, which iscurrently only '0' in the PNG 1.2 specification. The 'filters'parameter sets which filter(s), if any, should be used for eachscanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERSto turn filtering on and off, respectively.Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwiseORed together '|' to specify one or more filters to use. Thesefilters are described in more detail in the PNG specification. Ifyou intend to change the filter type during the course of writingthe image, you should start with flags set for all of the filtersyou intend to use so that libpng can initialize its internalstructures appropriately for all of the filter types.filters = PNG_FILTER_NONE | PNG_FILTER_SUB| PNG_FILTER_UP;png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,filters);It is also possible to influence how libpng chooses from among theavailable filters. This is done in two ways - by telling it howimportant it is to keep the same filter for successive rows, andby telling it the relative computational costs of the filters.double weights[3] = {1.5, 1.3, 1.1},costs[PNG_FILTER_VALUE_LAST] ={1.0, 1.3, 1.3, 1.5, 1.7};png_set_filter_selection(png_ptr,PNG_FILTER_SELECTION_WEIGHTED, 3,weights, costs);The weights are multiplying factors that indicate to libpng that therow filter should be the same for successive rows unless another row filteris that many times better than the previous filter. In the above example,if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a"sum of absolute differences" 1.5 x 1.3 times higher than other filtersand still be chosen, while the NONE filter could have a sum 1.1 timeshigher than other filters and still be chosen. Unspecified weights aretaken to be 1.0, and the specified weights should probably be declininglike those above in order to emphasize recent filters over older filters.The filter costs specify for each filter type a relative decoding costto be considered when selecting row filters. This means that filterswith higher costs are less likely to be chosen over filters with lowercosts, unless their "sum of absolute differences" is that much smaller.The costs do not necessarily reflect the exact computational speeds ofthe various filters, since this would unduly influence the final imagesize.Note that the numbers above were invented purely for this example andare given only to help explain the function usage. Little testing hasbeen done to find optimum values for either the costs or the weights.Removing unwanted object code:There are a bunch of #define's in pngconf.h that control what parts oflibpng are compiled. All the defines end in _SUPPORTED. If you arenever going to use a capability, you can change the #define to #undefbefore recompiling libpng and save yourself code and data space, oryou can turn off individual capabilities with defines that begin withPNG_NO_.You can also turn all of the transforms and ancillary chunk capabilitiesoff en masse with compiler directives that definePNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,or all four,along with directives to turn on any of the capabilities that you dowant. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disablethe extra transformations but still leave the library fully capable of readingand writing PNG files with all known public chunks [except for sPLT].Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directiveproduces a library that is incapable of reading or writing ancillary chunks.If you are not using the progressive reading capability, you canturn that off with PNG_NO_PROGRESSIVE_READ (don't confusethis with the INTERLACING capability, which you'll still have).All the reading and writing specific code are in separate files, so thelinker should only grab the files it needs. However, if you want tomake sure, or if you are building a stand alone library, all thereading files start with pngr and all the writing files start withpngw. The files that don't match either (like png.c, pngtrans.c, etc.)are used for both reading and writing, and always need to be included.The progressive reader is in pngpread.cIf you are creating or distributing a dynamically linked library (a .soor DLL file), you should not remove or disable any parts of the library,as this will cause applications linked with different versions of thelibrary to fail if they call functions not available in your library.The size of the library itself should not be an issue, because onlythose sections that are actually used will be loaded into memory.Requesting debug printout:The macro definition PNG_DEBUG can be used to request debuggingprintout. Set it to an integer value in the range 0 to 3. Highernumbers result in increasing amounts of debugging information. Theinformation is printed to the "stderr" file, unless another filename is specified in the PNG_DEBUG_FILE macro definition.When PNG_DEBUG > 0, the following functions (macros) become available:png_debug(level, message)png_debug1(level, message, p1)png_debug2(level, message, p1, p2)in which "level" is compared to PNG_DEBUG to decide whether to printthe message, "message" is the formatted string to be printed,and p1 and p2 are parameters that are to be embedded in the stringaccording to printf-style formatting directives. For example,png_debug1(2, "foo=%d\n", foo);is expanded toif(PNG_DEBUG > 2)fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);When PNG_DEBUG is defined but is zero, the macros aren't defined, but youcan still use PNG_DEBUG to control your own debugging:#ifdef PNG_DEBUGfprintf(stderr, ...#endifWhen PNG_DEBUG = 1, the macros are defined, but only png_debug statementshaving level = 0 will be printed. There aren't any such statements inthis version of libpng, but if you insert some they will be printed..SH VI. Changes to Libpng from version 0.88It should be noted that versions of libpng later than 0.96 are notdistributed by the original libpng author, Guy Schalnat, nor byAndreas Dilger, who had taken over from Guy during 1996 and 1997, anddistributed versions 0.89 through 0.96, but rather by another memberof the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas arestill alive and well, but they have moved on to other things.The old libpng functions png_read_init(), png_write_init(),png_info_init(), png_read_destroy(), and png_write_destory() have beenmoved to PNG_INTERNAL in version 0.95 to discourage their use. Thepreferred method of creating and initializing the libpng structures isvia the png_create_read_struct(), png_create_write_struct(), andpng_create_info_struct() because they isolate the size of the structuresfrom the application, allow version error checking, and also allow theuse of custom error handling routines during the initialization, whichthe old functions do not. The functions png_read_destroy() andpng_write_destroy() do not actually free the memory that libpngallocated for these structs, but just reset the data structures, so theycan be used instead of png_destroy_read_struct() andpng_destroy_write_struct() if you feel there is too much system overheadallocating and freeing the png_struct for each image read.Setting the error callbacks via png_set_message_fn() beforepng_read_init() as was suggested in libpng-0.88 is no longer supportedbecause this caused applications that do not use custom error functionsto fail if the png_ptr was not initialized to zero. It is still possibleto set the error callbacks AFTER png_read_init(), or to change them withpng_set_error_fn(), which is essentially the same function, but with anew name to force compilation errors with applications that try to usethe old method..SH VII. Y2K Compliance in libpngOctober 15, 1999Since the PNG Development group is an ad-hoc body, we can't makean official declaration.This is your unofficial assurance that libpng from version 0.71 andupward through 1.0.5 are Y2K compliant. It is my belief that earlierversions were also Y2K compliant.Libpng only has three year fields. One is a 2-byte unsigned integer thatwill hold years up to 65535. The other two hold the date in textformat, and will hold years up to 9999.The integer is"png_uint_16 year" in png_time_struct.The strings are"png_charp time_buffer" in png_struct and"near_time_buffer", which is a local character string in png.c.There are seven time-related functions:png_convert_to_rfc_1123() in png.c(formerly png_convert_to_rfc_1152() in error)png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.cpng_convert_from_time_t() in pngwrite.cpng_get_tIME() in pngget.cpng_handle_tIME() in pngrutil.c, called in pngread.cpng_set_tIME() in pngset.cpng_write_tIME() in pngwutil.c, called in pngwrite.cAll appear to handle dates properly in a Y2K environment. Thepng_convert_from_time_t() function calls gmtime() to convert from systemclock time, which returns (year - 1900), which we properly convert tothe full 4-digit year. There is a possibility that applications usinglibpng are not passing 4-digit years into the png_convert_to_rfc_1123()function, or that they are incorrectly passing only a 2-digit yearinstead of "year - 1900" into the png_convert_from_struct_tm() function,but this is not under our control. The libpng documentation has alwaysstated that it works with 4-digit years, and the APIs have beendocumented as such.The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsignedinteger to hold the year, and can hold years as large as 65535.zlib, upon which libpng depends, is also Y2K compliant. It containsno date-related code.Glenn Randers-Pehrsonlibpng maintainerPNG Development Group.SH NOTENote about libpng version numbers:Due to various miscommunications, unforeseen code incompatibilitiesand occasional factors outside the authors' control, version numberingon the library has not always been consistent and straightforward.The following table summarizes matters since version 0.89c, which wasthe first widely used release:source png.h png.h shared-libversion string int version------- ------ ------ ----------0.89c 0.89 89 1.0.890.90 0.90 90 0.90 [should be 2.0.90]0.95 0.95 95 0.95 [should be 2.0.95]0.96 0.96 96 0.96 [should be 2.0.96]0.97b 1.00.97 97 1.0.1 [should be 2.0.97]0.97c 0.97 97 2.0.970.98 0.98 98 2.0.980.99 0.99 98 2.0.990.99a-m 0.99 99 2.0.991.00 1.00 100 2.1.0 [int should be 10000]1.0.0 1.0.0 100 2.1.0 [int should be 10000]1.0.1 1.0.1 10001 2.1.0Henceforth the source version will match the shared-libraryminor and patch numbers; the shared-library major version number will beused for changes in backward compatibility, as it is intended.The PNG_PNGLIB_VER macro, which is not used within libpng butis available for applications, is an unsigned integer of the formxyyzz corresponding to the source version x.y.z (leading zeros in y and z)..SH "SEE ALSO"libpngpf(3), png(5).LP.IR libpng :.IPftp://ftp.uu.net/graphics/pnghttp://www.cdrom.com/pub/png.LP.IR zlib :.IP(generally) at the same location as.I libpngor at.brftp://ftp.uu.net/pub/archiving/zip/zlib.brhttp://www.cdrom.com/pub/infozip/zlib.LP.IR PNG specification: RFC 2083.IP(generally) at the same location as.I libpngor at.brftp://ds.internic.net/rfc/rfc2083.txt.bror (as a W3C Recommendation) at.brhttp://www.w3.org/TR/REC-png.html.LPIn the case of any inconsistency between the PNG specificationand this library, the specification takes precedence..SH AUTHORSThis man page: Glenn Randers-Pehrson<randeg@alum.rpi.edu>The contributing authors would like to thank all those who helpedwith testing, bug fixes, and patience. This wouldn't have beenpossible without all of you.Thanks to Frank J. T. Wojcik for helping with the documentation.Libpng version 1.0.5 - October 15, 1999:Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.Currently maintained by Glenn Randers-Pehrson (randeg@alum.rpi.edu).Supported by the PNG development group.br(png-implement@ccrc.wustl.edu)..SH COPYRIGHT NOTICE:Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.(libpng versions 0.5, May 1995, through 0.89c, May 1996)Copyright (c) 1996, 1997 Andreas Dilger(libpng versions 0.90, December 1996, through 0.96, May 1997)Copyright (c) 1998, 1999 Glenn Randers-Pehrson(libpng versions 0.97, January 1998, through 1.0.5, October 15, 1999)For the purposes of this copyright and license, "Contributing Authors"is defined as the following set of individuals:John BowlerKevin BraceySam BushellAndreas DilgerMagnus HolmgrenTom LaneDave MartindaleGlenn Randers-PehrsonGreg RoelofsGuy Eric SchalnatPaul SchmidtTom TannerWillem van SchaikTim WegnerThe PNG Reference Library (libpng) is supplied "AS IS". The ContributingAuthors and Group 42, Inc. disclaim all warranties, expressed or implied,including, without limitation, the warranties of merchantability and offitness for any purpose. The Contributing Authors and Group 42, Inc.assume no liability for direct, indirect, incidental, special, exemplary,or consequential damages, which may result from the use of the PNGReference Library, even if advised of the possibility of such damage.Permission is hereby granted to use, copy, modify, and distribute thissource code, or portions hereof, for any purpose, without fee, subjectto the following restrictions:1. The origin of this source code must not bemisrepresented.2. Altered versions must be plainly marked as suchand must not be misrepresented as being theoriginal source.3. This Copyright notice may not be removed oraltered from any source or altered sourcedistribution.The Contributing Authors and Group 42, Inc. specifically permit, withoutfee, and encourage the use of this source code as a component tosupporting the PNG file format in commercial products. If you use thissource code in a product, acknowledgment is not required but would beappreciated.A "png_get_copyright" function is available, for convenient use in "about"boxes and the like:printf("%s",png_get_copyright(NULL));Also, the PNG logo (in PNG format, of course) is supplied in thefile "pngnow.png".Libpng is OSI Certified Open Source Software. OSI Certified is acertification mark of the Open Source Initiative..\" end of man page