?? libpng.txt
字號:
If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keywordseparately, do not transfer responsibility for freeing text_ptr to libpng,because when libpng fills a png_text structure it combines these members withthe key member, and png_free_data() will free only text_ptr.key. Similarly,if you transfer responsibility for free'ing text_ptr from libpng to yourapplication, your application must not separately free those members.The png_free_data() function will turn off the "valid" flag for anythingit frees. If you need to turn the flag off for a chunk that was freed by yourapplication instead of by libpng, you can use 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_IDATFor a more compact example of reading a PNG image, see the file example.c.Reading PNG files progressivelyThe 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 would initialize the progressive reader in your application. */ int initialize_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 (ERROR); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return (ERROR); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } /* This one's new. You can provide functions to be called when the header info is valid, when each row is completed, and when the image is finished. If you aren't using all functions, you can specify NULL parameters. Even when all three functions are NULL, you need to call png_set_progressive_read_fn(). You can use any struct as the user_ptr (cast to a void pointer for the function call), and retrieve the pointer from inside the callbacks using the function png_get_progressive_ptr(png_ptr); which will return a void pointer, which you have to 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 blocks of data */ int process_data(png_bytep buffer, png_uint_32 length) { if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return (ERROR); } /* This one's new also. Simply give it a chunk of data from the file stream (in order, of course). On machines with segmented memory models machines, don't give it any more than 64K. The library seems to run fine with sizes of 4K. Although you can give it much less if necessary (I assume you can give it chunks of 1 byte, I haven't tried less then 256 bytes yet). When this function returns, you may want to display any rows that were generated in the row callback if you don't already do so there. */ png_process_data(png_ptr, info_ptr, buffer, length); return 0; } /* This function is called (as set by png_set_progressive_read_fn() above) when enough data has been supplied so all of the header has been read. */ void info_callback(png_structp png_ptr, png_infop info) { /* Do any setup here, including setting any of the transformations mentioned in the Reading PNG files section. For now, you _must_ call either png_start_read_image() or png_read_update_info() after all the transformations are set (even if you don't set any). You may start getting rows before png_process_data() returns, so this is your last chance to prepare for that. */ } /* This function is called when each row of image data is complete */ void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) { /* If the image is interlaced, and you turned on the interlace handler, this function will be called for every row in every pass. Some of these rows will not be changed from the previous pass. When the row is not changed, the new_row variable will be NULL. The rows and passes are called in order, so you don't really need the row_num and pass, but I'm supplying them because it may make your life easier. For the non-NULL rows of interlaced images, you must call png_progressive_combine_row() passing in the row and the old row. You can call this function for NULL rows (it will just return) and for non-interlaced images (it just does the memcpy for you) if it will make the code easier. Thus, you can just do this for all cases: */ png_progressive_combine_row(png_ptr, old_row, new_row); /* where old_row is what was displayed for previously for the row. Note that the first pass (pass == 0, really) will completely cover the old row, so the rows do not have to be initialized. After the first pass (and only for interlaced images), you will have to pass the current row, and the function will combine the old row and the new row. */ } void end_callback(png_structp png_ptr, png_infop info) { /* This function is called after the whole image has been read, including any chunks after the image (up to and including the IEND). You will usually have the same info chunk as you had in the header, although some data may have been added to the comments and time fields. Most people won't do much here, perhaps setting a flag that marks the image as finished. */ }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.SetupYou 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 (ERROR); }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 (ERROR); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return (ERROR); }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_write_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_jmpbuf(png_ptr). If youwrite the file from different routines, you will need to updatethe png_jmpbuf(png_ptr) 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_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return (ERROR); } ... return;If you would rather avoid the complexity of setjmp/longjmp issues,you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which caseerrors will result in a call to PNG_ABORT() which defaults to abort().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);Write callbacksAt 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 function void 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, use png_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 values are 0 (as of theJuly 1999 PNG specification, version 1.2) or 64 (if you are writinga PNG datastream that is to be embedded in a MNG datastream). The thirdparameter is a flag that indicates which filter type(s) are to be testedfor each scanline.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -