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

📄 libpng.txt

📁 神龙卡开发原代码
💻 TXT
📖 第 1 页 / 共 5 页
字号:
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);   else      png_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_uint_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);Finally, you can write your own transformation function if none ofthe existing ones meets your needs.  This is done by setting a callbackwith    png_set_read_user_transform_fn(png_ptr,       read_transform_fn);You must supply the function    void read_transform_fn(png_ptr ptr, row_info_ptr       row_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 thefunction    png_set_user_transform_info(png_ptr, user_ptr,       user_depth, user_channels);The user's application, not libpng, is responsible for allocating andfreeing any memory required for the user structure.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);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.Reading image dataAfter 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 witha single row_pointer instead of an array of row_pointers:    png_bytep row_pointer = row;    png_read_row(png_ptr, row_pointer, NULL);If the file is interlaced (interlace_type != 0 in the IHDR chunk), thingsget somewhat 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);Finishing a sequential readAfter you are finished reading the image through either the high- orlow-level interfaces, you can finish reading the file.  If you areinterested in comments or time, which may be stored either before orafter the image data, you should pass the separate png_info struct ifyou want to keep the comments from before and after the imageseparate.  If you are not interested, you can 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);It is also possible to individually free the info_ptr members thatpoint to libpng-allocated storage with the following function:    png_free_data(png_ptr, info_ptr, mask, seq)    mask - identifies data to be freed, a mask           containing the logical OR of one or           more of             PNG_FREE_PLTE, PNG_FREE_TRNS,             PNG_FREE_HIST, PNG_FREE_ICCP,             PNG_FREE_PCAL, PNG_FREE_ROWS,             PNG_FREE_SCAL, PNG_FREE_SPLT,             PNG_FREE_TEXT, PNG_FREE_UNKN,           or simply PNG_FREE_ALL    seq  - sequence number of item to be freed           (-1 for all items)This function may be safely called when the relevant storage hasalready been freed, or has not yet been allocated, or was allocatedby the user and not by libpng,  and will in thosecases do nothing.  The "seq" parameter is ignored if only one itemof the selected data type, such as PLTE, is allowed.  If "seq" is not-1, and multiple items are allowed for the data type identified inthe mask, such as text or sPLT, only the n'th item in the structureis freed, where n is "seq".The default behavior is only to free data that was allocated internallyby libpng.  This can be changed, so that libpng will not free the data,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    png_data_freer(png_ptr, info_ptr, freer, mask)    mask   - which data elements are affected             same choices as in png_free_data()    freer  - one of               PNG_DESTROY_WILL_FREE_DATA               PNG_SET_WILL_FREE_DATA               PNG_USER_WILL_FREE_DATAThis function only affects data that has already been allocated.You can call this function after reading the PNG data but before callingany png_set_*() functions, to control whether the user or the png_set_*()function is responsible for freeing any existing data that might be present,and again after the png_set_*() functions to control whether the useror png_destroy_*() is supposed to free the data.  When the user assumesresponsibility for libpng-allocated data, the application must usepng_free() to free it, and when the user transfers responsibility to libpngfor data that the user has allocated, the user must have used png_malloc()or png_zalloc() to allocate it.If you allocated your row_pointers in a single block, as suggested above inthe description of the high level read interface, you must not transferresponsibility for freeing it to the png_set_rows or png_read_destroy function,because they would also try to free the individual row_pointers[i].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);

⌨️ 快捷键说明

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