📄 pngrutil.c
字号:
return; } png_crc_read(png_ptr, buf, 1); if (png_crc_finish(png_ptr, 0)) return; intent = buf[0]; /* check for bad intent */ if (intent >= PNG_sRGB_INTENT_LAST) { png_warning(png_ptr, "Unknown sRGB intent"); return; }#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) if ((info_ptr->valid & PNG_INFO_gAMA)) { int igamma;#ifdef PNG_FIXED_POINT_SUPPORTED igamma=(int)info_ptr->int_gamma;#else# ifdef PNG_FLOATING_POINT_SUPPORTED igamma=(int)(info_ptr->gamma * 100000.);# endif#endif if(igamma < 45000L || igamma > 46000L) { png_warning(png_ptr, "Ignoring incorrect gAMA value when sRGB is also present");#ifndef PNG_NO_CONSOLE_IO# ifdef PNG_FIXED_POINT_SUPPORTED fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);# else# ifdef PNG_FLOATING_POINT_SUPPORTED fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);# endif# endif#endif } }#endif /* PNG_READ_gAMA_SUPPORTED */#ifdef PNG_READ_cHRM_SUPPORTED#ifdef PNG_FIXED_POINT_SUPPORTED if (info_ptr->valid & PNG_INFO_cHRM) if (abs(info_ptr->int_x_white - 31270L) > 1000 || abs(info_ptr->int_y_white - 32900L) > 1000 || abs(info_ptr->int_x_red - 64000L) > 1000 || abs(info_ptr->int_y_red - 33000L) > 1000 || abs(info_ptr->int_x_green - 30000L) > 1000 || abs(info_ptr->int_y_green - 60000L) > 1000 || abs(info_ptr->int_x_blue - 15000L) > 1000 || abs(info_ptr->int_y_blue - 6000L) > 1000) { png_warning(png_ptr, "Ignoring incorrect cHRM value when sRGB is also present"); }#endif /* PNG_FIXED_POINT_SUPPORTED */#endif /* PNG_READ_cHRM_SUPPORTED */ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);}#endif /* PNG_READ_sRGB_SUPPORTED */#if defined(PNG_READ_iCCP_SUPPORTED)void /* PRIVATE */png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)/* Note: this does not properly handle chunks that are > 64K under DOS */{ png_charp chunkdata; png_byte compression_type; png_bytep pC; png_charp profile; png_uint_32 skip = 0; png_uint_32 profile_size = 0; png_uint_32 profile_length = 0; png_size_t slength, prefix_length, data_length; png_debug(1, "in png_handle_iCCP\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before iCCP"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid iCCP after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Out of place iCCP chunk"); else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) { png_warning(png_ptr, "Duplicate iCCP chunk"); png_crc_finish(png_ptr, length); return; }#ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "iCCP chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; }#endif chunkdata = (png_charp)png_malloc(png_ptr, length + 1); slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, skip)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (profile = chunkdata; *profile; profile++) /* empty loop to find end of name */ ; ++profile; /* there should be at least one zero (the compression type byte) following the separator, and we should be on it */ if ( profile >= chunkdata + slength) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "Malformed iCCP chunk"); return; } /* compression_type should always be zero */ compression_type = *profile++; if (compression_type) { png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 wrote nonzero) */ } prefix_length = profile - chunkdata; chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata, slength, prefix_length, &data_length); profile_length = data_length - prefix_length; if ( prefix_length > data_length || profile_length < 4) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "Profile size field missing from iCCP chunk"); return; } /* Check the profile_size recorded in the first 32 bits of the ICC profile */ pC = (png_bytep)(chunkdata+prefix_length); profile_size = ((*(pC ))<<24) | ((*(pC+1))<<16) | ((*(pC+2))<< 8) | ((*(pC+3)) ); if(profile_size < profile_length) profile_length = profile_size; if(profile_size > profile_length) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "Ignoring truncated iCCP profile.\n"); return; } png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type, chunkdata + prefix_length, profile_length); png_free(png_ptr, chunkdata);}#endif /* PNG_READ_iCCP_SUPPORTED */#if defined(PNG_READ_sPLT_SUPPORTED)void /* PRIVATE */png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)/* Note: this does not properly handle chunks that are > 64K under DOS */{ png_bytep chunkdata; png_bytep entry_start; png_sPLT_t new_palette;#ifdef PNG_NO_POINTER_INDEXING png_sPLT_entryp pp;#endif int data_length, entry_size, i; png_uint_32 skip = 0; png_size_t slength; png_debug(1, "in png_handle_sPLT\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sPLT"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid sPLT after IDAT"); png_crc_finish(png_ptr, length); return; }#ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "sPLT chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; }#endif chunkdata = (png_bytep)png_malloc(png_ptr, length + 1); slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, skip)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (entry_start = chunkdata; *entry_start; entry_start++) /* empty loop to find end of name */ ; ++entry_start; /* a sample depth should follow the separator, and we should be on it */ if (entry_start > chunkdata + slength) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "malformed sPLT chunk"); return; } new_palette.depth = *entry_start++; entry_size = (new_palette.depth == 8 ? 6 : 10); data_length = (slength - (entry_start - chunkdata)); /* integrity-check the data length */ if (data_length % entry_size) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "sPLT chunk has bad length"); return; } new_palette.nentries = data_length / entry_size; new_palette.entries = (png_sPLT_entryp)png_malloc( png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));#ifndef PNG_NO_POINTER_INDEXING for (i = 0; i < new_palette.nentries; i++) { png_sPLT_entryp pp = new_palette.entries + i; if (new_palette.depth == 8) { pp->red = *entry_start++; pp->green = *entry_start++; pp->blue = *entry_start++; pp->alpha = *entry_start++; } else { pp->red = png_get_uint_16(entry_start); entry_start += 2; pp->green = png_get_uint_16(entry_start); entry_start += 2; pp->blue = png_get_uint_16(entry_start); entry_start += 2; pp->alpha = png_get_uint_16(entry_start); entry_start += 2; } pp->frequency = png_get_uint_16(entry_start); entry_start += 2; }#else pp = new_palette.entries; for (i = 0; i < new_palette.nentries; i++) { if (new_palette.depth == 8) { pp[i].red = *entry_start++; pp[i].green = *entry_start++; pp[i].blue = *entry_start++; pp[i].alpha = *entry_start++; } else { pp[i].red = png_get_uint_16(entry_start); entry_start += 2; pp[i].green = png_get_uint_16(entry_start); entry_start += 2; pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; } pp->frequency = png_get_uint_16(entry_start); entry_start += 2; }#endif /* discard all chunk data except the name and stash that */ new_palette.name = (png_charp)chunkdata; png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); png_free(png_ptr, chunkdata); png_free(png_ptr, new_palette.entries);}#endif /* PNG_READ_sPLT_SUPPORTED */#if defined(PNG_READ_tRNS_SUPPORTED)void /* PRIVATE */png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){ png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_tRNS\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tRNS"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid tRNS after IDAT"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) { png_warning(png_ptr, "Duplicate tRNS chunk"); png_crc_finish(png_ptr, length); return; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (!(png_ptr->mode & PNG_HAVE_PLTE)) { /* Should be an error, but we can cope with it */ png_warning(png_ptr, "Missing PLTE before tRNS"); } else if (length > (png_uint_32)png_ptr->num_palette) { png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); return; } if (length == 0) { png_warning(png_ptr, "Zero length tRNS chunk"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, readbuf, (png_size_t)length); png_ptr->num_trans = (png_uint_16)length; } else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { png_byte buf[6]; if (length != 6) { png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, (png_size_t)length); png_ptr->num_trans = 1; png_ptr->trans_values.red = png_get_uint_16(buf); png_ptr->trans_values.green = png_get_uint_16(buf + 2); png_ptr->trans_values.blue = png_get_uint_16(buf + 4); } else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { png_byte buf[6]; if (length != 2) { png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 2); png_ptr->num_trans = 1; png_ptr->trans_values.gray = png_get_uint_16(buf); } else { png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); png_crc_finish(png_ptr, length); return; } if (png_crc_finish(png_ptr, 0)) return; png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, &(png_ptr->trans_values));}#endif#if defined(PNG_READ_bKGD_SUPPORTED)void /* PRIVATE */png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){ png_size_t truelen; png_byte buf[6]; png_debug(1, "in png_handle_bKGD\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before bKGD"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid bKGD after IDAT"); png_crc_finish(png_ptr, length); return; } else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && !(png_ptr->mode & PNG_HAVE_PLTE)) { png_warning(png_ptr, "Missing PLTE before bKGD"); png_crc_finish(png_ptr, length); return; } else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) { png_warning(png_ptr, "Duplicate bKGD chunk"); png_crc_finish(png_ptr, length); return; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) truelen = 1; else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) truelen = 6; else truelen = 2; if (length != truelen) { png_warning(png_ptr, "Incorrect bKGD chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, truelen); if (png_crc_finish(png_ptr, 0)) return; /* We convert the index value into RGB components so that we can allow
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -