⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libpng.txt

📁 神龙卡开发原代码
💻 TXT
📖 第 1 页 / 共 5 页
字号:
    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.  See the PNG specification for details on the specific filtertypes.    /* 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       or more PNG_FILTER_NAME masks. */    png_set_filter(png_ptr, 0,       PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |       PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |       PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |       PNG_FILTER_AVE   | PNG_FILTER_VALUE_AVE  |   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -