📄 pngrtran.c
字号:
png_ptr->trans[i], back.green); png_composite(palette[i].blue, palette[i].blue, png_ptr->trans[i], back.blue); } } }#endif#if defined(PNG_READ_SHIFT_SUPPORTED) if ((png_ptr->transformations & PNG_SHIFT) && color_type == PNG_COLOR_TYPE_PALETTE) { png_uint_16 i; png_uint_16 istop = png_ptr->num_palette; int sr = 8 - png_ptr->sig_bit.red; int sg = 8 - png_ptr->sig_bit.green; int sb = 8 - png_ptr->sig_bit.blue; if (sr < 0 || sr > 8) sr = 0; if (sg < 0 || sg > 8) sg = 0; if (sb < 0 || sb > 8) sb = 0; for (i = 0; i < istop; i++) { png_ptr->palette[i].red >>= sr; png_ptr->palette[i].green >>= sg; png_ptr->palette[i].blue >>= sb; } }#endif }}/* Modify the info structure to reflect the transformations. The * info should be updated so a PNG file could be written with it, * assuming the transformations result in valid PNG data. */voidpng_read_transform_info(png_structp png_ptr, png_infop info_ptr){ png_debug(1, "in png_read_transform_info\n");#if defined(PNG_READ_EXPAND_SUPPORTED) if (png_ptr->transformations & PNG_EXPAND) { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (png_ptr->num_trans) info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; else info_ptr->color_type = PNG_COLOR_TYPE_RGB; info_ptr->bit_depth = 8; info_ptr->num_trans = 0; } else { if (png_ptr->num_trans) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; if (info_ptr->bit_depth < 8) info_ptr->bit_depth = 8; info_ptr->num_trans = 0; } }#endif#if defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->transformations & PNG_BACKGROUND) { info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; info_ptr->num_trans = 0; info_ptr->background = png_ptr->background; }#endif#if defined(PNG_READ_GAMMA_SUPPORTED) if (png_ptr->transformations & PNG_GAMMA) info_ptr->gamma = png_ptr->gamma;#endif#if defined(PNG_READ_16_TO_8_SUPPORTED) if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16) info_ptr->bit_depth = 8;#endif#if defined(PNG_READ_DITHER_SUPPORTED) if (png_ptr->transformations & PNG_DITHER) { if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && png_ptr->palette_lookup && info_ptr->bit_depth == 8) { info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; } }#endif#if defined(PNG_READ_PACK_SUPPORTED) if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8) info_ptr->bit_depth = 8;#endif#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) if (png_ptr->transformations & PNG_GRAY_TO_RGB) info_ptr->color_type |= PNG_COLOR_MASK_COLOR;#endif if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) info_ptr->channels = 3; else info_ptr->channels = 1;#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_STRIP_ALPHA) info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;#endif if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) info_ptr->channels++;#if defined(PNG_READ_FILLER_SUPPORTED) /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ if (png_ptr->transformations & PNG_FILLER && (info_ptr->color_type == PNG_COLOR_TYPE_RGB || info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) ++info_ptr->channels;#endif info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);}/* Transform the row. The order of transformations is significant, * and is very touchy. If you add a transformation, take care to * decide how it fits in with the other transformations here. */voidpng_do_read_transformations(png_structp png_ptr){ png_debug(1, "in png_do_read_transformations\n");#if !defined(PNG_USELESS_TESTS_SUPPORTED) if (png_ptr->row_buf == NULL) {#if !defined(PNG_NO_STDIO) char msg[50]; sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number, png_ptr->pass); png_error(png_ptr, msg);#else png_error(png_ptr, "NULL row buffer");#endif }#endif#if defined(PNG_READ_EXPAND_SUPPORTED) if (png_ptr->transformations & PNG_EXPAND) { if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) { png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->palette, png_ptr->trans, png_ptr->num_trans); } else { if (png_ptr->num_trans) png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->trans_values)); else png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, NULL); } }#endif#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_STRIP_ALPHA) png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, PNG_FLAG_FILLER_AFTER);#endif/*From Andreas Dilger e-mail to png-implement, 26 March 1998: In most cases, the "simple transparency" should be done prior to doing gray-to-RGB, or you will have to test 3x as many bytes to check if a pixel is transparent. You would also need to make sure that the transparency information is upgraded to RGB. To summarize, the current flow is: - Gray + simple transparency -> compare 1 or 2 gray bytes and composite with background "in place" if transparent, convert to RGB if necessary - Gray + alpha -> composite with gray background and remove alpha bytes, convert to RGB if necessary To support RGB backgrounds for gray images we need: - Gray + simple transparency -> convert to RGB + simple transparency, compare 3 or 6 bytes and composite with background "in place" if transparent (3x compare/pixel compared to doing composite with gray bkgrnd) - Gray + alpha -> convert to RGB + alpha, composite with background and remove alpha bytes (3x float operations/pixel compared with composite on gray background) Greg's change will do this. The reason it wasn't done before is for performance, as this increases the per-pixel operations. If we would check in advance if the background was gray or RGB, and position the gray-to-RGB transform appropriately, then it would save a lot of work/time. */#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* if gray -> RGB, do so now only if background is non-gray; else do later * for performance reasons */ if (png_ptr->transformations & PNG_GRAY_TO_RGB && !(png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_BACKGROUND_SUPPORTED) if ((png_ptr->transformations & PNG_BACKGROUND) && ((png_ptr->num_trans != 0 ) || (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->trans_values), &(png_ptr->background), &(png_ptr->background_1), png_ptr->gamma_table, png_ptr->gamma_from_1, png_ptr->gamma_to_1, png_ptr->gamma_16_table, png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, png_ptr->gamma_shift);#endif#if defined(PNG_READ_GAMMA_SUPPORTED) if ((png_ptr->transformations & PNG_GAMMA) &&#if defined(PNG_READ_BACKGROUND_SUPPORTED) !((png_ptr->transformations & PNG_BACKGROUND) && ((png_ptr->num_trans != 0) || (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&#endif (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->gamma_table, png_ptr->gamma_16_table, png_ptr->gamma_shift);#endif#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & PNG_RGB_TO_GRAY) png_do_rgb_to_gray(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_16_TO_8_SUPPORTED) if (png_ptr->transformations & PNG_16_TO_8) png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_DITHER_SUPPORTED) if (png_ptr->transformations & PNG_DITHER) { png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->palette_lookup, png_ptr->dither_index); if(png_ptr->row_info.rowbytes == (png_uint_32)0) png_error(png_ptr, "png_do_dither returned rowbytes=0"); }#endif#if defined(PNG_READ_INVERT_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_MONO) png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->shift));#endif#if defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* if gray -> RGB, do so now only if we did not do so above */ if (png_ptr->transformations & PNG_GRAY_TO_RGB && png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_FILLER) png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, (png_uint_32)png_ptr->filler, png_ptr->flags);#endif#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_ALPHA) png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_ALPHA) png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);#endif#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) if(png_ptr->read_user_transform_fn != NULL) (*(png_ptr->read_user_transform_fn)) /* user read transform function */ (png_ptr, /* png_ptr */ &(png_ptr->row_info), /* row_info: */ /* png_uint_32 width; width of row */ /* png_uint_32 rowbytes; number of bytes in row */ /* png_byte color_type; color type of pixels */ /* png_byte bit_depth; bit depth of samples */ /* png_byte channels; number of channels (1-4) */ /* png_byte pixel_depth; bits per pixel (depth*channels) */ png_ptr->row_buf + 1); /* start of pixel data for row */#endif}#if defined(PNG_READ_PACK_SUPPORTED)/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, * without changing the actual values. Thus, if you had a row with * a bit depth of 1, you would end up with bytes that only contained * the numbers 0 or 1. If you would rather they contain 0 and 255, use * png_do_shift() after this. */voidpng_do_unpack(png_row_infop row_info, png_bytep row){ png_debug(1, "in png_do_unpack\n");#if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && row_info->bit_depth < 8)#else if (row_info->bit_depth < 8)#endif { png_uint_32 i; png_uint_32 row_width=row_info->width; switch (row_info->bit_depth) { case 1: { png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); png_bytep dp = row + (png_size_t)row_width - 1; png_uint_32 shift = 7 - (int)((row_width + 7) & 7); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x1); if (shift == 7) { shift = 0; sp--; } else shift++; dp--; } break; } case 2: { png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); png_bytep dp = row + (png_size_t)row_width - 1; png_uint_32 shift = (int)((3 - ((row_width + 3) & 3)) << 1); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x3); if (shift == 6) { shift = 0; sp--; } else shift += 2; dp--; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -