--- libpng.3-orig 2006-12-20 04:36:34.000000000 -0500 +++ libpng.3 2006-12-20 04:41:00.000000000 -0500 @@ -1,3 +1,19 @@ +.\" EX and EE are used for displays that are pure code +.de EX +.nf +.ft CW +.. +.de EE +.ft R +.fi +.. +.\" DS/DE displays may have running text in them +.de DS +.nf +.. +.de DE +.fi +.. .TH LIBPNG 3 "April 23, 2006" .SH NAME libpng \- Portable Network Graphics (PNG) Reference Library 1.2.10 @@ -342,14 +358,6 @@ \fI\fB -\fBDEPRECATED: void png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP - -\fI\fB - -\fBDEPRECATED: void png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\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 @@ -374,10 +382,6 @@ \fI\fB -\fBDEPRECATED: void 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 @@ -398,14 +402,6 @@ \fI\fB -\fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP - -\fI\fB - -\fBDEPRECATED: void png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\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 @@ -774,14 +770,6 @@ \fI\fB -\fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP - -\fI\fB - -\fBDEPRECATED: void png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\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 @@ -810,6 +798,36 @@ \fI\fB +.SH DEPRECATED FUNCTIONS + +\fBvoid png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\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_read_init (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_init (png_structp \fIpng_ptr\fP\fB);\fP + +\fI\fB + +\fBvoid png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP + +\fI\fB + .SH DESCRIPTION The .I libpng @@ -936,7 +954,9 @@ 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: +.EX #include +.EE .SH III. Reading @@ -968,7 +988,7 @@ to replace them with custom functions. See the discussion under Customizing libpng. - +.EX FILE *fp = fopen(file_name, "rb"); if (!fp) { @@ -980,7 +1000,7 @@ { return (NOT_PNG); } - +.EE Next, png_struct and png_info need to be allocated and initialized. In order to ensure that the size of these structures is correct even with a @@ -993,6 +1013,7 @@ The structure allocation functions quietly return NULL if they fail to create the structure, so your application should check for that. +.EX png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); @@ -1014,15 +1035,18 @@ (png_infopp)NULL); return (ERROR); } +.EE If you want to use your own memory allocation routines, define PNG_USER_MEM_SUPPORTED and use png_create_read_struct_2() instead of png_create_read_struct(): +.EX 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); +.EE The error handling routines passed to png_create_read_struct() and the memory alloc/free routines passed to png_create_struct_2() @@ -1042,6 +1066,7 @@ back to your setjmp, you will want to call png_destroy_read_struct() to free any memory. +.EX if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, @@ -1049,12 +1074,13 @@ fclose(fp); return (ERROR); } +.EE If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case errors will result in a call to PNG_ABORT() which defaults to abort(). -Now you need to set up the input code. The default for libpng is to +Now you need to set up the input code. The default for libpng is to use the C function fread(). If you use this, you will need to pass a valid FILE * in the function png_init_io(). Be sure that the file is opened in binary mode. If you wish to handle reading data in another @@ -1062,19 +1088,24 @@ implement the libpng I/O methods discussed in the Customizing Libpng section below. +.EX png_init_io(png_ptr, fp); +.EE If you had previously opened the file and read any of the signature from the beginning in order to see if this was a PNG file, you need to let libpng know that there are some bytes missing from the start of the file. +.EX png_set_sig_bytes(png_ptr, number); +.EE .SS Setting up callback code You can set up a callback function to handle any unknown chunks in the input stream. You must supply the function +.EX read_chunk_callback(png_ptr ptr, png_unknown_chunkp chunk); { @@ -1093,36 +1124,45 @@ return (0); /* did not recognize */ return (n); /* success */ } +.EE (You can give your function another name that you like instead of "read_chunk_callback") To inform libpng about your function, use +.EX png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, read_chunk_callback); +.EE This names not only the callback function, but also a user pointer that you can retrieve with +.EX png_get_user_chunk_ptr(png_ptr); +.EE At this point, you can set up a callback function that will be called after each row has been read, which you can use to control a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function +.EX void read_row_callback(png_ptr ptr, png_uint_32 row, int pass); { /* put your code here */ } +.EE (You can give it another name that you like instead of "read_row_callback") To inform libpng about your function, use +.EX png_set_read_status_fn(png_ptr, read_row_callback); +.EE .SS Width and height limits @@ -1143,8 +1183,10 @@ before calling png_read_info(), png_read_png(), or png_process_data(). If you need to retrieve the limits that are being applied, use +.EX width_max = png_get_user_width_max(png_ptr); height_max = png_get_user_height_max(png_ptr); +.EE .SS Unknown-chunk handling @@ -1154,6 +1196,7 @@ various info_ptr members; unknown chunks will be discarded. To change this, you can call: +.DS png_set_keep_unknown_chunks(png_ptr, keep, chunk_list, num_chunks); keep - 0: do not handle as unknown @@ -1171,6 +1214,7 @@ num_chunks - number of chunks affected; if 0, all unknown chunks are affected. If nonzero, only the chunks in the list are affected +.DE Unknown chunks declared in this way will be saved as raw data onto a list of png_unknown_chunk structures. If a chunk that is normally @@ -1188,30 +1232,29 @@ the entire image into memory, and (b) the input transformations you want to do are limited to the following set: - PNG_TRANSFORM_IDENTITY No transformation - PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to - 8 bits - PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel - PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit - samples to bytes - PNG_TRANSFORM_PACKSWAP Change order of packed - pixels to LSB first - PNG_TRANSFORM_EXPAND Perform set_expand() - PNG_TRANSFORM_INVERT_MONO Invert monochrome images - PNG_TRANSFORM_SHIFT Normalize pixels to the - sBIT depth - PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA - to BGRA - PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA - to AG - PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity - to transparency - PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples +.TS +tab(:); +l l. +PNG_TRANSFORM_IDENTITY:No transformation +PNG_TRANSFORM_STRIP_16:Strip 16-bit samples to 8 bits +PNG_TRANSFORM_STRIP_ALPHA:Discard the alpha channel +PNG_TRANSFORM_PACKING:Expand 1, 2 and 4-bit samples to bytes +PNG_TRANSFORM_PACKSWAP:Change order of packed pixels to LSB first +PNG_TRANSFORM_EXPAND:Perform set_expand() +PNG_TRANSFORM_INVERT_MONO:Invert monochrome images +PNG_TRANSFORM_SHIFT:Normalize pixels to the sBIT depth +PNG_TRANSFORM_BGR:Flip RGB to BGR, RGBA to BGRA +PNG_TRANSFORM_SWAP_ALPHA:Flip RGBA to ARGB or GA to AG +PNG_TRANSFORM_INVERT_ALPHA:Change alpha from opacity to transparency +PNG_TRANSFORM_SWAP_ENDIAN:Byte-swap 16-bit samples +.TE (This excludes setting a background color, doing gamma transformation, dithering, and setting filler.) If this is the case, simply do this: +.EX png_read_png(png_ptr, info_ptr, png_transforms, NULL) +.EE where png_transforms is an integer containing the logical OR of some set of transformation flags. This call is equivalent to png_read_info(), @@ -1227,15 +1270,20 @@ After you have called png_read_png(), you can retrieve the image data with +.EX row_pointers = png_get_rows(png_ptr, info_ptr); +.EE where row_pointers is an array of pointers to the pixel data for each row: +.EX png_bytep row_pointers[height]; +.EE If you know your image size and pixel size ahead of time, you can allocate row_pointers prior to calling png_read_png() with +.EX if (height > PNG_UINT_32_MAX/png_sizeof(png_byte)) png_error (png_ptr, "Image is too tall to process in memory"); @@ -1248,6 +1296,7 @@ row_pointers[i]=png_malloc(png_ptr, width*pixel_size); png_set_rows(png_ptr, info_ptr, &row_pointers); +.EE Alternatively you could allocate your image in one big block and define row_pointers[i] to point into the proper places in your block. @@ -1264,7 +1313,9 @@ the file information up to the actual image data. You do this with a call to png_read_info(). +.EX png_read_info(png_ptr, info_ptr); +.EE This will process all chunks up to but not including the image data. @@ -1274,6 +1325,7 @@ has been read. Note that these fields may not be completely filled in until png_read_end() has read the chunk data following the image. +.DS png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); @@ -1351,7 +1403,7 @@ info_ptr); interlace_type = png_get_interlace_type(png_ptr, info_ptr); - +,DE These are also important, but their validity depends on whether the chunk has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_) and @@ -1360,6 +1412,7 @@ png_get_ are set directly if they are simple data types, or a pointer into the info_ptr is returned for any complex types. +.DS png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); palette - the palette for the file @@ -1501,40 +1554,37 @@ The value of "i" corresponds to the order in which the chunks were read from the PNG file or inserted with the png_set_unknown_chunks() function. +.DE The data from the pHYs chunk can be retrieved in several convenient forms: - 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) - res_x = png_get_x_pixels_per_inch(png_ptr, - info_ptr) - res_y = png_get_y_pixels_per_inch(png_ptr, - info_ptr) - res_x_and_y = png_get_pixels_per_inch(png_ptr, - info_ptr) - aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, - info_ptr) - - (Each of these returns 0 [signifying "unknown"] if - the data is not present or if res_x is 0; - res_x_and_y is 0 if res_x != res_y) +.EX + 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) + res_x = png_get_x_pixels_per_inch(png_ptr, info_ptr) + res_y = png_get_y_pixels_per_inch(png_ptr, info_ptr) + res_x_and_y = png_get_pixels_per_inch(png_ptr, info_ptr) + aspect_ratio = png_get_pixel_aspect_ratio(png_ptr, info_ptr) +.EE + +(Each of these returns 0 [signifying "unknown"] if the data is not +present or if res_x is 0; res_x_and_y is 0 if res_x != res_y) The data from the oFFs chunk can be retrieved in several convenient forms: +.EX x_offset = png_get_x_offset_microns(png_ptr, info_ptr); y_offset = png_get_y_offset_microns(png_ptr, info_ptr); x_offset = png_get_x_offset_inches(png_ptr, info_ptr); y_offset = png_get_y_offset_inches(png_ptr, info_ptr); +.EE - (Each of these returns 0 [signifying "unknown" if both - x and y are 0] if the data is not present or if the - chunk is present but the unit is the pixel) +(Each of these returns 0 [signifying "unknown" if both x and y are 0] +if the data is not present or if the chunk is present but the unit is +the pixel) For more information, see the png_info definition in png.h and the PNG specification for chunk contents. Be careful with trusting @@ -1604,6 +1654,7 @@ grayscale images with bit depths of 2 or 4 or if there is a multiple-image viewing application that wishes to treat all images in the same way. +.EX if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); @@ -1612,6 +1663,7 @@ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); +.EE These three functions are actually aliases for png_set_expand(), added in libpng version 1.0.4, with the function names expanded to improve code @@ -1626,16 +1678,20 @@ PNG can have files with 16 bits per channel. If you only can handle 8 bits per channel, this will strip the pixels down to 8 bit. +.EX if (bit_depth == 16) png_set_strip_16(png_ptr); +.EE 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* combine it with the background, so that's what you should probably do): +.EX if (color_type & PNG_COLOR_MASK_ALPHA) png_set_strip_alpha(png_ptr); +.EE In PNG files, the alpha channel in an image is the level of opacity. If you need the alpha channel in an image to @@ -1644,15 +1700,19 @@ fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit images) is fully transparent, with +.EX png_set_invert_alpha(png_ptr); +.EE PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as they can, resulting in, for example, 8 pixels per byte for 1 bit files. This code expands to 1 pixel per byte without changing the values of the pixels: +.EX if (bit_depth < 8) png_set_packing(png_ptr); +.EE PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels stored in a PNG image have been "scaled" or "shifted" up to the next @@ -1661,23 +1721,29 @@ convert 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: +.EX png_color_8p sig_bit; if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) png_set_shift(png_ptr, sig_bit); +.EE PNG files store 3-color pixels in red, green, blue order. This code changes the storage of the pixels to blue, green, red: +.EX if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_bgr(png_ptr); +.EE PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them into 4 or 8 bytes for windowing systems that need them in this format: +.EX if (color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE); +.EE where "filler" is the 8 or 16-bit number to fill with, and the location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether @@ -1699,19 +1765,24 @@ If you are reading an image with an alpha channel, and you need the data as ARGB instead of the normal PNG format RGBA: +.EX if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_swap_alpha(png_ptr); +.EE For some uses, you may want a grayscale image to be represented as RGB. This code will do that conversion: +.EX if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); +.EE Conversely, you can convert an RGB or RGBA image to grayscale or grayscale with alpha. +.DS if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_rgb_to_gray_fixed(png_ptr, error_action, @@ -1730,6 +1801,7 @@ green_weight: weight of green component times 100000 If either weight is negative, default weights (21268, 71514) are used. +.DE If you have set error_action = 1 or 2, you can later check whether the image really was gray, after processing @@ -1742,24 +1814,32 @@ With red_weight+green_weight<=100000, the normalized graylevel is computed: +.EX int rw = red_weight * 65536; int gw = green_weight * 65536; int bw = 65536 - (rw + gw); gray = (rw*red + gw*green + bw*blue)/65536; +.EE The default values approximate those recommended in the Charles Poynton's Color FAQ, Copyright (c) 1998-01-04 Charles Poynton +.EX Y = 0.212671 * R + 0.715160 * G + 0.072169 * B +.EE Libpng approximates this with +.EX Y = 0.21268 * R + 0.7151 * G + 0.07217 * B +.EE which can be expressed with integers as +.EX Y = (6969 * R + 23434 * G + 2365 * B)/32768 +.EE The calculation is done in a linear colorspace, if the image gamma is known. @@ -1773,6 +1853,7 @@ must 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). +.EX png_color_16 my_background; png_color_16p image_background; @@ -1782,6 +1863,7 @@ else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); +.EE The png_set_background() function tells libpng to composite images with alpha or simple transparency against the supplied background @@ -1807,6 +1889,7 @@ the physical gamma exponent of the monitor is needed, while in a dark room a slightly smaller exponent is better. +.EX double gamma, screen_gamma; if (/* We have a user-defined screen @@ -1831,6 +1914,7 @@ screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */ } +.EE The png_set_gamma() function handles gamma transformations of the data. Pass both the file gamma and the current screen_gamma. If the file does @@ -1841,10 +1925,12 @@ gamma is, and why all applications should support it. It is strongly recommended that PNG viewers support gamma correction. +.EX if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, screen_gamma, gamma); else png_set_gamma(png_ptr, screen_gamma, 0.45455); +.EE If you need to reduce an RGB file to a paletted file, or if a paletted file has more entries then will fit on your screen, png_set_dither() @@ -1857,6 +1943,7 @@ more intelligent choices when reducing the palette. If there is no histogram, it may not do as good a job. +.EX if (color_type & PNG_COLOR_MASK_COLOR) { if (png_get_valid(png_ptr, info_ptr, @@ -1879,45 +1966,58 @@ NULL,0); } } +.EE PNG files describe monochrome as black being zero and white being one. The following code will reverse this (make black be one and white be zero): +.EX if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY) png_set_invert_mono(png_ptr); +.EE This function can also be used to invert grayscale and gray-alpha images: +.EX if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_invert_mono(png_ptr); +.EE PNG files store 16 bit pixels in network byte order (big-endian, ie. most significant bits first). This code changes the storage to the other way (little-endian, i.e. least significant bits first, the way PCs store them): +.EX if (bit_depth == 16) png_set_swap(png_ptr); +.EE If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you need to change the order the pixels are packed into bytes, you can use: +.EX if (bit_depth < 8) png_set_packswap(png_ptr); +.EE Finally, you can write your own transformation function if none of the existing ones meets your needs. This is done by setting a callback with +.EX png_set_read_user_transform_fn(png_ptr, read_transform_fn); +.EE You must supply the function +.EX void read_transform_fn(png_ptr ptr, row_info_ptr row_info, png_bytep data) +.EE See pngtest.c for a working example. Your function will be called after all of the other transformations have been processed. @@ -1927,8 +2027,10 @@ function will change the number of channels or bit depth with the function +.EX png_set_user_transform_info(png_ptr, user_ptr, user_depth, user_channels); +.EE The user's application, not libpng, is responsible for allocating and freeing any memory required for the user structure. @@ -1936,14 +2038,18 @@ You can retrieve the pointer via the function png_get_user_transform_ptr(). For example: +.EX voidp read_user_transform_ptr = png_get_user_transform_ptr(png_ptr); +.EE 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 expansion of the interlaced image. +.EX number_of_passes = png_set_interlace_handling(png_ptr); +.EE After setting the transformations, libpng can update your png_info structure to reflect any transformations you've requested with this @@ -1952,7 +2058,9 @@ will also update your palette with the correct screen_gamma and background if these have been given with the calls above. +.EX png_read_update_info(png_ptr, info_ptr); +.EE After you call png_read_update_info(), you can allocate any memory you need to hold the image. The row data is simply @@ -1975,11 +2083,15 @@ to call png_set_interlace_handling() or call this function multiple times, or any of that other stuff necessary with png_read_rows(). +.EX png_read_image(png_ptr, row_pointers); +.EE where row_pointers is: +.EX png_bytep row_pointers[height]; +.EE You can point to void or char or whatever you use for pixels. @@ -1987,16 +2099,20 @@ use png_read_rows() instead. If there is no interlacing (check interlace_type == PNG_INTERLACE_NONE), this is simple: +.EX png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); +.EE 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 with a single row_pointer instead of an array of row_pointers: +.EX png_bytep row_pointer = row; png_read_row(png_ptr, row_pointer, NULL); +.EE If the file is interlaced (interlace_type != 0 in the IHDR chunk), things get somewhat harder. The only current (PNG Specification version 1.2) @@ -2039,9 +2155,11 @@ If you want libpng to expand the images, call this before calling png_start_read_image() or png_read_update_info(): +.EX if (interlace_type == PNG_INTERLACE_ADAM7) number_of_passes = png_set_interlace_handling(png_ptr); +.EE This will return the number of passes needed. Currently, this is seven, but may change if another interlace type is added. @@ -2062,15 +2180,19 @@ not the data. Each pass only writes the pixels appropriate for that pass, and assumes the data from previous passes is still valid. +.EX png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); +.EE If you only want the first effect (the rectangles), do the same as before except pass the row buffer in the third parameter, and leave the second parameter NULL. +.EX png_read_rows(png_ptr, NULL, row_pointers, number_of_rows); +.EE .SS Finishing a sequential read @@ -2081,16 +2203,21 @@ you want to keep the comments from before and after the image separate. If you are not interested, you can pass NULL. +.EX png_read_end(png_ptr, end_info); +.EE When you are done, you can free all memory allocated by libpng like this: +.EX png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); +.EE It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: +.DS png_free_data(png_ptr, info_ptr, mask, seq) mask - identifies data to be freed, a mask containing the logical OR of one or @@ -2103,6 +2230,7 @@ or simply PNG_FREE_ALL seq - sequence number of item to be freed (-1 for all items) +.DE This function may be safely called when the relevant storage has already been freed, or has not yet been allocated, or was allocated @@ -2118,6 +2246,7 @@ or so that it will free data that was allocated by the user with png_malloc() or png_zalloc() and passed in via a png_set_*() function, with +.DS png_data_freer(png_ptr, info_ptr, freer, mask) mask - which data elements are affected same choices as in png_free_data() @@ -2125,6 +2254,7 @@ PNG_DESTROY_WILL_FREE_DATA PNG_SET_WILL_FREE_DATA PNG_USER_WILL_FREE_DATA +.DE This function only affects data that has already been allocated. You can call this function after reading the PNG data but before calling @@ -2153,18 +2283,16 @@ it frees. If you need to turn the flag off for a chunk that was freed by your application instead of by libpng, you can use +.EX png_set_invalid(png_ptr, info_ptr, mask); - mask - identifies the chunks to be made invalid, - containing the logical OR of one or - more of - PNG_INFO_gAMA, PNG_INFO_sBIT, - PNG_INFO_cHRM, PNG_INFO_PLTE, - PNG_INFO_tRNS, PNG_INFO_bKGD, - PNG_INFO_hIST, PNG_INFO_pHYs, - PNG_INFO_oFFs, PNG_INFO_tIME, - PNG_INFO_pCAL, PNG_INFO_sRGB, - PNG_INFO_iCCP, PNG_INFO_sPLT, - PNG_INFO_sCAL, PNG_INFO_IDAT +.EE + +The mask identifies the chunks to be made invalid, containing the +logical OR of one or more of PNG_INFO_gAMA, PNG_INFO_sBIT, +PNG_INFO_cHRM, PNG_INFO_PLTE, PNG_INFO_tRNS, PNG_INFO_bKGD, +PNG_INFO_hIST, PNG_INFO_pHYs, PNG_INFO_oFFs, PNG_INFO_tIME, +PNG_INFO_pCAL, PNG_INFO_sRGB, PNG_INFO_iCCP, PNG_INFO_sPLT, +PNG_INFO_sCAL, or PNG_INFO_IDAT. For a more compact example of reading a PNG image, see the file example.c. @@ -2181,6 +2309,7 @@ so I will only highlight the differences (although I will show all of the code). +.EX png_structp png_ptr; png_infop info_ptr; @@ -2336,8 +2465,7 @@ a flag that marks the image as finished. */ } - - +.EE .SH IV. Writing @@ -2352,11 +2480,13 @@ using the standard I/O functions, you will need to replace them with custom writing functions. See the discussion under Customizing libpng. +.EX FILE *fp = fopen(file_name, "wb"); if (!fp) { return (ERROR); } +.EE 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 these @@ -2366,6 +2496,7 @@ both "png_ptr"; you can call them anything you like, such as "read_ptr" and "write_ptr". Look at pngtest.c, for example. +.EX png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr, user_error_fn, user_warning_fn); @@ -2379,15 +2510,18 @@ (png_infopp)NULL); return (ERROR); } +.EE If you want to use your own memory allocation routines, define PNG_USER_MEM_SUPPORTED and use png_create_write_struct_2() instead of png_create_write_struct(): +.EX 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); +.EE After you have these structures, you will need to set up the error handling. When libpng encounters an error, it expects to @@ -2400,6 +2534,7 @@ the discussion on libpng error handling in the Customizing Libpng section below for more information on the libpng error handling. +.EX if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); @@ -2408,6 +2543,7 @@ } ... return; +.EE If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case @@ -2420,7 +2556,9 @@ another way, see the discussion on libpng I/O handling in the Customizing Libpng section below. +.EX png_init_io(png_ptr, fp); +.EE If you are embedding your PNG into a datastream such as MNG, and don't want libpng to write the 8-byte signature, or if you have already @@ -2437,17 +2575,21 @@ a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function +.EX void write_row_callback(png_ptr, png_uint_32 row, int pass); { /* put your code here */ } +.EE (You can give it another name that you like instead of "write_row_callback") To inform libpng about your function, use +.EX png_set_write_status_fn(png_ptr, write_row_callback); +.EE You now have the option of modifying how the compression library will run. The following functions are mainly for testing, but may be useful @@ -2461,10 +2603,10 @@ July 1999 PNG specification, version 1.2) or 64 (if you are writing a PNG datastream that is to be embedded in a MNG datastream). The third parameter is a flag that indicates which filter type(s) are to be tested -for each scanline. See the PNG specification for details on the specific filter -types. - +for each scanline. See the PNG specification for details on the +specific filter types. +.EX /* turn on or off filtering, and/or choose specific filters. You can use either a single PNG_FILTER_VALUE_NAME or the logical OR of one @@ -2476,12 +2618,13 @@ PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| PNG_ALL_FILTERS); +.EE -If an application -wants to start and stop using particular filters during compression, -it should start out with all of the filters (to ensure that the previous -row of pixels will be stored in case it's needed later), and then add -and remove them after the start of compression. +If an application wants to start and stop using particular filters +during compression, it should start out with all of the filters (to +ensure that the previous row of pixels will be stored in case it's +needed later), and then add and remove them after the start of +compression. If you are writing a PNG datastream that is to be embedded in a MNG datastream, the second parameter can be either 0 or 64. @@ -2493,6 +2636,7 @@ data. See the Compression Library (zlib.h and algorithm.txt, distributed with zlib) for details on the compression levels. +.EX /* set the zlib compression level */ png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); @@ -2504,8 +2648,7 @@ png_set_compression_window_bits(png_ptr, 15); png_set_compression_method(png_ptr, 8); png_set_compression_buffer_size(png_ptr, 8192) - -extern PNG_EXPORT(void,png_set_zbuf_size) +.EE .SS Setting the contents of info for output @@ -2522,6 +2665,7 @@ Some of the more important parts of the png_info are: +.DS png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, compression_type, filter_method) @@ -2712,6 +2856,7 @@ PNG_HAVE_IHDR: before PLTE PNG_HAVE_PLTE: before IDAT PNG_AFTER_IDAT: after IDAT +.DE The "location" member is set automatically according to what part of the output file has already been written. @@ -2744,19 +2889,20 @@ The keywords that are given in the PNG Specification are: - Title Short (one line) title or - caption for image - Author Name of image's creator - Description Description of image (possibly long) - Copyright Copyright notice - Creation Time Time of original image creation - (usually RFC 1123 format, see below) - Software Software used to create the image - Disclaimer Legal disclaimer - Warning Warning of nature of content - Source Device used to create the image - Comment Miscellaneous comment; conversion - from other image format +.TS +tab(:); +l l. +Title:Short (one line) title or caption for image +Author:Name of image's creator +Description:Description of image (possibly long) +Copyright:Copyright notice +Creation Time:Time of original image creation (usually RFC 1123 format, see below) +Software:Software used to create the image +Disclaimer:Legal disclaimer +Warning:Warning of nature of content +Source:Device used to create the image +Comment:Miscellaneous comment; conversion from other image format +.TE The keyword-text pairs work like this. Keywords should be short simple descriptions of what the comment is about. Some typical @@ -2819,26 +2965,27 @@ in the info structure. All defined output transformations are permitted, enabled by the following masks. - PNG_TRANSFORM_IDENTITY No transformation - PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples - PNG_TRANSFORM_PACKSWAP Change order of packed - pixels to LSB first - PNG_TRANSFORM_INVERT_MONO Invert monochrome images - PNG_TRANSFORM_SHIFT Normalize pixels to the - sBIT depth - PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA - to BGRA - PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA - to AG - PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity - to transparency - PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples - PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes. +.TS +.tab(:); +l l. +PNG_TRANSFORM_IDENTITY:No transformation +PNG_TRANSFORM_PACKING:Pack 1, 2 and 4-bit samples +PNG_TRANSFORM_PACKSWAP:Change order of packed pixels to LSB first +PNG_TRANSFORM_INVERT_MONO:Invert monochrome images +PNG_TRANSFORM_SHIFT:Normalize pixels to the sBIT depth +PNG_TRANSFORM_BGR:Flip RGB to BGR, RGBA to BGRA +PNG_TRANSFORM_SWAP_ALPHA:Flip RGBA to ARGB or GA to AG +PNG_TRANSFORM_INVERT_ALPHA:Change alpha from opacity to transparency +PNG_TRANSFORM_SWAP_ENDIAN:Byte-swap 16-bit samples +PNG_TRANSFORM_STRIP_FILLER:Strip out filler bytes. +.TE If you have valid image data in the info structure (you can use png_set_rows() to put image data in the info structure), simply do this: +.EX png_write_png(png_ptr, info_ptr, png_transforms, NULL) +.EE where png_transforms is an integer containing the logical OR of some set of transformation flags. This call is equivalent to png_write_info(), @@ -2857,7 +3004,9 @@ write all the file information up to the actual image data. You do this with a call to png_write_info(). +.EX png_write_info(png_ptr, info_ptr); +.EE Note that there is one transformation you may need to do before png_write_info(). In PNG files, the alpha channel in an image is the @@ -2866,7 +3015,9 @@ that 0 is fully transparent and 255 (in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque, with +.EX png_set_invert_alpha(png_ptr); +.EE This must appear before png_write_info() instead of later with the other transformations because in the case of paletted images the tRNS @@ -2880,9 +3031,11 @@ the PLTE chunk when PLTE is present, you can write the PNG info in two steps, and insert code to write your own chunk between them: +.EX png_write_info_before_PLTE(png_ptr, info_ptr); png_set_unknown_chunks(png_ptr, info_ptr, ...); png_write_info(png_ptr, info_ptr); +.EE After you've written the file information, you can set up the library to handle any special transformations of the image data. The various @@ -2899,7 +3052,9 @@ to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2 bytes per pixel). +.EX png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); +.EE where the 0 is unused, and the location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel @@ -2910,12 +3065,15 @@ If the data is supplied at 1 pixel per byte, use this code, which will correctly pack the pixels into a single byte: +.EX png_set_packing(png_ptr); +.EE PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your data is of another bit depth, you can write an sBIT chunk into the file so that decoders can recover the original data if desired. +.EX /* Set the true bit depth of the image data */ if (color_type & PNG_COLOR_MASK_COLOR) { @@ -2933,50 +3091,65 @@ } png_set_sBIT(png_ptr, info_ptr, &sig_bit); +.EE If the data is stored in the row buffer in a bit depth other than one 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 as is required by PNG. +.EX png_set_shift(png_ptr, &sig_bit); +.EE PNG files store 16 bit pixels in network byte order (big-endian, ie. most significant bits first). This code would be used if they are supplied the other way (little-endian, i.e. least significant bits first, the way PCs store them): +.EX if (bit_depth > 8) png_set_swap(png_ptr); +.EE If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you need to change the order the pixels are packed into bytes, you can use: +.EX if (bit_depth < 8) png_set_packswap(png_ptr); +.EE PNG files store 3 color pixels in red, green, blue order. This code would be used if they are supplied as blue, green, red: +.EX png_set_bgr(png_ptr); +.EE PNG files describe monochrome as black being zero and white being one. This code would be used if the pixels are supplied with this reversed (black being one and white being zero): +.EX png_set_invert_mono(png_ptr); +.EE Finally, you can write your own transformation function if none of the existing ones meets your needs. This is done by setting a callback with +.EX png_set_write_user_transform_fn(png_ptr, write_transform_fn); +.EE You must supply the function +.EX void write_transform_fn(png_ptr ptr, row_info_ptr row_info, png_bytep data) +.EE See pngtest.c for a working example. Your function will be called before any of the other transformations are processed. @@ -2984,7 +3157,9 @@ You can also set up a pointer to a user structure for use by your callback function. +.EX png_set_user_transform_info(png_ptr, user_ptr, 0, 0); +.EE The user_channels and user_depth parameters of this function are ignored when writing; you can set them to zero as shown. @@ -2992,19 +3167,25 @@ You can retrieve the pointer via the function png_get_user_transform_ptr(). For example: +.EX voidp write_user_transform_ptr = png_get_user_transform_ptr(png_ptr); +.EE It is possible to have libpng flush any pending output, either manually, or automatically after a certain number of lines have been written. To flush the output stream a single time call: +.EX png_write_flush(png_ptr); +.EE and to have libpng flush the output stream periodically after a certain number of scanlines have been written, call: +.EX png_set_flush(png_ptr, nrows); +.EE 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. @@ -3027,11 +3208,15 @@ need to call png_set_interlace_handling() or call this function multiple times, or any of that other stuff necessary with png_write_rows(). +.EX png_write_image(png_ptr, row_pointers); +.EE where row_pointers is: +.EX png_byte *row_pointers[height]; +.EE You can point to void or char or whatever you use for pixels. @@ -3039,17 +3224,21 @@ use png_write_rows() instead. If the file is not interlaced, this is simple: +.EX png_write_rows(png_ptr, row_pointers, number_of_rows); +.EE 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 with a single row_pointer instead of an array of row_pointers: +.EX png_bytep row_pointer = row; png_write_row(png_ptr, row_pointer); +.EE When the file is interlaced, things can get a good deal more complicated. The only currently (as of the PNG Specification @@ -3067,16 +3256,20 @@ If you want libpng to build the sub-images, call this before you start writing any rows: +.EX number_of_passes = png_set_interlace_handling(png_ptr); +.EE This will return the number of passes needed. Currently, this is seven, but may change if another interlace type is added. Then write the complete image number_of_passes times. +.EX png_write_rows(png_ptr, row_pointers, number_of_rows); +.EE As some of these rows are not used, and thus return immediately, you may want to read about interlacing in the PNG specification, @@ -3089,15 +3282,20 @@ pass an appropriately filled png_info pointer. If you are not interested, you can pass NULL. +.EX png_write_end(png_ptr, info_ptr); +.EE When you are done, you can free all memory used by libpng like this: +.EX png_destroy_write_struct(&png_ptr, &info_ptr); +.EE It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: +.DS png_free_data(png_ptr, info_ptr, mask, seq) mask - identifies data to be freed, a mask containing the logical OR of one or @@ -3110,6 +3308,7 @@ or simply PNG_FREE_ALL seq - sequence number of item to be freed (-1 for all items) +.DE This function may be safely called when the relevant storage has already been freed, or has not yet been allocated, or was allocated @@ -3129,6 +3328,7 @@ or so that it will free data that was allocated by the user with png_malloc() or png_zalloc() and passed in via a png_set_*() function, with +.DS png_data_freer(png_ptr, info_ptr, freer, mask) mask - which data elements are affected same choices as in png_free_data() @@ -3136,16 +3336,19 @@ PNG_DESTROY_WILL_FREE_DATA PNG_SET_WILL_FREE_DATA PNG_USER_WILL_FREE_DATA +.DE For example, to transfer responsibility for some data from a read structure to a write structure, you could use +.EX png_data_freer(read_ptr, read_info_ptr, PNG_USER_WILL_FREE_DATA, PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) png_data_freer(write_ptr, write_info_ptr, PNG_DESTROY_WILL_FREE_DATA, PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST) +.EE thereby briefly reassigning responsibility for freeing to the user but immediately afterwards reassigning it once more to the write_destroy @@ -3184,7 +3387,7 @@ assembly-language (and therefore compiler- and platform-dependent) versions. -Memory allocation, input/output, and error handling +.SS Memory allocation, input/output, and error handling All of the memory allocation, input/output, and error handling in libpng goes through callbacks that are user-settable. The default routines are @@ -3202,13 +3405,17 @@ your own functions as described above. These functions also provide a void pointer that can be retrieved via +.EX mem_ptr=png_get_mem_ptr(png_ptr); +.EE Your replacement memory functions must have prototypes as follows: +.EX png_voidp malloc_fn(png_structp png_ptr, png_size_t size); void free_fn(png_structp png_ptr, png_voidp ptr); +.EE Your malloc_fn() must return NULL in case of failure. The png_malloc() function will normally call png_error() if it receives a NULL from the @@ -3223,6 +3430,7 @@ also provide a void pointer that can be retrieved via the function png_get_io_ptr(). For example: +.EX png_set_read_fn(png_structp read_ptr, voidp read_io_ptr, png_rw_ptr read_data_fn) @@ -3232,14 +3440,17 @@ voidp read_io_ptr = png_get_io_ptr(read_ptr); voidp write_io_ptr = png_get_io_ptr(write_ptr); +.EE The replacement I/O functions must have prototypes as follows: +.EX void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length); void user_flush_data(png_structp png_ptr); +.EE Supplying NULL for the read, write, or flush functions sets them back to using the default C stream functions. It is an error to read from @@ -3263,21 +3474,25 @@ It is also possible to redirect errors and warnings to your own replacement functions after png_create_*_struct() has been called by calling: +.EX 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); +.EE If NULL is supplied for either error_fn or warning_fn, then the libpng default function will be used, calling fprintf() and/or longjmp() if a problem is encountered. The replacement error functions should have parameters as follows: +.EX 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); +.EE The motivation behind using setjmp() and longjmp() is the C++ throw and catch exception handling methods. This makes the code much easier to write, @@ -3368,7 +3583,9 @@ files larger than just storing the raw bitmap. You can specify the compression level by calling: +.EX png_set_compression_level(png_ptr, level); +.EE 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 are @@ -3378,18 +3595,22 @@ data being emitted in smaller stored blocks, with a correspondingly larger relative overhead of up to 15% in the worst case. +.EX png_set_compression_mem_level(png_ptr, level); +.EE The other functions are for configuring zlib. They are not recommended for normal use and may result in writing an invalid PNG file. See zlib.h for more information on what these mean. +.EX png_set_compression_strategy(png_ptr, strategy); png_set_compression_window_bits(png_ptr, window_bits); png_set_compression_method(png_ptr, method); png_set_compression_buffer_size(png_ptr, size); +.EE .SS Controlling row filtering @@ -3411,6 +3632,7 @@ Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise ORed together with '|' to specify one or more filters to use. +(The value PNG_ALL_FILTERS includes all filter bits.) These filters are described in more detail in the PNG specification. If you intend to change the filter type during the course of writing the image, you should start with flags set for all of the filters @@ -3420,24 +3642,20 @@ currently does not allocate the filter buffers until png_write_row() is called for the first time.) - filters = PNG_FILTER_NONE | PNG_FILTER_SUB - PNG_FILTER_UP | PNG_FILTER_AVE | - PNG_FILTER_PAETH | PNG_ALL_FILTERS; - - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, - filters); - The second parameter can also be - PNG_INTRAPIXEL_DIFFERENCING if you are - writing a PNG to be embedded in a MNG - datastream. This parameter must be the - same as the value of filter_method used - in png_set_IHDR(). +.EX + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters); +.EE + +The second parameter can also be PNG_INTRAPIXEL_DIFFERENCING if you +are writing a PNG to be embedded in a MNG datastream. This parameter +must be the same as the value of filter_method used in png_set_IHDR(). It is also possible to influence how libpng chooses from among the available filters. This is done in one or both of two ways - by telling it how important it is to keep the same filter for successive rows, and by telling it the relative computational costs of the filters. +.EX double weights[3] = {1.5, 1.3, 1.1}, costs[PNG_FILTER_VALUE_LAST] = {1.0, 1.3, 1.3, 1.5, 1.7}; @@ -3445,6 +3663,7 @@ png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_WEIGHTED, 3, weights, costs); +.EE The weights are multiplying factors that indicate to libpng that the row filter should be the same for successive rows unless another row filter @@ -3516,28 +3735,36 @@ When PNG_DEBUG > 0, the following functions (macros) become available: +.EX png_debug(level, message) png_debug1(level, message, p1) png_debug2(level, message, p1, p2) +.EE in which "level" is compared to PNG_DEBUG to decide whether to print the message, "message" is the formatted string to be printed, and p1 and p2 are parameters that are to be embedded in the string according to printf-style formatting directives. For example, +.EX png_debug1(2, "foo=%d\n", foo); +.EE is expanded to - if(PNG_DEBUG > 2) +.EX + if (PNG_DEBUG > 2) fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo); +.EE When PNG_DEBUG is defined but is zero, the macros aren't defined, but you can still use PNG_DEBUG to control your own debugging: +.EX #ifdef PNG_DEBUG fprintf(stderr, ... #endif +.EE When PNG_DEBUG = 1, the macros are defined, but only png_debug statements having level = 0 will be printed. There aren't any such statements in @@ -3565,6 +3792,7 @@ enable all possible optimizations (bearing in mind that some "optimizations" may actually run more slowly in rare cases): +.EX #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) png_uint_32 mask, flags; @@ -3572,27 +3800,32 @@ mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags | mask); #endif +.EE To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ by itself when calling png_get_asm_flagmask(); similarly for optimizing only writing. To disable all optimizations: +.EX #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) flags = png_get_asm_flags(png_ptr); mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE); png_set_asm_flags(png_ptr, flags & ~mask); #endif +.EE To enable or disable only MMX-related features, use png_get_mmx_flagmask() in place of png_get_asm_flagmask(). The mmx version takes one additional parameter: +.EX #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) int selection = PNG_SELECT_READ | PNG_SELECT_WRITE; int compilerID; mask = png_get_mmx_flagmask(selection, &compilerID); #endif +.EE On return, compilerID will indicate which version of the MMX assembler optimizations was compiled. Currently two flavors exist: Microsoft @@ -3607,6 +3840,7 @@ written and compiled. It is also possible, of course, to enable only known, specific optimizations; for example: +.EX #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ | PNG_ASM_FLAG_MMX_READ_INTERLACE \ @@ -3616,6 +3850,7 @@ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; png_set_asm_flags(png_ptr, flags); #endif +.EE This method would enable only the MMX read-optimizations available at the time of libpng 1.2.0's release, regardless of whether a later version of @@ -3626,9 +3861,11 @@ To determine whether the processor supports MMX instructions at all, use the png_mmx_support() function: +.EX #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) mmxsupport = png_mmx_support(); #endif +.EE It returns -1 if MMX support is not compiled into libpng, 0 if MMX code is compiled but MMX is not supported by the processor, or 1 if MMX support @@ -3641,6 +3878,7 @@ thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK defined: +.EX #if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \ && defined(PNG_THREAD_UNSAFE_OK) /* Disable thread-unsafe features of pnggccrd */ @@ -3657,6 +3895,7 @@ png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask); } #endif +.EE For more extensive examples of runtime querying, enabling and disabling of optimized features, see contrib/gregbook/readpng2.c in the libpng @@ -3669,6 +3908,7 @@ Libpng can support some of these extensions. To enable them, use the png_permit_mng_features() function: +.EX feature_set = png_permit_mng_features(png_ptr, mask) mask is a png_uint_32 containing the logical OR of the features you want to enable. These include @@ -3678,6 +3918,7 @@ feature_set is a png_uint_32 that is the logical AND of your mask with the set of MNG features that is supported by the version of libpng that you are using. +.EE It is an error to use this function when reading or writing a standalone PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped @@ -3725,7 +3966,9 @@ Starting with version 1.0.7, you can find out which version of the library you are using at run-time: +.EX png_uint_32 libpng_vn = png_access_version_number(); +.EE The number libpng_vn is constructed from the major version, minor version with leading zero, and release number with leading zero, @@ -3734,7 +3977,9 @@ You can also check which version of png.h you used when compiling your application: +.EX png_uint_32 application_vn = PNG_LIBPNG_VER; +.EE .SH IX. Y2K Compliance in libpng @@ -3752,23 +3997,35 @@ format, and will hold years up to 9999. The integer is - "png_uint_16 year" in png_time_struct. +.IP * +"png_uint_16 year" in png_time_struct. +.PP The strings are - "png_charp time_buffer" in png_struct and - "near_time_buffer", which is a local character string in png.c. +.IP * +"png_charp time_buffer" in png_struct and +.IP * +"near_time_buffer", which is a local character string in png.c. +.PP 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.c - png_convert_from_time_t() in pngwrite.c - png_get_tIME() in pngget.c - png_handle_tIME() in pngrutil.c, called in pngread.c - png_set_tIME() in pngset.c - png_write_tIME() in pngwutil.c, called in pngwrite.c +.IP * +png_convert_to_rfc_1123() in png.c (formerly png_convert_to_rfc_1152() +in error) +.IP * +png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c +.IP * +png_convert_from_time_t() in pngwrite.c +.IP * +png_get_tIME() in pngget.c +.IP * +png_handle_tIME() in pngrutil.c, called in pngread.c +.IP * +png_set_tIME() in pngset.c +.IP * +png_write_tIME() in pngwutil.c, called in pngwrite.c +.PP All appear to handle dates properly in a Y2K environment. The png_convert_from_time_t() function calls gmtime() to convert from system @@ -3787,10 +4044,11 @@ zlib, upon which libpng depends, is also Y2K compliant. It contains no date-related code. - +.DS Glenn Randers-Pehrson libpng maintainer PNG Development Group +.DE .SH NOTE @@ -3802,6 +4060,7 @@ The following table summarizes matters since version 0.89c, which was the first widely used release: +.DS source png.h png.h shared-lib version string int version ------- ------ ----- ---------- @@ -3904,6 +4163,7 @@ 1.2.10beta1-8 13 10210 12.so.0.10[.0] 1.2.10rc1-3 13 10210 12.so.0.10[.0] 1.2.10 13 10210 12.so.0.10[.0] +.DE Henceforth the source version will match the shared-library minor and patch numbers; the shared-library major version number will be @@ -3917,9 +4177,7 @@ .SH "SEE ALSO" libpngpf(3), png(5) -.LP .IR libpng : -.IP http://libpng.sourceforge.net (follow the [DOWNLOAD] link) http://www.libpng.org/pub/png @@ -3932,7 +4190,7 @@ .br ftp://ftp.info-zip.org/pub/infozip/zlib -.LP +.TP .IR PNG specification: RFC 2083 .IP (generally) at the same location as @@ -3971,6 +4229,32 @@ https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe). +.SH VERSION HISTORY + +.DS + libpng version 1.2.5 - October 3, 2002 + Updated and distributed by Glenn Randers-Pehrson + + Copyright (c) 1998-2002 Glenn Randers-Pehrson + For conditions of distribution and use, see copyright + notice in png.h. + + based on: + + libpng 1.0 beta 6 version 0.96 May 28, 1997 + Updated and distributed by Andreas Dilger + Copyright (c) 1996, 1997 Andreas Dilger + + libpng 1.0 beta 2 - version 0.88 January 26, 1996 + For conditions of distribution and use, see copyright + notice in png.h. Copyright (c) 1995, 1996 Guy Eric + Schalnat, Group 42, Inc. + + Updated/rewritten per request in the libpng FAQ + Copyright (c) 1995, 1996 Frank J. T. Wojcik + December 18, 1995 & January 20, 1996 +.DE + .SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: (This copy of the libpng notices is provided for your convenience. In case of @@ -3992,12 +4276,15 @@ distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors +.DS Simon-Pierre Cadieux Eric S. Raymond Gilles Vollant +.DE and with the following additions to the disclaimer: +.DS There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our efforts or the library @@ -4005,27 +4292,32 @@ This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. +.DE libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998, 1999 Glenn Randers-Pehrson Distributed according to the same disclaimer and license as libpng-0.96, with the following individuals added to the list of Contributing Authors: +.DS Tom Lane Glenn Randers-Pehrson Willem van Schaik +.DE libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996, 1997 Andreas Dilger Distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: +.DS John Bowler Kevin Bracey Sam Bushell Magnus Holmgren Greg Roelofs Tom Tanner +.DE libpng versions 0.5, May 1995, through 0.88, January 1996, are Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. @@ -4033,11 +4325,13 @@ For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: +.DS Andreas Dilger Dave Martindale Guy Eric Schalnat Paul Schmidt Tim Wegner +.DE The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, @@ -4065,11 +4359,12 @@ source code in a product, acknowledgment is not required but would be appreciated. - A "png_get_copyright" function is available, for convenient use in "about" boxes and the like: +.EX printf("%s",png_get_copyright(NULL)); +.EE Also, the PNG logo (in PNG format, of course) is supplied in the files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).