=========================================================================== FUN_001077c0 =========================================================================== Real name: png_chunk_unknown_handling OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function swaps the bytes of a given parameter and passes it to | | the png_handle_as_unknown() function. | +------------------------------------------------------------------------+ libpng/png.c:962 | Decompilation: FUN_001077c0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ | void FUN_001077c0(undefined8 param_1,uint param_2) defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) | int /* PRIVATE */ | { png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) | long in_FS_OFFSET; { | uint local_15; png_byte chunk_string[5]; | undefined local_11; | long local_10; PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); | return png_handle_as_unknown(png_ptr, chunk_string); | local_15 = param_2 >> 0x18 | (param_2 & 0xff0000) >> 8 | (param_2 & 0xff00) << 8 | param_2 << 0x18 } | ; #endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ | local_10 = *(long *)(in_FS_OFFSET + 0x28); #endif /* SET_UNKNOWN_CHUNKS */ | local_11 = 0; | png_handle_as_unknown(param_1,&local_15); | if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) { | return; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_00119fb0 =========================================================================== Real name: png_zlib_inflate OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function returns the inflate of a given parameter and checks if | | the window size is valid. | +------------------------------------------------------------------------+ libpng/pngrutil.c:454 | Decompilation: FUN_00119fb0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #if ZLIB_VERNUM >= 0x1240 | undefined8 FUN_00119fb0(long param_1) /* Handle the start of the inflate stream if we called inflateInit2(strm,0); | * in this case some zlib versions skip validation of the CINFO field and, in | { * certain circumstances, libpng may end up displaying an invalid image, in | undefined8 uVar1; * contrast to implementations that call zlib in the normal way (e.g. libpng | * 1.5). | if ((*(char *)(param_1 + 0x270) != '\0') && (*(int *)(param_1 + 0x148) != 0)) { */ | if (**(char **)(param_1 + 0x140) < '\0') { int /* PRIVATE */ | *(char **)(param_1 + 0x170) = "invalid window size (libpng)"; png_zlib_inflate(png_structrp png_ptr, int flush) | return 0xfffffffd; { | } if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0) | *(undefined *)(param_1 + 0x270) = 0; { | } if ((*png_ptr->zstream.next_in >> 4) > 7) | uVar1 = inflate(param_1 + 0x140); { | return uVar1; png_ptr->zstream.msg = "invalid window size (libpng)"; | } return Z_DATA_ERROR; | } | | png_ptr->zstream_start = 0; | } | | return inflate(&png_ptr->zstream, flush); | } | #endif /* Zlib >= 1.2.4 */ | =========================================================================== FUN_00107840 =========================================================================== Real name: png_zstream_error OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function sets an error message for a given zlib return code in | | the memory location pointed to by param_1 + 0x170. | +------------------------------------------------------------------------+ libpng/png.c:999 | Decompilation: FUN_00107840 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) | void FUN_00107840(long param_1,undefined4 param_2) /* Ensure that png_ptr->zstream.msg holds some appropriate error message string. | * If it doesn't 'ret' is used to set it to something appropriate, even in cases | { * like Z_OK or Z_STREAM_END where the error code is apparently a success code. | if (*(long *)(param_1 + 0x170) != 0) { */ | return; void /* PRIVATE */ | } png_zstream_error(png_structrp png_ptr, int ret) | switch(param_2) { { | default: /* Translate 'ret' into an appropriate error string, priority is given to the | *(char **)(param_1 + 0x170) = "unexpected zlib return code"; * one in zstream if set. This always returns a string, even in cases like | return; * Z_OK or Z_STREAM_END where the error code is a success code. | case 1: */ | *(char **)(param_1 + 0x170) = "unexpected end of LZ stream"; if (png_ptr->zstream.msg == NULL) switch (ret) | return; { | case 2: default: | *(char **)(param_1 + 0x170) = "missing LZ dictionary"; case Z_OK: | return; png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); | case 0xfffffff9: break; | *(char **)(param_1 + 0x170) = "unexpected zlib return"; | return; case Z_STREAM_END: | case 0xfffffffa: /* Normal exit */ | *(char **)(param_1 + 0x170) = "unsupported zlib version"; png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); | return; break; | case 0xfffffffb: | *(char **)(param_1 + 0x170) = "truncated"; case Z_NEED_DICT: | return; /* This means the deflate stream did not have a dictionary; this | case 0xfffffffc: * indicates a bogus PNG. | *(char **)(param_1 + 0x170) = "insufficient memory"; */ | return; png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); | case 0xfffffffd: break; | *(char **)(param_1 + 0x170) = "damaged LZ stream"; | return; case Z_ERRNO: | case 0xfffffffe: /* gz APIs only: should not happen */ | *(char **)(param_1 + 0x170) = "bad parameters to zlib"; png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); | return; break; | case 0xffffffff: | *(char **)(param_1 + 0x170) = "zlib IO error"; case Z_STREAM_ERROR: | return; /* internal libpng error */ | } png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); | } break; | | case Z_DATA_ERROR: | png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); | break; | | case Z_MEM_ERROR: | png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); | break; | | case Z_BUF_ERROR: | /* End of input or output; not a problem if the caller is doing | * incremental read or write. | */ | png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); | break; | | case Z_VERSION_ERROR: | png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); | break; | | case PNG_UNEXPECTED_ZLIB_RETURN: | /* Compile errors here mean that zlib now uses the value co-opted in | * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above | * and change pngpriv.h. Note that this message is "... return", | * whereas the default/Z_OK one is "... return code". | */ | png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); | break; | } | } | =========================================================================== FUN_00106590 =========================================================================== Real name: is_ICC_signature_char OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if the given parameter is between 0x41 and 0x5A | | (inclusive). | +------------------------------------------------------------------------+ libpng/png.c:1809 | Decompilation: FUN_00106590 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- static int | bool FUN_00106590(ulong param_1) is_ICC_signature_char(png_alloc_size_t it) | { | { return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || | return (param_1 & 0xffffffffffffffdf) - 0x41 < 0x1a; (it >= 97 && it <= 122); | } } | =========================================================================== FUN_001068b0 =========================================================================== Real name: png_reset_crc OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function calculates and stores a CRC32 value into the memory | | location specified by the parameter `param_1`. | +------------------------------------------------------------------------+ libpng/png.c:128 | Decompilation: FUN_001068b0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Reset the CRC variable to 32 bits of 1's. Care must be taken | void FUN_001068b0(long param_1) * in case CRC is > 32 bits to leave the top bits 0. | */ | { void /* PRIVATE */ | undefined4 uVar1; png_reset_crc(png_structrp png_ptr) | { | uVar1 = crc32(0,0,0); /* The cast is safe because the crc is a 32-bit value. */ | *(undefined4 *)(param_1 + 0x24c) = uVar1; png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); | return; } | } =========================================================================== FUN_0010b470 =========================================================================== Real name: png_app_warning OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks a byte of data at a given address, and if it is | | set to a certain value, it calls the png_warning function, otherwise | | it calls the png_error function. | +------------------------------------------------------------------------+ libpng/pngerror.c:393 | Decompilation: FUN_0010b470 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_0010b470(long param_1) png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) | { | { if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) | if ((*(byte *)(param_1 + 0x132) & 0x20) != 0) { png_warning(png_ptr, error_message); | png_warning(); else | return; png_error(png_ptr, error_message); | } | /* WARNING: Subroutine does not return */ # ifndef PNG_ERROR_TEXT_SUPPORTED | png_error(); PNG_UNUSED(error_message) | } # endif | } | =========================================================================== FUN_0010b490 =========================================================================== Real name: png_app_error OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set and if it is, it calls the png_warning() function, | | otherwise it calls the png_error() function. | +------------------------------------------------------------------------+ libpng/pngerror.c:406 | Decompilation: FUN_0010b490 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_0010b490(long param_1) png_app_error(png_const_structrp png_ptr, png_const_charp error_message) | { | { if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) | if ((*(byte *)(param_1 + 0x132) & 0x40) != 0) { png_warning(png_ptr, error_message); | png_warning(); else | return; png_error(png_ptr, error_message); | } | /* WARNING: Subroutine does not return */ # ifndef PNG_ERROR_TEXT_SUPPORTED | png_error(); PNG_UNUSED(error_message) | } # endif | } | #endif /* BENIGN_ERRORS */ | =========================================================================== FUN_0010cbb0 =========================================================================== Real name: png_malloc_base OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function allocates a block of memory of size param_2 and returns | | a pointer to it, or a pointer to a function if param_1 is not 0. | +------------------------------------------------------------------------+ libpng/pngmem.c:70 | Decompilation: FUN_0010cbb0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* png_malloc_base, an internal function added at libpng 1.6.0, does the work of | void * FUN_0010cbb0(long param_1,size_t param_2) * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. | * Checking and error handling must happen outside this routine; it returns NULL | { * if the allocation cannot be done (for any reason.) | void *pvVar1; */ | PNG_FUNCTION(png_voidp /* PRIVATE */, | if (param_2 == 0) { png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), | return (void *)0x0; PNG_ALLOCATED) | } { | if ((param_1 != 0) && (*(code **)(param_1 + 0x3f0) != (code *)0x0)) { /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS | /* WARNING: Could not recover jumptable at 0x0010cbca. Too many branches */ * allocators have also been removed in 1.6.0, so any 16-bit system now has | /* WARNING: Treating indirect jump as call */ * to implement a user memory handler. This checks to be sure it isn't | pvVar1 = (void *)(**(code **)(param_1 + 0x3f0))(); * called with big numbers. | return pvVar1; */ | } #ifndef PNG_USER_MEM_SUPPORTED | pvVar1 = malloc(param_2); PNG_UNUSED(png_ptr) | return pvVar1; #endif | } | /* Some compilers complain that this is always true. However, it | * can be false when integer overflow happens. | */ | if (size > 0 && size <= PNG_SIZE_MAX | # ifdef PNG_MAX_MALLOC_64K | && size <= 65536U | # endif | ) | { | #ifdef PNG_USER_MEM_SUPPORTED | if (png_ptr != NULL && png_ptr->malloc_fn != NULL) | return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); | | else | #endif | return malloc((size_t)size); /* checked for truncation above */ | } | | else | return NULL; | } | =========================================================================== FUN_0011d6f0 =========================================================================== Real name: png_check_chunk_name OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a chunk type is valid and if it is not, throws | | an error. | +------------------------------------------------------------------------+ libpng/pngrutil.c:3136 | Decompilation: FUN_0011d6f0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_0011d6f0(undefined8 param_1,uint param_2) png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name) | { | { int i; | int iVar1; png_uint_32 cn=chunk_name; | | iVar1 = 4; png_debug(1, "in png_check_chunk_name"); | while( true ) { | if ((0x39 < (param_2 & 0xff) - 0x41) || ((param_2 & 0xff) - 0x5b < 6)) break; for (i=1; i<=4; ++i) | param_2 = param_2 >> 8; { | iVar1 = iVar1 + -1; int c = cn & 0xff; | if (iVar1 == 0) { | return; if (c < 65 || c > 122 || (c > 90 && c < 97)) | } png_chunk_error(png_ptr, "invalid chunk type"); | } | /* WARNING: Subroutine does not return */ cn >>= 8; | png_chunk_error(param_1,"invalid chunk type"); } | } } | =========================================================================== FUN_00113740 =========================================================================== Real name: png_read_data OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, and if | | it is, calls the function pointed to. If not, it calls the png_error | | function with an error message. | +------------------------------------------------------------------------+ libpng/pngrio.c:33 | Decompilation: FUN_00113740 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Read the data from whatever input you are using. The default routine | void FUN_00113740(long param_1) * reads from a file pointer. Note that this routine sometimes gets called | * with very small lengths, so you should implement some kind of simple | { * buffering if you are using unbuffered reads. This should never be asked | if (*(code **)(param_1 + 0x100) != (code *)0x0) { * to read more than 64K on a 16-bit machine. | /* WARNING: Could not recover jumptable at 0x00113750. Too many branches */ */ | /* WARNING: Treating indirect jump as call */ void /* PRIVATE */ | (**(code **)(param_1 + 0x100))(); png_read_data(png_structrp png_ptr, png_bytep data, size_t length) | return; { | } png_debug1(4, "reading %d bytes", (int)length); | /* WARNING: Subroutine does not return */ | png_error(param_1,"Call to NULL read function"); if (png_ptr->read_data_fn != NULL) | } (*(png_ptr->read_data_fn))(png_ptr, data, length); | | else | png_error(png_ptr, "Call to NULL read function"); | } | =========================================================================== FUN_001068d0 =========================================================================== Real name: png_calculate_crc OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function computes a CRC32 checksum of a given memory region. | +------------------------------------------------------------------------+ libpng/png.c:140 | Decompilation: FUN_001068d0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Calculate the CRC over a section of data. We can only pass as | void FUN_001068d0(long param_1,long param_2,ulong param_3) * much data to this routine as the largest single buffer size. We | * also check that this data will actually be used before going to the | { * trouble of calculating it. | ulong uVar1; */ | ulong uVar2; void /* PRIVATE */ | ulong uVar3; png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length) | { | if ((*(byte *)(param_1 + 0x21b) & 0x20) == 0) { int need_crc = 1; | if ((*(uint *)(param_1 + 0x130) & 0x800) != 0) { | return; if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) | } { | } if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == | else if ((*(uint *)(param_1 + 0x130) & 0x300) == 0x300) { (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) | return; need_crc = 0; | } } | if (param_3 != 0) { | uVar1 = (ulong)*(uint *)(param_1 + 0x24c); else /* critical */ | do { { | uVar2 = param_3 & 0xffffffff; if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) | uVar3 = param_3 & 0xffffffff; need_crc = 0; | if ((int)param_3 == 0) { } | uVar3 = 0xffffffff; | uVar2 = 0xffffffff; /* 'uLong' is defined in zlib.h as unsigned long; this means that on some | } * systems it is a 64-bit value. crc32, however, returns 32 bits so the | uVar1 = crc32(uVar1,param_2,uVar2); * following cast is safe. 'uInt' may be no more than 16 bits, so it is | param_3 = param_3 - uVar3; * necessary to perform a loop here. | param_2 = param_2 + uVar3; */ | } while (param_3 != 0); if (need_crc != 0 && length > 0) | *(int *)(param_1 + 0x24c) = (int)uVar1; { | } uLong crc = png_ptr->crc; /* Should never issue a warning */ | return; | } do | { | uInt safe_length = (uInt)length; | #ifndef __COVERITY__ | if (safe_length == 0) | safe_length = (uInt)-1; /* evil, but safe */ | #endif | | crc = crc32(crc, ptr, safe_length); | | /* The following should never issue compiler warnings; if they do the | * target system has characteristics that will probably violate other | * assumptions within the libpng code. | */ | ptr += safe_length; | length -= safe_length; | } | while (length > 0); | | /* And the following is always safe because the crc is only 32 bits. */ | png_ptr->crc = (png_uint_32)crc; | } | } | =========================================================================== FUN_0011d730 =========================================================================== Real name: png_check_chunk_length OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if the size of a given chunk is valid and returns | | an error if it is too large. | +------------------------------------------------------------------------+ libpng/pngrutil.c:3155 | Decompilation: FUN_0011d730 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_0011d730(long param_1,uint param_2) png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) | { | { png_alloc_size_t limit = PNG_UINT_31_MAX; | ulong uVar1; | long lVar2; # ifdef PNG_SET_USER_LIMITS_SUPPORTED | ulong uVar3; if (png_ptr->user_chunk_malloc_max > 0 && | ulong uVar4; png_ptr->user_chunk_malloc_max < limit) | long lVar5; limit = png_ptr->user_chunk_malloc_max; | # elif PNG_USER_CHUNK_MALLOC_MAX > 0 | uVar1 = *(ulong *)(param_1 + 0x430); if (PNG_USER_CHUNK_MALLOC_MAX < limit) | if (0x7ffffffd < uVar1 - 1) { limit = PNG_USER_CHUNK_MALLOC_MAX; | uVar1 = 0x7fffffff; # endif | } if (png_ptr->chunk_name == png_IDAT) | if (*(int *)(param_1 + 0x218) == 0x49444154) { { | lVar2 = (ulong)*(uint *)(param_1 + 0x1f8) * (ulong)*(byte *)(param_1 + 0x26b); png_alloc_size_t idat_limit = PNG_UINT_31_MAX; | if (8 < *(byte *)(param_1 + 0x268)) { size_t row_factor = | lVar2 = lVar2 * 2; (size_t)png_ptr->width | } * (size_t)png_ptr->channels | lVar5 = 0x80000005; * (png_ptr->bit_depth > 8? 2: 1) | uVar4 = lVar2 + 1 + (ulong)(~-(uint)(*(char *)(param_1 + 0x264) == '\0') & 6); + 1 | uVar3 = 0x7fffffff; + (png_ptr->interlaced? 6: 0); | if ((ulong)*(uint *)(param_1 + 0x1fc) <= if (png_ptr->height > PNG_UINT_32_MAX/row_factor) | SUB168((ZEXT816(0) << 0x40 | ZEXT816(0xffffffff)) / ZEXT816(uVar4),0)) { idat_limit = PNG_UINT_31_MAX; | uVar3 = *(uint *)(param_1 + 0x1fc) * uVar4; else | lVar5 = uVar3 + 6; idat_limit = png_ptr->height * row_factor; | } row_factor = row_factor > 32566? 32566 : row_factor; | if (0x7f36 < uVar4) { idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */ | uVar4 = 0x7f36; idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX; | } limit = limit < idat_limit? idat_limit : limit; | uVar4 = (uVar3 / uVar4) * 5 + 5 + lVar5; } | if (0x7fffffff < uVar4) { | uVar4 = 0x7fffffff; if (length > limit) | } { | if (uVar1 < uVar4) { png_debug2(0," length = %lu, limit = %lu", | uVar1 = uVar4; (unsigned long)length,(unsigned long)limit); | } png_chunk_error(png_ptr, "chunk data is too large"); | } } | if (uVar1 < param_2) { } | /* WARNING: Subroutine does not return */ | png_chunk_error(param_1,"chunk data is too large"); | } | return; | } =========================================================================== FUN_001091d0 =========================================================================== Real name: png_reciprocal OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function computes a division of 10000000000 by the parameter, | | rounds it to the nearest integer, and returns either the integer or 0 | | if it is not between -2147483648 and 2147483647. | +------------------------------------------------------------------------+ libpng/png.c:3489 | Decompilation: FUN_001091d0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ | ulong FUN_001091d0(int param_1) /* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ | png_fixed_point | { png_reciprocal(png_fixed_point a) | ulong in_RAX; { | double dVar1; #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED | double r = floor(1E10/a+.5); | dVar1 = 10000000000.0 / (double)param_1 + 0.5; | if ((double)((ulong)dVar1 & 0x7fffffffffffffff) < 4503599627370496.0) { if (r <= 2147483647. && r >= -2147483648.) | in_RAX = (ulong)dVar1; return (png_fixed_point)r; | dVar1 = (double)((ulong)dVar1 & 0x8000000000000000 | #else | (ulong)((double)in_RAX - png_fixed_point res; | (double)(-(ulong)(dVar1 < (double)in_RAX) & 0x3ff0000000000000))); | } if (png_muldiv(&res, 100000, 100000, a) != 0) | if ((dVar1 <= 2147483647.0) && (-2147483648.0 <= dVar1)) { return res; | return in_RAX & 0xffffffff00000000 | (ulong)(uint)(int)dVar1; #endif | } | return 0; return 0; /* error/overflow */ | } } | =========================================================================== FUN_00119ae0 =========================================================================== Real name: png_get_fixed_point OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function calculates an integer value from the bytes of an array. | +------------------------------------------------------------------------+ libpng/pngrutil.c:43 | Decompilation: FUN_00119ae0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- static png_fixed_point /* PRIVATE */ | int FUN_00119ae0(byte *param_1) png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) | { | { png_uint_32 uval = png_get_uint_32(buf); | int iVar1; | if (uval <= PNG_UINT_31_MAX) | iVar1 = (uint)param_1[2] * 0x100 + return (png_fixed_point)uval; /* known to be in range */ | (uint)param_1[3] + (uint)param_1[1] * 0x10000 + (uint)*param_1 * 0x1000000; | if (iVar1 < 0) { /* The caller can turn off the warning by passing NULL. */ | iVar1 = -1; if (png_ptr != NULL) | } png_warning(png_ptr, "PNG fixed point integer out of range"); | return iVar1; | } return PNG_FIXED_ERROR; | } | #endif | =========================================================================== FUN_00107910 =========================================================================== Real name: png_colorspace_sync_info OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function sets bits in a variable based on the value of a ushort | | at a given address. | +------------------------------------------------------------------------+ libpng/png.c:1170 | Decompilation: FUN_00107910 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_00107910(undefined8 param_1,long param_2) png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) | { | { if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) | ushort uVar1; { | uint uVar2; /* Everything is invalid */ | uint uVar3; info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| | PNG_INFO_iCCP); | uVar1 = *(ushort *)(param_2 + 0x7e); | uVar3 = *(uint *)(param_2 + 8); # ifdef PNG_COLORSPACE_SUPPORTED | if (-1 < (short)uVar1) { /* Clean up the iCCP profile now if it won't be used. */ | uVar2 = uVar3 & 0xfffff7ff; png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); | if ((uVar1 & 0x80) != 0) { # else | uVar2 = uVar3 | 0x800; PNG_UNUSED(png_ptr) | } # endif | uVar3 = uVar2 & 0xfffffffb; } | if ((uVar1 & 2) != 0) { | uVar3 = uVar2 | 4; else | } { | uVar2 = uVar3 | 1; # ifdef PNG_COLORSPACE_SUPPORTED | if ((uVar1 & 1) == 0) { /* Leave the INFO_iCCP flag set if the pngset.c code has already set | uVar2 = uVar3 & 0xfffffffe; * it; this allows a PNG to contain a profile which matches sRGB and | } * yet still have that profile retrievable by the application. | *(uint *)(param_2 + 8) = uVar2; */ | return; if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) | } info_ptr->valid |= PNG_INFO_sRGB; | *(uint *)(param_2 + 8) = uVar3 & 0xffffe7fa; | png_free_data(param_1,param_2,0x10,0xffffffff); else | return; info_ptr->valid &= ~PNG_INFO_sRGB; | } | if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) | info_ptr->valid |= PNG_INFO_cHRM; | | else | info_ptr->valid &= ~PNG_INFO_cHRM; | # endif | | if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) | info_ptr->valid |= PNG_INFO_gAMA; | | else | info_ptr->valid &= ~PNG_INFO_gAMA; | } | } | =========================================================================== FUN_00108240 =========================================================================== Real name: png_check_fp_number OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function parses a string and sets flags based on the characters | | in the string. | +------------------------------------------------------------------------+ libpng/png.c:2714 | Decompilation: FUN_00108240 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- int /* PRIVATE */ | bool FUN_00108240(long param_1,ulong param_2,uint *param_3,ulong *param_4) png_check_fp_number(png_const_charp string, size_t size, int *statep, | png_size_tp whereami) | { { | byte bVar1; int state = *statep; | uint uVar2; size_t i = *whereami; | uint uVar3; | uint uVar4; while (i < size) | ulong uVar5; { | int type; | uVar5 = *param_4; /* First find the type of the next character */ | uVar4 = *param_3; switch (string[i]) | if ((param_2 <= uVar5) || (bVar1 = *(char *)(param_1 + uVar5) - 0x2b, 0x3a < bVar1)) { { | *param_3 = uVar4; case 43: type = PNG_FP_SAW_SIGN; break; | *param_4 = uVar5; case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; | return (uVar4 & 8) != 0; case 46: type = PNG_FP_SAW_DOT; break; | } case 48: type = PNG_FP_SAW_DIGIT; break; | do { case 49: case 50: case 51: case 52: | switch((long)&switchD_0010827d::switchdataD_001299c8 + case 53: case 54: case 55: case 56: | (long)(int)(&switchD_0010827d::switchdataD_001299c8)[bVar1]) { case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; | case 0x1082b0: case 69: | switchD_0010827d_caseD_1082b0: case 101: type = PNG_FP_SAW_E; break; | uVar2 = uVar4 & 8; default: goto PNG_FP_End; | LAB_001082b6: } | *param_3 = uVar4; | *param_4 = uVar5; /* Now deal with this type according to the current | return uVar2 != 0; * state, the type is arranged to not overlap the | case 0x1082d0: * bits of the PNG_FP_STATE. | uVar2 = 8; */ | uVar3 = 0x108; switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) | break; { | case 0x1082f8: case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: | uVar2 = 0x20; if ((state & PNG_FP_SAW_ANY) != 0) | uVar3 = 0x20; goto PNG_FP_End; /* not a part of the number */ | break; | case 0x108308: png_fp_add(state, type); | uVar2 = 8; break; | uVar3 = 8; | break; case PNG_FP_INTEGER + PNG_FP_SAW_DOT: | case 0x108318: /* Ok as trailer, ok as lead of fraction. */ | uVar2 = 0x10; if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ | uVar3 = 0x10; goto PNG_FP_End; | break; | case 0x1083f0: else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ | uVar2 = 4; png_fp_add(state, type); | uVar3 = 4; | break; else | case 0x108400: png_fp_set(state, PNG_FP_FRACTION | type); | uVar2 = 4; | uVar3 = 0x84; break; | } | switch(uVar4 & 3 | uVar2) { case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: | case 4: if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ | if ((uVar4 & 0x3c) != 0) goto switchD_0010827d_caseD_1082b0; png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); | uVar4 = uVar4 | uVar3; | break; png_fp_add(state, type | PNG_FP_WAS_VALID); | default: | goto switchD_0010827d_caseD_1082b0; break; | case 6: | if ((uVar4 & 0x3c) != 0) goto switchD_0010827d_caseD_1082b0; case PNG_FP_INTEGER + PNG_FP_SAW_E: | uVar4 = uVar4 | 4; if ((state & PNG_FP_SAW_DIGIT) == 0) | break; goto PNG_FP_End; | case 8: | if ((uVar4 & 0x10) != 0) { png_fp_set(state, PNG_FP_EXPONENT); | uVar4 = uVar4 & 0x1c0 | 0x11; | } break; | uVar4 = uVar4 | uVar3 | 0x40; | break; /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: | case 9: goto PNG_FP_End; ** no sign in fraction */ | uVar4 = uVar4 | uVar3 | 0x40; | break; /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: | case 10: goto PNG_FP_End; ** Because SAW_DOT is always set */ | uVar4 = uVar4 | 0x48; | break; case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: | case 0x10: png_fp_add(state, type | PNG_FP_WAS_VALID); | uVar2 = uVar4 & 8; break; | if ((uVar4 & 0x10) != 0) goto LAB_001082b6; | if (uVar2 == 0) { case PNG_FP_FRACTION + PNG_FP_SAW_E: | uVar4 = uVar4 & 0x1c0 | uVar3 | 1; /* This is correct because the trailing '.' on an | } * integer is handled above - so we can only get here | else { * with the sequence ".E" (with no preceding digits). | uVar4 = uVar4 | uVar3; */ | } if ((state & PNG_FP_SAW_DIGIT) == 0) | break; goto PNG_FP_End; | case 0x20: | case 0x21: png_fp_set(state, PNG_FP_EXPONENT); | uVar2 = uVar4 & 8; | if (uVar2 == 0) goto LAB_001082b6; break; | uVar4 = uVar4 & 0x1c0 | 2; | } case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: | uVar5 = uVar5 + 1; if ((state & PNG_FP_SAW_ANY) != 0) | if ((param_2 == uVar5) || (bVar1 = *(char *)(param_1 + uVar5) - 0x2b, 0x3a < bVar1)) goto PNG_FP_End; /* not a part of the number */ | goto switchD_0010827d_caseD_1082b0; | } while( true ); png_fp_add(state, PNG_FP_SAW_SIGN); | } | break; | | /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: | goto PNG_FP_End; */ | | case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: | png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); | | break; | | /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: | goto PNG_FP_End; */ | | default: goto PNG_FP_End; /* I.e. break 2 */ | } | | /* The character seems ok, continue. */ | ++i; | } | | PNG_FP_End: | /* Here at the end, update the state and return the correct | * return code. | */ | *statep = state; | *whereami = i; | | return (state & PNG_FP_SAW_DIGIT) != 0; | } | =========================================================================== FUN_001062e0 =========================================================================== Real name: png_colorspace_endpoints_match OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function returns true if all elements of two arrays, plus or | | minus a given parameter, are equal. | +------------------------------------------------------------------------+ libpng/png.c:1595 | Decompilation: FUN_001062e0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- static int | bool FUN_001062e0(int *param_1,int *param_2,int param_3) png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) | { | { /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ | bool bVar1; if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || | bool bVar2; PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || | PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || | bVar2 = false; PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || | bVar1 = false; PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || | if ((param_2[6] - param_3 <= param_1[6]) && (param_1[6] <= param_2[6] + param_3)) { PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || | if ((param_2[7] - param_3 <= param_1[7]) && (bVar2 = bVar1, param_1[7] <= param_2[7] + param_3)) PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || | { PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) | if ((*param_2 - param_3 <= *param_1) && (*param_1 <= *param_2 + param_3)) { return 0; | if ((param_2[1] - param_3 <= param_1[1]) && (param_1[1] <= param_2[1] + param_3)) { return 1; | if ((param_2[2] - param_3 <= param_1[2]) && (param_1[2] <= param_2[2] + param_3)) { } | if ((param_2[3] - param_3 <= param_1[3]) && (param_1[3] <= param_2[3] + param_3)) { | if ((param_2[4] - param_3 <= param_1[4]) && (param_1[4] <= param_2[4] + param_3)) { | if (param_2[5] - param_3 <= param_1[5]) { | bVar2 = param_1[5] <= param_2[5] + param_3; | } | } | } | } | } | } | } | } | return bVar2; | } =========================================================================== FUN_00108ce0 =========================================================================== Real name: png_muldiv OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function calculates the result of the division of two integers, | | rounds it to the nearest integer, and stores it in the first | | parameter. | +------------------------------------------------------------------------+ libpng/png.c:3351 | Decompilation: FUN_00108ce0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ | int FUN_00108ce0(int *param_1,int param_2,int param_3,int param_4) defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) | /* muldiv functions */ | { /* This API takes signed arguments and rounds the result to the nearest | double dVar1; * integer (or, for a fixed point number - the standard argument - to | * the nearest .00001). Overflow and divide by zero are signalled in | if (param_4 != 0) { * the result, a boolean - true on success, false on overflow. | if ((param_2 == 0) || (param_3 == 0)) { */ | *param_1 = 0; #if GCC_STRICT_OVERFLOW /* from above */ | return 1; /* It is not obvious which comparison below gets optimized in such a way that | } * signed overflow would change the result; looking through the code does not | dVar1 = ((double)param_3 * (double)param_2) / (double)param_4 + 0.5; * reveal any tests which have the form GCC complains about, so presumably the | if (dVar1 < 4503599627370496.0) { * optimizer is moving an add or subtract into the 'if' somewhere. | dVar1 = (double)((ulong)dVar1 & 0x8000000000000000 | */ | (ulong)((double)(long)dVar1 - #pragma GCC diagnostic push | (double)(-(ulong)(dVar1 < (double)(long)dVar1) & 0x3ff0000000000000))); #pragma GCC diagnostic warning "-Wstrict-overflow=2" | } #endif /* GCC_STRICT_OVERFLOW */ | if ((dVar1 <= 2147483647.0) && (-2147483648.0 <= dVar1)) { int | *param_1 = (int)dVar1; png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, | return 1; png_int_32 divisor) | } { | param_4 = 0; /* Return a * times / divisor, rounded. */ | } if (divisor != 0) | return param_4; { | } if (a == 0 || times == 0) | { | *res = 0; | return 1; | } | else | { | #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED | double r = a; | r *= times; | r /= divisor; | r = floor(r+.5); | | /* A png_fixed_point is a 32-bit integer. */ | if (r <= 2147483647. && r >= -2147483648.) | { | *res = (png_fixed_point)r; | return 1; | } | #else | int negative = 0; | png_uint_32 A, T, D; | png_uint_32 s16, s32, s00; | | if (a < 0) | negative = 1, A = -a; | else | A = a; | | if (times < 0) | negative = !negative, T = -times; | else | T = times; | | if (divisor < 0) | negative = !negative, D = -divisor; | else | D = divisor; | | /* Following can't overflow because the arguments only | * have 31 bits each, however the result may be 32 bits. | */ | s16 = (A >> 16) * (T & 0xffff) + | (A & 0xffff) * (T >> 16); | /* Can't overflow because the a*times bit is only 30 | * bits at most. | */ | s32 = (A >> 16) * (T >> 16) + (s16 >> 16); | s00 = (A & 0xffff) * (T & 0xffff); | | s16 = (s16 & 0xffff) << 16; | s00 += s16; | | if (s00 < s16) | ++s32; /* carry */ | | if (s32 < D) /* else overflow */ | { | /* s32.s00 is now the 64-bit product, do a standard | * division, we know that s32 < D, so the maximum | * required shift is 31. | */ | int bitshift = 32; | png_fixed_point result = 0; /* NOTE: signed */ | | while (--bitshift >= 0) | { | png_uint_32 d32, d00; | | if (bitshift > 0) | d32 = D >> (32-bitshift), d00 = D << bitshift; | | else | d32 = 0, d00 = D; | | if (s32 > d32) | { | if (s00 < d00) --s32; /* carry */ | s32 -= d32, s00 -= d00, result += 1<<bitshift; | } | | else | if (s32 == d32 && s00 >= d00) | s32 = 0, s00 -= d00, result += 1<<bitshift; | } | | /* Handle the rounding. */ | if (s00 >= (D >> 1)) | ++result; | | if (negative != 0) | result = -result; | | /* Check for overflow. */ | if ((negative != 0 && result <= 0) || | (negative == 0 && result >= 0)) | { | *res = result; | return 1; | } | } | #endif | } | } | | return 0; | } | #if GCC_STRICT_OVERFLOW | #pragma GCC diagnostic pop | #endif /* GCC_STRICT_OVERFLOW */ | #endif /* READ_GAMMA || INCH_CONVERSIONS */ | =========================================================================== FUN_00109960 =========================================================================== Real name: png_gamma_significant OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function returns true if the value of param_1 is greater than | | 105000, and false otherwise. | +------------------------------------------------------------------------+ libpng/png.c:3510 | Decompilation: FUN_00109960 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* This is the shared test on whether a gamma value is 'significant' - whether | bool FUN_00109960(int param_1) * it is worth doing gamma correction. | */ | { int /* PRIVATE */ | return 10000 < param_1 - 95000U; png_gamma_significant(png_fixed_point gamma_val) | } { | return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || | gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; | } | #endif | =========================================================================== FUN_0010ae00 =========================================================================== Real name: png_format_number OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function converts a number to a string of hexadecimal or decimal | | characters. | +------------------------------------------------------------------------+ libpng/pngerror.c:135 | Decompilation: FUN_0010ae00 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) | char * FUN_0010ae00(char *param_1,long param_2,int param_3,ulong param_4) /* Utility to dump an unsigned value into a buffer, given a start pointer and | * and end pointer (which should point just *beyond* the end of the buffer!) | { * Returns the pointer to the start of the formatted string. | bool bVar1; */ | int iVar2; png_charp | int iVar3; png_format_number(png_const_charp start, png_charp end, int format, | char *pcVar4; png_alloc_size_t number) | { | pcVar4 = (char *)(param_2 - 1); int count = 0; /* number of digits output */ | *(undefined *)(param_2 + -1) = 0; int mincount = 1; /* minimum number required */ | if (pcVar4 <= param_1) { int output = 0; /* digit output (for the fixed point format) */ | return pcVar4; | } *--end = '\0'; | bVar1 = false; | iVar3 = 0; /* This is written so that the loop always runs at least once, even with | iVar2 = 1; * number zero. | LAB_0010ae48: */ | do { while (end > start && (number != 0 || count < mincount)) | iVar3 = iVar3 + 1; { | switch(param_3) { | default: static const char digits[] = "0123456789ABCDEF"; | param_4 = 0; | goto LAB_0010aed0; switch (format) | case 2: { | iVar2 = param_3; case PNG_NUMBER_FORMAT_fixed: | case 1: /* Needs five digits (the fraction) */ | pcVar4 = pcVar4 + -1; mincount = 5; | *pcVar4 = "0123456789ABCDEF"[param_4 % 10]; if (output != 0 || number % 10 != 0) | param_4 = param_4 / 10; { | break; *--end = digits[number % 10]; | case 4: output = 1; | iVar2 = 2; } | case 3: number /= 10; | pcVar4 = pcVar4 + -1; break; | *pcVar4 = "0123456789ABCDEF"[(uint)param_4 & 0xf]; | param_4 = param_4 >> 4; case PNG_NUMBER_FORMAT_02u: | break; /* Expects at least 2 digits. */ | case 5: mincount = 2; | if ((bVar1) || (param_4 % 10 != 0)) { /* FALLTHROUGH */ | pcVar4 = pcVar4 + -1; | bVar1 = true; case PNG_NUMBER_FORMAT_u: | *pcVar4 = "0123456789ABCDEF"[param_4 % 10]; *--end = digits[number % 10]; | } number /= 10; | param_4 = param_4 / 10; break; | iVar2 = param_3; | } case PNG_NUMBER_FORMAT_02x: | if ((param_3 == 5) && (iVar3 == 5)) { /* This format expects at least two digits */ | if (pcVar4 <= param_1) { mincount = 2; | return pcVar4; /* FALLTHROUGH */ | } | if (!bVar1) { case PNG_NUMBER_FORMAT_x: | if (param_4 == 0) { *--end = digits[number & 0xf]; | pcVar4[-1] = '0'; number >>= 4; | return pcVar4 + -1; break; | } | iVar3 = 5; default: /* an error */ | goto LAB_0010ae48; number = 0; | } break; | pcVar4[-1] = '.'; } | pcVar4 = pcVar4 + -1; | } /* Keep track of the number of digits added */ | LAB_0010aed0: ++count; | if (pcVar4 <= param_1) { | return pcVar4; /* Float a fixed number here: */ | } if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start)) | if ((param_4 == 0) && (iVar2 <= iVar3)) { { | return pcVar4; /* End of the fraction, but maybe nothing was output? In that case | } * drop the decimal point. If the number is a true zero handle that | } while( true ); * here. | } */ | if (output != 0) | *--end = '.'; | else if (number == 0) /* and !output */ | *--end = '0'; | } | } | | return end; | } | #endif | =========================================================================== FUN_0010adb0 =========================================================================== Real name: png_safecat OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function copies a string from param_4 to param_1, up to a maximum | | of param_2 characters or until the end of the string is reached. | +------------------------------------------------------------------------+ libpng/pngerror.c:114 | Decompilation: FUN_0010adb0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Utility to safely appends strings to a buffer. This never errors out so | void FUN_0010adb0(long param_1,ulong param_2,ulong param_3,char *param_4) * error checking is not required in the caller. | */ | { size_t | ulong uVar1; png_safecat(png_charp buffer, size_t bufsize, size_t pos, | char cVar2; png_const_charp string) | { | if ((param_1 != 0) && (param_3 < param_2)) { if (buffer != NULL && pos < bufsize) | uVar1 = param_3; { | if ((param_4 != (char *)0x0) && ((cVar2 = *param_4, cVar2 != '\0' && (param_3 < param_2 - 1)))) if (string != NULL) | { while (*string != '\0' && pos < bufsize-1) | do { buffer[pos++] = *string++; | uVar1 = uVar1 + 1; | *(char *)(param_1 + -1 + uVar1) = cVar2; buffer[pos] = '\0'; | cVar2 = param_4[uVar1 - param_3]; } | if (cVar2 == '\0') break; | } while (uVar1 < param_2 - 1); return pos; | } } | *(undefined *)(param_1 + uVar1) = 0; | } | return; | } =========================================================================== FUN_0011a130 =========================================================================== Real name: png_inflate OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function inflates given data and checks for errors, setting an | | error message in the memory location pointed to by param_1 + 0x170 if | | necessary. | +------------------------------------------------------------------------+ libpng/pngrutil.c:484 | Decompilation: FUN_0011a130 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* png_inflate_claim: claim the zstream for some nefarious purpose that involves | int FUN_0011a130(long param_1,int param_2,undefined8 param_3,int *param_4,long param_5,long *param_6 * decompression. Returns Z_OK on success, else a zlib error code. It checks | ) * the owner but, in final release builds, just issues a warning if some other | * chunk apparently owns the stream. Prior to release it does a png_error. | { */ | uint uVar1; static int | int iVar2; png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) | ulong uVar3; { | uint uVar4; if (png_ptr->zowner != 0) | int iVar5; { | long lVar6; char msg[64]; | ulong uVar7; | long in_FS_OFFSET; PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); | undefined local_448 [1032]; /* So the message that results is "<chunk> using zstream"; this is an | long local_40; * internal error, but is very useful for debugging. i18n requirements | * are minimal. | local_40 = *(long *)(in_FS_OFFSET + 0x28); */ | if (*(int *)(param_1 + 0x138) == param_2) { (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); | lVar6 = *param_6; #if PNG_RELEASE_BUILD | iVar2 = *param_4; png_chunk_warning(png_ptr, msg); | *(undefined8 *)(param_1 + 0x140) = param_3; png_ptr->zowner = 0; | if (param_5 != 0) { #else | *(long *)(param_1 + 0x158) = param_5; png_chunk_error(png_ptr, msg); | } #endif | uVar7 = 0; } | iVar5 = 0; | uVar1 = (-(uint)(param_5 == 0) & 0x401) - 1; /* Implementation note: unlike 'png_deflate_claim' this internal function | while( true ) { * does not take the size of the data as an argument. Some efficiency could | uVar7 = lVar6 + uVar7; * be gained by using this when it is known *if* the zlib stream itself does | *(int *)(param_1 + 0x148) = iVar2 + iVar5; * not record the number; however, this is an illusion: the original writer | if (param_5 == 0) { * of the PNG may have selected a lower window size, and we really must | *(undefined **)(param_1 + 0x158) = local_448; * follow that because, for systems with with limited capabilities, we | } * would otherwise reject the application's attempts to use a smaller window | uVar3 = (ulong)uVar1; * size (zlib doesn't have an interface to say "this or lower"!). | uVar4 = uVar1; * | if (uVar7 < uVar1) { * inflateReset2 was added to zlib 1.2.4; before this the window could not be | uVar3 = uVar7; * reset, therefore it is necessary to always allocate the maximum window | uVar4 = (uint)uVar7; * size with earlier zlibs just in case later compressed chunks need it. | } */ | *(uint *)(param_1 + 0x160) = uVar4; { | lVar6 = uVar7 - uVar3; int ret; /* zlib return code */ | iVar2 = FUN_00119fb0(param_1,(ulong)(lVar6 == 0) << 2); #if ZLIB_VERNUM >= 0x1240 | if (iVar2 != 0) break; int window_bits = 0; | iVar5 = *(int *)(param_1 + 0x148); | uVar7 = (ulong)*(uint *)(param_1 + 0x160); # if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) | iVar2 = 0; if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == | } PNG_OPTION_ON) | if (param_5 == 0) { { | *(undefined8 *)(param_1 + 0x158) = 0; window_bits = 15; | } png_ptr->zstream_start = 0; /* fixed window size */ | iVar5 = *(int *)(param_1 + 0x148); } | lVar6 = lVar6 + (ulong)*(uint *)(param_1 + 0x160); | if (lVar6 != 0) { else | *param_6 = *param_6 - lVar6; { | } png_ptr->zstream_start = 1; | if (iVar5 != 0) { } | *param_4 = *param_4 - iVar5; # endif | } | FUN_00107840(param_1,iVar2); #endif /* ZLIB_VERNUM >= 0x1240 */ | } | else { /* Set this for safety, just in case the previous owner left pointers to | *(char **)(param_1 + 0x170) = "zstream unclaimed"; * memory allocations. | iVar2 = -2; */ | } png_ptr->zstream.next_in = NULL; | if (local_40 != *(long *)(in_FS_OFFSET + 0x28)) { png_ptr->zstream.avail_in = 0; | /* WARNING: Subroutine does not return */ png_ptr->zstream.next_out = NULL; | __stack_chk_fail(); png_ptr->zstream.avail_out = 0; | } | return iVar2; if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) | } { | #if ZLIB_VERNUM >= 0x1240 | ret = inflateReset2(&png_ptr->zstream, window_bits); | #else | ret = inflateReset(&png_ptr->zstream); | #endif | } | | else | { | #if ZLIB_VERNUM >= 0x1240 | ret = inflateInit2(&png_ptr->zstream, window_bits); | #else | ret = inflateInit(&png_ptr->zstream); | #endif | | if (ret == Z_OK) | png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; | } | | #if ZLIB_VERNUM >= 0x1290 && \ | defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) | if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) | /* Turn off validation of the ADLER32 checksum in IDAT chunks */ | ret = inflateValidate(&png_ptr->zstream, 0); | #endif | | if (ret == Z_OK) | png_ptr->zowner = owner; | | else | png_zstream_error(png_ptr, ret); | | return ret; | } | | #ifdef window_bits | # undef window_bits | #endif | } | =========================================================================== FUN_0010b520 =========================================================================== Real name: png_chunk_report OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set and calls the appropriate function depending on the | | value of the bit and the value of the parameter. | +------------------------------------------------------------------------+ libpng/pngerror.c:532 | Decompilation: FUN_0010b520 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_0010b520(long param_1,undefined8 param_2,int param_3) png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error) | { | { # ifndef PNG_WARNINGS_SUPPORTED | if ((*(byte *)(param_1 + 0x12d) & 0x80) == 0) { PNG_UNUSED(message) | if (0 < param_3) { # endif | FUN_0010b490(); | return; /* This is always supported, but for just read or just write it | } * unconditionally does the right thing. | FUN_0010b470(); */ | return; # if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) | } if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) | if (1 < param_3) { # endif | png_chunk_benign_error(); | return; # ifdef PNG_READ_SUPPORTED | } { | png_chunk_warning(); if (error < PNG_CHUNK_ERROR) | return; png_chunk_warning(png_ptr, message); | } | else | png_chunk_benign_error(png_ptr, message); | } | # endif | | # if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) | else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) | # endif | | # ifdef PNG_WRITE_SUPPORTED | { | if (error < PNG_CHUNK_WRITE_ERROR) | png_app_warning(png_ptr, message); | | else | png_app_error(png_ptr, message); | } | # endif | } | =========================================================================== FUN_0010cc20 =========================================================================== Real name: png_realloc_array OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function allocates a block of memory of size param_2 and copies | | param_3 elements of data stored in param_2 into it, filling the rest | | of the block with zeroes, then returns a pointer to it. | +------------------------------------------------------------------------+ libpng/pngmem.c:134 | Decompilation: FUN_0010cc20 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- PNG_FUNCTION(png_voidp /* PRIVATE */, | void * FUN_0010cc20(undefined8 param_1,void *param_2,int param_3,int param_4,ulong param_5) png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, | int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) | { { | void *__dest; /* These are internal errors: */ | if (add_elements <= 0 || element_size == 0 || old_elements < 0 || | if (((0 < param_4 && param_5 != 0) && (-1 < param_3)) && (old_array == NULL && old_elements > 0)) | ((param_2 != (void *)0x0 || (param_3 < 1)))) { png_error(png_ptr, "internal error: array realloc"); | if (((param_4 <= 0x7fffffff - param_3) && | (SUB168(ZEXT816((ulong)(long)(param_4 + param_3)) * ZEXT816(param_5) >> 0x40,0) == 0)) && /* Check for overflow on the elements count (so the caller does not have to | (__dest = (void *)FUN_0010cbb0(), __dest != (void *)0x0)) { * check.) | if (param_3 != 0) { */ | memcpy(__dest,param_2,(long)param_3 * param_5); if (add_elements <= INT_MAX - old_elements) | } { | memset((void *)((long)__dest + (long)param_3 * param_5),0,(long)param_4 * param_5); png_voidp new_array = png_malloc_array_checked(png_ptr, | return __dest; old_elements+add_elements, element_size); | } | return (void *)0x0; if (new_array != NULL) | } { | /* WARNING: Subroutine does not return */ /* Because png_malloc_array worked the size calculations below cannot | png_error(param_1,"internal error: array realloc"); * overflow. | } */ | if (old_elements > 0) | memcpy(new_array, old_array, element_size*(unsigned)old_elements); | | memset((char*)new_array + element_size*(unsigned)old_elements, 0, | element_size*(unsigned)add_elements); | | return new_array; | } | } | | return NULL; /* error */ | } | #endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ | =========================================================================== FUN_00119a20 =========================================================================== Real name: png_read_buffer OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function allocates a block of memory of size param_2 and returns | | a pointer to it, or returns a pointer to a function and/or displays a | | warning or error message if param_1 is not 0. | +------------------------------------------------------------------------+ libpng/pngrutil.c:299 | Decompilation: FUN_00119a20 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ | void * FUN_00119a20(long param_1,ulong param_2,int param_3) defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ | defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ | { defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) | void *pvVar1; /* Manage the read buffer; this simply reallocates the buffer if it is not small | * enough (or if it is not allocated). The routine returns a pointer to the | pvVar1 = *(void **)(param_1 + 0x460); * buffer; if an error occurs and 'warn' is set the routine returns NULL, else | if (pvVar1 != (void *)0x0) { * it will call png_error (via png_malloc) on failure. (warn == 2 means | if (param_2 <= *(ulong *)(param_1 + 0x468)) { * 'silent'). | return pvVar1; */ | } static png_bytep | *(undefined8 *)(param_1 + 0x460) = 0; png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) | *(undefined8 *)(param_1 + 0x468) = 0; { | png_free(param_1,pvVar1); png_bytep buffer = png_ptr->read_buffer; | } | pvVar1 = (void *)FUN_0010cbb0(param_1); if (buffer != NULL && new_size > png_ptr->read_buffer_size) | if (pvVar1 == (void *)0x0) { { | if (param_3 != 2) { png_ptr->read_buffer = NULL; | if (param_3 == 0) { png_ptr->read_buffer_size = 0; | /* WARNING: Subroutine does not return */ png_free(png_ptr, buffer); | png_chunk_error(param_1,"insufficient memory to read chunk"); buffer = NULL; | } } | png_chunk_warning(); | } if (buffer == NULL) | return (void *)0x0; { | } buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); | memset(pvVar1,0,param_2); | *(void **)(param_1 + 0x460) = pvVar1; if (buffer != NULL) | *(ulong *)(param_1 + 0x468) = param_2; { | return pvVar1; memset(buffer, 0, new_size); /* just in case */ | } png_ptr->read_buffer = buffer; | png_ptr->read_buffer_size = new_size; | } | | else if (warn < 2) /* else silent */ | { | if (warn != 0) | png_chunk_warning(png_ptr, "insufficient memory to read chunk"); | | else | png_chunk_error(png_ptr, "insufficient memory to read chunk"); | } | } | | return buffer; | } | #endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ | =========================================================================== FUN_00119cf0 =========================================================================== Real name: png_crc_error OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if the pointer at the given address is valid and | | calls the function pointed to, or calls the png_error function with an | | error message if not. | +------------------------------------------------------------------------+ libpng/pngrutil.c:252 | Decompilation: FUN_00119cf0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Compare the CRC stored in the PNG file with that calculated by libpng from | bool FUN_00119cf0(long param_1) * the data it has read thus far. | */ | { int /* PRIVATE */ | long in_FS_OFFSET; png_crc_error(png_structrp png_ptr) | bool bVar1; { | byte local_14; png_byte crc_bytes[4]; | byte local_13; png_uint_32 crc; | byte local_12; int need_crc = 1; | byte local_11; | long local_10; if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) | { | local_10 = *(long *)(in_FS_OFFSET + 0x28); if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == | if ((*(byte *)(param_1 + 0x21b) & 0x20) == 0) { (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) | if ((*(uint *)(param_1 + 0x130) & 0x800) != 0) goto LAB_00119d95; need_crc = 0; | } } | else if ((*(uint *)(param_1 + 0x130) & 0x300) == 0x300) { | LAB_00119d95: else /* critical */ | *(undefined4 *)(param_1 + 0x474) = 0x81; { | FUN_00113740(param_1,&local_14,4); if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) | bVar1 = false; need_crc = 0; | goto LAB_00119d74; } | } | *(undefined4 *)(param_1 + 0x474) = 0x81; #ifdef PNG_IO_STATE_SUPPORTED | FUN_00113740(param_1,&local_14,4); png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; | bVar1 = (uint)local_12 * 0x100 + #endif | (uint)local_11 + (uint)local_13 * 0x10000 + (uint)local_14 * 0x1000000 != | *(int *)(param_1 + 0x24c); /* The chunk CRC must be serialized in a single I/O call. */ | LAB_00119d74: png_read_data(png_ptr, crc_bytes, 4); | if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) { | return bVar1; if (need_crc != 0) | } { | /* WARNING: Subroutine does not return */ crc = png_get_uint_32(crc_bytes); | __stack_chk_fail(); return ((int)(crc != png_ptr->crc)); | } } | | else | return (0); | } | =========================================================================== FUN_00119be0 =========================================================================== Real name: png_read_sig OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks the validity of a pointer to a given address and | | calls the corresponding function if it is valid, otherwise it calls | | the png_error function with an error message. | +------------------------------------------------------------------------+ libpng/pngrutil.c:122 | Decompilation: FUN_00119be0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Read and check the PNG file signature */ | void FUN_00119be0(long param_1,long param_2) void /* PRIVATE */ | png_read_sig(png_structrp png_ptr, png_inforp info_ptr) | { { | byte bVar1; size_t num_checked, num_to_check; | int iVar2; | ulong uVar3; /* Exit if the user application does not expect a signature. */ | if (png_ptr->sig_bytes >= 8) | bVar1 = *(byte *)(param_1 + 0x26d); return; | if (bVar1 < 8) { | uVar3 = (ulong)bVar1; num_checked = png_ptr->sig_bytes; | *(undefined4 *)(param_1 + 0x474) = 0x11; num_to_check = 8 - num_checked; | FUN_00113740(param_1,param_2 + 0x2c + uVar3,8 - uVar3); | *(undefined *)(param_1 + 0x26d) = 8; #ifdef PNG_IO_STATE_SUPPORTED | iVar2 = png_sig_cmp(param_2 + 0x2c,uVar3,8 - uVar3); png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; | if (iVar2 != 0) { #endif | if (bVar1 < 4) { | iVar2 = png_sig_cmp(param_2 + 0x2c,uVar3,4 - uVar3); /* The signature must be serialized in a single I/O call. */ | if (iVar2 != 0) { png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); | /* WARNING: Subroutine does not return */ png_ptr->sig_bytes = 8; | png_error(param_1,"Not a PNG file"); | } if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) | } { | /* WARNING: Subroutine does not return */ if (num_checked < 4 && | png_error(param_1,"PNG file corrupted by ASCII conversion"); png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) | } png_error(png_ptr, "Not a PNG file"); | if (bVar1 < 3) { else | *(uint *)(param_1 + 300) = *(uint *)(param_1 + 300) | 0x1000; png_error(png_ptr, "PNG file corrupted by ASCII conversion"); | return; } | } if (num_checked < 3) | } png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; | return; } | } =========================================================================== FUN_00119cb0 =========================================================================== Real name: png_crc_read OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, and computes a CRC32 checksum of the given | | memory region. | +------------------------------------------------------------------------+ libpng/pngrutil.c:197 | Decompilation: FUN_00119cb0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Read data, and (optionally) run it through the CRC. */ | void FUN_00119cb0(long param_1,undefined8 param_2,undefined4 param_3) void /* PRIVATE */ | png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) | { { | if (param_1 != 0) { if (png_ptr == NULL) | FUN_00113740(param_1,param_2,param_3); return; | FUN_001068d0(param_1,param_2,param_3); | return; png_read_data(png_ptr, buf, length); | } png_calculate_crc(png_ptr, buf, length); | return; } | } =========================================================================== FUN_0011d820 =========================================================================== Real name: png_read_chunk_header OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a given chunk type is valid, computes a CRC32 | | checksum of its memory region, and throws an error if the size of the | | chunk is too large. | +------------------------------------------------------------------------+ libpng/pngrutil.c:157 | Decompilation: FUN_0011d820 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Read the chunk header (length + type name). | undefined4 FUN_0011d820(long param_1) * Put the type name into png_ptr->chunk_name, and return the length. | */ | { png_uint_32 /* PRIVATE */ | undefined4 uVar1; png_read_chunk_header(png_structrp png_ptr) | long in_FS_OFFSET; { | undefined auStack40 [4]; png_byte buf[8]; | uint local_24; png_uint_32 length; | long local_20; | #ifdef PNG_IO_STATE_SUPPORTED | local_20 = *(long *)(in_FS_OFFSET + 0x28); png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; | *(undefined4 *)(param_1 + 0x474) = 0x21; #endif | FUN_00113740(param_1,auStack40,8); | uVar1 = png_get_uint_31(param_1,auStack40); /* Read the length and the chunk name. | *(uint *)(param_1 + 0x218) = * This must be performed in a single I/O call. | local_24 >> 0x18 | (local_24 & 0xff0000) >> 8 | (local_24 & 0xff00) << 8 | local_24 << 0x18; */ | FUN_001068b0(param_1); png_read_data(png_ptr, buf, 8); | FUN_001068d0(param_1,&local_24,4); length = png_get_uint_31(png_ptr, buf); | FUN_0011d6f0(param_1,*(undefined4 *)(param_1 + 0x218)); | FUN_0011d730(param_1,uVar1); /* Put the chunk name into png_ptr->chunk_name. */ | *(undefined4 *)(param_1 + 0x474) = 0x41; png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); | if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) { | return uVar1; png_debug2(0, "Reading %lx chunk, length = %lu", | } (unsigned long)png_ptr->chunk_name, (unsigned long)length); | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); /* Reset the crc and run it over the chunk name. */ | } png_reset_crc(png_ptr); | png_calculate_crc(png_ptr, buf + 4, 4); | | /* Check to see if chunk name is valid. */ | png_check_chunk_name(png_ptr, png_ptr->chunk_name); | | /* Check for too-large chunk length */ | png_check_chunk_length(png_ptr, length); | | #ifdef PNG_IO_STATE_SUPPORTED | png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; | #endif | | return length; | } | =========================================================================== FUN_00107970 =========================================================================== Real name: png_colorspace_sync OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function sets bits in a variable based on the value of a ushort | | at a given address and stores the result in a second variable. | +------------------------------------------------------------------------+ libpng/png.c:1216 | Decompilation: FUN_00107970 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_00107970(long param_1,long param_2) png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) | { | { if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) | undefined4 uVar1; { | undefined8 uVar2; /* Everything is invalid */ | undefined8 uVar3; info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| | undefined8 uVar4; PNG_INFO_iCCP); | undefined8 uVar5; | undefined8 uVar6; # ifdef PNG_COLORSPACE_SUPPORTED | undefined8 uVar7; /* Clean up the iCCP profile now if it won't be used. */ | undefined8 uVar8; png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); | undefined8 uVar9; # else | PNG_UNUSED(png_ptr) | if (param_2 != 0) { # endif | uVar2 = *(undefined8 *)(param_1 + 0x4a0); } | uVar3 = *(undefined8 *)(param_1 + 0x4a8); | uVar4 = *(undefined8 *)(param_1 + 0x4b0); else | uVar5 = *(undefined8 *)(param_1 + 0x4b8); { | uVar6 = *(undefined8 *)(param_1 + 0x4c0); # ifdef PNG_COLORSPACE_SUPPORTED | uVar7 = *(undefined8 *)(param_1 + 0x4c8); /* Leave the INFO_iCCP flag set if the pngset.c code has already set | *(undefined8 *)(param_2 + 0x74) = *(undefined8 *)(param_1 + 0x4e0); * it; this allows a PNG to contain a profile which matches sRGB and | uVar1 = *(undefined4 *)(param_1 + 0x4e8); * yet still have that profile retrievable by the application. | uVar8 = *(undefined8 *)(param_1 + 0x4d0); */ | uVar9 = *(undefined8 *)(param_1 + 0x4d8); if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) | *(undefined8 *)(param_2 + 0x34) = uVar2; info_ptr->valid |= PNG_INFO_sRGB; | *(undefined8 *)(param_2 + 0x3c) = uVar3; | *(undefined4 *)(param_2 + 0x7c) = uVar1; else | *(undefined8 *)(param_2 + 0x44) = uVar4; info_ptr->valid &= ~PNG_INFO_sRGB; | *(undefined8 *)(param_2 + 0x4c) = uVar5; | *(undefined8 *)(param_2 + 0x54) = uVar6; if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) | *(undefined8 *)(param_2 + 0x5c) = uVar7; info_ptr->valid |= PNG_INFO_cHRM; | *(undefined8 *)(param_2 + 100) = uVar8; | *(undefined8 *)(param_2 + 0x6c) = uVar9; else | FUN_00107910(uVar2,uVar4,uVar6,uVar8); info_ptr->valid &= ~PNG_INFO_cHRM; | return; # endif | } | return; if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) | } info_ptr->valid |= PNG_INFO_gAMA; | | else | info_ptr->valid &= ~PNG_INFO_gAMA; | } | } | =========================================================================== FUN_00106470 =========================================================================== Real name: png_colorspace_set_xy_and_XYZ OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function compares two arrays and returns true if all elements are | | equal, plus or minus a given parameter. | +------------------------------------------------------------------------+ libpng/png.c:1676 | Decompilation: FUN_00106470 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- static int | undefined4 png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, | FUN_00106470(undefined8 param_1,long param_2,undefined8 *param_3,undefined8 *param_4,int param_5) png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, | int preferred) | { { | undefined8 uVar1; if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) | undefined8 uVar2; return 0; | undefined8 uVar3; | undefined8 uVar4; /* The consistency check is performed on the chromaticities; this factors out | undefined8 uVar5; * variations because of the normalization (or not) of the end point Y | undefined8 uVar6; * values. | undefined8 uVar7; */ | undefined8 uVar8; if (preferred < 2 && | int iVar9; (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) | ushort uVar10; { | /* The end points must be reasonably close to any we already have. The | uVar10 = *(ushort *)(param_2 + 0x4a); * following allows an error of up to +/-.001 | if ((short)uVar10 < 0) { */ | return 0; if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, | } 100) == 0) | if ((param_5 < 2) && ((uVar10 & 2) != 0)) { { | iVar9 = FUN_001062e0(param_3,param_2 + 4,100); colorspace->flags |= PNG_COLORSPACE_INVALID; | if (iVar9 == 0) { png_benign_error(png_ptr, "inconsistent chromaticities"); | *(ushort *)(param_2 + 0x4a) = uVar10 | 0x8000; return 0; /* failed */ | png_benign_error(param_1,"inconsistent chromaticities"); } | return 0; | } /* Only overwrite with preferred values */ | if (param_5 == 0) { if (preferred == 0) | return 1; return 1; /* ok, but no change */ | } } | } | uVar1 = *param_3; colorspace->end_points_xy = *xy; | uVar2 = param_3[1]; colorspace->end_points_XYZ = *XYZ; | uVar3 = param_3[2]; colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; | uVar4 = param_3[3]; | uVar5 = *param_4; /* The end points are normally quoted to two decimal digits, so allow +/-0.01 | uVar6 = param_4[1]; * on this test. | *(undefined4 *)(param_2 + 0x44) = *(undefined4 *)(param_4 + 4); */ | uVar7 = param_4[2]; if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) | uVar8 = param_4[3]; colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; | *(undefined8 *)(param_2 + 4) = uVar1; | *(undefined8 *)(param_2 + 0xc) = uVar2; else | *(ushort *)(param_2 + 0x4a) = uVar10 | 2; colorspace->flags &= PNG_COLORSPACE_CANCEL( | *(undefined8 *)(param_2 + 0x14) = uVar3; PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); | *(undefined8 *)(param_2 + 0x1c) = uVar4; | *(undefined8 *)(param_2 + 0x24) = uVar5; return 2; /* ok and changed */ | *(undefined8 *)(param_2 + 0x2c) = uVar6; } | *(undefined8 *)(param_2 + 0x34) = uVar7; | *(undefined8 *)(param_2 + 0x3c) = uVar8; | iVar9 = FUN_001062e0(uVar1,uVar3,uVar5,uVar7); | if (iVar9 == 0) { | *(ushort *)(param_2 + 0x4a) = uVar10 & 0xffbf | 2; | return 2; | } | *(ushort *)(param_2 + 0x4a) = uVar10 | 0x42; | return 2; | } =========================================================================== FUN_00109270 =========================================================================== Real name: png_XYZ_from_xy OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function calculates the result of the division of two integers, | | rounds it to the nearest integer, stores it in the first parameter and | | returns either the integer or 0 if it is not between -2147483648 and | | 2147483647. | +------------------------------------------------------------------------+ libpng/png.c:1277 | Decompilation: FUN_00109270 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- static int | undefined FUN_00109270(long param_1,uint *param_2) png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) | { | { png_fixed_point red_inverse, green_inverse, blue_scale; | uint uVar1; png_fixed_point left, right, denominator; | uint uVar2; | uint uVar3; /* Check xy and, implicitly, z. Note that wide gamut color spaces typically | uint uVar4; * have end points with 0 tristimulus values (these are impossible end | int iVar5; * points, but they are used to cover the possible colors). We check | int iVar6; * xy->whitey against 5, not 0, to avoid a possible integer overflow. | int iVar7; */ | long in_FS_OFFSET; if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; | undefined uVar8; if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; | int local_50; if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; | int local_4c; if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; | int local_48; if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; | int local_44; if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; | long local_40; if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; | if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1; | local_40 = *(long *)(in_FS_OFFSET + 0x28); | if (*param_2 < 0x186a1) { /* The reverse calculation is more difficult because the original tristimulus | uVar1 = param_2[1]; * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 | if ((((((-1 < (int)uVar1) && ((int)uVar1 <= (int)(100000 - *param_2))) && * derived values were recorded in the cHRM chunk; | (uVar2 = param_2[2], uVar2 < 0x186a1)) && * (red,green,blue,white)x(x,y). This loses one degree of freedom and | ((-1 < (int)param_2[3] && ((int)param_2[3] <= (int)(100000 - uVar2))))) && * therefore an arbitrary ninth value has to be introduced to undo the | ((uVar3 = param_2[4], uVar3 < 0x186a1 && * original transformations. | ((uVar4 = param_2[5], -1 < (int)uVar4 && ((int)uVar4 <= (int)(100000 - uVar3))))))) && * | (param_2[6] < 0x186a1)) { * Think of the original end-points as points in (X,Y,Z) space. The | if ((4 < (int)param_2[7]) && ((int)param_2[7] <= (int)(100000 - param_2[6]))) { * chromaticity values (c) have the property: | iVar5 = FUN_00108ce0(&local_48,uVar2 - uVar3,uVar1 - uVar4,7); * | if (iVar5 != 0) { * C | iVar6 = FUN_00108ce0(&local_44,param_2[3] - param_2[5],*param_2 - param_2[4],7); * c = --------- | iVar7 = local_44; * X + Y + Z | iVar5 = local_48; * | if (iVar6 != 0) { * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the | iVar6 = FUN_00108ce0(&local_48,param_2[2] - param_2[4],param_2[7] - param_2[5],7); * three chromaticity values (x,y,z) for each end-point obey the | if (iVar6 != 0) { * relationship: | iVar6 = FUN_00108ce0(&local_44,param_2[3] - param_2[5],param_2[6] - param_2[4],7); * | if (iVar6 != 0) { * x + y + z = 1 | iVar6 = FUN_00108ce0(&local_50,param_2[7],iVar5 - iVar7,local_48 - local_44); * | if ((iVar6 == 0) || (local_50 <= (int)param_2[7])) goto LAB_001095a0; * This describes the plane in (X,Y,Z) space that intersects each axis at the | iVar6 = FUN_00108ce0(&local_48,param_2[1] - param_2[5],param_2[6] - param_2[4],7); * value 1.0; call this the chromaticity plane. Thus the chromaticity | if (iVar6 != 0) { * calculation has scaled each end-point so that it is on the x+y+z=1 plane | iVar6 = FUN_00108ce0(&local_44,*param_2 - param_2[4],param_2[7] - param_2[5],7); * and chromaticity is the intersection of the vector from the origin to the | if (iVar6 != 0) { * (X,Y,Z) value with the chromaticity plane. | iVar5 = FUN_00108ce0(&local_4c,param_2[7],iVar5 - iVar7,local_48 - local_44); * | if ((iVar5 != 0) && ((int)param_2[7] < local_4c)) { * To fully invert the chromaticity calculation we would need the three | iVar5 = FUN_001091d0(); * end-point scale factors, (red-scale, green-scale, blue-scale), but these | iVar7 = FUN_001091d0(local_50); * were not recorded. Instead we calculated the reference white (X,Y,Z) and | iVar6 = FUN_001091d0(local_4c); * recorded the chromaticity of this. The reference white (X,Y,Z) would have | iVar6 = (iVar5 - iVar7) - iVar6; * given all three of the scale factors since: | if (0 < iVar6) { * | iVar5 = FUN_00108ce0(param_1,*param_2,100000,local_50); * color-C = color-c * color-scale | if (iVar5 != 0) { * white-C = red-C + green-C + blue-C | iVar5 = FUN_00108ce0(param_1 + 4,param_2[1],100000,local_50); * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale | if (iVar5 != 0) { * | iVar5 = FUN_00108ce0(param_1 + 8,(100000 - *param_2) - param_2[1],100000 * But cHRM records only white-x and white-y, so we have lost the white scale | ,local_50); * factor: | if (iVar5 != 0) { * | iVar5 = FUN_00108ce0(param_1 + 0xc,param_2[2],100000,local_4c); * white-C = white-c*white-scale | if (iVar5 != 0) { * | iVar5 = FUN_00108ce0(param_1 + 0x10,param_2[3],100000,local_4c); * To handle this the inverse transformation makes an arbitrary assumption | if (iVar5 != 0) { * about white-scale: | iVar5 = FUN_00108ce0(param_1 + 0x14, * | (100000 - param_2[2]) - param_2[3],100000, * Assume: white-Y = 1.0 | local_4c); * Hence: white-scale = 1/white-y | if (iVar5 != 0) { * Or: red-Y + green-Y + blue-Y = 1.0 | iVar5 = FUN_00108ce0(param_1 + 0x18,param_2[4],iVar6,100000); * | if (iVar5 != 0) { * Notice the last statement of the assumption gives an equation in three of | iVar5 = FUN_00108ce0(param_1 + 0x1c,param_2[5],iVar6,100000); * the nine values we want to calculate. 8 more equations come from the | if (iVar5 != 0) { * above routine as summarised at the top above (the chromaticity | iVar5 = FUN_00108ce0(param_1 + 0x20, * calculation): | (100000 - param_2[4]) - param_2[5], * | iVar6,100000); * Given: color-x = color-X / (color-X + color-Y + color-Z) | uVar8 = iVar5 == 0; * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 | goto LAB_001095a5; * | } * This is 9 simultaneous equations in the 9 variables "color-C" and can be | } * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix | } * determinants, however this is not as bad as it seems because only 28 of | } * the total of 90 terms in the various matrices are non-zero. Nevertheless | } * Cramer's rule is notoriously numerically unstable because the determinant | } * calculation involves the difference of large, but similar, numbers. It is | } * difficult to be sure that the calculation is stable for real world values | } * and it is certain that it becomes unstable where the end points are close | } * together. | } * | goto LAB_001095a0; * So this code uses the perhaps slightly less optimal but more | } * understandable and totally obvious approach of calculating color-scale. | } * | } * This algorithm depends on the precision in white-scale and that is | } * (1/white-y), so we can immediately see that as white-y approaches 0 the | } * accuracy inherent in the cHRM chunk drops off substantially. | } * | uVar8 = 2; * libpng arithmetic: a simple inversion of the above equations | goto LAB_001095a5; * ------------------------------------------------------------ | } * | } * white_scale = 1/white-y | } * white-X = white-x * white-scale | LAB_001095a0: * white-Y = 1.0 | uVar8 = 1; * white-Z = (1 - white-x - white-y) * white_scale | LAB_001095a5: * | if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) { * white-C = red-C + green-C + blue-C | return uVar8; * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale | } * | /* WARNING: Subroutine does not return */ * This gives us three equations in (red-scale,green-scale,blue-scale) where | __stack_chk_fail(); * all the coefficients are now known: | } * | * red-x*red-scale + green-x*green-scale + blue-x*blue-scale | * = white-x/white-y | * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 | * red-z*red-scale + green-z*green-scale + blue-z*blue-scale | * = (1 - white-x - white-y)/white-y | * | * In the last equation color-z is (1 - color-x - color-y) so we can add all | * three equations together to get an alternative third: | * | * red-scale + green-scale + blue-scale = 1/white-y = white-scale | * | * So now we have a Cramer's rule solution where the determinants are just | * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve | * multiplication of three coefficients so we can't guarantee to avoid | * overflow in the libpng fixed point representation. Using Cramer's rule in | * floating point is probably a good choice here, but it's not an option for | * fixed point. Instead proceed to simplify the first two equations by | * eliminating what is likely to be the largest value, blue-scale: | * | * blue-scale = white-scale - red-scale - green-scale | * | * Hence: | * | * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = | * (white-x - blue-x)*white-scale | * | * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = | * 1 - blue-y*white-scale | * | * And now we can trivially solve for (red-scale,green-scale): | * | * green-scale = | * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale | * ----------------------------------------------------------- | * green-x - blue-x | * | * red-scale = | * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale | * --------------------------------------------------------- | * red-y - blue-y | * | * Hence: | * | * red-scale = | * ( (green-x - blue-x) * (white-y - blue-y) - | * (green-y - blue-y) * (white-x - blue-x) ) / white-y | * ------------------------------------------------------------------------- | * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) | * | * green-scale = | * ( (red-y - blue-y) * (white-x - blue-x) - | * (red-x - blue-x) * (white-y - blue-y) ) / white-y | * ------------------------------------------------------------------------- | * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) | * | * Accuracy: | * The input values have 5 decimal digits of accuracy. The values are all in | * the range 0 < value < 1, so simple products are in the same range but may | * need up to 10 decimal digits to preserve the original precision and avoid | * underflow. Because we are using a 32-bit signed representation we cannot | * match this; the best is a little over 9 decimal digits, less than 10. | * | * The approach used here is to preserve the maximum precision within the | * signed representation. Because the red-scale calculation above uses the | * difference between two products of values that must be in the range -1..+1 | * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The | * factor is irrelevant in the calculation because it is applied to both | * numerator and denominator. | * | * Note that the values of the differences of the products of the | * chromaticities in the above equations tend to be small, for example for | * the sRGB chromaticities they are: | * | * red numerator: -0.04751 | * green numerator: -0.08788 | * denominator: -0.2241 (without white-y multiplication) | * | * The resultant Y coefficients from the chromaticities of some widely used | * color space definitions are (to 15 decimal places): | * | * sRGB | * 0.212639005871510 0.715168678767756 0.072192315360734 | * Kodak ProPhoto | * 0.288071128229293 0.711843217810102 0.000085653960605 | * Adobe RGB | * 0.297344975250536 0.627363566255466 0.075291458493998 | * Adobe Wide Gamut RGB | * 0.258728243040113 0.724682314948566 0.016589442011321 | */ | /* By the argument, above overflow should be impossible here. The return | * value of 2 indicates an internal error to the caller. | */ | if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0) | return 2; | if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0) | return 2; | denominator = left - right; | | /* Now find the red numerator. */ | if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) | return 2; | if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0) | return 2; | | /* Overflow is possible here and it indicates an extreme set of PNG cHRM | * chunk values. This calculation actually returns the reciprocal of the | * scale value because this allows us to delay the multiplication of white-y | * into the denominator, which tends to produce a small number. | */ | if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 || | red_inverse <= xy->whitey /* r+g+b scales = white scale */) | return 1; | | /* Similarly for green_inverse: */ | if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0) | return 2; | if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) | return 2; | if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 || | green_inverse <= xy->whitey) | return 1; | | /* And the blue scale, the checks above guarantee this can't overflow but it | * can still produce 0 for extreme cHRM values. | */ | blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - | png_reciprocal(green_inverse); | if (blue_scale <= 0) | return 1; | | | /* And fill in the png_XYZ: */ | if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) | return 1; | if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) | return 1; | if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, | red_inverse) == 0) | return 1; | | if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) | return 1; | if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) | return 1; | if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, | green_inverse) == 0) | return 1; | | if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) | return 1; | if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) | return 1; | if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, | PNG_FP_1) == 0) | return 1; | | return 0; /*success*/ | } | =========================================================================== FUN_00108dd0 =========================================================================== Real name: png_xy_from_XYZ OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function calculates the result of multiple divisions of integers, | | rounds it to the nearest integer, and stores it in the first | | parameter. | +------------------------------------------------------------------------+ libpng/png.c:1234 | Decompilation: FUN_00108dd0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_COLORSPACE_SUPPORTED | bool FUN_00108dd0(long param_1,int *param_2) /* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for | * cHRM, as opposed to using chromaticities. These internal APIs return | { * non-zero on a parameter error. The X, Y and Z values are required to be | int iVar1; * positive and less than 1.0. | int iVar2; */ | int iVar3; static int | int iVar4; png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) | int iVar5; { | int iVar6; png_int_32 d, dwhite, whiteX, whiteY; | int iVar7; | int iVar8; d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; | int iVar9; if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0) | int iVar10; return 1; | int iVar11; if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0) | int iVar12; return 1; | dwhite = d; | iVar11 = *param_2; whiteX = XYZ->red_X; | iVar1 = param_2[1]; whiteY = XYZ->red_Y; | iVar2 = param_2[2]; | iVar8 = FUN_00108ce0(param_1,iVar11,100000); d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; | if ((iVar8 != 0) && (iVar8 = FUN_00108ce0(param_1 + 4,param_2[1],100000), iVar8 != 0)) { if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0) | iVar8 = param_2[3]; return 1; | iVar3 = *param_2; if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0) | iVar4 = param_2[4]; return 1; | iVar5 = param_2[1]; dwhite += d; | iVar6 = param_2[5]; whiteX += XYZ->green_X; | iVar9 = FUN_00108ce0(param_1 + 8,iVar8,100000); whiteY += XYZ->green_Y; | if ((iVar9 != 0) && (iVar9 = FUN_00108ce0(param_1 + 0xc,param_2[4],100000), iVar9 != 0)) { | iVar9 = param_2[4]; d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; | iVar7 = param_2[3]; if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0) | iVar12 = param_2[7] + param_2[6] + param_2[8]; return 1; | iVar10 = FUN_00108ce0(param_1 + 0x10,param_2[6],100000); if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0) | if ((iVar10 != 0) && return 1; | (iVar10 = FUN_00108ce0(param_1 + 0x14,param_2[7],100000,iVar12), iVar10 != 0)) { dwhite += d; | iVar10 = param_2[7]; whiteX += XYZ->blue_X; | iVar12 = iVar4 + iVar8 + iVar6 + iVar1 + iVar11 + iVar2 + iVar12; whiteY += XYZ->blue_Y; | iVar11 = FUN_00108ce0(param_1 + 0x18,iVar7 + iVar3 + param_2[6],100000,iVar12); | if (iVar11 != 0) { /* The reference white is simply the sum of the end-point (X,Y,Z) vectors, | iVar11 = FUN_00108ce0(param_1 + 0x1c,iVar10 + iVar5 + iVar9,100000,iVar12); * thus: | return iVar11 == 0; */ | } if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) | } return 1; | } if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) | } return 1; | return true; | } return 0; | } | =========================================================================== FUN_00119890 =========================================================================== Real name: png_inflate_claim OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function initializes the zlib stream for compression or | | decompression and sets an error message for a given zlib return code. | +------------------------------------------------------------------------+ libpng/pngrutil.c:342 | Decompilation: FUN_00119890 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* png_inflate_claim: claim the zstream for some nefarious purpose that involves | int FUN_00119890(long param_1,undefined4 param_2) * decompression. Returns Z_OK on success, else a zlib error code. It checks | * the owner but, in final release builds, just issues a warning if some other | { * chunk apparently owns the stream. Prior to release it does a png_error. | long lVar1; */ | uint uVar2; static int | int iVar3; png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) | undefined8 uVar4; { | long in_FS_OFFSET; if (png_ptr->zowner != 0) | bool bVar5; { | uint local_78 [18]; char msg[64]; | long local_30; | PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); | local_30 = *(long *)(in_FS_OFFSET + 0x28); /* So the message that results is "<chunk> using zstream"; this is an | uVar2 = *(uint *)(param_1 + 0x138); * internal error, but is very useful for debugging. i18n requirements | if (*(int *)(param_1 + 0x138) != 0) { * are minimal. | local_78[0] = uVar2 >> 0x18 | (uVar2 & 0xff0000) >> 8 | (uVar2 & 0xff00) << 8 | uVar2 << 0x18; */ | FUN_0010adb0(local_78,0x40,4," using zstream"); (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); | png_chunk_warning(param_1,local_78); #if PNG_RELEASE_BUILD | *(undefined4 *)(param_1 + 0x138) = 0; png_chunk_warning(png_ptr, msg); | } png_ptr->zowner = 0; | *(undefined8 *)(param_1 + 0x140) = 0; #else | lVar1 = param_1 + 0x140; png_chunk_error(png_ptr, msg); | *(undefined4 *)(param_1 + 0x148) = 0; #endif | *(undefined8 *)(param_1 + 0x158) = 0; } | *(undefined4 *)(param_1 + 0x160) = 0; | bVar5 = (*(uint *)(param_1 + 0x388) >> 2 & 3) != 3; /* Implementation note: unlike 'png_deflate_claim' this internal function | uVar4 = 0xf; * does not take the size of the data as an argument. Some efficiency could | if (bVar5) { * be gained by using this when it is known *if* the zlib stream itself does | uVar4 = 0; * not record the number; however, this is an illusion: the original writer | } * of the PNG may have selected a lower window size, and we really must | *(bool *)(param_1 + 0x270) = bVar5; * follow that because, for systems with with limited capabilities, we | if ((*(byte *)(param_1 + 0x130) & 2) == 0) { * would otherwise reject the application's attempts to use a smaller window | iVar3 = inflateInit2_(lVar1,uVar4,"1.2.11",0x70); * size (zlib doesn't have an interface to say "this or lower"!). | if (iVar3 != 0) { * | if ((((byte)((uint)*(undefined4 *)(param_1 + 0x388) >> 8) ^ 3) & 3) == 0) goto LAB_001199a0; * inflateReset2 was added to zlib 1.2.4; before this the window could not be | goto LAB_001199c6; * reset, therefore it is necessary to always allocate the maximum window | } * size with earlier zlibs just in case later compressed chunks need it. | *(uint *)(param_1 + 0x130) = *(uint *)(param_1 + 0x130) | 2; */ | if ((((byte)((uint)*(undefined4 *)(param_1 + 0x388) >> 8) ^ 3) & 3) == 0) { { | LAB_001199a0: int ret; /* zlib return code */ | iVar3 = inflateValidate(lVar1,0); #if ZLIB_VERNUM >= 0x1240 | goto joined_r0x001199b0; int window_bits = 0; | } | } # if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) | else { if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == | iVar3 = inflateReset2(lVar1); PNG_OPTION_ON) | if ((((byte)((uint)*(undefined4 *)(param_1 + 0x388) >> 8) ^ 3) & 3) == 0) goto LAB_001199a0; { | joined_r0x001199b0: window_bits = 15; | if (iVar3 != 0) { png_ptr->zstream_start = 0; /* fixed window size */ | LAB_001199c6: } | FUN_00107840(param_1,iVar3); | goto LAB_0011994d; else | } { | } png_ptr->zstream_start = 1; | *(undefined4 *)(param_1 + 0x138) = param_2; } | iVar3 = 0; # endif | LAB_0011994d: | if (local_30 != *(long *)(in_FS_OFFSET + 0x28)) { #endif /* ZLIB_VERNUM >= 0x1240 */ | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); /* Set this for safety, just in case the previous owner left pointers to | } * memory allocations. | return iVar3; */ | } png_ptr->zstream.next_in = NULL; | png_ptr->zstream.avail_in = 0; | png_ptr->zstream.next_out = NULL; | png_ptr->zstream.avail_out = 0; | | if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) | { | #if ZLIB_VERNUM >= 0x1240 | ret = inflateReset2(&png_ptr->zstream, window_bits); | #else | ret = inflateReset(&png_ptr->zstream); | #endif | } | | else | { | #if ZLIB_VERNUM >= 0x1240 | ret = inflateInit2(&png_ptr->zstream, window_bits); | #else | ret = inflateInit(&png_ptr->zstream); | #endif | | if (ret == Z_OK) | png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; | } | | #if ZLIB_VERNUM >= 0x1290 && \ | defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) | if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) | /* Turn off validation of the ADLER32 checksum in IDAT chunks */ | ret = inflateValidate(&png_ptr->zstream, 0); | #endif | | if (ret == Z_OK) | png_ptr->zowner = owner; | | else | png_zstream_error(png_ptr, ret); | | return ret; | } | | #ifdef window_bits | # undef window_bits | #endif | } | =========================================================================== FUN_00109980 =========================================================================== Real name: png_colorspace_check_gamma OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set and calls functions to calculate the result of the | | division of two integers, round it to the nearest integer, and check | | if the value of param_1 is greater than 105000, returning true or | | false depending on the results. | +------------------------------------------------------------------------+ libpng/png.c:1070 | Decompilation: FUN_00109980 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ | bool FUN_00109980(undefined8 param_1,undefined8 param_2,byte *param_3,undefined8 param_4,int param_5 #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ | ) static int | png_colorspace_check_gamma(png_const_structrp png_ptr, | { png_colorspacerp colorspace, png_fixed_point gAMA, int from) | int iVar1; /* This is called to check a new gamma value against an existing one. The | long in_FS_OFFSET; * routine returns false if the new gamma value should not be written. | bool bVar2; * | undefined4 local_24; * 'from' says where the new gamma value comes from: | long local_20; * | * 0: the new gamma value is the libpng estimate for an ICC profile | local_20 = *(long *)(in_FS_OFFSET + 0x28); * 1: the new gamma value comes from a gAMA chunk | if (((*param_3 & 1) != 0) && * 2: the new gamma value comes from an sRGB chunk | ((iVar1 = FUN_00108ce0(&local_24,param_2,100000), iVar1 == 0 || */ | (iVar1 = FUN_00109960(local_24), iVar1 != 0)))) { { | bVar2 = param_5 == 2; png_fixed_point gtest; | if (((*param_3 & 0x20) != 0) || (bVar2)) { | FUN_0010b520(param_1,"gamma value does not match sRGB",2); if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && | goto LAB_001099a2; (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || | } png_gamma_significant(gtest) != 0)) | FUN_0010b520(param_1,"gamma value does not match libpng estimate",0); { | } /* Either this is an sRGB image, in which case the calculated gamma | bVar2 = true; * approximation should match, or this is an image with a profile and the | LAB_001099a2: * value libpng calculates for the gamma of the profile does not match the | if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) { * value recorded in the file. The former, sRGB, case is an error, the | /* WARNING: Subroutine does not return */ * latter is just a warning. | __stack_chk_fail(); */ | } if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) | return bVar2; { | } png_chunk_report(png_ptr, "gamma value does not match sRGB", | PNG_CHUNK_ERROR); | /* Do not overwrite an sRGB value */ | return from == 2; | } | | else /* sRGB tag not involved */ | { | png_chunk_report(png_ptr, "gamma value does not match libpng estimate", | PNG_CHUNK_WARNING); | return from == 1; | } | } | | return 1; | } | =========================================================================== FUN_001065b0 =========================================================================== Real name: png_icc_profile_error OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set, checks if the given parameter is between 0x41 and | | 0x5A (inclusive), converts a number to a string of hexadecimal or | | decimal characters, copies a string from param_4 to param_1, up to a | | maximum of param_2 characters or until the end of the string is | | reached, and calls the appropriate function depending on the value of | | the bit and the value of the parameter. | +------------------------------------------------------------------------+ libpng/png.c:1825 | Decompilation: FUN_001065b0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- static int | undefined8 png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, | FUN_001065b0(undefined8 param_1,long param_2,undefined8 param_3,ulong param_4,undefined8 param_5) png_const_charp name, png_alloc_size_t value, png_const_charp reason) | { | { size_t pos; | int iVar1; char message[196]; /* see below for calculation */ | long lVar2; | undefined8 uVar3; if (colorspace != NULL) | long lVar4; colorspace->flags |= PNG_COLORSPACE_INVALID; | byte bVar5; | byte bVar6; pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ | ulong uVar7; pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ | long in_FS_OFFSET; pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ | undefined auStack296 [24]; if (is_ICC_signature(value) != 0) | undefined local_110 [8]; { | byte local_108 [200]; /* So 'value' is at most 4 bytes and the following cast is safe */ | long local_40; png_icc_tag_name(message+pos, (png_uint_32)value); | pos += 6; /* total +8; less than the else clause */ | local_40 = *(long *)(in_FS_OFFSET + 0x28); message[pos++] = ':'; | if (param_2 != 0) { message[pos++] = ' '; | *(ushort *)(param_2 + 0x4a) = *(ushort *)(param_2 + 0x4a) | 0x8000; } | } # ifdef PNG_WARNINGS_SUPPORTED | lVar2 = FUN_0010adb0(local_108,0xc4,0,"profile \'"); else | uVar3 = FUN_0010adb0(local_108,lVar2 + 0x4f,lVar2,param_3); { | lVar2 = FUN_0010adb0(local_108,0xc4,uVar3); char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ | if (((param_4 >> 0x18) - 0x30 < 10) || (param_4 >> 0x18 == 0x20)) { | LAB_001066f8: pos = png_safecat(message, (sizeof message), pos, | uVar7 = param_4 >> 0x10 & 0xff; png_format_number(number, number+(sizeof number), | if ((9 < uVar7 - 0x30) && (uVar7 != 0x20)) { PNG_NUMBER_FORMAT_x, value)); | iVar1 = FUN_00106590(); pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ | if (iVar1 == 0) goto LAB_00106661; } | } # endif | bVar6 = (byte)(param_4 >> 8); /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ | if ((9 < (ulong)bVar6 - 0x30) && ((ulong)bVar6 != 0x20)) { pos = png_safecat(message, (sizeof message), pos, reason); | iVar1 = FUN_00106590(); PNG_UNUSED(pos) | if (iVar1 == 0) goto LAB_00106661; | } /* This is recoverable, but make it unconditionally an app_error on write to | if ((9 < (param_4 & 0xff) - 0x30) && ((param_4 & 0xff) != 0x20)) { * avoid writing invalid ICC profiles into PNG files (i.e., we handle them | iVar1 = FUN_00106590(); * on read, with a warning, but on write unless the app turns off | if (iVar1 == 0) goto LAB_00106661; * application errors the PNG won't be written.) | } */ | local_108[lVar2] = 0x27; png_chunk_report(png_ptr, message, | local_108[lVar2 + 5] = 0x27; (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); | bVar5 = (byte)((param_4 & 0xffffffff) >> 0x18); | if (0x5e < (int)((param_4 & 0xffffffff) >> 0x18) - 0x20U) { return 0; | bVar5 = 0x3f; } | } #endif /* sRGB || iCCP */ | local_108[lVar2 + 1] = bVar5; | bVar5 = (byte)((param_4 & 0xffffffff) >> 0x10); | if (0x5e < ((uint)((param_4 & 0xffffffff) >> 0x10) & 0xff) - 0x20) { | bVar5 = 0x3f; | } | local_108[lVar2 + 2] = bVar5; | if (0x5e < bVar6 - 0x20) { | bVar6 = 0x3f; | } | if (0x5e < ((uint)param_4 & 0xff) - 0x20) { | param_4 = 0x3f; | } | local_108[lVar2 + 3] = bVar6; | local_108[lVar2 + 4] = (byte)param_4; | lVar4 = lVar2 + 8; | local_108[lVar2 + 6] = 0x3a; | local_108[lVar2 + 7] = 0x20; | } | else { | iVar1 = FUN_00106590(); | if (iVar1 != 0) goto LAB_001066f8; | LAB_00106661: | uVar3 = FUN_0010ae00(auStack296,local_110,3,param_4); | uVar3 = FUN_0010adb0(local_108,0xc4,lVar2,uVar3); | lVar4 = FUN_0010adb0(local_108,0xc4,uVar3,&DAT_0012902a); | } | FUN_0010adb0(local_108,0xc4,lVar4,param_5); | FUN_0010b520(param_1,local_108,(param_2 != 0) + '\x01'); | if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) { | return 0; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_001200e0 =========================================================================== Real name: png_set_text_2 OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks the parameters, allocates a block of memory, | | copies data into it, and calls the appropriate function depending on | | the value of the bit and the value of the parameter. | +------------------------------------------------------------------------+ libpng/pngset.c:775 | Decompilation: FUN_001200e0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- int /* PRIVATE */ | undefined8 FUN_001200e0(long param_1,long param_2,int *param_3,int param_4) png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, | png_const_textp text_ptr, int num_text) | { { | int *piVar1; int i; | int iVar2; | char *__s; png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U : | size_t __n; (unsigned long)png_ptr->chunk_name); | void *pvVar3; | size_t __n_00; if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) | long lVar4; return(0); | undefined8 uVar5; | int iVar6; /* Make sure we have enough space in the "text" array in info_struct | int iVar7; * to hold all of the incoming text_ptr objects. This compare can't overflow | uint uVar8; * because max_text >= num_text (anyway, subtract of two positive integers | size_t local_60; * can't overflow in any case.) | size_t local_58; */ | if (num_text > info_ptr->max_text - info_ptr->num_text) | if ((((param_1 == 0) || (param_2 == 0)) || (param_4 < 1)) || (param_3 == (int *)0x0)) { { | LAB_00120330: int old_num_text = info_ptr->num_text; | uVar5 = 0; int max_text; | } png_textp new_text = NULL; | else { | iVar6 = *(int *)(param_2 + 0x94); /* Calculate an appropriate max_text, checking for overflow. */ | if (param_4 <= *(int *)(param_2 + 0x98) - iVar6) { max_text = old_num_text; | lVar4 = *(long *)(param_2 + 0xa0); if (num_text <= INT_MAX - max_text) | LAB_00120141: { | iVar7 = 0; max_text += num_text; | do { | if (*(char **)(param_3 + 2) != (char *)0x0) { /* Round up to a multiple of 8 */ | iVar2 = *param_3; if (max_text < INT_MAX-8) | if (iVar2 + 1U < 4) { max_text = (max_text + 8) & ~0x7; | piVar1 = (int *)(lVar4 + (long)iVar6 * 0x38); | __n = strlen(*(char **)(param_3 + 2)); else | __s = *(char **)(param_3 + 4); max_text = INT_MAX; | if (iVar2 < 1) { | if ((__s != (char *)0x0) && (*__s != '\0')) { /* Now allocate a new array and copy the old members in; this does all | local_60 = 0; * the overflow checks. | local_58 = 0; */ | goto LAB_00120365; new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, | } info_ptr->text, old_num_text, max_text-old_num_text, | *piVar1 = -1; sizeof *new_text)); | __n_00 = 0; } | local_58 = 0; | local_60 = 0; if (new_text == NULL) | } { | else { png_chunk_report(png_ptr, "too many text chunks", | local_60 = 0; PNG_CHUNK_WRITE_ERROR); | if (*(char **)(param_3 + 10) != (char *)0x0) { | local_60 = strlen(*(char **)(param_3 + 10)); return 1; | } } | local_58 = 0; | if (*(char **)(param_3 + 0xc) != (char *)0x0) { png_free(png_ptr, info_ptr->text); | local_58 = strlen(*(char **)(param_3 + 0xc)); | } info_ptr->text = new_text; | if ((__s == (char *)0x0) || (*__s == '\0')) { info_ptr->free_me |= PNG_FREE_TEXT; | *piVar1 = 1; info_ptr->max_text = max_text; | __n_00 = 0; /* num_text is adjusted below as the entries are copied in */ | } | else { png_debug1(3, "allocated %d entries for info_ptr->text", max_text); | LAB_00120365: } | __n_00 = strlen(__s); | *piVar1 = iVar2; for (i = 0; i < num_text; i++) | } { | } size_t text_length, key_len; | pvVar3 = (void *)FUN_0010cbb0(param_1,__n_00 + 4 + __n + local_58 + local_60); size_t lang_len, lang_key_len; | *(void **)(piVar1 + 2) = pvVar3; png_textp textp = &(info_ptr->text[info_ptr->num_text]); | if (pvVar3 == (void *)0x0) { | FUN_0010b520(param_1,"text chunk: out of memory",1); if (text_ptr[i].key == NULL) | return 1; continue; | } | pvVar3 = memcpy(pvVar3,*(void **)(param_3 + 2),__n); if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || | iVar6 = *param_3; text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) | *(undefined *)((long)pvVar3 + __n) = 0; { | pvVar3 = (void *)((long)pvVar3 + __n + 1); png_chunk_report(png_ptr, "text compression mode is out of range", | if (iVar6 < 1) { PNG_CHUNK_WRITE_ERROR); | *(undefined8 *)(piVar1 + 10) = 0; continue; | *(undefined8 *)(piVar1 + 0xc) = 0; } | *(void **)(piVar1 + 4) = pvVar3; | if (__n_00 != 0) goto LAB_001202fb; key_len = strlen(text_ptr[i].key); | LAB_0012016d: | *(undefined *)((long)pvVar3 + __n_00) = 0; if (text_ptr[i].compression <= 0) | if (*piVar1 < 1) goto LAB_0012031b; { | LAB_0012017d: lang_len = 0; | *(undefined8 *)(piVar1 + 6) = 0; lang_key_len = 0; | *(size_t *)(piVar1 + 8) = __n_00; } | } | else { else | *(void **)(piVar1 + 10) = pvVar3; # ifdef PNG_iTXt_SUPPORTED | pvVar3 = memcpy(pvVar3,*(void **)(param_3 + 10),local_60); { | *(undefined *)((long)pvVar3 + local_60) = 0; /* Set iTXt data */ | pvVar3 = (void *)(*(long *)(piVar1 + 10) + 1 + local_60); | *(void **)(piVar1 + 0xc) = pvVar3; if (text_ptr[i].lang != NULL) | memcpy(pvVar3,*(void **)(param_3 + 0xc),local_58); lang_len = strlen(text_ptr[i].lang); | *(undefined *)(*(long *)(piVar1 + 0xc) + local_58) = 0; | pvVar3 = (void *)(*(long *)(piVar1 + 0xc) + 1 + local_58); else | *(void **)(piVar1 + 4) = pvVar3; lang_len = 0; | if (__n_00 == 0) goto LAB_0012016d; | LAB_001202fb: if (text_ptr[i].lang_key != NULL) | memcpy(pvVar3,*(void **)(param_3 + 4),__n_00); lang_key_len = strlen(text_ptr[i].lang_key); | *(undefined *)(*(long *)(piVar1 + 4) + __n_00) = 0; | if (0 < *piVar1) goto LAB_0012017d; else | LAB_0012031b: lang_key_len = 0; | *(size_t *)(piVar1 + 6) = __n_00; } | *(undefined8 *)(piVar1 + 8) = 0; # else /* iTXt */ | } { | *(int *)(param_2 + 0x94) = *(int *)(param_2 + 0x94) + 1; png_chunk_report(png_ptr, "iTXt chunk not supported", | } PNG_CHUNK_WRITE_ERROR); | else { continue; | FUN_0010b520(param_1,"text compression mode is out of range",1); } | } # endif | } | iVar7 = iVar7 + 1; if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') | param_3 = param_3 + 0xe; { | if (param_4 <= iVar7) goto LAB_00120330; text_length = 0; | lVar4 = *(long *)(param_2 + 0xa0); # ifdef PNG_iTXt_SUPPORTED | iVar6 = *(int *)(param_2 + 0x94); if (text_ptr[i].compression > 0) | } while( true ); textp->compression = PNG_ITXT_COMPRESSION_NONE; | } | iVar7 = 0x7fffffff - iVar6; else | if (param_4 <= iVar7) { # endif | uVar8 = 0x7fffffff; textp->compression = PNG_TEXT_COMPRESSION_NONE; | if (param_4 + iVar6 < 0x7ffffff7) { } | uVar8 = param_4 + iVar6 + 8U & 0xfffffff8; | iVar7 = uVar8 - iVar6; else | } { | lVar4 = FUN_0010cc20(param_1,*(undefined8 *)(param_2 + 0xa0),iVar6,iVar7,0x38); text_length = strlen(text_ptr[i].text); | if (lVar4 != 0) { textp->compression = text_ptr[i].compression; | png_free(param_1,*(undefined8 *)(param_2 + 0xa0)); } | *(long *)(param_2 + 0xa0) = lVar4; | iVar6 = *(int *)(param_2 + 0x94); textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, | *(uint *)(param_2 + 300) = *(uint *)(param_2 + 300) | 0x4000; key_len + text_length + lang_len + lang_key_len + 4)); | *(uint *)(param_2 + 0x98) = uVar8; | goto LAB_00120141; if (textp->key == NULL) | } { | } png_chunk_report(png_ptr, "text chunk: out of memory", | FUN_0010b520(param_1,"too many text chunks",1); PNG_CHUNK_WRITE_ERROR); | uVar5 = 1; | } return 1; | return uVar5; } | } | png_debug2(2, "Allocated %lu bytes at %p in png_set_text", | (unsigned long)(png_uint_32) | (key_len + lang_len + lang_key_len + text_length + 4), | textp->key); | | memcpy(textp->key, text_ptr[i].key, key_len); | *(textp->key + key_len) = '\0'; | | if (text_ptr[i].compression > 0) | { | textp->lang = textp->key + key_len + 1; | memcpy(textp->lang, text_ptr[i].lang, lang_len); | *(textp->lang + lang_len) = '\0'; | textp->lang_key = textp->lang + lang_len + 1; | memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); | *(textp->lang_key + lang_key_len) = '\0'; | textp->text = textp->lang_key + lang_key_len + 1; | } | | else | { | textp->lang=NULL; | textp->lang_key=NULL; | textp->text = textp->key + key_len + 1; | } | | if (text_length != 0) | memcpy(textp->text, text_ptr[i].text, text_length); | | *(textp->text + text_length) = '\0'; | | # ifdef PNG_iTXt_SUPPORTED | if (textp->compression > 0) | { | textp->text_length = 0; | textp->itxt_length = text_length; | } | | else | # endif | { | textp->text_length = text_length; | textp->itxt_length = 0; | } | | info_ptr->num_text++; | png_debug1(3, "transferred text chunk %d", info_ptr->num_text); | } | | return(0); | } | #endif | =========================================================================== FUN_0011a000 =========================================================================== Real name: png_inflate_read OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function inflates a given parameter, sets an error message for a | | given zlib return code, checks if a pointer at a given address is | | valid, calls the function pointed to, and computes a CRC32 checksum of | | the given memory region. | +------------------------------------------------------------------------+ libpng/pngrutil.c:773 | Decompilation: FUN_0011a000 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_iCCP_SUPPORTED | int FUN_0011a000(long param_1,undefined8 param_2,uint *param_3,ulong *param_4) /* Perform a partial read and decompress, producing 'avail_out' bytes and | * reading from the current chunk as required. | { */ | uint uVar1; static int | int iVar2; png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, | ulong uVar3; png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, | ulong uVar4; int finish) | uint uVar5; { | if (png_ptr->zowner == png_ptr->chunk_name) | uVar5 = 0x400; { | while( true ) { int ret; | uVar1 = *param_3; | if (*(int *)(param_1 + 0x148) == 0) { /* next_in and avail_in must have been initialized by the caller. */ | if (uVar1 < uVar5) { png_ptr->zstream.next_out = next_out; | uVar5 = uVar1; png_ptr->zstream.avail_out = 0; /* set in the loop */ | } | *param_3 = uVar1 - uVar5; do | if (uVar5 != 0) { { | FUN_00119cb0(param_1,param_2,uVar5); if (png_ptr->zstream.avail_in == 0) | } { | *(undefined8 *)(param_1 + 0x140) = param_2; if (read_size > *chunk_bytes) | *(uint *)(param_1 + 0x148) = uVar5; read_size = (uInt)*chunk_bytes; | } *chunk_bytes -= read_size; | if (*(int *)(param_1 + 0x160) == 0) { | uVar3 = *param_4; if (read_size > 0) | uVar4 = 0; png_crc_read(png_ptr, read_buffer, read_size); | if (0xfffffffe < uVar3) { | uVar4 = uVar3 - 0xffffffff; png_ptr->zstream.next_in = read_buffer; | uVar3 = 0xffffffff; png_ptr->zstream.avail_in = read_size; | } } | *param_4 = uVar4; | *(int *)(param_1 + 0x160) = (int)uVar3; if (png_ptr->zstream.avail_out == 0) | } { | iVar2 = FUN_00119fb0(param_1); uInt avail = ZLIB_IO_MAX; | if (iVar2 != 0) break; if (avail > *out_size) | if ((*param_4 == 0) && (uVar1 = *(uint *)(param_1 + 0x160), uVar1 == 0)) { avail = (uInt)*out_size; | LAB_0011a0ce: *out_size -= avail; | *param_4 = *param_4 + (ulong)uVar1; | *(undefined4 *)(param_1 + 0x160) = 0; png_ptr->zstream.avail_out = avail; | FUN_00107840(param_1,iVar2); } | return iVar2; | } /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all | } * the available output is produced; this allows reading of truncated | uVar1 = *(uint *)(param_1 + 0x160); * streams. | goto LAB_0011a0ce; */ | } ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ? | Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); | } | while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); | | *out_size += png_ptr->zstream.avail_out; | png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ | | /* Ensure the error message pointer is always set: */ | png_zstream_error(png_ptr, ret); | return ret; | } | | else | { | png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); | return Z_STREAM_ERROR; | } | } | #endif /* READ_iCCP */ | =========================================================================== FUN_00119dc0 =========================================================================== Real name: png_crc_finish OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, and calls the png_error/png_chunk_warning functions with an | | error message or warning, respectively. | +------------------------------------------------------------------------+ libpng/pngrutil.c:212 | Decompilation: FUN_00119dc0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Optionally skip data and then check the CRC. Depending on whether we | undefined8 FUN_00119dc0(long param_1,uint param_2) * are reading an ancillary or critical chunk, and how the program has set | * things up, we may calculate the CRC on the data and print a message. | { * Returns '1' if there was a CRC error, '0' otherwise. | byte bVar1; */ | undefined8 uVar2; int /* PRIVATE */ | uint uVar3; png_crc_finish(png_structrp png_ptr, png_uint_32 skip) | long in_FS_OFFSET; { | undefined auStack1080 [1032]; /* The size of the local buffer for inflate is a good guess as to a | long local_30; * reasonable size to use for buffering reads from the application. | */ | uVar3 = param_2 & 0x3ff; while (skip > 0) | local_30 = *(long *)(in_FS_OFFSET + 0x28); { | if (param_2 != 0) { png_uint_32 len; | do { png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; | if (param_2 == uVar3) { | FUN_00119cb0(param_1,auStack1080,param_2); len = (sizeof tmpbuf); | break; if (len > skip) | } len = skip; | param_2 = param_2 - 0x400; skip -= len; | FUN_00119cb0(param_1,auStack1080,0x400); | } while (param_2 != 0); png_crc_read(png_ptr, tmpbuf, len); | } } | uVar2 = FUN_00119cf0(param_1); | if ((int)uVar2 != 0) { if (png_crc_error(png_ptr) != 0) | if ((*(byte *)(param_1 + 0x21b) & 0x20) == 0) { { | bVar1 = (byte)(*(uint *)(param_1 + 0x130) >> 10); if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? | } (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : | else { (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) | bVar1 = (byte)(*(uint *)(param_1 + 0x130) >> 9) ^ 1; { | } png_chunk_warning(png_ptr, "CRC error"); | if ((bVar1 & 1) == 0) { } | /* WARNING: Subroutine does not return */ | png_chunk_error(param_1,"CRC error"); else | } png_chunk_error(png_ptr, "CRC error"); | png_chunk_warning(); | uVar2 = 1; return (1); | } } | if (local_30 != *(long *)(in_FS_OFFSET + 0x28)) { | /* WARNING: Subroutine does not return */ return (0); | __stack_chk_fail(); } | } | return uVar2; | } =========================================================================== FUN_00108f30 =========================================================================== Real name: png_colorspace_check_xy OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function calculates the result of multiple divisions of integers, | | rounds it to the nearest integer, checks if the result and a given | | array, plus or minus a given parameter, are equal, and returns true if | | they are. | +------------------------------------------------------------------------+ libpng/png.c:1618 | Decompilation: FUN_00108f30 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Added in libpng-1.6.0, a different check for the validity of a set of cHRM | ulong FUN_00108f30(undefined8 param_1,undefined8 param_2) * chunk chromaticities. Earlier checks used to simply look for the overflow | * condition (where the determinant of the matrix to solve for XYZ ends up zero | { * because the chromaticity values are not all distinct.) Despite this it is | int iVar1; * theoretically possible to produce chromaticities that are apparently valid | ulong uVar2; * but that rapidly degrade to invalid, potentially crashing, sets because of | long in_FS_OFFSET; * arithmetic inaccuracies when calculations are performed on them. The new | undefined auStack72 [40]; * check is to round-trip xy -> XYZ -> xy and then check that the result is | long local_20; * within a small percentage of the original. | */ | local_20 = *(long *)(in_FS_OFFSET + 0x28); static int | uVar2 = FUN_00108dd0(auStack72,param_1); png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) | if ((int)uVar2 == 0) { { | iVar1 = FUN_001062e0(param_2,auStack72,5); int result; | uVar2 = (ulong)(iVar1 == 0); png_xy xy_test; | } | if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) { /* As a side-effect this routine also returns the XYZ endpoints. */ | return uVar2; result = png_XYZ_from_xy(XYZ, xy); | } if (result != 0) | /* WARNING: Subroutine does not return */ return result; | __stack_chk_fail(); | } result = png_xy_from_XYZ(&xy_test, XYZ); | if (result != 0) | return result; | | if (png_colorspace_endpoints_match(xy, &xy_test, | 5/*actually, the math is pretty accurate*/) != 0) | return 0; | | /* Too much slip */ | return 1; | } | =========================================================================== FUN_0011a2b0 =========================================================================== Real name: png_decompress_chunk OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function inflates given data, allocates a block of memory, | | initializes the zlib stream, sets an error message, and checks for | | errors. | +------------------------------------------------------------------------+ libpng/pngrutil.c:609 | Decompilation: FUN_0011a2b0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* | int FUN_0011a2b0(long param_1,int param_2,uint param_3,long *param_4) * Decompress trailing data in a chunk. The assumption is that read_buffer | * points at an allocated area holding the contents of a chunk with a | { * trailing compressed part. What we get back is an allocated area | size_t __n; * holding the original prefix part and an uncompressed version of the | void *__src; * trailing part (the malloc area passed in is freed). | int iVar1; */ | ulong uVar2; static int | long lVar3; png_decompress_chunk(png_structrp png_ptr, | void *pvVar4; png_uint_32 chunklength, png_uint_32 prefix_size, | long in_FS_OFFSET; png_alloc_size_t *newlength /* must be initialized to the maximum! */, | int local_44; int terminate /*add a '\0' to the end of the uncompressed data*/) | long local_40; { | /* TODO: implement different limits for different types of chunk. | local_40 = *(long *)(in_FS_OFFSET + 0x28); * | uVar2 = *(ulong *)(param_1 + 0x430); * The caller supplies *newlength set to the maximum length of the | if (uVar2 - 1 < 0xfffffffffffffffe) { * uncompressed data, but this routine allocates space for the prefix and | if (uVar2 < param_3 + 1) { * maybe a '\0' terminator too. We have to assume that 'prefix_size' is | FUN_00107840(param_1,0xfffffffc); * limited only by the maximum chunk size. | iVar1 = -4; */ | goto LAB_0011a31e; png_alloc_size_t limit = PNG_SIZE_MAX; | } | } # ifdef PNG_SET_USER_LIMITS_SUPPORTED | else { if (png_ptr->user_chunk_malloc_max > 0 && | uVar2 = 0xffffffffffffffff; png_ptr->user_chunk_malloc_max < limit) | } limit = png_ptr->user_chunk_malloc_max; | lVar3 = uVar2 - (param_3 + 1); # elif PNG_USER_CHUNK_MALLOC_MAX > 0 | if (lVar3 != -1) { if (PNG_USER_CHUNK_MALLOC_MAX < limit) | *param_4 = lVar3; limit = PNG_USER_CHUNK_MALLOC_MAX; | } # endif | iVar1 = FUN_00119890(param_1,*(undefined4 *)(param_1 + 0x218)); | if (iVar1 != 0) { if (limit >= prefix_size + (terminate != 0)) | if (iVar1 == 1) { { | iVar1 = -7; int ret; | } | goto LAB_0011a31e; limit -= prefix_size + (terminate != 0); | } | uVar2 = (ulong)param_3; if (limit < *newlength) | local_44 = param_2 - param_3; *newlength = limit; | iVar1 = FUN_0011a130(param_1,*(undefined4 *)(param_1 + 0x218),*(long *)(param_1 + 0x460) + uVar2, | &local_44,0,param_4); /* Now try to claim the stream. */ | if (iVar1 == 1) { ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); | iVar1 = inflateReset(param_1 + 0x140); | if (iVar1 == 0) { if (ret == Z_OK) | lVar3 = *param_4; { | __n = uVar2 + 1 + lVar3; png_uint_32 lzsize = chunklength - prefix_size; | pvVar4 = (void *)FUN_0010cbb0(param_1); | if (pvVar4 == (void *)0x0) { ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, | FUN_00107840(param_1,0xfffffffc); /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, | iVar1 = -4; /* output: */ NULL, newlength); | } | else { if (ret == Z_STREAM_END) | pvVar4 = memset(pvVar4,0,__n); { | iVar1 = FUN_0011a130(param_1,*(undefined4 *)(param_1 + 0x218), /* Use 'inflateReset' here, not 'inflateReset2' because this | *(long *)(param_1 + 0x460) + uVar2,&local_44); * preserves the previously decided window size (otherwise it would | if (iVar1 == 1) { * be necessary to store the previous window size.) In practice | if (lVar3 != *param_4) goto LAB_0011a490; * this doesn't matter anyway, because png_inflate will call inflate | __src = *(void **)(param_1 + 0x460); * with Z_FINISH in almost all cases, so the window will not be | *(undefined *)((long)pvVar4 + lVar3 + uVar2) = 0; * maintained. | if (param_3 != 0) { */ | pvVar4 = memcpy(pvVar4,__src,uVar2); if (inflateReset(&png_ptr->zstream) == Z_OK) | } { | *(void **)(param_1 + 0x460) = pvVar4; /* Because of the limit checks above we know that the new, | *(size_t *)(param_1 + 0x468) = __n; * expanded, size will fit in a size_t (let alone an | png_free(param_1,__src); * png_alloc_size_t). Use png_malloc_base here to avoid an | if (param_2 - param_3 != local_44) { * extra OOM message. | png_chunk_benign_error(param_1,"extra compressed data"); */ | } png_alloc_size_t new_size = *newlength; | } png_alloc_size_t buffer_size = prefix_size + new_size + | else if (iVar1 == 0) { (terminate != 0); | LAB_0011a490: png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, | png_free(param_1,pvVar4); buffer_size)); | iVar1 = -7; | } if (text != NULL) | else { { | png_free(param_1,pvVar4); memset(text, 0, buffer_size); | } | } ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, | } png_ptr->read_buffer + prefix_size, &lzsize, | else { text + prefix_size, newlength); | FUN_00107840(param_1,1); | iVar1 = -7; if (ret == Z_STREAM_END) | } { | } if (new_size == *newlength) | else if (iVar1 == 0) { { | iVar1 = -7; if (terminate != 0) | } text[prefix_size + *newlength] = 0; | *(undefined4 *)(param_1 + 0x138) = 0; | LAB_0011a31e: if (prefix_size > 0) | if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) { memcpy(text, png_ptr->read_buffer, prefix_size); | return iVar1; | } { | /* WARNING: Subroutine does not return */ png_bytep old_ptr = png_ptr->read_buffer; | __stack_chk_fail(); | } png_ptr->read_buffer = text; | png_ptr->read_buffer_size = buffer_size; | text = old_ptr; /* freed below */ | } | } | | else | { | /* The size changed on the second read, there can be no | * guarantee that anything is correct at this point. | * The 'msg' pointer has been set to "unexpected end of | * LZ stream", which is fine, but return an error code | * that the caller won't accept. | */ | ret = PNG_UNEXPECTED_ZLIB_RETURN; | } | } | | else if (ret == Z_OK) | ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ | | /* Free the text pointer (this is the old read_buffer on | * success) | */ | png_free(png_ptr, text); | | /* This really is very benign, but it's still an error because | * the extra space may otherwise be used as a Trojan Horse. | */ | if (ret == Z_STREAM_END && | chunklength - prefix_size != lzsize) | png_chunk_benign_error(png_ptr, "extra compressed data"); | } | | else | { | /* Out of memory allocating the buffer */ | ret = Z_MEM_ERROR; | png_zstream_error(png_ptr, Z_MEM_ERROR); | } | } | | else | { | /* inflateReset failed, store the error message */ | png_zstream_error(png_ptr, ret); | ret = PNG_UNEXPECTED_ZLIB_RETURN; | } | } | | else if (ret == Z_OK) | ret = PNG_UNEXPECTED_ZLIB_RETURN; | | /* Release the claimed stream */ | png_ptr->zowner = 0; | } | | else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ | ret = PNG_UNEXPECTED_ZLIB_RETURN; | | return ret; | } | | else | { | /* Application/configuration limits exceeded */ | png_zstream_error(png_ptr, Z_MEM_ERROR); | return Z_MEM_ERROR; | } | } | #endif /* READ_zTXt || READ_iTXt */ | #endif /* READ_COMPRESSED_TEXT */ | =========================================================================== FUN_00109a40 =========================================================================== Real name: png_colorspace_set_gamma OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set and calls the appropriate function depending on the | | value of the bit and the value of the parameter, and calculates the | | result of the division of two integers, rounds it to the nearest | | integer and checks if the value of param_1 is greater than 105000. | +------------------------------------------------------------------------+ libpng/png.c:1116 | Decompilation: FUN_00109a40 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_00109a40(long param_1,int *param_2,int param_3) png_colorspace_set_gamma(png_const_structrp png_ptr, | png_colorspacerp colorspace, png_fixed_point gAMA) | { { | ushort uVar1; /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't | int iVar2; * occur. Since the fixed point representation is asymmetrical it is | char *pcVar3; * possible for 1/gamma to overflow the limit of 21474 and this means the | * gamma value must be at least 5/100000 and hence at most 20000.0. For | uVar1 = *(ushort *)((long)param_2 + 0x4a); * safety the limits here are a little narrower. The values are 0.00016 to | if (param_3 - 0x10U < 0x2540be31) { * 6250.0, which are truly ridiculous gamma values (and will produce | if (((*(byte *)(param_1 + 0x12d) & 0x80) == 0) || ((uVar1 & 8) == 0)) { * displays that are all black or all white.) | if (-1 < (short)uVar1) { * | iVar2 = FUN_00109980(param_1,*param_2,(long)param_2 + 0x4a,param_3,1); * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk | if (iVar2 != 0) { * handling code, which only required the value to be >0. | *param_2 = param_3; */ | *(ushort *)((long)param_2 + 0x4a) = *(ushort *)((long)param_2 + 0x4a) | 9; png_const_charp errmsg; | return; | } if (gAMA < 16 || gAMA > 625000000) | } errmsg = "gamma value out of range"; | return; | } # ifdef PNG_READ_gAMA_SUPPORTED | pcVar3 = "duplicate"; /* Allow the application to set the gamma value more than once */ | } else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && | else { (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) | pcVar3 = "gamma value out of range"; errmsg = "duplicate"; | } # endif | *(ushort *)((long)param_2 + 0x4a) = uVar1 | 0x8000; | FUN_0010b520(param_1,pcVar3,1); /* Do nothing if the colorspace is already invalid */ | return; else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) | } return; | | else | { | if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, | 1/*from gAMA*/) != 0) | { | /* Store this gamma value. */ | colorspace->gamma = gAMA; | colorspace->flags |= | (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); | } | | /* At present if the check_gamma test fails the gamma of the colorspace is | * not updated however the colorspace is not invalidated. This | * corresponds to the case where the existing gamma comes from an sRGB | * chunk or profile. An error message has already been output. | */ | return; | } | | /* Error exit - errmsg has been set. */ | colorspace->flags |= PNG_COLORSPACE_INVALID; | png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); | } | =========================================================================== FUN_00107e00 =========================================================================== Real name: png_icc_check_tag_table OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set and calls the appropriate function depending on the | | value of the bit and the value of the parameter, as well as converting | | a number to a string of hexadecimal or decimal characters, and copying | | a string from param_4 to param_1, up to a maximum of param_2 | | characters or until the end of the string is reached. | +------------------------------------------------------------------------+ libpng/png.c:2200 | Decompilation: FUN_00107e00 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- int /* PRIVATE */ | undefined8 png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, | FUN_00107e00(undefined8 param_1,undefined8 param_2,undefined8 param_3,uint param_4,long param_5) png_const_charp name, png_uint_32 profile_length, | png_const_bytep profile /* header plus whole tag table */) | { { | byte *pbVar1; png_uint_32 tag_count = png_get_uint_32(profile+128); | int iVar2; png_uint_32 itag; | uint uVar3; png_const_bytep tag = profile+132; /* The first tag */ | undefined8 uVar4; | byte *pbVar5; /* First scan all the tags in the table and add bits to the icc_info value | * (temporarily in 'tags'). | iVar2 = (uint)*(byte *)(param_5 + 0x81) * 0x10000 + (uint)*(byte *)(param_5 + 0x80) * 0x1000000 + */ | (uint)*(byte *)(param_5 + 0x83) + (uint)*(byte *)(param_5 + 0x82) * 0x100; for (itag=0; itag < tag_count; ++itag, tag += 12) | if (iVar2 != 0) { { | pbVar5 = (byte *)(param_5 + 0x84); png_uint_32 tag_id = png_get_uint_32(tag+0); | pbVar1 = (byte *)(param_5 + 0x90 + (ulong)(iVar2 - 1) * 0xc); png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ | do { png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ | while( true ) { | iVar2 = (uint)pbVar5[2] * 0x100 + /* The ICC specification does not exclude zero length tags, therefore the | (uint)pbVar5[3] + (uint)pbVar5[1] * 0x10000 + (uint)*pbVar5 * 0x1000000; * start might actually be anywhere if there is no data, but this would be | uVar3 = (uint)pbVar5[6] * 0x100 + * a clear abuse of the intent of the standard so the start is checked for | (uint)pbVar5[7] + (uint)pbVar5[5] * 0x10000 + (uint)pbVar5[4] * 0x1000000; * being in range. All defined tag types have an 8 byte header - a 4 byte | if ((param_4 < uVar3) || * type signature then 0. | (param_4 - uVar3 < */ | (uint)pbVar5[9] * 0x10000 + (uint)pbVar5[8] * 0x1000000 + (uint)pbVar5[0xb] + | (uint)pbVar5[10] * 0x100)) { /* This is a hard error; potentially it can cause read outside the | uVar4 = FUN_001065b0(param_1,param_2,param_3,iVar2,"ICC profile tag outside profile"); * profile. | return uVar4; */ | } if (tag_start > profile_length || tag_length > profile_length - tag_start) | if ((uVar3 & 3) == 0) break; return png_icc_profile_error(png_ptr, colorspace, name, tag_id, | FUN_001065b0(param_1,0,param_3,iVar2,"ICC profile tag start not a multiple of 4"); "ICC profile tag outside profile"); | pbVar5 = pbVar5 + 0xc; | if (pbVar5 == pbVar1) { if ((tag_start & 3) != 0) | return 1; { | } /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is | } * only a warning here because libpng does not care about the | pbVar5 = pbVar5 + 0xc; * alignment. | } while (pbVar5 != pbVar1); */ | } (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, | return 1; "ICC profile tag start not a multiple of 4"); | } } | } | | return 1; /* success, maybe with warnings */ | } | =========================================================================== FUN_00109ad0 =========================================================================== Real name: png_colorspace_set_sRGB OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set, performs various checks and calculations depending on | | the bit and parameter values, and calls the appropriate function | | depending on the bit and parameter values. | +------------------------------------------------------------------------+ libpng/png.c:1874 | Decompilation: FUN_00109ad0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_sRGB_SUPPORTED | undefined8 FUN_00109ad0(undefined8 param_1,undefined8 *param_2,uint param_3) int /* PRIVATE */ | png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, | { int intent) | ushort uVar1; { | int iVar2; /* sRGB sets known gamma, end points and (from the chunk) intent. */ | undefined8 uVar3; /* IMPORTANT: these are not necessarily the values found in an ICC profile | char *pcVar4; * because ICC profiles store values adapted to a D50 environment; it is | * expected that the ICC profile mediaWhitePointTag will be D50; see the | uVar1 = *(ushort *)((long)param_2 + 0x4a); * checks and code elsewhere to understand this better. | if ((short)uVar1 < 0) { * | return 0; * These XYZ values, which are accurate to 5dp, produce rgb to gray | } * coefficients of (6968,23435,2366), which are reduced (because they add up | pcVar4 = "invalid sRGB rendering intent"; * to 32769 not 32768) to (6968,23434,2366). These are the values that | if (param_3 < 4) { * libpng has traditionally used (and are the best values given the 15bit | if ((uVar1 & 4) != 0) { * algorithm used by the rgb to gray code.) | if (*(ushort *)(param_2 + 9) != param_3) { */ | pcVar4 = "inconsistent rendering intents"; static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ | goto LAB_00109c0e; { | } /* color X Y Z */ | } /* red */ 41239, 21264, 1933, | if ((uVar1 & 0x20) == 0) { /* green */ 35758, 71517, 11919, | if ((uVar1 & 2) != 0) { /* blue */ 18048, 7219, 95053 | iVar2 = FUN_001062e0(&DAT_0012a4c0,(long)param_2 + 4,100); }; | if (iVar2 == 0) { | FUN_0010b520(param_1,"cHRM chunk does not match sRGB",2); /* Do nothing if the colorspace is already invalidated. */ | } if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) | } return 0; | FUN_00109980(param_1,*(undefined4 *)param_2,(long)param_2 + 0x4a,0xb18f,2); | *(ushort *)((long)param_2 + 0x4a) = *(ushort *)((long)param_2 + 0x4a) | 0xe7; /* Check the intent, then check for existing settings. It is valid for the | *param_2 = 0xfa000000b18f; * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must | param_2[1] = 0x7530000080e8; * be consistent with the correct values. If, however, this function is | param_2[2] = 0x3a980000ea60; * called below because an iCCP chunk matches sRGB then it is quite | param_2[3] = 0x7a2600001770; * conceivable that an older app recorded incorrect gAMA and cHRM because of | param_2[4] = 0xa11700008084; * an incorrect calculation based on the values in the profile - this does | param_2[5] = 0x78d00005310; * *not* invalidate the profile (though it still produces an error, which can | param_2[6] = 0x1175d00008bae; * be ignored.) | *(short *)(param_2 + 9) = (short)param_3; */ | param_2[7] = 0x468000002e8f; if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) | param_2[8] = 0x1734d00001c33; return png_icc_profile_error(png_ptr, colorspace, "sRGB", | uVar3 = 1; (png_alloc_size_t)intent, "invalid sRGB rendering intent"); | } | else { if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && | png_benign_error(param_1,"duplicate sRGB information ignored"); colorspace->rendering_intent != intent) | uVar3 = 0; return png_icc_profile_error(png_ptr, colorspace, "sRGB", | } (png_alloc_size_t)intent, "inconsistent rendering intents"); | return uVar3; | } if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) | LAB_00109c0e: { | uVar3 = FUN_001065b0(param_1,param_2,&DAT_0012938b,(long)(int)param_3,pcVar4); png_benign_error(png_ptr, "duplicate sRGB information ignored"); | return uVar3; return 0; | } } | | /* If the standard sRGB cHRM chunk does not match the one from the PNG file | * warn but overwrite the value with the correct one. | */ | if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && | !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, | 100)) | png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", | PNG_CHUNK_ERROR); | | /* This check is just done for the error reporting - the routine always | * returns true when the 'from' argument corresponds to sRGB (2). | */ | (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, | 2/*from sRGB*/); | | /* intent: bugs in GCC force 'int' to be used as the parameter type. */ | colorspace->rendering_intent = (png_uint_16)intent; | colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; | | /* endpoints */ | colorspace->end_points_xy = sRGB_xy; | colorspace->end_points_XYZ = sRGB_XYZ; | colorspace->flags |= | (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); | | /* gamma */ | colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; | colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; | | /* Finally record that we have an sRGB profile */ | colorspace->flags |= | (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); | | return 1; /* set */ | } | #endif /* sRGB */ | =========================================================================== FUN_00107a60 =========================================================================== Real name: png_icc_check_header OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set, checks if the given parameter is between 0x41 and | | 0x5A (inclusive), converts a number to a string of hexadecimal or | | decimal characters, copies a string from param_4 to param_1, up to a | | maximum of param_2 characters or until the end of the string is | | reached, and calls the appropriate function depending on the value of | | the bit and the value of the parameter, while also validating certain | | parameters and checking for various conditions. | +------------------------------------------------------------------------+ libpng/png.c:2017 | Decompilation: FUN_00107a60 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- int /* PRIVATE */ | undefined8 png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, | FUN_00107a60(undefined8 param_1,undefined8 param_2,undefined8 param_3,uint param_4,byte *param_5, png_const_charp name, png_uint_32 profile_length, | uint param_6) png_const_bytep profile/* first 132 bytes only */, int color_type) | { | { png_uint_32 temp; | uint uVar1; | undefined8 uVar2; /* Length check; this cannot be ignored in this code because profile_length | char *pcVar3; * is used later to check the tag table, so even if the profile seems over | * long profile_length from the caller must be correct. The caller can fix | uVar1 = (uint)param_5[2] * 0x100 + * this up on read or write by just passing in the profile header length. | (uint)param_5[3] + (uint)param_5[1] * 0x10000 + (uint)*param_5 * 0x1000000; */ | if (uVar1 != param_4) { temp = png_get_uint_32(profile); | uVar2 = FUN_001065b0(param_1,param_2,param_3,uVar1,"length does not match profile"); if (temp != profile_length) | return uVar2; return png_icc_profile_error(png_ptr, colorspace, name, temp, | } "length does not match profile"); | if ((3 < param_5[8]) && ((uVar1 & 3) != 0)) { | pcVar3 = "invalid length"; temp = (png_uint_32) (*(profile+8)); | goto LAB_00107c51; if (temp > 3 && (profile_length & 3)) | } return png_icc_profile_error(png_ptr, colorspace, name, profile_length, | uVar1 = (uint)param_5[0x82] * 0x100 + "invalid length"); | (uint)param_5[0x83] + (uint)param_5[0x81] * 0x10000 + (uint)param_5[0x80] * 0x1000000; | if ((0x1555554a < uVar1) || (param_4 < uVar1 * 0xc + 0x84)) { temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ | pcVar3 = "tag count too large"; if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ | goto LAB_00107c51; profile_length < 132+12*temp) /* truncated tag table */ | } return png_icc_profile_error(png_ptr, colorspace, name, temp, | pcVar3 = "invalid rendering intent"; "tag count too large"); | uVar1 = (uint)param_5[0x42] * 0x100 + | (uint)param_5[0x43] + (uint)param_5[0x41] * 0x10000 + (uint)param_5[0x40] * 0x1000000; /* The 'intent' must be valid or we can't store it, ICC limits the intent to | if (0xfffe < uVar1) goto LAB_00107c51; * 16 bits. | if (3 < uVar1) { */ | FUN_001065b0(); temp = png_get_uint_32(profile+64); | } if (temp >= 0xffff) /* The ICC limit */ | pcVar3 = "invalid signature"; return png_icc_profile_error(png_ptr, colorspace, name, temp, | uVar1 = (uint)param_5[0x26] * 0x100 + "invalid rendering intent"); | (uint)param_5[0x27] + (uint)param_5[0x25] * 0x10000 + (uint)param_5[0x24] * 0x1000000; | if (uVar1 != 0x61637370) goto LAB_00107c51; /* This is just a warning because the profile may be valid in future | if ((*(long *)(param_5 + 0x44) != 0x100d6f60000) || (*(int *)(param_5 + 0x4c) != 0x2dd30000)) { * versions. | FUN_001065b0(); */ | } if (temp >= PNG_sRGB_INTENT_LAST) | uVar1 = (uint)param_5[0x12] * 0x100 + (void)png_icc_profile_error(png_ptr, NULL, name, temp, | (uint)param_5[0x13] + (uint)param_5[0x11] * 0x10000 + (uint)param_5[0x10] * 0x1000000; "intent outside defined range"); | if (uVar1 == 0x47524159) { | pcVar3 = "Gray color space not permitted on RGB PNG"; /* At this point the tag table can't be checked because it hasn't necessarily | uVar1 = 0x47524159; * been loaded; however, various header fields can be checked. These checks | if ((param_6 & 2) != 0) goto LAB_00107c51; * are for values permitted by the PNG spec in an ICC profile; the PNG spec | } * restricts the profiles that can be passed in an iCCP chunk (they must be | else { * appropriate to processing PNG data!) | if (uVar1 != 0x52474220) { */ | pcVar3 = "invalid ICC profile color space"; | goto LAB_00107c51; /* Data checks (could be skipped). These checks must be independent of the | } * version number; however, the version number doesn't accommodate changes in | pcVar3 = "RGB color space not permitted on grayscale PNG"; * the header fields (just the known tags and the interpretation of the | uVar1 = 0x52474220; * data.) | if ((param_6 & 2) == 0) goto LAB_00107c51; */ | } temp = png_get_uint_32(profile+36); /* signature 'ascp' */ | uVar1 = (uint)param_5[0xe] * 0x100 + if (temp != 0x61637370) | (uint)param_5[0xf] + (uint)param_5[0xd] * 0x10000 + (uint)param_5[0xc] * 0x1000000; return png_icc_profile_error(png_ptr, colorspace, name, temp, | if (uVar1 != 0x6d6e7472) { "invalid signature"); | if (uVar1 < 0x6d6e7473) { | if (uVar1 == 0x61627374) { /* Currently the PCS illuminant/adopted white point (the computational | pcVar3 = "invalid embedded Abstract ICC profile"; * white point) are required to be D50, | uVar1 = 0x61627374; * however the profile contains a record of the illuminant so perhaps ICC | goto LAB_00107c51; * expects to be able to change this in the future (despite the rationale in | } * the introduction for using a fixed PCS adopted white.) Consequently the | if (uVar1 == 0x6c696e6b) { * following is just a warning. | pcVar3 = "unexpected DeviceLink ICC profile class"; */ | uVar1 = 0x6c696e6b; if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) | goto LAB_00107c51; (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, | } "PCS illuminant is not D50"); | LAB_00107cd4: | FUN_001065b0(); /* The PNG spec requires this: | } * "If the iCCP chunk is present, the image samples conform to the colour | else if (uVar1 == 0x6e6d636c) { * space represented by the embedded ICC profile as defined by the | FUN_001065b0(); * International Color Consortium [ICC]. The colour space of the ICC profile | } * shall be an RGB colour space for colour images (PNG colour types 2, 3, and | else if ((uVar1 < 0x6e6d636c) || * 6), or a greyscale colour space for greyscale images (PNG colour types 0 | (((uVar1 != 0x73636e72 && (uVar1 != 0x73706163)) && (uVar1 != 0x70727472)))) * and 4)." | goto LAB_00107cd4; * | } * This checking code ensures the embedded profile (on either read or write) | uVar1 = (uint)param_5[0x16] * 0x100 + * conforms to the specification requirements. Notice that an ICC 'gray' | (uint)param_5[0x17] + (uint)param_5[0x15] * 0x10000 + (uint)param_5[0x14] * 0x1000000; * color-space profile contains the information to transform the monochrome | if ((uVar1 == 0x4c616220) || (uVar1 == 0x58595a20)) { * data to XYZ or L*a*b (according to which PCS the profile uses) and this | return 1; * should be used in preference to the standard libpng K channel replication | } * into R, G and B channels. | pcVar3 = "unexpected ICC PCS encoding"; * | LAB_00107c51: * Previously it was suggested that an RGB profile on grayscale data could be | uVar2 = FUN_001065b0(param_1,param_2,param_3,uVar1,pcVar3); * handled. However it it is clear that using an RGB profile in this context | return uVar2; * must be an error - there is no specification of what it means. Thus it is | } * almost certainly more correct to ignore the profile. | */ | temp = png_get_uint_32(profile+16); /* data colour space field */ | switch (temp) | { | case 0x52474220: /* 'RGB ' */ | if ((color_type & PNG_COLOR_MASK_COLOR) == 0) | return png_icc_profile_error(png_ptr, colorspace, name, temp, | "RGB color space not permitted on grayscale PNG"); | break; | | case 0x47524159: /* 'GRAY' */ | if ((color_type & PNG_COLOR_MASK_COLOR) != 0) | return png_icc_profile_error(png_ptr, colorspace, name, temp, | "Gray color space not permitted on RGB PNG"); | break; | | default: | return png_icc_profile_error(png_ptr, colorspace, name, temp, | "invalid ICC profile color space"); | } | | /* It is up to the application to check that the profile class matches the | * application requirements; the spec provides no guidance, but it's pretty | * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer | * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these | * cases. Issue an error for device link or abstract profiles - these don't | * contain the records necessary to transform the color-space to anything | * other than the target device (and not even that for an abstract profile). | * Profiles of these classes may not be embedded in images. | */ | temp = png_get_uint_32(profile+12); /* profile/device class */ | switch (temp) | { | case 0x73636e72: /* 'scnr' */ | case 0x6d6e7472: /* 'mntr' */ | case 0x70727472: /* 'prtr' */ | case 0x73706163: /* 'spac' */ | /* All supported */ | break; | | case 0x61627374: /* 'abst' */ | /* May not be embedded in an image */ | return png_icc_profile_error(png_ptr, colorspace, name, temp, | "invalid embedded Abstract ICC profile"); | | case 0x6c696e6b: /* 'link' */ | /* DeviceLink profiles cannot be interpreted in a non-device specific | * fashion, if an app uses the AToB0Tag in the profile the results are | * undefined unless the result is sent to the intended device, | * therefore a DeviceLink profile should not be found embedded in a | * PNG. | */ | return png_icc_profile_error(png_ptr, colorspace, name, temp, | "unexpected DeviceLink ICC profile class"); | | case 0x6e6d636c: /* 'nmcl' */ | /* A NamedColor profile is also device specific, however it doesn't | * contain an AToB0 tag that is open to misinterpretation. Almost | * certainly it will fail the tests below. | */ | (void)png_icc_profile_error(png_ptr, NULL, name, temp, | "unexpected NamedColor ICC profile class"); | break; | | default: | /* To allow for future enhancements to the profile accept unrecognized | * profile classes with a warning, these then hit the test below on the | * tag content to ensure they are backward compatible with one of the | * understood profiles. | */ | (void)png_icc_profile_error(png_ptr, NULL, name, temp, | "unrecognized ICC profile class"); | break; | } | | /* For any profile other than a device link one the PCS must be encoded | * either in XYZ or Lab. | */ | temp = png_get_uint_32(profile+20); | switch (temp) | { | case 0x58595a20: /* 'XYZ ' */ | case 0x4c616220: /* 'Lab ' */ | break; | | default: | return png_icc_profile_error(png_ptr, colorspace, name, temp, | "unexpected ICC PCS encoding"); | } | | return 1; | } | =========================================================================== FUN_001079d0 =========================================================================== Real name: png_icc_check_length OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks a bit in a byte at a specified location, checks | | if a parameter is between 0x41 and 0x5A (inclusive), converts a number | | to a string of hexadecimal or decimal characters, copies a string from | | one parameter to another, and calls the appropriate function depending | | on the value of the bit and the value of the parameter. | +------------------------------------------------------------------------+ libpng/png.c:1983 | Decompilation: FUN_001079d0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_iCCP_SUPPORTED | undefined8 FUN_001079d0(long param_1,undefined8 param_2,undefined8 param_3,uint param_4) int /* PRIVATE */ | png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, | { png_const_charp name, png_uint_32 profile_length) | undefined8 uVar1; { | if (!icc_check_length(png_ptr, colorspace, name, profile_length)) | if ((0x83 < param_4) || (uVar1 = FUN_001065b0(), (int)uVar1 != 0)) { return 0; | uVar1 = 1; | if ((*(ulong *)(param_1 + 0x430) != 0) && /* This needs to be here because the 'normal' check is in | (uVar1 = 1, *(ulong *)(param_1 + 0x430) < (ulong)param_4)) { * png_decompress_chunk, yet this happens after the attempt to | uVar1 = FUN_001065b0(param_1,param_2,param_3,(ulong)param_4,"exceeds application limits"); * png_malloc_base the required data. We only need this on read; on write | return uVar1; * the caller supplies the profile buffer so libpng doesn't allocate it. See | } * the call to icc_check_length below (the write case). | } */ | return uVar1; # ifdef PNG_SET_USER_LIMITS_SUPPORTED | } else if (png_ptr->user_chunk_malloc_max > 0 && | png_ptr->user_chunk_malloc_max < profile_length) | return png_icc_profile_error(png_ptr, colorspace, name, profile_length, | "exceeds application limits"); | # elif PNG_USER_CHUNK_MALLOC_MAX > 0 | else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length) | return png_icc_profile_error(png_ptr, colorspace, name, profile_length, | "exceeds libpng limits"); | # else /* !SET_USER_LIMITS */ | /* This will get compiled out on all 32-bit and better systems. */ | else if (PNG_SIZE_MAX < profile_length) | return png_icc_profile_error(png_ptr, colorspace, name, profile_length, | "exceeds system limits"); | # endif /* !SET_USER_LIMITS */ | | return 1; | } | #endif /* READ_iCCP */ | =========================================================================== FUN_0011c9f0 =========================================================================== Real name: png_handle_sCAL OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function sets flags based on the characters in a given string, | | allocates memory, validates pointers, computes CRC32 checksums, and | | calls png_error/png_chunk_warning functions with error messages or | | warnings. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2378 | Decompilation: FUN_0011c9f0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_sCAL_SUPPORTED | void FUN_0011c9f0(long param_1,long param_2,ulong param_3) /* Read the sCAL chunk */ | void /* PRIVATE */ | { png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | ulong uVar1; { | char *pcVar2; png_bytep buffer; | int iVar3; size_t i; | char *pcVar4; int state; | long in_FS_OFFSET; | uint local_4c; png_debug(1, "in png_handle_sCAL"); | ulong local_48; | long local_40; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | png_chunk_error(png_ptr, "missing IHDR"); | local_40 = *(long *)(in_FS_OFFSET + 0x28); | if ((*(uint *)(param_1 + 300) & 1) == 0) { else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | /* WARNING: Subroutine does not return */ { | png_chunk_error(param_1,"missing IHDR"); png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "out of place"); | param_3 = param_3 & 0xffffffff; return; | if ((*(uint *)(param_1 + 300) & 4) == 0) { } | if ((param_2 == 0) || ((*(byte *)(param_2 + 9) & 0x40) == 0)) { | if ((uint)param_3 < 4) { else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) | FUN_00119dc0(param_1,param_3); { | png_chunk_benign_error(param_1,"invalid"); png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "duplicate"); | else { return; | pcVar4 = (char *)FUN_00119a20(param_1,(uint)param_3 + 1,2); } | if (pcVar4 == (char *)0x0) { | png_chunk_benign_error(param_1,"out of memory"); /* Need unit type, width, \0, height: minimum 4 bytes */ | FUN_00119dc0(param_1,param_3); else if (length < 4) | } { | else { png_crc_finish(png_ptr, length); | FUN_00119cb0(param_1,pcVar4,param_3); png_chunk_benign_error(png_ptr, "invalid"); | pcVar4[param_3] = '\0'; return; | iVar3 = FUN_00119dc0(param_1,0); } | if (iVar3 == 0) { | if ((byte)(*pcVar4 - 1U) < 2) { png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", | local_48 = 1; length + 1); | local_4c = 0; | iVar3 = FUN_00108240(pcVar4,param_3,&local_4c,&local_48); buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); | if ((iVar3 != 0) && (local_48 < param_3)) { | uVar1 = local_48 + 1; if (buffer == NULL) | pcVar2 = pcVar4 + local_48; { | local_48 = uVar1; png_chunk_benign_error(png_ptr, "out of memory"); | if (*pcVar2 == '\0') { png_crc_finish(png_ptr, length); | if ((local_4c & 0x188) == 0x108) { return; | local_4c = 0; } | iVar3 = FUN_00108240(pcVar4,param_3,&local_4c,&local_48); | if ((iVar3 == 0) || (param_3 != local_48)) { png_crc_read(png_ptr, buffer, length); | png_chunk_benign_error(param_1,"bad height format"); buffer[length] = 0; /* Null terminate the last string */ | } | else if ((local_4c & 0x188) == 0x108) { if (png_crc_finish(png_ptr, 0) != 0) | png_set_sCAL_s(param_1,param_2,*pcVar4,pcVar4 + 1,pcVar4 + uVar1); return; | } | else { /* Validate the unit. */ | png_chunk_benign_error(param_1,"non-positive height"); if (buffer[0] != 1 && buffer[0] != 2) | } { | } png_chunk_benign_error(png_ptr, "invalid unit"); | else { return; | png_chunk_benign_error(param_1,"non-positive width"); } | } | goto LAB_0011cb32; /* Validate the ASCII numbers, need two ASCII numbers separated by | } * a '\0' and they need to fit exactly in the chunk data. | } */ | png_chunk_benign_error(param_1,"bad width format"); i = 1; | } state = 0; | else { | png_chunk_benign_error(param_1,"invalid unit"); if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 || | } i >= length || buffer[i++] != 0) | } png_chunk_benign_error(png_ptr, "bad width format"); | } | } else if (PNG_FP_IS_POSITIVE(state) == 0) | } png_chunk_benign_error(png_ptr, "non-positive width"); | else { | FUN_00119dc0(param_1,param_3); else | png_chunk_benign_error(param_1,"duplicate"); { | } size_t heighti = i; | } | else { state = 0; | FUN_00119dc0(param_1,param_3); if (png_check_fp_number((png_const_charp)buffer, length, | png_chunk_benign_error(param_1,"out of place"); &state, &i) == 0 || i != length) | } png_chunk_benign_error(png_ptr, "bad height format"); | LAB_0011cb32: | if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) { else if (PNG_FP_IS_POSITIVE(state) == 0) | return; png_chunk_benign_error(png_ptr, "non-positive height"); | } | /* WARNING: Subroutine does not return */ else | __stack_chk_fail(); /* This is the (only) success case. */ | } png_set_sCAL_s(png_ptr, info_ptr, buffer[0], | (png_charp)buffer+1, (png_charp)buffer+heighti); | } | } | #endif | =========================================================================== FUN_0011c040 =========================================================================== Real name: png_handle_eXIf OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, calls the png_error/png_chunk_warning functions with an error | | message or warning, and sets the eXIf data. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2039 | Decompilation: FUN_0011c040 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_eXIf_SUPPORTED | void FUN_0011c040(long param_1,long param_2,uint param_3) void /* PRIVATE */ | png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | int iVar1; unsigned int i; | long lVar2; | ulong uVar3; png_debug(1, "in png_handle_eXIf"); | long in_FS_OFFSET; | bool bVar4; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | byte local_41; png_chunk_error(png_ptr, "missing IHDR"); | long local_40; | if (length < 2) | local_40 = *(long *)(in_FS_OFFSET + 0x28); { | if ((*(byte *)(param_1 + 300) & 1) == 0) { png_crc_finish(png_ptr, length); | /* WARNING: Subroutine does not return */ png_chunk_benign_error(png_ptr, "too short"); | png_chunk_error(param_1,"missing IHDR"); return; | } } | if (param_3 < 2) { | FUN_00119dc0(param_1,param_3); else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0) | png_chunk_benign_error(param_1,"too short"); { | } png_crc_finish(png_ptr, length); | else if ((param_2 == 0) || ((*(byte *)(param_2 + 10) & 1) != 0)) { png_chunk_benign_error(png_ptr, "duplicate"); | FUN_00119dc0(param_1,param_3); return; | png_chunk_benign_error(param_1,"duplicate"); } | } | else { info_ptr->free_me |= PNG_FREE_EXIF; | *(uint *)(param_2 + 300) = *(uint *)(param_2 + 300) | 0x8000; | lVar2 = png_malloc_warn(param_1,param_3); info_ptr->eXIf_buf = png_voidcast(png_bytep, | *(long *)(param_2 + 0xf8) = lVar2; png_malloc_warn(png_ptr, length)); | if (lVar2 == 0) { | FUN_00119dc0(param_1,param_3); if (info_ptr->eXIf_buf == NULL) | png_chunk_benign_error(param_1,"out of memory"); { | } png_crc_finish(png_ptr, length); | else { png_chunk_benign_error(png_ptr, "out of memory"); | FUN_00119cb0(param_1,&local_41,1); return; | **(byte **)(param_2 + 0xf8) = local_41; } | uVar3 = 1; | do { for (i = 0; i < length; i++) | FUN_00119cb0(param_1,&local_41,1); { | *(byte *)(*(long *)(param_2 + 0xf8) + uVar3) = local_41; png_byte buf[1]; | if ((uVar3 == 1) && png_crc_read(png_ptr, buf, 1); | (((local_41 & 0xfb) != 0x49 || (local_41 != **(byte **)(param_2 + 0xf8))))) { info_ptr->eXIf_buf[i] = buf[0]; | FUN_00119dc0(param_1,param_3 - 2); if (i == 1) | png_chunk_benign_error(param_1,"incorrect byte-order specifier"); { | png_free(param_1,*(undefined8 *)(param_2 + 0xf8)); if ((buf[0] != 'M' && buf[0] != 'I') || | *(undefined8 *)(param_2 + 0xf8) = 0; (info_ptr->eXIf_buf[0] != buf[0])) | goto LAB_0011c0a6; { | } png_crc_finish(png_ptr, length - 2); | bVar4 = uVar3 != param_3 - 1; png_chunk_benign_error(png_ptr, "incorrect byte-order specifier"); | uVar3 = uVar3 + 1; png_free(png_ptr, info_ptr->eXIf_buf); | } while (bVar4); info_ptr->eXIf_buf = NULL; | iVar1 = FUN_00119dc0(param_1,0); return; | if (iVar1 == 0) { } | png_set_eXIf_1(param_1,param_2,param_3,*(undefined8 *)(param_2 + 0xf8)); } | } } | png_free(param_1,*(undefined8 *)(param_2 + 0xf8)); | *(undefined8 *)(param_2 + 0xf8) = 0; if (png_crc_finish(png_ptr, 0) == 0) | } png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf); | } | LAB_0011c0a6: png_free(png_ptr, info_ptr->eXIf_buf); | if (local_40 != *(long *)(in_FS_OFFSET + 0x28)) { info_ptr->eXIf_buf = NULL; | /* WARNING: Subroutine does not return */ } | __stack_chk_fail(); #endif | } | return; | } =========================================================================== FUN_00119eb0 =========================================================================== Real name: png_cache_unknown_chunk OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, allocates memory for the pointer if necessary and calls the | | png_error/png_chunk_warning functions with an error message or | | warning, respectively. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2865 | Decompilation: FUN_00119eb0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED | undefined8 FUN_00119eb0(long param_1,uint param_2) /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ | static int | { png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) | uint uVar1; { | long lVar2; png_alloc_size_t limit = PNG_SIZE_MAX; | | if (*(long *)(param_1 + 0x440) != 0) { if (png_ptr->unknown_chunk.data != NULL) | png_free(); { | *(undefined8 *)(param_1 + 0x440) = 0; png_free(png_ptr, png_ptr->unknown_chunk.data); | } png_ptr->unknown_chunk.data = NULL; | if ((*(ulong *)(param_1 + 0x430) - 1 < 0xfffffffffffffffe) && } | (*(ulong *)(param_1 + 0x430) < (ulong)param_2)) { | lVar2 = *(long *)(param_1 + 0x440); # ifdef PNG_SET_USER_LIMITS_SUPPORTED | if (lVar2 == 0) { if (png_ptr->user_chunk_malloc_max > 0 && | if (param_2 != 0) { png_ptr->user_chunk_malloc_max < limit) | LAB_00119f87: limit = png_ptr->user_chunk_malloc_max; | FUN_00119dc0(param_1,param_2); | png_chunk_benign_error(param_1,"unknown chunk exceeds memory limits"); # elif PNG_USER_CHUNK_MALLOC_MAX > 0 | return 0; if (PNG_USER_CHUNK_MALLOC_MAX < limit) | } limit = PNG_USER_CHUNK_MALLOC_MAX; | goto LAB_00119f25; # endif | } | if (param_2 == 0) goto LAB_00119f25; if (length <= limit) | } { | else { PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); | uVar1 = *(uint *)(param_1 + 0x218); /* The following is safe because of the PNG_SIZE_MAX init above */ | *(undefined *)(param_1 + 0x43c) = 0; png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/; | *(ulong *)(param_1 + 0x448) = (ulong)param_2; /* 'mode' is a flag array, only the bottom four bits matter here */ | *(uint *)(param_1 + 0x438) = png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; | uVar1 >> 0x18 | (uVar1 & 0xff0000) >> 8 | (uVar1 & 0xff00) << 8 | uVar1 << 0x18; | *(char *)(param_1 + 0x450) = (char)*(undefined4 *)(param_1 + 300); if (length == 0) | if (param_2 == 0) { png_ptr->unknown_chunk.data = NULL; | *(undefined8 *)(param_1 + 0x440) = 0; | goto LAB_00119f25; else | } { | lVar2 = png_malloc_warn(param_1); /* Do a 'warn' here - it is handled below. */ | *(long *)(param_1 + 0x440) = lVar2; png_ptr->unknown_chunk.data = png_voidcast(png_bytep, | if (lVar2 == 0) goto LAB_00119f87; png_malloc_warn(png_ptr, length)); | } } | FUN_00119cb0(param_1,lVar2,param_2); } | LAB_00119f25: | FUN_00119dc0(param_1,0); if (png_ptr->unknown_chunk.data == NULL && length > 0) | return 1; { | } /* This is benign because we clean up correctly */ | png_crc_finish(png_ptr, length); | png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); | return 0; | } | | else | { | if (length > 0) | png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); | png_crc_finish(png_ptr, 0); | return 1; | } | } | #endif /* READ_UNKNOWN_CHUNKS */ | =========================================================================== FUN_0011c520 =========================================================================== Real name: png_handle_oFFs OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, calls the png_error/png_chunk_warning functions with an error | | message or warning, and sets the oFFs chunk in a png file. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2202 | Decompilation: FUN_0011c520 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_oFFs_SUPPORTED | void FUN_0011c520(long param_1,long param_2,int param_3) void /* PRIVATE */ | png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | int iVar1; png_byte buf[9]; | int iVar2; png_int_32 offset_x, offset_y; | long in_FS_OFFSET; int unit_type; | byte local_29; | byte local_28; png_debug(1, "in png_handle_oFFs"); | byte local_27; | byte local_26; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | byte local_25; png_chunk_error(png_ptr, "missing IHDR"); | byte local_24; | byte local_23; else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | byte local_22; { | undefined local_21; png_crc_finish(png_ptr, length); | long local_20; png_chunk_benign_error(png_ptr, "out of place"); | return; | local_20 = *(long *)(in_FS_OFFSET + 0x28); } | if ((*(uint *)(param_1 + 300) & 1) == 0) { | /* WARNING: Subroutine does not return */ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) | png_chunk_error(param_1,"missing IHDR"); { | } png_crc_finish(png_ptr, length); | if ((*(uint *)(param_1 + 300) & 4) == 0) { png_chunk_benign_error(png_ptr, "duplicate"); | if ((param_2 == 0) || ((*(byte *)(param_2 + 9) & 1) == 0)) { return; | if (param_3 == 9) { } | FUN_00119cb0(param_1,&local_29,9); | iVar1 = FUN_00119dc0(param_1); if (length != 9) | if (iVar1 == 0) { { | iVar1 = (uint)local_27 * 0x100 + png_crc_finish(png_ptr, length); | (uint)local_26 + (uint)local_28 * 0x10000 + (uint)local_29 * 0x1000000; png_chunk_benign_error(png_ptr, "invalid"); | if ((char)local_29 < '\0') { return; | iVar1 = -(-iVar1 & 0x7fffffffU); } | } | iVar2 = (uint)local_23 * 0x100 + png_crc_read(png_ptr, buf, 9); | (uint)local_22 + (uint)local_24 * 0x10000 + (uint)local_25 * 0x1000000; | if ((char)local_25 < '\0') { if (png_crc_finish(png_ptr, 0) != 0) | iVar2 = -(-iVar2 & 0x7fffffffU); return; | } | png_set_oFFs(param_1,param_2,iVar1,iVar2,local_21); offset_x = png_get_int_32(buf); | } offset_y = png_get_int_32(buf + 4); | } unit_type = buf[8]; | else { png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); | FUN_00119dc0(param_1); } | png_chunk_benign_error(param_1,"invalid"); #endif | } | } | else { | FUN_00119dc0(); | png_chunk_benign_error(param_1,"duplicate"); | } | } | else { | FUN_00119dc0(); | png_chunk_benign_error(param_1,"out of place"); | } | if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) { | return; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_0011aba0 =========================================================================== Real name: png_handle_sBIT OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks a given memory region for validity, calls the | | function pointed to, computes a CRC32 checksum, and calls | | png_error/png_chunk_warning with an error message or warning. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1158 | Decompilation: FUN_0011aba0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_sBIT_SUPPORTED | void FUN_0011aba0(long param_1,long param_2,uint param_3) void /* PRIVATE */ | png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | int iVar1; unsigned int truelen, i; | byte *pbVar2; png_byte sample_depth; | byte bVar3; png_byte buf[4]; | uint uVar4; | long in_FS_OFFSET; png_debug(1, "in png_handle_sBIT"); | byte local_44 [4]; | long local_40; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | png_chunk_error(png_ptr, "missing IHDR"); | local_40 = *(long *)(in_FS_OFFSET + 0x28); | if ((*(uint *)(param_1 + 300) & 1) == 0) { else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) | /* WARNING: Subroutine does not return */ { | png_chunk_error(param_1,"missing IHDR"); png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "out of place"); | if ((*(uint *)(param_1 + 300) & 6) != 0) { return; | FUN_00119dc0(param_1,param_3); } | png_chunk_benign_error(param_1,"out of place"); | goto LAB_0011aca0; if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0) | } { | if ((param_2 != 0) && ((*(byte *)(param_2 + 8) & 2) != 0)) { png_crc_finish(png_ptr, length); | FUN_00119dc0(param_1,param_3); png_chunk_benign_error(png_ptr, "duplicate"); | png_chunk_benign_error(param_1,"duplicate"); return; | goto LAB_0011aca0; } | } | if (*(char *)(param_1 + 0x267) == '\x03') { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | uVar4 = 3; { | bVar3 = 8; truelen = 3; | if (param_3 == 3) goto LAB_0011ac16; sample_depth = 8; | } } | else { | uVar4 = (uint)*(byte *)(param_1 + 0x26b); else | bVar3 = *(byte *)(param_1 + 0x268); { | if (*(byte *)(param_1 + 0x26b) == param_3) { truelen = png_ptr->channels; | LAB_0011ac16: sample_depth = png_ptr->bit_depth; | if (param_3 < 5) { } | pbVar2 = local_44; | local_44[0] = bVar3; if (length != truelen || length > 4) | local_44[1] = bVar3; { | local_44[2] = bVar3; png_chunk_benign_error(png_ptr, "invalid"); | local_44[3] = bVar3; png_crc_finish(png_ptr, length); | FUN_00119cb0(param_1,pbVar2,uVar4); return; | iVar1 = FUN_00119dc0(param_1,0); } | if (iVar1 == 0) { | if (uVar4 != 0) { buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; | do { png_crc_read(png_ptr, buf, truelen); | if ((*pbVar2 == 0) || (bVar3 < *pbVar2)) { | png_chunk_benign_error(param_1,"invalid"); if (png_crc_finish(png_ptr, 0) != 0) | goto LAB_0011aca0; return; | } | pbVar2 = pbVar2 + 1; for (i=0; i<truelen; ++i) | } while (local_44 + (ulong)(uVar4 - 1) + 1 != pbVar2); { | } if (buf[i] == 0 || buf[i] > sample_depth) | if ((*(byte *)(param_1 + 0x267) & 2) == 0) { { | *(byte *)(param_1 + 0x2db) = local_44[0]; png_chunk_benign_error(png_ptr, "invalid"); | *(byte *)(param_1 + 0x2d8) = local_44[0]; return; | *(byte *)(param_1 + 0x2d9) = local_44[0]; } | *(byte *)(param_1 + 0x2da) = local_44[0]; } | *(byte *)(param_1 + 0x2dc) = local_44[1]; | } if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) | else { { | *(byte *)(param_1 + 0x2d8) = local_44[0]; png_ptr->sig_bit.red = buf[0]; | *(byte *)(param_1 + 0x2d9) = local_44[1]; png_ptr->sig_bit.green = buf[1]; | *(byte *)(param_1 + 0x2da) = local_44[2]; png_ptr->sig_bit.blue = buf[2]; | *(byte *)(param_1 + 0x2dc) = local_44[3]; png_ptr->sig_bit.alpha = buf[3]; | } } | png_set_sBIT(param_1,param_2,param_1 + 0x2d8); | } else | goto LAB_0011aca0; { | } png_ptr->sig_bit.gray = buf[0]; | } png_ptr->sig_bit.red = buf[0]; | } png_ptr->sig_bit.green = buf[0]; | png_chunk_benign_error(param_1,"invalid"); png_ptr->sig_bit.blue = buf[0]; | FUN_00119dc0(param_1,param_3); png_ptr->sig_bit.alpha = buf[1]; | LAB_0011aca0: } | if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) { | return; png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); | } } | /* WARNING: Subroutine does not return */ #endif | __stack_chk_fail(); | } =========================================================================== FUN_0011a760 =========================================================================== Real name: png_handle_PLTE OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, calls the png_error/png_chunk_warning functions with an error | | message or warning, and sets the PNG palette. | +------------------------------------------------------------------------+ libpng/pngrutil.c:913 | Decompilation: FUN_0011a760 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Read and check the palette */ | void FUN_0011a760(long param_1,long param_2,uint param_3) void /* PRIVATE */ | png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | undefined *puVar1; png_color palette[PNG_MAX_PALETTE_LENGTH]; | undefined *puVar2; int max_palette_length, num, i; | char *pcVar3; #ifdef PNG_POINTER_INDEXING_SUPPORTED | uint uVar4; png_colorp pal_ptr; | long in_FS_OFFSET; #endif | undefined *local_350; | undefined local_348 [773]; png_debug(1, "in png_handle_PLTE"); | undefined local_43; | undefined local_42; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | undefined local_41; png_chunk_error(png_ptr, "missing IHDR"); | long local_40; | /* Moved to before the 'after IDAT' check below because otherwise duplicate | local_40 = *(long *)(in_FS_OFFSET + 0x28); * PLTE chunks are potentially ignored (the spec says there shall not be more | uVar4 = *(uint *)(param_1 + 300); * than one PLTE, the error is not treated as benign, so this check trumps | if ((uVar4 & 1) == 0) { * the requirement that PLTE appears before IDAT.) | /* WARNING: Subroutine does not return */ */ | png_chunk_error(param_1,"missing IHDR"); else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) | } png_chunk_error(png_ptr, "duplicate"); | if ((uVar4 & 2) != 0) { | /* WARNING: Subroutine does not return */ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | png_chunk_error(param_1,"duplicate"); { | } /* This is benign because the non-benign error happened before, when an | if ((uVar4 & 4) != 0) { * IDAT was encountered in a color-mapped image with no PLTE. | FUN_00119dc0(param_1,param_3); */ | png_chunk_benign_error(param_1,"out of place"); png_crc_finish(png_ptr, length); | goto LAB_0011a91f; png_chunk_benign_error(png_ptr, "out of place"); | } return; | *(uint *)(param_1 + 300) = uVar4 | 2; } | if ((*(byte *)(param_1 + 0x267) & 2) == 0) { | FUN_00119dc0(param_1,param_3); png_ptr->mode |= PNG_HAVE_PLTE; | png_chunk_benign_error(param_1,"ignored in grayscale PNG"); | goto LAB_0011a91f; if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) | } { | if ((param_3 < 0x301) && (param_3 * -0x55555555 < 0x55555556)) { png_crc_finish(png_ptr, length); | uVar4 = 0x100; png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); | if (*(byte *)(param_1 + 0x267) == 3) { return; | uVar4 = 1 << (*(byte *)(param_1 + 0x268) & 0x1f); } | } | if ((int)(param_3 / 3) < (int)uVar4) { #ifndef PNG_READ_OPT_PLTE_SUPPORTED | uVar4 = param_3 / 3; if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) | } { | if (0 < (int)uVar4) { png_crc_finish(png_ptr, length); | puVar1 = local_348; return; | do { } | puVar2 = puVar1 + 3; #endif | FUN_00119cb0(param_1,&local_43,3); | *puVar1 = local_43; if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) | puVar1[1] = local_42; { | puVar1[2] = local_41; png_crc_finish(png_ptr, length); | puVar1 = puVar2; | } while (puVar2 != local_348 + (ulong)(uVar4 - 1) * 3 + 3); if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) | } png_chunk_benign_error(png_ptr, "invalid"); | local_350 = local_348; | FUN_00119dc0(param_1,param_3 + uVar4 * -3); else | png_set_PLTE(param_1,param_2,local_350,uVar4); png_chunk_error(png_ptr, "invalid"); | if (*(short *)(param_1 + 0x260) == 0) { | if (param_2 == 0) goto LAB_0011a91f; return; | uVar4 = *(uint *)(param_2 + 8); } | if ((uVar4 & 0x10) != 0) goto LAB_0011a8bb; | } /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ | else { num = (int)length / 3; | *(undefined2 *)(param_1 + 0x260) = 0; | if (param_2 == 0) { /* If the palette has 256 or fewer entries but is too large for the bit | pcVar3 = "tRNS must be after"; * depth, we don't issue an error, to preserve the behavior of previous | goto LAB_0011a91a; * libpng versions. We silently truncate the unused extra palette entries | } * here. | LAB_0011a8bb: */ | *(undefined2 *)(param_2 + 0x22) = 0; if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | png_chunk_benign_error(param_1,"tRNS must be after"); max_palette_length = (1 << png_ptr->bit_depth); | uVar4 = *(uint *)(param_2 + 8); else | } max_palette_length = PNG_MAX_PALETTE_LENGTH; | if ((uVar4 & 0x40) != 0) { | png_chunk_benign_error(param_1,"hIST must be after"); if (num > max_palette_length) | uVar4 = *(uint *)(param_2 + 8); num = max_palette_length; | } | if ((uVar4 & 0x20) != 0) { #ifdef PNG_POINTER_INDEXING_SUPPORTED | png_chunk_benign_error(param_1,"bKGD must be after"); for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) | } { | } png_byte buf[3]; | else { | FUN_00119dc0(param_1,param_3); png_crc_read(png_ptr, buf, 3); | pcVar3 = "invalid"; pal_ptr->red = buf[0]; | if (*(char *)(param_1 + 0x267) == '\x03') { pal_ptr->green = buf[1]; | /* WARNING: Subroutine does not return */ pal_ptr->blue = buf[2]; | png_chunk_error(param_1,"invalid"); } | } #else | LAB_0011a91a: for (i = 0; i < num; i++) | png_chunk_benign_error(param_1,pcVar3); { | } png_byte buf[3]; | LAB_0011a91f: | if (local_40 != *(long *)(in_FS_OFFSET + 0x28)) { png_crc_read(png_ptr, buf, 3); | /* WARNING: Subroutine does not return */ /* Don't depend upon png_color being any order */ | __stack_chk_fail(); palette[i].red = buf[0]; | } palette[i].green = buf[1]; | return; palette[i].blue = buf[2]; | } } | #endif | | /* If we actually need the PLTE chunk (ie for a paletted image), we do | * whatever the normal CRC configuration tells us. However, if we | * have an RGB image, the PLTE can be considered ancillary, so | * we will act as though it is. | */ | #ifndef PNG_READ_OPT_PLTE_SUPPORTED | if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | #endif | { | png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3)); | } | | #ifndef PNG_READ_OPT_PLTE_SUPPORTED | else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */ | { | /* If we don't want to use the data from an ancillary chunk, | * we have two options: an error abort, or a warning and we | * ignore the data in this chunk (which should be OK, since | * it's considered ancillary for a RGB or RGBA image). | * | * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the | * chunk type to determine whether to check the ancillary or the critical | * flags. | */ | if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0) | { | if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0) | return; | | else | png_chunk_error(png_ptr, "CRC error"); | } | | /* Otherwise, we (optionally) emit a warning and use the chunk. */ | else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0) | png_chunk_warning(png_ptr, "CRC error"); | } | #endif | | /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its | * own copy of the palette. This has the side effect that when png_start_row | * is called (this happens after any call to png_read_update_info) the | * info_ptr palette gets changed. This is extremely unexpected and | * confusing. | * | * Fix this by not sharing the palette in this way. | */ | png_set_PLTE(png_ptr, info_ptr, palette, num); | | /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before | * IDAT. Prior to 1.6.0 this was not checked; instead the code merely | * checked the apparent validity of a tRNS chunk inserted before PLTE on a | * palette PNG. 1.6.0 attempts to rigorously follow the standard and | * therefore does a benign error if the erroneous condition is detected *and* | * cancels the tRNS if the benign error returns. The alternative is to | * amend the standard since it would be rather hypocritical of the standards | * maintainers to ignore it. | */ | #ifdef PNG_READ_tRNS_SUPPORTED | if (png_ptr->num_trans > 0 || | (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) | { | /* Cancel this because otherwise it would be used if the transforms | * require it. Don't cancel the 'valid' flag because this would prevent | * detection of duplicate chunks. | */ | png_ptr->num_trans = 0; | | if (info_ptr != NULL) | info_ptr->num_trans = 0; | | png_chunk_benign_error(png_ptr, "tRNS must be after"); | } | #endif | | #ifdef PNG_READ_hIST_SUPPORTED | if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) | png_chunk_benign_error(png_ptr, "hIST must be after"); | #endif | | #ifdef PNG_READ_bKGD_SUPPORTED | if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) | png_chunk_benign_error(png_ptr, "bKGD must be after"); | #endif | } | =========================================================================== FUN_0011cd90 =========================================================================== Real name: png_handle_tEXt OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks the parameters, allocates a block of memory, | | copies data into it, calls the appropriate function depending on the | | value of the bit and the value of the parameter, checks if a pointer | | at a given address is valid, calls the function pointed to, computes a | | CRC32 checksum of the given memory region, and calls the | | png_error/png_chunk_warning functions with an error message or | | warning, respectively. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2517 | Decompilation: FUN_0011cd90 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_tEXt_SUPPORTED | void FUN_0011cd90(long param_1,undefined8 param_2,ulong param_3) /* Note: this does not properly handle chunks that are > 64K under DOS */ | void /* PRIVATE */ | { png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | char cVar1; { | uint uVar2; png_text text_info; | int iVar3; png_bytep buffer; | char *pcVar4; png_charp key; | long in_FS_OFFSET; png_charp text; | undefined4 local_68 [2]; png_uint_32 skip = 0; | char *local_60; | char *local_58; png_debug(1, "in png_handle_tEXt"); | size_t local_50; | undefined8 local_48; #ifdef PNG_USER_LIMITS_SUPPORTED | undefined8 local_40; if (png_ptr->user_chunk_cache_max != 0) | undefined8 local_38; { | long local_30; if (png_ptr->user_chunk_cache_max == 1) | { | param_3 = param_3 & 0xffffffff; png_crc_finish(png_ptr, length); | local_30 = *(long *)(in_FS_OFFSET + 0x28); return; | iVar3 = *(int *)(param_1 + 0x42c); } | if (iVar3 != 0) { | if (iVar3 == 1) { if (--png_ptr->user_chunk_cache_max == 1) | FUN_00119dc0(param_1,param_3); { | goto LAB_0011cea1; png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "no space in chunk cache"); | *(int *)(param_1 + 0x42c) = iVar3 + -1; return; | if (iVar3 + -1 == 1) { } | FUN_00119dc0(param_1,param_3); } | png_chunk_benign_error(param_1,"no space in chunk cache"); #endif | goto LAB_0011cea1; | } if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | } png_chunk_error(png_ptr, "missing IHDR"); | uVar2 = *(uint *)(param_1 + 300); | if ((uVar2 & 1) == 0) { if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | /* WARNING: Subroutine does not return */ png_ptr->mode |= PNG_AFTER_IDAT; | png_chunk_error(param_1,"missing IHDR"); | } #ifdef PNG_MAX_MALLOC_64K | if ((uVar2 & 4) != 0) { if (length > 65535U) | *(uint *)(param_1 + 300) = uVar2 | 8; { | } png_crc_finish(png_ptr, length); | pcVar4 = (char *)FUN_00119a20(param_1,(int)param_3 + 1,1); png_chunk_benign_error(png_ptr, "too large to fit in memory"); | if (pcVar4 == (char *)0x0) { return; | png_chunk_benign_error(param_1,"out of memory"); } | } #endif | else { | FUN_00119cb0(param_1,pcVar4,param_3); buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); | iVar3 = FUN_00119dc0(param_1,0); | if (iVar3 == 0) { if (buffer == NULL) | pcVar4[param_3] = '\0'; { | cVar1 = *pcVar4; png_chunk_benign_error(png_ptr, "out of memory"); | local_58 = pcVar4; return; | while (cVar1 != '\0') { } | local_58 = local_58 + 1; | cVar1 = *local_58; png_crc_read(png_ptr, buffer, length); | } | local_68[0] = 0xffffffff; if (png_crc_finish(png_ptr, skip) != 0) | local_40 = 0; return; | local_58 = local_58 + (pcVar4 + param_3 != local_58); | local_38 = 0; key = (png_charp)buffer; | local_48 = 0; key[length] = 0; | local_60 = pcVar4; | local_50 = strlen(local_58); for (text = key; *text; text++) | iVar3 = FUN_001200e0(param_1,param_2,local_68,1); /* Empty loop to find end of key */ ; | if (iVar3 != 0) { | png_warning(param_1,"Insufficient memory to process text chunk"); if (text != key + length) | } text++; | } | } text_info.compression = PNG_TEXT_COMPRESSION_NONE; | LAB_0011cea1: text_info.key = key; | if (local_30 != *(long *)(in_FS_OFFSET + 0x28)) { text_info.lang = NULL; | /* WARNING: Subroutine does not return */ text_info.lang_key = NULL; | __stack_chk_fail(); text_info.itxt_length = 0; | } text_info.text = text; | return; text_info.text_length = strlen(text); | } | if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0) | png_warning(png_ptr, "Insufficient memory to process text chunk"); | } | #endif | =========================================================================== FUN_0011bb10 =========================================================================== Real name: png_handle_tRNS OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, and sets a transparency channel if valid and appropriate. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1817 | Decompilation: FUN_0011bb10 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_tRNS_SUPPORTED | void FUN_0011bb10(long param_1,long param_2,uint param_3) void /* PRIVATE */ | png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | char cVar1; png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; | uint uVar2; | int iVar3; png_debug(1, "in png_handle_tRNS"); | long in_FS_OFFSET; | byte local_138; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | byte local_137; png_chunk_error(png_ptr, "missing IHDR"); | byte local_136; | byte local_135; else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | byte local_134; { | byte local_133; png_crc_finish(png_ptr, length); | long local_30; png_chunk_benign_error(png_ptr, "out of place"); | return; | local_30 = *(long *)(in_FS_OFFSET + 0x28); } | uVar2 = *(uint *)(param_1 + 300); | if ((uVar2 & 1) == 0) { else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) | /* WARNING: Subroutine does not return */ { | png_chunk_error(param_1,"missing IHDR"); png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "duplicate"); | if ((uVar2 & 4) != 0) { return; | LAB_0011bc50: } | FUN_00119dc0(param_1,param_3); | png_chunk_benign_error(param_1,"out of place"); if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) | goto LAB_0011bbca; { | } png_byte buf[2]; | if ((param_2 != 0) && ((*(byte *)(param_2 + 8) & 0x10) != 0)) { | FUN_00119dc0(param_1,param_3); if (length != 2) | png_chunk_benign_error(param_1,"duplicate"); { | goto LAB_0011bbca; png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "invalid"); | cVar1 = *(char *)(param_1 + 0x267); return; | if (cVar1 == '\0') { } | if (param_3 == 2) { | FUN_00119cb0(param_1,&local_138,2); png_crc_read(png_ptr, buf, 2); | *(undefined2 *)(param_1 + 0x260) = 1; png_ptr->num_trans = 1; | *(ushort *)(param_1 + 0x2f8) = (ushort)local_138 * 0x100 + (ushort)local_137; png_ptr->trans_color.gray = png_get_uint_16(buf); | LAB_0011bc2a: } | iVar3 = FUN_00119dc0(param_1,0); | if (iVar3 == 0) { else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) | png_set_tRNS(param_1,param_2,&local_138,*(undefined2 *)(param_1 + 0x260),param_1 + 0x2f0); { | } png_byte buf[6]; | else { | *(undefined2 *)(param_1 + 0x260) = 0; if (length != 6) | } { | goto LAB_0011bbca; png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "invalid"); | } return; | else if (cVar1 == '\x02') { } | if (param_3 == 6) { | FUN_00119cb0(param_1,&local_138,6); png_crc_read(png_ptr, buf, length); | *(undefined2 *)(param_1 + 0x260) = 1; png_ptr->num_trans = 1; | *(ushort *)(param_1 + 0x2f2) = (ushort)local_138 * 0x100 + (ushort)local_137; png_ptr->trans_color.red = png_get_uint_16(buf); | *(ushort *)(param_1 + 0x2f4) = (ushort)local_136 * 0x100 + (ushort)local_135; png_ptr->trans_color.green = png_get_uint_16(buf + 2); | *(ushort *)(param_1 + 0x2f6) = (ushort)local_134 * 0x100 + (ushort)local_133; png_ptr->trans_color.blue = png_get_uint_16(buf + 4); | goto LAB_0011bc2a; } | } | } else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | else { { | if (cVar1 != '\x03') { if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) | FUN_00119dc0(param_1,param_3); { | png_chunk_benign_error(param_1,"invalid with alpha channel"); /* TODO: is this actually an error in the ISO spec? */ | goto LAB_0011bbca; png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "out of place"); | if ((uVar2 & 2) == 0) goto LAB_0011bc50; return; | if ((param_3 <= *(ushort *)(param_1 + 600)) && (param_3 - 1 < 0x100)) { } | FUN_00119cb0(param_1,&local_138,param_3); | *(short *)(param_1 + 0x260) = (short)param_3; if (length > (unsigned int) png_ptr->num_palette || | goto LAB_0011bc2a; length > (unsigned int) PNG_MAX_PALETTE_LENGTH || | } length == 0) | } { | FUN_00119dc0(param_1,param_3); png_crc_finish(png_ptr, length); | png_chunk_benign_error(param_1,"invalid"); png_chunk_benign_error(png_ptr, "invalid"); | LAB_0011bbca: return; | if (local_30 != *(long *)(in_FS_OFFSET + 0x28)) { } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); png_crc_read(png_ptr, readbuf, length); | } png_ptr->num_trans = (png_uint_16)length; | return; } | } | else | { | png_crc_finish(png_ptr, length); | png_chunk_benign_error(png_ptr, "invalid with alpha channel"); | return; | } | | if (png_crc_finish(png_ptr, 0) != 0) | { | png_ptr->num_trans = 0; | return; | } | | /* TODO: this is a horrible side effect in the palette case because the | * png_struct ends up with a pointer to the tRNS buffer owned by the | * png_info. Fix this. | */ | png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, | &(png_ptr->trans_color)); | } | #endif | =========================================================================== FUN_0011bd80 =========================================================================== Real name: png_handle_bKGD OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, calls the png_error/png_chunk_warning functions with an error | | message or warning, and sets the background color using the parameters | | provided. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1921 | Decompilation: FUN_0011bd80 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_bKGD_SUPPORTED | void FUN_0011bd80(long param_1,long param_2,uint param_3) void /* PRIVATE */ | png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | byte bVar1; unsigned int truelen; | uint uVar2; png_byte buf[6]; | int iVar3; png_color_16 background; | byte *pbVar4; | uint uVar5; png_debug(1, "in png_handle_bKGD"); | long in_FS_OFFSET; | byte local_30 [2]; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | uint local_2e; png_chunk_error(png_ptr, "missing IHDR"); | ushort local_2a; | ushort local_28; else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || | byte local_26; (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && | byte local_25; (png_ptr->mode & PNG_HAVE_PLTE) == 0)) | byte local_24; { | byte local_23; png_crc_finish(png_ptr, length); | byte local_22; png_chunk_benign_error(png_ptr, "out of place"); | byte local_21; return; | long local_20; } | | local_20 = *(long *)(in_FS_OFFSET + 0x28); else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) | uVar2 = *(uint *)(param_1 + 300); { | uVar5 = uVar2 & 1; png_crc_finish(png_ptr, length); | if (uVar5 == 0) { png_chunk_benign_error(png_ptr, "duplicate"); | /* WARNING: Subroutine does not return */ return; | png_chunk_error(param_1,"missing IHDR"); } | } | if ((uVar2 & 4) != 0) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | LAB_0011bea4: truelen = 1; | FUN_00119dc0(param_1); | png_chunk_benign_error(param_1,"out of place"); else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) | goto LAB_0011be06; truelen = 6; | } | if (*(byte *)(param_1 + 0x267) == 3) { else | if ((uVar2 & 2) == 0) goto LAB_0011bea4; truelen = 2; | if ((param_2 != 0) && ((*(byte *)(param_2 + 8) & 0x20) != 0)) goto LAB_0011bed8; | } if (length != truelen) | else { { | if ((param_2 != 0) && ((*(byte *)(param_2 + 8) & 0x20) != 0)) { png_crc_finish(png_ptr, length); | LAB_0011bed8: png_chunk_benign_error(png_ptr, "invalid"); | FUN_00119dc0(param_1); return; | png_chunk_benign_error(param_1,"duplicate"); } | goto LAB_0011be06; | } png_crc_read(png_ptr, buf, truelen); | uVar5 = (-(uint)((*(byte *)(param_1 + 0x267) & 2) == 0) & 0xfffffffc) + 6; | } if (png_crc_finish(png_ptr, 0) != 0) | if (uVar5 != param_3) { return; | FUN_00119dc0(param_1); | png_chunk_benign_error(param_1,"invalid"); /* We convert the index value into RGB components so that we can allow | goto LAB_0011be06; * arbitrary RGB values for background when we have transparency, and | } * so it is easy to determine the RGB values of the background color | FUN_00119cb0(param_1); * from the info_ptr struct. | iVar3 = FUN_00119dc0(param_1); */ | if (iVar3 != 0) goto LAB_0011be06; if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | if (*(byte *)(param_1 + 0x267) == 3) { { | local_30[0] = local_26; background.index = buf[0]; | if ((param_2 == 0) || (*(ushort *)(param_2 + 0x20) == 0)) { | local_2e = 0; if (info_ptr != NULL && info_ptr->num_palette != 0) | local_2a = 0; { | } if (buf[0] >= info_ptr->num_palette) | else { { | if (*(ushort *)(param_2 + 0x20) <= (ushort)local_26) { png_chunk_benign_error(png_ptr, "invalid index"); | png_chunk_benign_error(param_1,"invalid index"); return; | goto LAB_0011be06; } | } | pbVar4 = (byte *)((ulong)local_26 * 3 + *(long *)(param_1 + 0x250)); background.red = (png_uint_16)png_ptr->palette[buf[0]].red; | local_2e = (uint)CONCAT12(pbVar4[1],(ushort)*pbVar4); background.green = (png_uint_16)png_ptr->palette[buf[0]].green; | local_2a = (ushort)pbVar4[2]; background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; | } } | LAB_0011bf48: | local_28 = 0; else | } background.red = background.green = background.blue = 0; | else { | bVar1 = *(byte *)(param_1 + 0x268); background.gray = 0; | if ((*(byte *)(param_1 + 0x267) & 2) != 0) { } | if ((bVar1 < 9) && ((byte)(local_26 | local_24 | local_22) != 0)) { | png_chunk_benign_error(param_1,"invalid color"); else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ | goto LAB_0011be06; { | } if (png_ptr->bit_depth <= 8) | local_30[0] = 0; { | local_2e = CONCAT22((ushort)local_24 * 0x100 + (ushort)local_23, if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth)) | (ushort)local_26 * 0x100 + (ushort)local_25); { | local_2a = (ushort)local_22 * 0x100 + (ushort)local_21; png_chunk_benign_error(png_ptr, "invalid gray level"); | goto LAB_0011bf48; return; | } } | if ((bVar1 < 9) && ((local_26 != 0 || (local_25 >> (bVar1 & 0x1f) != 0)))) { } | png_chunk_benign_error(param_1,"invalid gray level"); | goto LAB_0011be06; background.index = 0; | } background.red = | local_30[0] = 0; background.green = | local_2a = (ushort)local_26 * 0x100 + (ushort)local_25; background.blue = | local_2e = CONCAT22(local_2a,local_2a); background.gray = png_get_uint_16(buf); | local_28 = local_2a; } | } | png_set_bKGD(param_1,param_2,local_30); else | LAB_0011be06: { | if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) { if (png_ptr->bit_depth <= 8) | /* WARNING: Subroutine does not return */ { | __stack_chk_fail(); if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0) | } { | return; png_chunk_benign_error(png_ptr, "invalid color"); | } return; | } | } | | background.index = 0; | background.red = png_get_uint_16(buf); | background.green = png_get_uint_16(buf + 2); | background.blue = png_get_uint_16(buf + 4); | background.gray = 0; | } | | png_set_bKGD(png_ptr, info_ptr, &background); | } | #endif | =========================================================================== FUN_0011cc80 =========================================================================== Real name: png_handle_tIME OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, and calls the png_error/png_chunk_warning functions with an | | error message or warning, respectively, as well as setting the tIME | | chunk if the parameters are valid. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2471 | Decompilation: FUN_0011cc80 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_tIME_SUPPORTED | void FUN_0011cc80(long param_1,long param_2,int param_3) void /* PRIVATE */ | png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | uint uVar1; png_byte buf[7]; | int iVar2; png_time mod_time; | long in_FS_OFFSET; | short local_30; png_debug(1, "in png_handle_tIME"); | undefined4 local_2e; | undefined local_2a; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | byte local_27; png_chunk_error(png_ptr, "missing IHDR"); | byte local_26; | undefined4 local_25; else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0) | undefined local_21; { | long local_20; png_crc_finish(png_ptr, length); | png_chunk_benign_error(png_ptr, "duplicate"); | local_20 = *(long *)(in_FS_OFFSET + 0x28); return; | uVar1 = *(uint *)(param_1 + 300); } | if ((uVar1 & 1) == 0) { | /* WARNING: Subroutine does not return */ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | png_chunk_error(param_1,"missing IHDR"); png_ptr->mode |= PNG_AFTER_IDAT; | } | if ((param_2 == 0) || ((*(byte *)(param_2 + 9) & 2) == 0)) { if (length != 7) | if ((uVar1 & 4) != 0) { { | *(uint *)(param_1 + 300) = uVar1 | 8; png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "invalid"); | if (param_3 == 7) { return; | FUN_00119cb0(param_1,&local_27,7); } | iVar2 = FUN_00119dc0(param_1,0); | if (iVar2 == 0) { png_crc_read(png_ptr, buf, 7); | local_2e = local_25; | local_2a = local_21; if (png_crc_finish(png_ptr, 0) != 0) | local_30 = (ushort)local_27 * 0x100 + (ushort)local_26; return; | png_set_tIME(param_1,param_2,&local_30); | } mod_time.second = buf[6]; | } mod_time.minute = buf[5]; | else { mod_time.hour = buf[4]; | FUN_00119dc0(param_1); mod_time.day = buf[3]; | png_chunk_benign_error(param_1,"invalid"); mod_time.month = buf[2]; | } mod_time.year = png_get_uint_16(buf); | } | else { png_set_tIME(png_ptr, info_ptr, &mod_time); | FUN_00119dc0(); } | png_chunk_benign_error(param_1,"duplicate"); #endif | } | if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) { | return; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_0011c6b0 =========================================================================== Real name: png_handle_pCAL OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, and sets parameters for a PNG file if valid. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2249 | Decompilation: FUN_0011c6b0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_pCAL_SUPPORTED | void FUN_0011c6b0(long param_1,long param_2,ulong param_3) /* Read the pCAL chunk (described in the PNG Extensions document) */ | void /* PRIVATE */ | { png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | char cVar1; { | int iVar2; png_int_32 X0, X1; | char *pcVar3; png_byte type, nparams; | char **ppcVar4; png_bytep buffer, buf, units, endptr; | char **ppcVar5; png_charpp params; | byte bVar6; int i; | char *pcVar7; | char *pcVar8; png_debug(1, "in png_handle_pCAL"); | char *pcVar9; | int iVar10; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | byte bVar11; png_chunk_error(png_ptr, "missing IHDR"); | undefined8 uVar12; | else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | if ((*(uint *)(param_1 + 300) & 1) == 0) { { | /* WARNING: Subroutine does not return */ png_crc_finish(png_ptr, length); | png_chunk_error(param_1,"missing IHDR"); png_chunk_benign_error(png_ptr, "out of place"); | } return; | param_3 = param_3 & 0xffffffff; } | if ((*(uint *)(param_1 + 300) & 4) != 0) { | FUN_00119dc0(param_1,param_3); else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0) | pcVar9 = "out of place"; { | goto LAB_0011c7e8; png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "duplicate"); | if ((param_2 != 0) && ((*(byte *)(param_2 + 9) & 4) != 0)) { return; | FUN_00119dc0(param_1,param_3); } | pcVar9 = "duplicate"; | goto LAB_0011c7e8; png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", | } length + 1); | pcVar3 = (char *)FUN_00119a20(param_1,(int)param_3 + 1,2); | if (pcVar3 == (char *)0x0) { buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); | FUN_00119dc0(param_1,param_3); | pcVar9 = "out of memory"; if (buffer == NULL) | goto LAB_0011c7e8; { | } png_crc_finish(png_ptr, length); | FUN_00119cb0(param_1,pcVar3,param_3); png_chunk_benign_error(png_ptr, "out of memory"); | iVar2 = FUN_00119dc0(param_1,0); return; | if (iVar2 != 0) { } | return; | } png_crc_read(png_ptr, buffer, length); | pcVar8 = pcVar3 + param_3; | *pcVar8 = '\0'; if (png_crc_finish(png_ptr, 0) != 0) | cVar1 = *pcVar3; return; | pcVar7 = pcVar3; | while (cVar1 != '\0') { buffer[length] = 0; /* Null terminate the last string */ | pcVar7 = pcVar7 + 1; | cVar1 = *pcVar7; png_debug(3, "Finding end of pCAL purpose string"); | } for (buf = buffer; *buf; buf++) | pcVar9 = "invalid"; /* Empty loop */ ; | if ((long)pcVar8 - (long)pcVar7 < 0xd) goto LAB_0011c7e8; | iVar2 = (uint)(byte)pcVar7[3] * 0x100 + endptr = buffer + length; | (uint)(byte)pcVar7[2] * 0x10000 + (uint)(byte)pcVar7[1] * 0x1000000 + | (uint)(byte)pcVar7[4]; /* We need to have at least 12 bytes after the purpose string | if (pcVar7[1] < '\0') { * in order to get the parameter information. | iVar2 = -(-iVar2 & 0x7fffffffU); */ | } if (endptr - buf <= 12) | iVar10 = (uint)(byte)pcVar7[7] * 0x100 + { | (uint)(byte)pcVar7[8] + png_chunk_benign_error(png_ptr, "invalid"); | (uint)(byte)pcVar7[6] * 0x10000 + (uint)(byte)pcVar7[5] * 0x1000000; return; | if (pcVar7[5] < '\0') { } | bVar11 = pcVar7[9]; | bVar6 = pcVar7[10]; png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); | iVar10 = -(-iVar10 & 0x7fffffffU); X0 = png_get_int_32((png_bytep)buf+1); | if (bVar11 == 0) goto LAB_0011c7cb; X1 = png_get_int_32((png_bytep)buf+5); | LAB_0011c7d0: type = buf[9]; | if (((1 < (byte)(bVar11 - 1)) || (bVar6 == 3)) && ((bVar11 != 3 || (bVar6 == 4)))) { nparams = buf[10]; | if (3 < bVar11) { units = buf + 11; | png_chunk_benign_error(param_1); | } png_debug(3, "Checking pCAL equation type and number of parameters"); | cVar1 = pcVar7[0xb]; /* Check that we have the right number of parameters for known | pcVar9 = pcVar7 + 0xb; * equation types. | while (cVar1 != '\0') { */ | pcVar9 = pcVar9 + 1; if ((type == PNG_EQUATION_LINEAR && nparams != 2) || | cVar1 = *pcVar9; (type == PNG_EQUATION_BASE_E && nparams != 3) || | } (type == PNG_EQUATION_ARBITRARY && nparams != 3) || | uVar12 = 0x11c8ab; (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) | ppcVar4 = (char **)png_malloc_warn(param_1); { | if (ppcVar4 != (char **)0x0) { png_chunk_benign_error(png_ptr, "invalid parameter count"); | if (bVar6 != 0) { return; | ppcVar5 = ppcVar4; } | do { | pcVar9 = pcVar9 + 1; else if (type >= PNG_EQUATION_LAST) | *ppcVar5 = pcVar9; { | if (pcVar8 < pcVar9) { png_chunk_benign_error(png_ptr, "unrecognized equation type"); | LAB_0011c9c0: } | png_free(param_1,ppcVar4); | pcVar9 = "invalid data"; for (buf = units; *buf; buf++) | goto LAB_0011c7e8; /* Empty loop to move past the units string. */ ; | } | while (*pcVar9 != '\0') { png_debug(3, "Allocating pCAL parameters array"); | pcVar9 = pcVar9 + 1; | if (pcVar8 + 1 == pcVar9) goto LAB_0011c9c0; params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, | } nparams * (sizeof (png_charp)))); | if (pcVar8 < pcVar9) goto LAB_0011c9c0; | ppcVar5 = ppcVar5 + 1; if (params == NULL) | } while (ppcVar4 + (ulong)(bVar6 - 1) + 1 != ppcVar5); { | } png_chunk_benign_error(png_ptr, "out of memory"); | png_set_pCAL(param_1,param_2,pcVar3,iVar2,iVar10,bVar11,bVar6,pcVar7 + 0xb,ppcVar4,uVar12); return; | png_free(param_1,ppcVar4); } | return; | } /* Get pointers to the start of each parameter string. */ | pcVar9 = "out of memory"; for (i = 0; i < nparams; i++) | goto LAB_0011c7e8; { | } buf++; /* Skip the null string terminator from previous parameter. */ | } | else { png_debug1(3, "Reading pCAL parameter %d", i); | bVar11 = pcVar7[9]; | bVar6 = pcVar7[10]; for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) | if (bVar11 != 0) goto LAB_0011c7d0; /* Empty loop to move past each parameter string */ ; | LAB_0011c7cb: | if (bVar6 == 2) goto LAB_0011c7d0; /* Make sure we haven't run out of data yet */ | } if (buf > endptr) | pcVar9 = "invalid parameter count"; { | LAB_0011c7e8: png_free(png_ptr, params); | png_chunk_benign_error(param_1,pcVar9); png_chunk_benign_error(png_ptr, "invalid data"); | return; return; | } } | } | | png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, | (png_charp)units, params); | | png_free(png_ptr, params); | } | #endif | =========================================================================== FUN_0011c240 =========================================================================== Real name: png_handle_hIST OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if the IHDR chunk is present, computes a CRC32 | | checksum of the given memory region, and calls the | | png_set_hIST/png_chunk_benign_error functions with a histogram or an | | error/warning message, respectively. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2103 | Decompilation: FUN_0011c240 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_hIST_SUPPORTED | void FUN_0011c240(long param_1,long param_2,ulong param_3) void /* PRIVATE */ | png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | ulong uVar1; unsigned int num, i; | uint uVar2; png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; | int iVar3; | short *psVar4; png_debug(1, "in png_handle_hIST"); | short *psVar5; | long in_FS_OFFSET; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | short local_238 [259]; png_chunk_error(png_ptr, "missing IHDR"); | byte local_32; | byte local_31; else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || | long local_30; (png_ptr->mode & PNG_HAVE_PLTE) == 0) | { | local_30 = *(long *)(in_FS_OFFSET + 0x28); png_crc_finish(png_ptr, length); | if ((*(uint *)(param_1 + 300) & 1) == 0) { png_chunk_benign_error(png_ptr, "out of place"); | /* WARNING: Subroutine does not return */ return; | png_chunk_error(param_1,"missing IHDR"); } | } | if ((*(uint *)(param_1 + 300) & 6) == 2) { else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) | if ((param_2 == 0) || ((*(byte *)(param_2 + 8) & 0x40) == 0)) { { | if ((param_3 & 1) == 0) { png_crc_finish(png_ptr, length); | uVar1 = (param_3 & 0xffffffff) >> 1; png_chunk_benign_error(png_ptr, "duplicate"); | uVar2 = (uint)uVar1; return; | if ((*(ushort *)(param_1 + 600) == uVar2) && ((uint)(param_3 & 0xffffffff) < 0x202)) { } | if (uVar1 != 0) { | psVar4 = local_238; num = length / 2 ; | do { | psVar5 = psVar4 + 1; if (length != num * 2 || | FUN_00119cb0(param_1,&local_32,2); num != (unsigned int)png_ptr->num_palette || | *psVar4 = (ushort)local_32 * 0x100 + (ushort)local_31; num > (unsigned int)PNG_MAX_PALETTE_LENGTH) | psVar4 = psVar5; { | } while (psVar5 != local_238 + (ulong)(uVar2 - 1) + 1); png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "invalid"); | iVar3 = FUN_00119dc0(param_1,0); return; | if (iVar3 == 0) { } | png_set_hIST(param_1,param_2,local_238); | } for (i = 0; i < num; i++) | goto LAB_0011c2c9; { | } png_byte buf[2]; | } | FUN_00119dc0(param_1); png_crc_read(png_ptr, buf, 2); | png_chunk_benign_error(param_1,"invalid"); readbuf[i] = png_get_uint_16(buf); | } } | else { | FUN_00119dc0(); if (png_crc_finish(png_ptr, 0) != 0) | png_chunk_benign_error(param_1,"duplicate"); return; | } | } png_set_hIST(png_ptr, info_ptr, readbuf); | else { } | FUN_00119dc0(); #endif | png_chunk_benign_error(param_1,"out of place"); | } | LAB_0011c2c9: | if (local_30 == *(long *)(in_FS_OFFSET + 0x28)) { | return; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_0011a560 =========================================================================== Real name: png_handle_IHDR OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, and calls the png_error/png_chunk_warning functions with an | | error message or warning, sets various parameters based on the input | | data, and calls the png_set_IHDR function. | +------------------------------------------------------------------------+ libpng/pngrutil.c:839 | Decompilation: FUN_0011a560 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | /* WARNING: Could not reconcile some variable overlaps */ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { | void FUN_0011a560(long param_1,undefined8 param_2,int param_3) png_byte buf[13]; | png_uint_32 width, height; | { int bit_depth, color_type, compression_type, filter_type; | uint uVar1; int interlace_type; | undefined4 uVar2; | byte bVar3; png_debug(1, "in png_handle_IHDR"); | uint uVar4; | ulong uVar5; if ((png_ptr->mode & PNG_HAVE_IHDR) != 0) | long in_FS_OFFSET; png_chunk_error(png_ptr, "out of place"); | undefined local_4d [8]; | undefined2 local_45; /* Check the length */ | undefined local_43; if (length != 13) | undefined local_42; png_chunk_error(png_ptr, "invalid"); | undefined local_41; | long local_40; png_ptr->mode |= PNG_HAVE_IHDR; | | local_40 = *(long *)(in_FS_OFFSET + 0x28); png_crc_read(png_ptr, buf, 13); | if ((*(uint *)(param_1 + 300) & 1) != 0) { png_crc_finish(png_ptr, 0); | /* WARNING: Subroutine does not return */ | png_chunk_error(param_1,"out of place"); width = png_get_uint_31(png_ptr, buf); | } height = png_get_uint_31(png_ptr, buf + 4); | if (param_3 == 0xd) { bit_depth = buf[8]; | *(uint *)(param_1 + 300) = *(uint *)(param_1 + 300) | 1; color_type = buf[9]; | FUN_00119cb0(param_1,local_4d,0xd); compression_type = buf[10]; | FUN_00119dc0(param_1,0); filter_type = buf[11]; | uVar1 = png_get_uint_31(param_1,local_4d); interlace_type = buf[12]; | uVar2 = png_get_uint_31(); | uVar5 = (ulong)(byte)local_45; /* Set internal variables */ | *(uint *)(param_1 + 0x1f8) = uVar1; png_ptr->width = width; | *(undefined4 *)(param_1 + 0x1fc) = uVar2; png_ptr->height = height; | *(undefined *)(param_1 + 0x264) = local_41; png_ptr->bit_depth = (png_byte)bit_depth; | *(ushort *)(param_1 + 0x267) = local_45 << 8 | local_45 >> 8; png_ptr->interlaced = (png_byte)interlace_type; | *(undefined *)(param_1 + 0x3e4) = local_42; png_ptr->color_type = (png_byte)color_type; | *(undefined *)(param_1 + 0x420) = local_43; #ifdef PNG_MNG_FEATURES_SUPPORTED | if (local_45._1_1_ == '\x04') { png_ptr->filter_type = (png_byte)filter_type; | uVar5 = (ulong)((uint)(byte)local_45 * 2); #endif | *(undefined *)(param_1 + 0x26b) = 2; png_ptr->compression_type = (png_byte)compression_type; | bVar3 = (byte)((uint)(byte)local_45 * 2); | *(byte *)(param_1 + 0x26a) = bVar3; /* Find number of channels */ | } switch (png_ptr->color_type) | else if (local_45._1_1_ == '\x06') { { | bVar3 = (byte)local_45 << 2; default: /* invalid, png_set_IHDR calls png_error */ | uVar5 = (ulong)(byte)local_45 << 2; case PNG_COLOR_TYPE_GRAY: | *(undefined *)(param_1 + 0x26b) = 4; case PNG_COLOR_TYPE_PALETTE: | *(byte *)(param_1 + 0x26a) = bVar3; png_ptr->channels = 1; | } break; | else if (local_45._1_1_ == '\x02') { | uVar4 = (uint)(byte)local_45 + (uint)(byte)local_45 * 2; case PNG_COLOR_TYPE_RGB: | uVar5 = (ulong)uVar4; png_ptr->channels = 3; | *(undefined *)(param_1 + 0x26b) = 3; break; | bVar3 = (byte)uVar4; | *(byte *)(param_1 + 0x26a) = bVar3; case PNG_COLOR_TYPE_GRAY_ALPHA: | } png_ptr->channels = 2; | else { break; | *(undefined *)(param_1 + 0x26b) = 1; | *(byte *)(param_1 + 0x26a) = (byte)local_45; case PNG_COLOR_TYPE_RGB_ALPHA: | bVar3 = (byte)local_45; png_ptr->channels = 4; | } break; | if (bVar3 < 8) { } | uVar5 = (uVar5 & 0xff) * (ulong)uVar1 + 7 >> 3; | } /* Set up other useful info */ | else { png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); | uVar5 = (ulong)((byte)(uVar5 >> 3) & 0x1f) * (ulong)uVar1; png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); | } png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); | *(ulong *)(param_1 + 0x208) = uVar5; png_debug1(3, "channels = %d", png_ptr->channels); | png_set_IHDR(param_1,param_2,uVar1); png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); | if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) { png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, | return; color_type, interlace_type, compression_type, filter_type); | } } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } | /* WARNING: Subroutine does not return */ | png_chunk_error(param_1,"invalid"); | } =========================================================================== FUN_0011c3c0 =========================================================================== Real name: png_handle_pHYs OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid and | | calls the function pointed to, computes a CRC32 checksum of the given | | memory region, and calls the png_error/png_chunk_warning functions | | with an error message or warning if necessary. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2156 | Decompilation: FUN_0011c3c0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_pHYs_SUPPORTED | void FUN_0011c3c0(long param_1,long param_2,int param_3) void /* PRIVATE */ | png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | int iVar1; png_byte buf[9]; | long in_FS_OFFSET; png_uint_32 res_x, res_y; | byte local_29; int unit_type; | byte local_28; | byte local_27; png_debug(1, "in png_handle_pHYs"); | byte local_26; | byte local_25; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | byte local_24; png_chunk_error(png_ptr, "missing IHDR"); | byte local_23; | byte local_22; else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | undefined local_21; { | long local_20; png_crc_finish(png_ptr, length); | png_chunk_benign_error(png_ptr, "out of place"); | local_20 = *(long *)(in_FS_OFFSET + 0x28); return; | if ((*(uint *)(param_1 + 300) & 1) == 0) { } | /* WARNING: Subroutine does not return */ | png_chunk_error(param_1,"missing IHDR"); else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) | } { | if ((*(uint *)(param_1 + 300) & 4) == 0) { png_crc_finish(png_ptr, length); | if ((param_2 == 0) || ((*(byte *)(param_2 + 8) & 0x80) == 0)) { png_chunk_benign_error(png_ptr, "duplicate"); | if (param_3 == 9) { return; | FUN_00119cb0(param_1,&local_29,9); } | iVar1 = FUN_00119dc0(param_1,0); | if (iVar1 == 0) { if (length != 9) | png_set_pHYs(param_1,param_2, { | (uint)local_27 * 0x100 + png_crc_finish(png_ptr, length); | (uint)local_26 + (uint)local_28 * 0x10000 + (uint)local_29 * 0x1000000, png_chunk_benign_error(png_ptr, "invalid"); | (uint)local_23 * 0x100 + return; | (uint)local_24 * 0x10000 + (uint)local_25 * 0x1000000 + (uint)local_22, } | local_21); | } png_crc_read(png_ptr, buf, 9); | } | else { if (png_crc_finish(png_ptr, 0) != 0) | FUN_00119dc0(param_1); return; | png_chunk_benign_error(param_1,"invalid"); | } res_x = png_get_uint_32(buf); | } res_y = png_get_uint_32(buf + 4); | else { unit_type = buf[8]; | FUN_00119dc0(); png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); | png_chunk_benign_error(param_1,"duplicate"); } | } #endif | } | else { | FUN_00119dc0(); | png_chunk_benign_error(param_1,"out of place"); | } | if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) { | return; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_0011aa40 =========================================================================== Real name: png_handle_IEND OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks the validity of a pointer, calls the related | | function, computes a CRC32 checksum, and calls the | | png_error/png_chunk_warning functions with an error message or | | warning. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1100 | Decompilation: FUN_0011aa40 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_0011aa40(long param_1,undefined8 param_2,int param_3) png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { | { png_debug(1, "in png_handle_IEND"); | if ((*(uint *)(param_1 + 300) & 5) != 5) { | /* WARNING: Subroutine does not return */ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 || | png_chunk_error(param_1,"out of place"); (png_ptr->mode & PNG_HAVE_IDAT) == 0) | } png_chunk_error(png_ptr, "out of place"); | *(uint *)(param_1 + 300) = *(uint *)(param_1 + 300) | 0x18; | FUN_00119dc0(param_1,param_3); png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); | if (param_3 == 0) { | return; png_crc_finish(png_ptr, length); | } | png_chunk_benign_error(param_1,"invalid"); if (length != 0) | return; png_chunk_benign_error(png_ptr, "invalid"); | } | PNG_UNUSED(info_ptr) | } | =========================================================================== FUN_0011b820 =========================================================================== Real name: png_handle_sPLT OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, and calls the png_set_sPLT function with an error message or | | warning. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1641 | Decompilation: FUN_0011b820 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_sPLT_SUPPORTED | void FUN_0011b820(long param_1,undefined8 param_2,ulong param_3) void /* PRIVATE */ | png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { /* Note: this does not properly handle chunks that are > 64K under DOS */ | char cVar1; { | ulong uVar2; png_bytep entry_start, buffer; | int iVar3; png_sPLT_t new_palette; | char *pcVar4; png_sPLT_entryp pp; | ushort *puVar5; png_uint_32 data_length; | ushort *puVar6; int entry_size, i; | uint uVar7; png_uint_32 skip = 0; | byte *pbVar8; png_uint_32 dl; | char *pcVar9; size_t max_dl; | byte *pbVar10; | uint uVar11; png_debug(1, "in png_handle_sPLT"); | long in_FS_OFFSET; | char *local_58; #ifdef PNG_USER_LIMITS_SUPPORTED | char local_50; if (png_ptr->user_chunk_cache_max != 0) | ushort *local_48; { | int local_40; if (png_ptr->user_chunk_cache_max == 1) | long local_30; { | png_crc_finish(png_ptr, length); | param_3 = param_3 & 0xffffffff; return; | local_30 = *(long *)(in_FS_OFFSET + 0x28); } | iVar3 = *(int *)(param_1 + 0x42c); | if (iVar3 == 0) { if (--png_ptr->user_chunk_cache_max == 1) | LAB_0011b86e: { | if ((*(uint *)(param_1 + 300) & 1) == 0) { png_warning(png_ptr, "No space in chunk cache for sPLT"); | /* WARNING: Subroutine does not return */ png_crc_finish(png_ptr, length); | png_chunk_error(param_1,"missing IHDR"); return; | } } | if ((*(uint *)(param_1 + 300) & 4) == 0) { } | uVar11 = (uint)param_3; #endif | pcVar4 = (char *)FUN_00119a20(param_1,uVar11 + 1,2); | if (pcVar4 == (char *)0x0) { if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | FUN_00119dc0(param_1,param_3); png_chunk_error(png_ptr, "missing IHDR"); | png_chunk_benign_error(param_1,"out of memory"); | } else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | else { { | FUN_00119cb0(param_1,pcVar4,param_3); png_crc_finish(png_ptr, length); | iVar3 = FUN_00119dc0(param_1,0); png_chunk_benign_error(png_ptr, "out of place"); | if (iVar3 == 0) { return; | pcVar4[param_3] = '\0'; } | cVar1 = *pcVar4; | pcVar9 = pcVar4; #ifdef PNG_MAX_MALLOC_64K | while (cVar1 != '\0') { if (length > 65535U) | pcVar9 = pcVar9 + 1; { | cVar1 = *pcVar9; png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "too large to fit in memory"); | if ((uVar11 < 2) || (pcVar4 + (uVar11 - 2) < pcVar9 + 1)) { return; | png_warning(param_1,"malformed sPLT chunk"); } | } #endif | else { | local_50 = pcVar9[1]; buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); | pbVar10 = (byte *)(pcVar9 + 2); if (buffer == NULL) | uVar11 = uVar11 - ((int)pbVar10 - (int)pcVar4); { | uVar7 = (uint)(local_50 != '\b') * 4 + 6; png_crc_finish(png_ptr, length); | uVar2 = (ulong)uVar11 / (ulong)uVar7; png_chunk_benign_error(png_ptr, "out of memory"); | if (uVar11 % uVar7 == 0) { return; | local_40 = (int)uVar2; } | local_48 = (ushort *)png_malloc_warn(param_1,uVar2 * 10); | if (local_48 == (ushort *)0x0) { | png_warning(param_1,"sPLT chunk requires too much memory"); /* WARNING: this may break if size_t is less than 32 bits; it is assumed | } * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a | else { * potential breakage point if the types in pngconf.h aren't exactly right. | if (0 < local_40) { */ | puVar6 = local_48; png_crc_read(png_ptr, buffer, length); | do { | if (local_50 == '\b') { if (png_crc_finish(png_ptr, skip) != 0) | *puVar6 = (ushort)*pbVar10; return; | pbVar8 = pbVar10 + 4; | puVar6[1] = (ushort)pbVar10[1]; buffer[length] = 0; | puVar6[2] = (ushort)pbVar10[2]; | puVar6[3] = (ushort)pbVar10[3]; for (entry_start = buffer; *entry_start; entry_start++) | } /* Empty loop to find end of name */ ; | else { | *puVar6 = (ushort)*pbVar10 * 0x100 + (ushort)pbVar10[1]; ++entry_start; | puVar6[1] = (ushort)pbVar10[2] * 0x100 + (ushort)pbVar10[3]; | puVar6[2] = (ushort)pbVar10[4] * 0x100 + (ushort)pbVar10[5]; /* A sample depth should follow the separator, and we should be on it */ | pbVar8 = pbVar10 + 8; if (length < 2U || entry_start > buffer + (length - 2U)) | puVar6[3] = (ushort)pbVar10[6] * 0x100 + (ushort)pbVar10[7]; { | } png_warning(png_ptr, "malformed sPLT chunk"); | puVar5 = puVar6 + 5; return; | pbVar10 = pbVar8 + 2; } | puVar6[4] = (ushort)*pbVar8 * 0x100 + (ushort)pbVar8[1]; | puVar6 = puVar5; new_palette.depth = *entry_start++; | } while (local_48 + (ulong)(local_40 - 1) * 5 + 5 != puVar5); entry_size = (new_palette.depth == 8 ? 6 : 10); | } /* This must fit in a png_uint_32 because it is derived from the original | local_58 = pcVar4; * chunk data length. | png_set_sPLT(param_1,param_2,&local_58,1); */ | png_free(param_1,local_48); data_length = length - (png_uint_32)(entry_start - buffer); | } | } /* Integrity-check the data length */ | else { if ((data_length % (unsigned int)entry_size) != 0) | png_warning(param_1,"sPLT chunk has bad length"); { | } png_warning(png_ptr, "sPLT chunk has bad length"); | } return; | } } | } | } dl = (png_uint_32)(data_length / (unsigned int)entry_size); | else { max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); | FUN_00119dc0(param_1,param_3); | png_chunk_benign_error(param_1,"out of place"); if (dl > max_dl) | } { | } png_warning(png_ptr, "sPLT chunk too long"); | else { return; | if (iVar3 != 1) { } | *(int *)(param_1 + 0x42c) = iVar3 + -1; | if (iVar3 + -1 != 1) goto LAB_0011b86e; new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size); | png_warning(param_1,"No space in chunk cache for sPLT"); | } new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, | FUN_00119dc0(param_1,param_3); (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry))); | } | if (local_30 == *(long *)(in_FS_OFFSET + 0x28)) { if (new_palette.entries == NULL) | return; { | } png_warning(png_ptr, "sPLT chunk requires too much memory"); | /* WARNING: Subroutine does not return */ return; | __stack_chk_fail(); } | } | #ifdef PNG_POINTER_INDEXING_SUPPORTED | for (i = 0; i < new_palette.nentries; i++) | { | 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[i].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)buffer; | | png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); | | png_free(png_ptr, new_palette.entries); | } | #endif /* READ_sPLT */ | =========================================================================== FUN_001098a0 =========================================================================== Real name: png_colorspace_set_chromaticities OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function calculates the result of multiple divisions of integers, | | rounds it to the nearest integer, compares the result with a given | | array plus or minus a given parameter, and returns true if they are | | equal. | +------------------------------------------------------------------------+ libpng/png.c:1722 | Decompilation: FUN_001098a0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- int /* PRIVATE */ | undefined8 FUN_001098a0(undefined8 param_1,long param_2,undefined8 param_3,undefined4 param_4) png_colorspace_set_chromaticities(png_const_structrp png_ptr, | png_colorspacerp colorspace, const png_xy *xy, int preferred) | { { | int iVar1; /* We must check the end points to ensure they are reasonable - in the past | undefined8 uVar2; * color management systems have crashed as a result of getting bogus | long in_FS_OFFSET; * colorant values, while this isn't the fault of libpng it is the | undefined auStack88 [40]; * responsibility of libpng because PNG carries the bomb and libpng is in a | long local_30; * position to protect against it. | */ | local_30 = *(long *)(in_FS_OFFSET + 0x28); png_XYZ XYZ; | iVar1 = FUN_00109270(auStack88,param_3); | if (iVar1 == 0) { switch (png_colorspace_check_xy(&XYZ, xy)) | iVar1 = FUN_00108f30(auStack88,param_3); { | if (iVar1 == 0) { case 0: /* success */ | uVar2 = FUN_00106470(param_1,param_2,param_3,auStack88,param_4); return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, | goto LAB_001098f9; preferred); | } | } case 1: | if (iVar1 != 1) { /* We can't invert the chromaticities so we can't produce value XYZ | *(ushort *)(param_2 + 0x4a) = *(ushort *)(param_2 + 0x4a) | 0x8000; * values. Likely as not a color management system will fail too. | /* WARNING: Subroutine does not return */ */ | png_error(param_1,"internal error checking chromaticities"); colorspace->flags |= PNG_COLORSPACE_INVALID; | } png_benign_error(png_ptr, "invalid chromaticities"); | *(ushort *)(param_2 + 0x4a) = *(ushort *)(param_2 + 0x4a) | 0x8000; break; | png_benign_error(param_1,"invalid chromaticities"); | uVar2 = 0; default: | LAB_001098f9: /* libpng is broken; this should be a warning but if it happens we | if (local_30 == *(long *)(in_FS_OFFSET + 0x28)) { * want error reports so for the moment it is an error. | return uVar2; */ | } colorspace->flags |= PNG_COLORSPACE_INVALID; | /* WARNING: Subroutine does not return */ png_error(png_ptr, "internal error checking chromaticities"); | __stack_chk_fail(); } | } | return 0; /* failed */ | } | =========================================================================== FUN_0011d1c0 =========================================================================== Real name: png_handle_iTXt OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks the parameters, allocates a block of memory, | | copies data into it, computes a CRC32 checksum of the given memory | | region, and calls the appropriate function depending on the value of | | the bit and the value of the parameter. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2715 | Decompilation: FUN_0011d1c0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_iTXt_SUPPORTED | void FUN_0011d1c0(long param_1,undefined8 param_2,uint param_3) /* Note: this does not correctly handle chunks that are > 64K under DOS */ | void /* PRIVATE */ | { png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | char cVar1; { | int iVar2; png_const_charp errmsg = NULL; | uint uVar3; png_bytep buffer; | long lVar4; png_uint_32 prefix_length; | ulong uVar5; | char *pcVar6; png_debug(1, "in png_handle_iTXt"); | uint uVar7; | ulong uVar8; #ifdef PNG_USER_LIMITS_SUPPORTED | long in_FS_OFFSET; if (png_ptr->user_chunk_cache_max != 0) | bool bVar9; { | ulong local_80; if (png_ptr->user_chunk_cache_max == 1) | undefined4 local_78 [2]; { | long local_70; png_crc_finish(png_ptr, length); | long local_68; return; | undefined8 local_60; } | ulong local_58; | long local_50; if (--png_ptr->user_chunk_cache_max == 1) | long local_48; { | long local_40; png_crc_finish(png_ptr, length); | png_chunk_benign_error(png_ptr, "no space in chunk cache"); | local_40 = *(long *)(in_FS_OFFSET + 0x28); return; | iVar2 = *(int *)(param_1 + 0x42c); } | if (iVar2 != 0) { } | if (iVar2 == 1) { #endif | FUN_00119dc0(param_1,param_3); | goto LAB_0011d3d0; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | } png_chunk_error(png_ptr, "missing IHDR"); | *(int *)(param_1 + 0x42c) = iVar2 + -1; | if (iVar2 + -1 == 1) { if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | FUN_00119dc0(param_1,param_3); png_ptr->mode |= PNG_AFTER_IDAT; | png_chunk_benign_error(param_1,"no space in chunk cache"); | goto LAB_0011d3d0; buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); | } | } if (buffer == NULL) | uVar3 = *(uint *)(param_1 + 300); { | if ((uVar3 & 1) == 0) { png_crc_finish(png_ptr, length); | /* WARNING: Subroutine does not return */ png_chunk_benign_error(png_ptr, "out of memory"); | png_chunk_error(param_1,"missing IHDR"); return; | } } | if ((uVar3 & 4) != 0) { | *(uint *)(param_1 + 300) = uVar3 | 8; png_crc_read(png_ptr, buffer, length); | } | lVar4 = FUN_00119a20(param_1,param_3 + 1,1); if (png_crc_finish(png_ptr, 0) != 0) | if (lVar4 == 0) { return; | FUN_00119dc0(param_1,param_3); | png_chunk_benign_error(param_1,"out of memory"); /* First the keyword. */ | goto LAB_0011d3d0; for (prefix_length=0; | } prefix_length < length && buffer[prefix_length] != 0; | FUN_00119cb0(param_1,lVar4,param_3); ++prefix_length) | iVar2 = FUN_00119dc0(); /* Empty loop */ ; | if (iVar2 != 0) goto LAB_0011d3d0; | if (param_3 == 0) { /* Perform a basic check on the keyword length here. */ | LAB_0011d410: if (prefix_length > 79 || prefix_length < 1) | pcVar6 = "bad keyword"; errmsg = "bad keyword"; | } | else { /* Expect keyword, compression flag, compression type, language, translated | uVar5 = 0; * keyword (both may be empty but are 0 terminated) then the text, which may | do { * be empty. | uVar3 = (uint)uVar5; */ | if (*(char *)(lVar4 + uVar5) == '\0') { else if (prefix_length + 5 > length) | uVar7 = uVar3; errmsg = "truncated"; | uVar3 = uVar3 - 1; | break; else if (buffer[prefix_length+1] == 0 || | } (buffer[prefix_length+1] == 1 && | uVar7 = uVar3 + 1; buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) | bVar9 = uVar5 != param_3 - 1; { | uVar5 = uVar5 + 1; int compressed = buffer[prefix_length+1] != 0; | } while (bVar9); png_uint_32 language_offset, translated_keyword_offset; | if (0x4e < uVar3) goto LAB_0011d410; png_alloc_size_t uncompressed_length = 0; | uVar5 = (ulong)(uVar7 + 5); | if (param_3 < uVar7 + 5) goto LAB_0011d428; /* Now the language tag */ | cVar1 = *(char *)(lVar4 + (ulong)(uVar7 + 1)); prefix_length += 3; | if ((cVar1 == '\0') || language_offset = prefix_length; | ((pcVar6 = "bad compression info", cVar1 == '\x01' && | (*(char *)(lVar4 + (ulong)(uVar7 + 2)) == '\0')))) { for (; prefix_length < length && buffer[prefix_length] != 0; | local_80 = 0; ++prefix_length) | uVar3 = uVar7 + 3; /* Empty loop */ ; | pcVar6 = (char *)((ulong)uVar3 + lVar4); | uVar8 = (ulong)uVar3; /* WARNING: the length may be invalid here, this is checked below. */ | if (uVar3 < param_3) { translated_keyword_offset = ++prefix_length; | do { | iVar2 = (int)uVar8; for (; prefix_length < length && buffer[prefix_length] != 0; | uVar8 = (ulong)(iVar2 + 1U); ++prefix_length) | uVar5 = (ulong)(iVar2 + 2U); /* Empty loop */ ; | if (*pcVar6 == '\0') goto LAB_0011d31d; | pcVar6 = pcVar6 + 1; /* prefix_length should now be at the trailing '\0' of the translated | } while (iVar2 + 1U < param_3); * keyword, but it may already be over the end. None of this arithmetic | uVar8 = (ulong)(iVar2 + 2U); * can overflow because chunks are at most 2^31 bytes long, but on 16-bit | uVar5 = (ulong)(iVar2 + 3); * systems the available allocation may overflow. | } */ | else { ++prefix_length; | uVar8 = (ulong)(uVar7 + 4); | } if (compressed == 0 && prefix_length <= length) | LAB_0011d31d: uncompressed_length = length - prefix_length; | if ((uint)uVar8 < param_3) { | pcVar6 = (char *)(uVar8 + lVar4); else if (compressed != 0 && prefix_length < length) | uVar5 = uVar8; { | do { uncompressed_length = PNG_SIZE_MAX; | iVar2 = (int)uVar5; | uVar7 = iVar2 + 1; /* TODO: at present png_decompress_chunk imposes a single application | uVar5 = (ulong)uVar7; * level memory limit, this should be split to different values for | if (*pcVar6 == '\0') goto LAB_0011d349; * iCCP and text chunks. | pcVar6 = pcVar6 + 1; */ | } while (param_3 != uVar7); if (png_decompress_chunk(png_ptr, length, prefix_length, | uVar5 = (ulong)(iVar2 + 2); &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) | } buffer = png_ptr->read_buffer; | LAB_0011d349: | uVar7 = (uint)uVar5; else | if (cVar1 == '\0') { errmsg = png_ptr->zstream.msg; | if (param_3 < uVar7) { } | LAB_0011d428: | pcVar6 = "truncated"; else | goto LAB_0011d417; errmsg = "truncated"; | } | local_80 = (ulong)(param_3 - uVar7); if (errmsg == NULL) | local_78[0] = 1; { | *(undefined *)(local_80 + lVar4 + uVar5) = 0; png_text text; | local_68 = uVar5 + lVar4; | } buffer[uncompressed_length+prefix_length] = 0; | else { | if (param_3 <= uVar7) goto LAB_0011d428; if (compressed == 0) | local_80 = 0xffffffffffffffff; text.compression = PNG_ITXT_COMPRESSION_NONE; | iVar2 = FUN_0011a2b0(param_1,param_3,uVar5,&local_80); | if (iVar2 == 1) { else | lVar4 = *(long *)(param_1 + 0x460); text.compression = PNG_ITXT_COMPRESSION_zTXt; | } | else { text.key = (png_charp)buffer; | pcVar6 = *(char **)(param_1 + 0x170); text.lang = (png_charp)buffer + language_offset; | if (pcVar6 != (char *)0x0) goto LAB_0011d417; text.lang_key = (png_charp)buffer + translated_keyword_offset; | } text.text = (png_charp)buffer + prefix_length; | local_68 = uVar5 + lVar4; text.text_length = 0; | *(undefined *)(local_80 + local_68) = 0; text.itxt_length = uncompressed_length; | local_78[0] = 2; | } if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) | local_50 = (ulong)uVar3 + lVar4; errmsg = "insufficient memory"; | local_48 = lVar4 + uVar8; } | local_60 = 0; } | local_58 = local_80; | local_70 = lVar4; else | iVar2 = FUN_001200e0(param_1,param_2,local_78,1); errmsg = "bad compression info"; | pcVar6 = "insufficient memory"; | if (iVar2 == 0) goto LAB_0011d3d0; if (errmsg != NULL) | } png_chunk_benign_error(png_ptr, errmsg); | } } | LAB_0011d417: #endif | png_chunk_benign_error(param_1,pcVar6); | LAB_0011d3d0: | if (local_40 == *(long *)(in_FS_OFFSET + 0x28)) { | return; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_0011cf40 =========================================================================== Real name: png_handle_zTXt OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks the parameters, allocates a block of memory, | | copies data into it, inflates given data, initializes the zlib stream, | | sets an error message, and calls the appropriate function depending on | | the value of the bit and the value of the parameter. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2598 | Decompilation: FUN_0011cf40 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_zTXt_SUPPORTED | void FUN_0011cf40(long param_1,undefined8 param_2,uint param_3) /* Note: this does not correctly handle chunks that are > 64K under DOS */ | void /* PRIVATE */ | { png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | int iVar1; { | int iVar2; png_const_charp errmsg = NULL; | long lVar3; png_bytep buffer; | ulong uVar4; png_uint_32 keyword_length; | uint uVar5; | char *pcVar6; png_debug(1, "in png_handle_zTXt"); | ulong uVar7; | long in_FS_OFFSET; #ifdef PNG_USER_LIMITS_SUPPORTED | bool bVar8; if (png_ptr->user_chunk_cache_max != 0) | long local_70; { | undefined4 local_68 [2]; if (png_ptr->user_chunk_cache_max == 1) | long local_60; { | long local_58; png_crc_finish(png_ptr, length); | long local_50; return; | undefined8 local_48; } | undefined8 local_40; | undefined8 local_38; if (--png_ptr->user_chunk_cache_max == 1) | long local_30; { | png_crc_finish(png_ptr, length); | local_30 = *(long *)(in_FS_OFFSET + 0x28); png_chunk_benign_error(png_ptr, "no space in chunk cache"); | iVar1 = *(int *)(param_1 + 0x42c); return; | if (iVar1 != 0) { } | if (iVar1 == 1) { } | FUN_00119dc0(param_1,param_3); #endif | goto LAB_0011d030; | } if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | *(int *)(param_1 + 0x42c) = iVar1 + -1; png_chunk_error(png_ptr, "missing IHDR"); | if (iVar1 + -1 == 1) { | FUN_00119dc0(param_1,param_3); if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | png_chunk_benign_error(param_1,"no space in chunk cache"); png_ptr->mode |= PNG_AFTER_IDAT; | goto LAB_0011d030; | } /* Note, "length" is sufficient here; we won't be adding | } * a null terminator later. | uVar5 = *(uint *)(param_1 + 300); */ | if ((uVar5 & 1) == 0) { buffer = png_read_buffer(png_ptr, length, 2/*silent*/); | /* WARNING: Subroutine does not return */ | png_chunk_error(param_1,"missing IHDR"); if (buffer == NULL) | } { | if ((uVar5 & 4) != 0) { png_crc_finish(png_ptr, length); | *(uint *)(param_1 + 300) = uVar5 | 8; png_chunk_benign_error(png_ptr, "out of memory"); | } return; | lVar3 = FUN_00119a20(param_1,param_3,2); } | if (lVar3 == 0) { | FUN_00119dc0(param_1,param_3); png_crc_read(png_ptr, buffer, length); | png_chunk_benign_error(param_1,"out of memory"); | goto LAB_0011d030; if (png_crc_finish(png_ptr, 0) != 0) | } return; | FUN_00119cb0(param_1,lVar3,param_3); | iVar1 = FUN_00119dc0(param_1); /* TODO: also check that the keyword contents match the spec! */ | if (iVar1 != 0) goto LAB_0011d030; for (keyword_length = 0; | if (param_3 == 0) { keyword_length < length && buffer[keyword_length] != 0; | LAB_0011d070: ++keyword_length) | pcVar6 = "bad keyword"; /* Empty loop to find end of name */ ; | } | else { if (keyword_length > 79 || keyword_length < 1) | uVar4 = 0; errmsg = "bad keyword"; | do { | uVar5 = (uint)uVar4; /* zTXt must have some LZ data after the keyword, although it may expand to | if (*(char *)(lVar3 + uVar4) == '\0') { * zero bytes; we need a '\0' at the end of the keyword, the compression type | uVar7 = uVar4 & 0xffffffff; * then the LZ data: | uVar5 = uVar5 - 1; */ | break; else if (keyword_length + 3 > length) | } errmsg = "truncated"; | uVar7 = (ulong)(uVar5 + 1); | bVar8 = uVar4 != param_3 - 1; else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) | uVar4 = uVar4 + 1; errmsg = "unknown compression type"; | } while (bVar8); | if (0x4e < uVar5) goto LAB_0011d070; else | iVar1 = (int)uVar7; { | if (param_3 < iVar1 + 3U) { png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; | png_chunk_benign_error(param_1,"truncated"); | goto LAB_0011d030; /* TODO: at present png_decompress_chunk imposes a single application | } * level memory limit, this should be split to different values for iCCP | pcVar6 = "unknown compression type"; * and text chunks. | if (*(char *)(lVar3 + (ulong)(iVar1 + 1)) == '\0') { */ | local_70 = -1; if (png_decompress_chunk(png_ptr, length, keyword_length+2, | iVar2 = FUN_0011a2b0(param_1,param_3,iVar1 + 2U,&local_70); &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) | if (iVar2 == 1) { { | lVar3 = *(long *)(param_1 + 0x460); png_text text; | if (lVar3 == 0) { | pcVar6 = "Read failure in png_handle_zTXt"; if (png_ptr->read_buffer == NULL) | } errmsg="Read failure in png_handle_zTXt"; | else { else | *(undefined *)((ulong)(iVar1 + 2U) + lVar3 + local_70) = 0; { | local_58 = lVar3 + 2 + uVar7; /* It worked; png_ptr->read_buffer now looks like a tEXt chunk | local_68[0] = 0; * except for the extra compression type byte and the fact that | local_50 = local_70; * it isn't necessarily '\0' terminated. | local_48 = 0; */ | local_40 = 0; buffer = png_ptr->read_buffer; | local_38 = 0; buffer[uncompressed_length+(keyword_length+2)] = 0; | local_60 = lVar3; | iVar1 = FUN_001200e0(param_1,param_2,local_68,1); text.compression = PNG_TEXT_COMPRESSION_zTXt; | if (iVar1 == 0) goto LAB_0011d030; text.key = (png_charp)buffer; | pcVar6 = "insufficient memory"; text.text = (png_charp)(buffer + keyword_length+2); | } text.text_length = uncompressed_length; | } text.itxt_length = 0; | else { text.lang = NULL; | pcVar6 = *(char **)(param_1 + 0x170); text.lang_key = NULL; | if (pcVar6 == (char *)0x0) goto LAB_0011d030; | } if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) | } errmsg = "insufficient memory"; | } } | png_chunk_benign_error(param_1,pcVar6); } | LAB_0011d030: | if (local_30 != *(long *)(in_FS_OFFSET + 0x28)) { else | /* WARNING: Subroutine does not return */ errmsg = png_ptr->zstream.msg; | __stack_chk_fail(); } | } | return; if (errmsg != NULL) | } png_chunk_benign_error(png_ptr, errmsg); | } | #endif | =========================================================================== FUN_0011aab0 =========================================================================== Real name: png_handle_gAMA OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set and calls the appropriate function depending on the | | value of the bit and the value of the parameter, calculates an integer | | value from the bytes of an array, sets bits in a variable based on the | | value of a ushort at a given address, calls functions to compute a | | CRC32 checksum of the given memory region, calls functions to print | | errors or warnings, calculates the result of the division of two | | integers and checks if the value of param_1 is greater than 105000. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1120 | Decompilation: FUN_0011aab0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_gAMA_SUPPORTED | void FUN_0011aab0(long param_1,undefined8 param_2,int param_3) void /* PRIVATE */ | png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | int iVar1; png_fixed_point igamma; | undefined4 uVar2; png_byte buf[4]; | long in_FS_OFFSET; | undefined local_24 [4]; png_debug(1, "in png_handle_gAMA"); | long local_20; | if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | local_20 = *(long *)(in_FS_OFFSET + 0x28); png_chunk_error(png_ptr, "missing IHDR"); | if ((*(uint *)(param_1 + 300) & 1) == 0) { | /* WARNING: Subroutine does not return */ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) | png_chunk_error(param_1,"missing IHDR"); { | } png_crc_finish(png_ptr, length); | if ((*(uint *)(param_1 + 300) & 6) == 0) { png_chunk_benign_error(png_ptr, "out of place"); | if (param_3 == 4) { return; | FUN_00119cb0(param_1,local_24,4); } | iVar1 = FUN_00119dc0(param_1,0); | if (iVar1 == 0) { if (length != 4) | uVar2 = FUN_00119ae0(local_24); { | FUN_00109a40(param_1,param_1 + 0x4a0,uVar2); png_crc_finish(png_ptr, length); | FUN_00107970(param_1,param_2); png_chunk_benign_error(png_ptr, "invalid"); | } return; | } } | else { | FUN_00119dc0(param_1,param_3); png_crc_read(png_ptr, buf, 4); | png_chunk_benign_error(param_1,"invalid"); | } if (png_crc_finish(png_ptr, 0) != 0) | } return; | else { | FUN_00119dc0(param_1,param_3); igamma = png_get_fixed_point(NULL, buf); | png_chunk_benign_error(param_1,"out of place"); | } png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); | if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) { png_colorspace_sync(png_ptr, info_ptr); | return; } | } #endif | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_0011aff0 =========================================================================== Real name: png_handle_sRGB OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set, calls the function pointed to, computes a CRC32 | | checksum of the given memory region, sets bits in a variable, and | | calls the png_error/png_chunk_warning functions with an error message | | or warning, respectively. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1312 | Decompilation: FUN_0011aff0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_sRGB_SUPPORTED | void FUN_0011aff0(long param_1,undefined8 param_2,int param_3) void /* PRIVATE */ | png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | ushort uVar1; png_byte intent; | int iVar2; | long in_FS_OFFSET; png_debug(1, "in png_handle_sRGB"); | undefined local_21; | long local_20; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | png_chunk_error(png_ptr, "missing IHDR"); | local_20 = *(long *)(in_FS_OFFSET + 0x28); | if ((*(uint *)(param_1 + 300) & 1) == 0) { else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) | /* WARNING: Subroutine does not return */ { | png_chunk_error(param_1,"missing IHDR"); png_crc_finish(png_ptr, length); | } png_chunk_benign_error(png_ptr, "out of place"); | if ((*(uint *)(param_1 + 300) & 6) == 0) { return; | if (param_3 == 1) { } | FUN_00119cb0(param_1,&local_21,1); | iVar2 = FUN_00119dc0(param_1,0); if (length != 1) | if ((iVar2 == 0) && (uVar1 = *(ushort *)(param_1 + 0x4ea), -1 < (short)uVar1)) { { | if ((uVar1 & 4) == 0) { png_crc_finish(png_ptr, length); | FUN_00109ad0(param_1,param_1 + 0x4a0,local_21); png_chunk_benign_error(png_ptr, "invalid"); | FUN_00107970(param_1,param_2); return; | } } | else { | *(ushort *)(param_1 + 0x4ea) = uVar1 | 0x8000; png_crc_read(png_ptr, &intent, 1); | FUN_00107970(param_1,param_2); | png_chunk_benign_error(param_1,"too many profiles"); if (png_crc_finish(png_ptr, 0) != 0) | } return; | } | } /* If a colorspace error has already been output skip this chunk */ | else { if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) | FUN_00119dc0(param_1,param_3); return; | png_chunk_benign_error(param_1,"invalid"); | } /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect | } * this. | else { */ | FUN_00119dc0(param_1,param_3); if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0) | png_chunk_benign_error(param_1,"out of place"); { | } png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; | if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) { png_colorspace_sync(png_ptr, info_ptr); | return; png_chunk_benign_error(png_ptr, "too many profiles"); | } return; | /* WARNING: Subroutine does not return */ } | __stack_chk_fail(); | } (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); | png_colorspace_sync(png_ptr, info_ptr); | } | #endif /* READ_sRGB */ | =========================================================================== FUN_00109c50 =========================================================================== Real name: png_icc_set_sRGB OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a certain bit in a byte at a specified | | location is set, performs various checks and calculations depending on | | the bit and parameter values, and calls the appropriate function | | depending on the bit and parameter values, as well as checking for | | known incorrect sRGB profiles and known out-of-date sRGB profiles with | | no signature. | +------------------------------------------------------------------------+ libpng/png.c:2430 | Decompilation: FUN_00109c50 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void /* PRIVATE */ | void FUN_00109c50(long param_1,undefined8 param_2,byte *param_3,ulong param_4) png_icc_set_sRGB(png_const_structrp png_ptr, | png_colorspacerp colorspace, png_const_bytep profile, uLong adler) | { { | int iVar1; /* Is this profile one of the known ICC sRGB profiles? If it is, just set | ulong uVar2; * the sRGB information. | undefined8 uVar3; */ | ulong uVar4; if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) | int *piVar5; (void)png_colorspace_set_sRGB(png_ptr, colorspace, | uint uVar6; (int)/*already checked*/png_get_uint_32(profile+64)); | uint uVar7; } | int iVar8; #endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ | #endif /* sRGB */ | if (((*(uint *)(param_1 + 0x388) ^ 0x30) & 0x30) == 0) { | return; | } | uVar6 = 0x10000; | iVar8 = 0; | uVar7 = 0; | iVar1 = 0x29f83dde; | piVar5 = &DAT_0012a3c8; | do { | if (((((uint)param_3[0x56] * 0x100 + | (uint)param_3[0x57] + (uint)param_3[0x55] * 0x10000 + (uint)param_3[0x54] * 0x1000000 == | iVar1) && | ((uint)param_3[0x5a] * 0x100 + | (uint)param_3[0x5b] + (uint)param_3[0x59] * 0x10000 + (uint)param_3[0x58] * 0x1000000 == | piVar5[2])) && | ((uint)param_3[0x5e] * 0x100 + | (uint)param_3[0x5f] + (uint)param_3[0x5d] * 0x10000 + (uint)param_3[0x5c] * 0x1000000 == | piVar5[3])) && | ((uint)param_3[0x62] * 0x100 + | (uint)param_3[99] + (uint)param_3[0x61] * 0x10000 + (uint)param_3[0x60] * 0x1000000 == | piVar5[4])) { | if (iVar8 == 0) { | iVar8 = (uint)param_3[2] * 0x100 + | (uint)param_3[3] + (uint)param_3[1] * 0x10000 + (uint)*param_3 * 0x1000000; | uVar6 = (uint)param_3[0x42] * 0x100 + | (uint)param_3[0x43] + | (uint)param_3[0x41] * 0x10000 + (uint)param_3[0x40] * 0x1000000; | } | if ((*piVar5 == iVar8) && (*(ushort *)((long)piVar5 + 0x16) == uVar6)) { | if (param_4 == 0) { | uVar3 = adler32(0,0,0); | param_4 = adler32(uVar3,param_3,iVar8); | } | uVar2 = (ulong)uVar7; | if ((uint)(&DAT_0012a3c0)[uVar2 * 8] == param_4) { | uVar3 = crc32(0,0,0); | uVar4 = crc32(uVar3,param_3,iVar8); | if (uVar4 == (uint)(&DAT_0012a3c4)[uVar2 * 8]) { | if ((&DAT_0012a3dd)[uVar2 * 0x20] == '\0') { | if ((&DAT_0012a3dc)[uVar2 * 0x20] == '\0') { | FUN_0010b520(param_1,"out-of-date sRGB profile with no signature",0); | } | } | else { | FUN_0010b520(param_1,"known incorrect sRGB profile",2); | } | FUN_00109ad0(param_1,param_2, | (uint)param_3[0x42] * 0x100 + | (uint)param_3[0x43] + | (uint)param_3[0x41] * 0x10000 + (uint)param_3[0x40] * 0x1000000); | return; | } | } | FUN_0010b520(param_1,"Not recognizing known sRGB profile that has been edited",0); | return; | } | } | uVar7 = uVar7 + 1; | if (uVar7 == 7) { | return; | } | iVar1 = piVar5[9]; | piVar5 = piVar5 + 8; | } while( true ); | } =========================================================================== FUN_0011d520 =========================================================================== Real name: png_handle_unknown OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | The function FUN_0011d520 checks if a pointer at a given address is | | valid, calls the function pointed to, computes a CRC32 checksum of the | | given memory region, allocates memory for the pointer if necessary, | | calls the png_error/png_chunk_warning functions with an error message | | or warning, and saves unknown chunks. | +------------------------------------------------------------------------+ libpng/pngrutil.c:2925 | Decompilation: FUN_0011d520 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- /* Handle an unknown, or known but disabled, chunk */ | void FUN_0011d520(long param_1,undefined8 param_2,undefined4 param_3,int param_4) void /* PRIVATE */ | png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, | { png_uint_32 length, int keep) | long lVar1; { | int iVar2; int handled = 0; /* the chunk was handled */ | | if (*(long *)(param_1 + 0x3b8) == 0) { png_debug(1, "in png_handle_unknown"); | if (param_4 == 0) { | param_4 = *(int *)(param_1 + 0x3c0); #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED | } /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing | if (param_4 == 3) { * the bug which meant that setting a non-default behavior for a specific | iVar2 = FUN_00119eb0(param_1,param_3); * chunk would be ignored (the default was always used unless a user | if (iVar2 != 0) goto LAB_0011d579; * callback was installed). | } * | else if ((param_4 == 2) && ((*(byte *)(param_1 + 0x21b) & 0x20) != 0)) { * 'keep' is the value from the png_chunk_unknown_handling, the setting for | iVar2 = FUN_00119eb0(param_1,param_3); * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it | if (iVar2 != 0) goto LAB_0011d66a; * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. | } * This is just an optimization to avoid multiple calls to the lookup | else { * function. | FUN_00119dc0(); */ | LAB_0011d665: # ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED | if (param_4 == 2) { # ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED | LAB_0011d66a: keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); | if ((*(byte *)(param_1 + 0x21b) & 0x20) == 0) { # endif | lVar1 = *(long *)(param_1 + 0x440); # endif | goto joined_r0x0011d681; | } /* One of the following methods will read the chunk or skip it (at least one | goto LAB_0011d579; * of these is always defined because this is the only way to switch on | } * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) | } */ | } # ifdef PNG_READ_USER_CHUNKS_SUPPORTED | else { /* The user callback takes precedence over the chunk keep value, but the | iVar2 = FUN_00119eb0(param_1,param_3); * keep value is still required to validate a save of a critical chunk. | if (iVar2 != 0) { */ | iVar2 = (**(code **)(param_1 + 0x3b8))(param_1,param_1 + 0x438); if (png_ptr->read_user_chunk_fn != NULL) | if (iVar2 < 0) { { | /* WARNING: Subroutine does not return */ if (png_cache_unknown_chunk(png_ptr, length) != 0) | png_chunk_error(param_1,"error in user chunk"); { | } /* Callback to user unknown chunk handler */ | if (iVar2 != 0) goto LAB_0011d5ad; int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, | if (param_4 < 2) { &png_ptr->unknown_chunk); | if (*(int *)(param_1 + 0x3c0) < 2) { | png_chunk_warning(param_1,"Saving unknown chunk:"); /* ret is: | FUN_0010b470(param_1, * negative: An error occurred; png_chunk_error will be called. | "forcing save of an unhandled chunk; please call png_set_keep_unknown_chunks" * zero: The chunk was not handled, the chunk will be discarded | ); * unless png_set_keep_unknown_chunks has been used to set | } * a 'keep' behavior for this particular chunk, in which | goto LAB_0011d66a; * case that will be used. A critical chunk will cause an | } * error at this point unless it is to be saved. | if (param_4 != 3) goto LAB_0011d665; * positive: The chunk was handled, libpng will ignore/discard it. | LAB_0011d579: */ | iVar2 = *(int *)(param_1 + 0x42c); if (ret < 0) | if (iVar2 != 1) { png_chunk_error(png_ptr, "error in user chunk"); | if (iVar2 != 2) { | if (iVar2 != 0) { else if (ret == 0) | *(int *)(param_1 + 0x42c) = iVar2 + -1; { | } /* If the keep value is 'default' or 'never' override it, but | png_set_unknown_chunks(param_1,param_2,param_1 + 0x438,1); * still error out on critical chunks unless the keep value is | LAB_0011d5ad: * 'always' While this is weird it is the behavior in 1.4.12. | if (*(long *)(param_1 + 0x440) == 0) { * A possible improvement would be to obey the value set for the | return; * chunk, but this would be an API change that would probably | } * damage some applications. | png_free(param_1); * | *(undefined8 *)(param_1 + 0x440) = 0; * The png_app_warning below catches the case that matters, where | return; * the application has not set specific save or ignore for this | } * chunk or global save or ignore. | *(undefined4 *)(param_1 + 0x42c) = 1; */ | png_chunk_benign_error(param_1,"no space in chunk cache"); if (keep < PNG_HANDLE_CHUNK_IF_SAFE) | } { | } # ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED | } if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) | lVar1 = *(long *)(param_1 + 0x440); { | joined_r0x0011d681: png_chunk_warning(png_ptr, "Saving unknown chunk:"); | if (lVar1 != 0) { png_app_warning(png_ptr, | png_free(param_1); "forcing save of an unhandled chunk;" | *(undefined8 *)(param_1 + 0x440) = 0; " please call png_set_keep_unknown_chunks"); | } /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ | if ((*(byte *)(param_1 + 0x21b) & 0x20) != 0) { } | return; # endif | } keep = PNG_HANDLE_CHUNK_IF_SAFE; | /* WARNING: Subroutine does not return */ } | png_chunk_error(param_1,"unhandled critical chunk"); } | } | else /* chunk was handled */ | { | handled = 1; | /* Critical chunks can be safely discarded at this point. */ | keep = PNG_HANDLE_CHUNK_NEVER; | } | } | | else | keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ | } | | else | /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ | # endif /* READ_USER_CHUNKS */ | | # ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED | { | /* keep is currently just the per-chunk setting, if there was no | * setting change it to the global default now (not that this may | * still be AS_DEFAULT) then obtain the cache of the chunk if required, | * if not simply skip the chunk. | */ | if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) | keep = png_ptr->unknown_default; | | if (keep == PNG_HANDLE_CHUNK_ALWAYS || | (keep == PNG_HANDLE_CHUNK_IF_SAFE && | PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) | { | if (png_cache_unknown_chunk(png_ptr, length) == 0) | keep = PNG_HANDLE_CHUNK_NEVER; | } | | else | png_crc_finish(png_ptr, length); | } | # else | # ifndef PNG_READ_USER_CHUNKS_SUPPORTED | # error no method to support READ_UNKNOWN_CHUNKS | # endif | | { | /* If here there is no read callback pointer set and no support is | * compiled in to just save the unknown chunks, so simply skip this | * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then | * the app has erroneously asked for unknown chunk saving when there | * is no support. | */ | if (keep > PNG_HANDLE_CHUNK_NEVER) | png_app_error(png_ptr, "no unknown chunk support available"); | | png_crc_finish(png_ptr, length); | } | # endif | | # ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED | /* Now store the chunk in the chunk list if appropriate, and if the limits | * permit it. | */ | if (keep == PNG_HANDLE_CHUNK_ALWAYS || | (keep == PNG_HANDLE_CHUNK_IF_SAFE && | PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) | { | # ifdef PNG_USER_LIMITS_SUPPORTED | switch (png_ptr->user_chunk_cache_max) | { | case 2: | png_ptr->user_chunk_cache_max = 1; | png_chunk_benign_error(png_ptr, "no space in chunk cache"); | /* FALLTHROUGH */ | case 1: | /* NOTE: prior to 1.6.0 this case resulted in an unknown critical | * chunk being skipped, now there will be a hard error below. | */ | break; | | default: /* not at limit */ | --(png_ptr->user_chunk_cache_max); | /* FALLTHROUGH */ | case 0: /* no limit */ | # endif /* USER_LIMITS */ | /* Here when the limit isn't reached or when limits are compiled | * out; store the chunk. | */ | png_set_unknown_chunks(png_ptr, info_ptr, | &png_ptr->unknown_chunk, 1); | handled = 1; | # ifdef PNG_USER_LIMITS_SUPPORTED | break; | } | # endif | } | # else /* no store support: the chunk must be handled by the user callback */ | PNG_UNUSED(info_ptr) | # endif | | /* Regardless of the error handling below the cached data (if any) can be | * freed now. Notice that the data is not freed if there is a png_error, but | * it will be freed by destroy_read_struct. | */ | if (png_ptr->unknown_chunk.data != NULL) | png_free(png_ptr, png_ptr->unknown_chunk.data); | png_ptr->unknown_chunk.data = NULL; | | #else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ | /* There is no support to read an unknown chunk, so just skip it. */ | png_crc_finish(png_ptr, length); | PNG_UNUSED(info_ptr) | PNG_UNUSED(keep) | #endif /* !READ_UNKNOWN_CHUNKS */ | | /* Check for unhandled critical chunks */ | if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) | png_chunk_error(png_ptr, "unhandled critical chunk"); | } | =========================================================================== FUN_0011add0 =========================================================================== Real name: png_handle_cHRM OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks if a pointer at a given address is valid, calls | | the function pointed to, computes a CRC32 checksum of the given memory | | region, and sets bits in a variable based on the value of a ushort at | | a given address and stores the result in a second variable. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1240 | Decompilation: FUN_0011add0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_cHRM_SUPPORTED | void FUN_0011add0(long param_1,undefined8 param_2,int param_3) void /* PRIVATE */ | png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { { | ushort uVar1; png_byte buf[32]; | int iVar2; png_xy xy; | int iVar3; | int iVar4; png_debug(1, "in png_handle_cHRM"); | int iVar5; | int iVar6; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | int iVar7; png_chunk_error(png_ptr, "missing IHDR"); | int iVar8; | long in_FS_OFFSET; else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) | int local_78; { | int local_74; png_crc_finish(png_ptr, length); | int local_70; png_chunk_benign_error(png_ptr, "out of place"); | int local_6c; return; | int local_68; } | int local_64; | int local_60; if (length != 32) | int local_5c; { | undefined local_58 [4]; png_crc_finish(png_ptr, length); | undefined local_54 [4]; png_chunk_benign_error(png_ptr, "invalid"); | undefined local_50 [4]; return; | undefined local_4c [4]; } | undefined local_48 [4]; | undefined local_44 [4]; png_crc_read(png_ptr, buf, 32); | undefined local_40 [4]; | undefined local_3c [12]; if (png_crc_finish(png_ptr, 0) != 0) | long local_30; return; | | local_30 = *(long *)(in_FS_OFFSET + 0x28); xy.whitex = png_get_fixed_point(NULL, buf); | if ((*(uint *)(param_1 + 300) & 1) == 0) { xy.whitey = png_get_fixed_point(NULL, buf + 4); | /* WARNING: Subroutine does not return */ xy.redx = png_get_fixed_point(NULL, buf + 8); | png_chunk_error(param_1,"missing IHDR"); xy.redy = png_get_fixed_point(NULL, buf + 12); | } xy.greenx = png_get_fixed_point(NULL, buf + 16); | if ((*(uint *)(param_1 + 300) & 6) == 0) { xy.greeny = png_get_fixed_point(NULL, buf + 20); | if (param_3 == 0x20) { xy.bluex = png_get_fixed_point(NULL, buf + 24); | FUN_00119cb0(param_1,local_58,0x20); xy.bluey = png_get_fixed_point(NULL, buf + 28); | iVar2 = FUN_00119dc0(param_1); | if (iVar2 == 0) { if (xy.whitex == PNG_FIXED_ERROR || | iVar2 = FUN_00119ae0(local_58); xy.whitey == PNG_FIXED_ERROR || | local_60 = iVar2; xy.redx == PNG_FIXED_ERROR || | iVar3 = FUN_00119ae0(local_54); xy.redy == PNG_FIXED_ERROR || | local_5c = iVar3; xy.greenx == PNG_FIXED_ERROR || | iVar4 = FUN_00119ae0(local_50); xy.greeny == PNG_FIXED_ERROR || | local_78 = iVar4; xy.bluex == PNG_FIXED_ERROR || | iVar5 = FUN_00119ae0(local_4c); xy.bluey == PNG_FIXED_ERROR) | local_74 = iVar5; { | iVar6 = FUN_00119ae0(local_48); png_chunk_benign_error(png_ptr, "invalid values"); | local_70 = iVar6; return; | iVar7 = FUN_00119ae0(local_44); } | local_6c = iVar7; | iVar8 = FUN_00119ae0(local_40); /* If a colorspace error has already been output skip this chunk */ | local_68 = iVar8; if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) | local_64 = FUN_00119ae0(local_3c); return; | if (((((((iVar2 == -1 || iVar3 == -1) || iVar4 == -1) || iVar5 == -1) || iVar6 == -1) || | iVar7 == -1) || iVar8 == -1) || (local_64 == -1)) { if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0) | png_chunk_benign_error(param_1,"invalid values"); { | } png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; | else { png_colorspace_sync(png_ptr, info_ptr); | uVar1 = *(ushort *)(param_1 + 0x4ea); png_chunk_benign_error(png_ptr, "duplicate"); | if (-1 < (short)uVar1) { return; | if ((uVar1 & 0x10) == 0) { } | *(ushort *)(param_1 + 0x4ea) = uVar1 | 0x10; | FUN_001098a0(param_1,param_1 + 0x4a0,&local_78,1); png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; | FUN_00107970(param_1,param_2); (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, | } 1/*prefer cHRM values*/); | else { png_colorspace_sync(png_ptr, info_ptr); | *(ushort *)(param_1 + 0x4ea) = uVar1 | 0x8000; } | FUN_00107970(param_1,param_2); #endif | png_chunk_benign_error(param_1,"duplicate"); | } | } | } | } | } | else { | FUN_00119dc0(param_1,param_3); | png_chunk_benign_error(param_1,"invalid"); | } | } | else { | FUN_00119dc0(param_1,param_3); | png_chunk_benign_error(param_1,"out of place"); | } | if (local_30 == *(long *)(in_FS_OFFSET + 0x28)) { | return; | } | /* WARNING: Subroutine does not return */ | __stack_chk_fail(); | } =========================================================================== FUN_0011b110 =========================================================================== Real name: png_handle_iCCP OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | The code performs a variety of operations related to compressed data, | | including bit checking, calculations, memory allocation, setting error | | messages, checking pointer validity, function calling, and CRC32 | | checksum calculation, as well as various conversions. | +------------------------------------------------------------------------+ libpng/pngrutil.c:1363 | Decompilation: FUN_0011b110 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_READ_iCCP_SUPPORTED | void FUN_0011b110(long param_1,long param_2,uint param_3) void /* PRIVATE */ | png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) | { /* Note: this does not properly handle profiles that are > 64K under DOS */ | long lVar1; { | uint uVar2; png_const_charp errmsg = NULL; /* error message output, or no error */ | int iVar3; int finished = 0; /* crc checked */ | undefined4 *puVar4; | long lVar5; png_debug(1, "in png_handle_iCCP"); | ulong uVar6; | uint uVar7; if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | uint uVar8; png_chunk_error(png_ptr, "missing IHDR"); | uint uVar9; | undefined4 *puVar10; else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) | char *pcVar11; { | undefined4 *puVar12; png_crc_finish(png_ptr, length); | ulong uVar13; png_chunk_benign_error(png_ptr, "out of place"); | uint uVar14; return; | char *pcVar15; } | long in_FS_OFFSET; | byte bVar16; /* Consistent with all the above colorspace handling an obviously *invalid* | uint local_54c [3]; * chunk is just ignored, so does not invalidate the color space. An | ulong local_540; * alternative is to set the 'invalid' flags at the start of this routine | char local_538 [96]; * and only clear them in they were not set before and all the tests pass. | undefined local_4d8 [16]; */ | undefined local_4c8 [16]; | undefined local_4b8 [16]; /* The keyword must be at least one character and there is a | undefined local_4a8 [16]; * terminator (0) byte and the compression method byte, and the | undefined local_498 [16]; * 'zlib' datastream is at least 11 bytes. | undefined local_488 [16]; */ | undefined local_478 [16]; if (length < 14) | undefined local_468 [16]; { | uint local_458; png_crc_finish(png_ptr, length); | undefined local_448 [1032]; png_chunk_benign_error(png_ptr, "too short"); | long local_40; return; | } | bVar16 = 0; | local_40 = *(long *)(in_FS_OFFSET + 0x28); /* If a colorspace error has already been output skip this chunk */ | local_54c[0] = param_3; if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) | if ((*(uint *)(param_1 + 300) & 1) == 0) { { | /* WARNING: Subroutine does not return */ png_crc_finish(png_ptr, length); | png_chunk_error(param_1,"missing IHDR"); return; | } } | uVar7 = *(uint *)(param_1 + 300) & 6; | if (uVar7 != 0) { /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect | FUN_00119dc0(); * this. | png_chunk_benign_error(param_1,"out of place"); */ | goto LAB_0011b367; if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) | } { | if (param_3 < 0xe) { uInt read_length, keyword_length; | LAB_0011b350: char keyword[81]; | FUN_00119dc0(param_1); | png_chunk_benign_error(param_1,"too short"); /* Find the keyword; the keyword plus separator and compression method | goto LAB_0011b367; * bytes can be at most 81 characters long. | } */ | if ((short)*(ushort *)(param_1 + 0x4ea) < 0) { read_length = 81; /* maximum */ | FUN_00119dc0(); if (read_length > length) | goto LAB_0011b367; read_length = (uInt)length; | } | if ((*(ushort *)(param_1 + 0x4ea) & 4) != 0) { png_crc_read(png_ptr, (png_bytep)keyword, read_length); | pcVar15 = "too many profiles"; length -= read_length; | goto LAB_0011b3b7; | } /* The minimum 'zlib' stream is assumed to be just the 2 byte header, | uVar14 = 0x51; * 5 bytes minimum 'deflate' stream, and the 4 byte checksum. | if (param_3 < 0x51) { */ | uVar14 = param_3; if (length < 11) | } { | FUN_00119cb0(param_1,local_538,uVar14); png_crc_finish(png_ptr, length); | local_54c[0] = local_54c[0] - uVar14; png_chunk_benign_error(png_ptr, "too short"); | pcVar15 = local_538; return; | if (local_54c[0] < 0xb) goto LAB_0011b350; } | while (uVar8 = uVar7, *pcVar15 != '\0') { | uVar7 = uVar8 + 1; keyword_length = 0; | pcVar15 = pcVar15 + 1; while (keyword_length < 80 && keyword_length < read_length && | uVar9 = uVar8; keyword[keyword_length] != 0) | if ((0x4f < uVar7) || (uVar14 <= uVar7)) goto LAB_0011b1e1; ++keyword_length; | } | uVar9 = uVar8 - 1; /* TODO: make the keyword checking common */ | uVar7 = uVar8; if (keyword_length >= 1 && keyword_length <= 79) | LAB_0011b1e1: { | if (uVar9 < 0x4f) { /* We only understand '0' compression - deflate - so if we get a | pcVar15 = "bad compression method"; * different value we can't safely decode the chunk. | if (uVar14 <= uVar7 + 1) goto LAB_0011b3b7; */ | uVar6 = (ulong)(uVar7 + 1); if (keyword_length+1 < read_length && | pcVar15 = "bad compression method"; keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) | if (local_538[uVar6] != '\0') goto LAB_0011b3b7; { | iVar3 = FUN_00119890(param_1,0x69434350); read_length -= keyword_length+2; | if (iVar3 == 0) { | local_4d8 = (undefined [16])0x0; if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) | *(uint *)(param_1 + 0x148) = (uVar14 - 2) - uVar7; { | *(char **)(param_1 + 0x140) = local_538 + (uVar7 + 2); Byte profile_header[132]={0}; | local_458 = 0; Byte local_buffer[PNG_INFLATE_BUF_SIZE]; | local_540 = 0x84; png_alloc_size_t size = (sizeof profile_header); | local_4c8 = (undefined [16])0x0; | local_4b8 = (undefined [16])0x0; png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); | local_4a8 = (undefined [16])0x0; png_ptr->zstream.avail_in = read_length; | local_498 = (undefined [16])0x0; (void)png_inflate_read(png_ptr, local_buffer, | local_488 = (undefined [16])0x0; (sizeof local_buffer), &length, profile_header, &size, | local_478 = (undefined [16])0x0; 0/*finish: don't, because the output is too small*/); | local_468 = (undefined [16])0x0; | if (*(int *)(param_1 + 0x138) != *(int *)(param_1 + 0x218)) { if (size == 0) | *(char **)(param_1 + 0x170) = "zstream unclaimed"; { | LAB_0011b30a: /* We have the ICC profile header; do the basic header checks. | *(undefined4 *)(param_1 + 0x138) = 0; */ | pcVar15 = *(char **)(param_1 + 0x170); png_uint_32 profile_length = png_get_uint_32(profile_header); | goto LAB_0011b320; | } if (png_icc_check_length(png_ptr, &png_ptr->colorspace, | *(undefined **)(param_1 + 0x158) = local_4d8; keyword, profile_length) != 0) | *(undefined4 *)(param_1 + 0x160) = 0; { | FUN_0011a000(0,param_1,local_448,local_54c,&local_540,0); /* The length is apparently ok, so we can check the 132 | if (local_540 != 0) goto LAB_0011b30a; * byte header. | lVar1 = param_1 + 0x4a0; */ | uVar7 = (uint)local_4d8[0] * 0x1000000 + (uint)local_4d8[1] * 0x10000 + (uint)local_4d8[3] + if (png_icc_check_header(png_ptr, &png_ptr->colorspace, | (uint)local_4d8[2] * 0x100; keyword, profile_length, profile_header, | iVar3 = FUN_001079d0(param_1,lVar1,local_538); png_ptr->color_type) != 0) | if ((iVar3 == 0) || { | (iVar3 = FUN_00107a60(param_1,lVar1,local_538,uVar7,local_4d8, /* Now read the tag table; a variable size buffer is | *(undefined *)(param_1 + 0x267)), uVar14 = local_458, iVar3 == 0)) { * needed at this point, allocate one for the whole | LAB_0011b46a: * profile. The header check has already validated | *(undefined4 *)(param_1 + 0x138) = 0; * that none of this stuff will overflow. | FUN_00119dc0(param_1,local_54c[0]); */ | *(ushort *)(param_1 + 0x4ea) = *(ushort *)(param_1 + 0x4ea) | 0x8000; png_uint_32 tag_count = | FUN_00107970(param_1,param_2); png_get_uint_32(profile_header + 128); | goto LAB_0011b367; png_bytep profile = png_read_buffer(png_ptr, | } profile_length, 2/*silent*/); | uVar8 = local_458 >> 8; | uVar2 = local_458 >> 0x10; if (profile != NULL) | uVar9 = local_458 >> 0x18; { | puVar4 = (undefined4 *)FUN_00119a20(param_1,(ulong)uVar7,2); memcpy(profile, profile_header, | if (puVar4 == (undefined4 *)0x0) { (sizeof profile_header)); | *(undefined4 *)(param_1 + 0x138) = 0; | pcVar15 = "out of memory"; size = 12 * tag_count; | goto LAB_0011b3b7; | } (void)png_inflate_read(png_ptr, local_buffer, | puVar10 = (undefined4 *)local_4d8; (sizeof local_buffer), &length, | puVar12 = puVar4; profile + (sizeof profile_header), &size, 0); | for (lVar5 = 0x21; lVar5 != 0; lVar5 = lVar5 + -1) { | *puVar12 = *puVar10; /* Still expect a buffer error because we expect | puVar10 = puVar10 + (ulong)bVar16 * -2 + 1; * there to be some tag data! | puVar12 = puVar12 + (ulong)bVar16 * -2 + 1; */ | } if (size == 0) | uVar13 = (ulong)((uVar14 * 0x1000000 + (uVar8 & 0xff) * 0x10000 + uVar9 + { | (uVar2 & 0xff) * 0x100) * 0xc); if (png_icc_check_tag_table(png_ptr, | local_540 = uVar13; &png_ptr->colorspace, keyword, profile_length, | if (*(int *)(param_1 + 0x138) == *(int *)(param_1 + 0x218)) { profile) != 0) | *(undefined4 **)(param_1 + 0x158) = puVar4 + 0x21; { | *(undefined4 *)(param_1 + 0x160) = 0; /* The profile has been validated for basic | FUN_0011a000(param_1,local_448,local_54c,&local_540,0); * security issues, so read the whole thing in. | } */ | else { size = profile_length - (sizeof profile_header) | *(char **)(param_1 + 0x170) = "zstream unclaimed"; - 12 * tag_count; | } | if (local_540 != 0) goto LAB_0011b30a; (void)png_inflate_read(png_ptr, local_buffer, | iVar3 = FUN_00107e00(param_1,lVar1,local_538); (sizeof local_buffer), &length, | if (iVar3 == 0) goto LAB_0011b46a; profile + (sizeof profile_header) + | local_540 = ((ulong)uVar7 - 0x84) - uVar13; 12 * tag_count, &size, 1/*finish*/); | if (*(int *)(param_1 + 0x138) == *(int *)(param_1 + 0x218)) { | *(ulong *)(param_1 + 0x158) = (long)puVar4 + uVar13 + 0x84; if (length > 0 && !(png_ptr->flags & | *(undefined4 *)(param_1 + 0x160) = 0; PNG_FLAG_BENIGN_ERRORS_WARN)) | FUN_0011a000(param_1,local_448,local_54c,&local_540); errmsg = "extra compressed data"; | } | else { /* But otherwise allow extra data: */ | *(char **)(param_1 + 0x170) = "zstream unclaimed"; else if (size == 0) | } { | if (local_54c[0] == 0) { if (length > 0) | if (local_540 != 0) { { | LAB_0011b779: /* This can be handled completely, so | *(undefined4 *)(param_1 + 0x138) = 0; * keep going. | pcVar15 = *(char **)(param_1 + 0x170); */ | goto LAB_0011b320; png_chunk_warning(png_ptr, | } "extra compressed data"); | } } | else { | if ((*(byte *)(param_1 + 0x132) & 0x10) == 0) { png_crc_finish(png_ptr, length); | *(undefined4 *)(param_1 + 0x138) = 0; finished = 1; | pcVar15 = "extra compressed data"; | goto LAB_0011b3b7; # if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 | } /* Check for a match against sRGB */ | if (local_540 != 0) goto LAB_0011b779; png_icc_set_sRGB(png_ptr, | png_chunk_warning(param_1,"extra compressed data"); &png_ptr->colorspace, profile, | } png_ptr->zstream.adler); | FUN_00119dc0(param_1,local_54c[0]); # endif | FUN_00109c50(param_1,lVar1,puVar4,*(undefined8 *)(param_1 + 0x1a0)); | if (param_2 == 0) { /* Steal the profile for info_ptr. */ | LAB_0011b76a: if (info_ptr != NULL) | *(undefined4 *)(param_1 + 0x138) = 0; { | goto LAB_0011b367; png_free_data(png_ptr, info_ptr, | } PNG_FREE_ICCP, 0); | png_free_data(param_1,param_2,0x10,0); | pcVar15 = (char *)FUN_0010cbb0(param_1,uVar6); info_ptr->iccp_name = png_voidcast(char*, | *(char **)(param_2 + 0x80) = pcVar15; png_malloc_base(png_ptr, | if (pcVar15 != (char *)0x0) { keyword_length+1)); | *(uint *)(param_2 + 300) = *(uint *)(param_2 + 300) | 0x10; if (info_ptr->iccp_name != NULL) | *(uint *)(param_2 + 0x90) = uVar7; { | pcVar11 = local_538; memcpy(info_ptr->iccp_name, keyword, | for (; uVar6 != 0; uVar6 = uVar6 - 1) { keyword_length+1); | *pcVar15 = *pcVar11; info_ptr->iccp_proflen = | pcVar11 = pcVar11 + (ulong)bVar16 * -2 + 1; profile_length; | pcVar15 = pcVar15 + (ulong)bVar16 * -2 + 1; info_ptr->iccp_profile = profile; | } png_ptr->read_buffer = NULL; /*steal*/ | *(uint *)(param_2 + 8) = *(uint *)(param_2 + 8) | 0x1000; info_ptr->free_me |= PNG_FREE_ICCP; | *(undefined4 **)(param_2 + 0x88) = puVar4; info_ptr->valid |= PNG_INFO_iCCP; | *(undefined8 *)(param_1 + 0x460) = 0; } | FUN_00107970(param_1,param_2); | goto LAB_0011b76a; else | } { | *(ushort *)(param_1 + 0x4ea) = *(ushort *)(param_1 + 0x4ea) | 0x8000; png_ptr->colorspace.flags |= | pcVar15 = "out of memory"; PNG_COLORSPACE_INVALID; | FUN_00107970(param_1,param_2); errmsg = "out of memory"; | *(ushort *)(param_1 + 0x4ea) = *(ushort *)(param_1 + 0x4ea) | 0x8000; } | *(undefined4 *)(param_1 + 0x138) = 0; } | FUN_00107970(param_1,param_2); | } /* else the profile remains in the read | else { * buffer which gets reused for subsequent | pcVar15 = *(char **)(param_1 + 0x170); * chunks. | LAB_0011b320: */ | FUN_00119dc0(param_1,local_54c[0]); | *(ushort *)(param_1 + 0x4ea) = *(ushort *)(param_1 + 0x4ea) | 0x8000; if (info_ptr != NULL) | FUN_00107970(param_1,param_2); png_colorspace_sync(png_ptr, info_ptr); | if (pcVar15 == (char *)0x0) goto LAB_0011b367; | } if (errmsg == NULL) | } { | else { png_ptr->zowner = 0; | pcVar15 = "bad keyword"; return; | LAB_0011b3b7: } | FUN_00119dc0(param_1,local_54c[0]); } | *(ushort *)(param_1 + 0x4ea) = *(ushort *)(param_1 + 0x4ea) | 0x8000; if (errmsg == NULL) | FUN_00107970(param_1,param_2); errmsg = png_ptr->zstream.msg; | } } | png_chunk_benign_error(param_1,pcVar15); /* else png_icc_check_tag_table output an error */ | LAB_0011b367: } | if (local_40 != *(long *)(in_FS_OFFSET + 0x28)) { else /* profile truncated */ | /* WARNING: Subroutine does not return */ errmsg = png_ptr->zstream.msg; | __stack_chk_fail(); } | } | return; else | } errmsg = "out of memory"; | } | | /* else png_icc_check_header output an error */ | } | | /* else png_icc_check_length output an error */ | } | | else /* profile truncated */ | errmsg = png_ptr->zstream.msg; | | /* Release the stream */ | png_ptr->zowner = 0; | } | | else /* png_inflate_claim failed */ | errmsg = png_ptr->zstream.msg; | } | | else | errmsg = "bad compression method"; /* or missing */ | } | | else | errmsg = "bad keyword"; | } | | else | errmsg = "too many profiles"; | | /* Failure: the reason is in 'errmsg' */ | if (finished == 0) | png_crc_finish(png_ptr, length); | | png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; | png_colorspace_sync(png_ptr, info_ptr); | if (errmsg != NULL) /* else already output */ | png_chunk_benign_error(png_ptr, errmsg); | } | #endif /* READ_iCCP */ | ========================================================================== png_read_info =========================================================================== Real name: png_read_info OpenAI text-davinci-003 Summary +------------------------------------------------------------------------+ | This function checks the validity of a pointer, calls the related | | function, computes a CRC32 checksum, and calls the | | png_error/png_chunk_warning functions with an error message or | | warning, as well as setting various parameters for a PNG file. | +------------------------------------------------------------------------+ libpng/pngread.c:93 | Decompilation: png_read_info ------------------------------------------------------------------------------------------------------------------------------------------------------------------- #ifdef PNG_SEQUENTIAL_READ_SUPPORTED | void png_read_info(long param_1,long param_2) /* Read the information before the actual image data. This has been | * changed in v0.90 to allow reading a file that already has the magic | { * bytes read from the stream. You can tell libpng how many bytes have | undefined4 uVar1; * been read from the beginning of the stream (up to the maximum of 8) | uint uVar2; * via png_set_sig_bytes(), and we will only check the remaining bytes | int iVar3; * here. The application can then have access to the signature bytes we | int iVar4; * read if it is determined that this isn't a valid PNG file. | */ | if (param_1 == 0) { void PNGAPI | return; png_read_info(png_structrp png_ptr, png_inforp info_ptr) | } { | if (param_2 != 0) { #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED | FUN_00119be0(); int keep; | while( true ) { #endif | uVar1 = FUN_0011d820(param_1); | iVar3 = *(int *)(param_1 + 0x218); png_debug(1, "in png_read_info"); | uVar2 = *(uint *)(param_1 + 300); | if (iVar3 == 0x49444154) break; if (png_ptr == NULL || info_ptr == NULL) | if ((uVar2 & 4) != 0) { return; | *(uint *)(param_1 + 300) = uVar2 | 0x2008; | } /* Read and check the PNG file signature. */ | if (iVar3 == 0x49484452) { png_read_sig(png_ptr, info_ptr); | FUN_0011a560(param_1,param_2,uVar1); | } for (;;) | else if (iVar3 == 0x49454e44) { { | FUN_0011aa40(param_1,param_2,uVar1); png_uint_32 length = png_read_chunk_header(png_ptr); | } png_uint_32 chunk_name = png_ptr->chunk_name; | else { | iVar4 = FUN_001077c0(param_1,iVar3); /* IDAT logic needs to happen here to simplify getting the two flags | if (iVar4 == 0) { * right. | if (iVar3 == 0x504c5445) { */ | FUN_0011a760(param_1,param_2,uVar1); if (chunk_name == png_IDAT) | } { | else if (iVar3 == 0x624b4744) { if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) | FUN_0011bd80(param_1,param_2,uVar1); png_chunk_error(png_ptr, "Missing IHDR before IDAT"); | } | else if (iVar3 == 0x6348524d) { else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && | FUN_0011add0(param_1,param_2,uVar1); (png_ptr->mode & PNG_HAVE_PLTE) == 0) | } png_chunk_error(png_ptr, "Missing PLTE before IDAT"); | else if (iVar3 == 0x65584966) { | FUN_0011c040(param_1,param_2,uVar1); else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) | } png_chunk_benign_error(png_ptr, "Too many IDATs found"); | else if (iVar3 == 0x67414d41) { | FUN_0011aab0(param_1,param_2,uVar1); png_ptr->mode |= PNG_HAVE_IDAT; | } } | else if (iVar3 == 0x68495354) { | FUN_0011c240(param_1,param_2,uVar1); else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) | } { | else if (iVar3 == 0x6f464673) { png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; | FUN_0011c520(param_1,param_2,uVar1); png_ptr->mode |= PNG_AFTER_IDAT; | } } | else if (iVar3 == 0x7043414c) { | FUN_0011c6b0(param_1,param_2,uVar1); /* This should be a binary subdivision search or a hash for | } * matching the chunk name rather than a linear search. | else if (iVar3 == 0x7343414c) { */ | FUN_0011c9f0(param_1,param_2,uVar1); if (chunk_name == png_IHDR) | } png_handle_IHDR(png_ptr, info_ptr, length); | else if (iVar3 == 0x70485973) { | FUN_0011c3c0(param_1,param_2,uVar1); else if (chunk_name == png_IEND) | } png_handle_IEND(png_ptr, info_ptr, length); | else if (iVar3 == 0x73424954) { | FUN_0011aba0(param_1,param_2,uVar1); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED | } else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) | else if (iVar3 == 0x73524742) { { | FUN_0011aff0(param_1,param_2,uVar1); png_handle_unknown(png_ptr, info_ptr, length, keep); | } | else if (iVar3 == 0x69434350) { if (chunk_name == png_PLTE) | FUN_0011b110(param_1,param_2,uVar1); png_ptr->mode |= PNG_HAVE_PLTE; | } | else if (iVar3 == 0x73504c54) { else if (chunk_name == png_IDAT) | FUN_0011b820(param_1,param_2,uVar1); { | } png_ptr->idat_size = 0; /* It has been consumed */ | else if (iVar3 == 0x74455874) { break; | FUN_0011cd90(param_1,param_2,uVar1); } | } } | else if (iVar3 == 0x74494d45) { #endif | FUN_0011cc80(param_1,param_2,uVar1); else if (chunk_name == png_PLTE) | } png_handle_PLTE(png_ptr, info_ptr, length); | else if (iVar3 == 0x74524e53) { | FUN_0011bb10(param_1,param_2,uVar1); else if (chunk_name == png_IDAT) | } { | else if (iVar3 == 0x7a545874) { png_ptr->idat_size = length; | FUN_0011cf40(param_1,param_2,uVar1); break; | } } | else if (iVar3 == 0x69545874) { | FUN_0011d1c0(param_1,param_2,uVar1); #ifdef PNG_READ_bKGD_SUPPORTED | } else if (chunk_name == png_bKGD) | else { png_handle_bKGD(png_ptr, info_ptr, length); | FUN_0011d520(param_1,param_2,uVar1,0); #endif | } | } #ifdef PNG_READ_cHRM_SUPPORTED | else { else if (chunk_name == png_cHRM) | FUN_0011d520(param_1,param_2,uVar1,iVar4); png_handle_cHRM(png_ptr, info_ptr, length); | if (iVar3 == 0x504c5445) { #endif | *(uint *)(param_1 + 300) = *(uint *)(param_1 + 300) | 2; | } #ifdef PNG_READ_eXIf_SUPPORTED | } else if (chunk_name == png_eXIf) | } png_handle_eXIf(png_ptr, info_ptr, length); | } #endif | if ((uVar2 & 1) == 0) { | /* WARNING: Subroutine does not return */ #ifdef PNG_READ_gAMA_SUPPORTED | png_chunk_error(param_1,"Missing IHDR before IDAT"); else if (chunk_name == png_gAMA) | } png_handle_gAMA(png_ptr, info_ptr, length); | if ((*(char *)(param_1 + 0x267) == '\x03') && ((uVar2 & 2) == 0)) { #endif | /* WARNING: Subroutine does not return */ | png_chunk_error(param_1,"Missing PLTE before IDAT"); #ifdef PNG_READ_hIST_SUPPORTED | } else if (chunk_name == png_hIST) | if ((uVar2 & 8) != 0) { png_handle_hIST(png_ptr, info_ptr, length); | png_chunk_benign_error(param_1,"Too many IDATs found"); #endif | uVar2 = *(uint *)(param_1 + 300); | } #ifdef PNG_READ_oFFs_SUPPORTED | *(uint *)(param_1 + 300) = uVar2 | 4; else if (chunk_name == png_oFFs) | iVar3 = FUN_001077c0(param_1,0x49444154); png_handle_oFFs(png_ptr, info_ptr, length); | if (iVar3 != 0) { #endif | FUN_0011d520(param_1,param_2,uVar1,iVar3); | *(undefined4 *)(param_1 + 0x248) = 0; #ifdef PNG_READ_pCAL_SUPPORTED | return; else if (chunk_name == png_pCAL) | } png_handle_pCAL(png_ptr, info_ptr, length); | *(undefined4 *)(param_1 + 0x248) = uVar1; #endif | } | return; #ifdef PNG_READ_sCAL_SUPPORTED | } else if (chunk_name == png_sCAL) | png_handle_sCAL(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_pHYs_SUPPORTED | else if (chunk_name == png_pHYs) | png_handle_pHYs(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_sBIT_SUPPORTED | else if (chunk_name == png_sBIT) | png_handle_sBIT(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_sRGB_SUPPORTED | else if (chunk_name == png_sRGB) | png_handle_sRGB(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_iCCP_SUPPORTED | else if (chunk_name == png_iCCP) | png_handle_iCCP(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_sPLT_SUPPORTED | else if (chunk_name == png_sPLT) | png_handle_sPLT(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_tEXt_SUPPORTED | else if (chunk_name == png_tEXt) | png_handle_tEXt(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_tIME_SUPPORTED | else if (chunk_name == png_tIME) | png_handle_tIME(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_tRNS_SUPPORTED | else if (chunk_name == png_tRNS) | png_handle_tRNS(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_zTXt_SUPPORTED | else if (chunk_name == png_zTXt) | png_handle_zTXt(png_ptr, info_ptr, length); | #endif | | #ifdef PNG_READ_iTXt_SUPPORTED | else if (chunk_name == png_iTXt) | png_handle_iTXt(png_ptr, info_ptr, length); | #endif | | else | png_handle_unknown(png_ptr, info_ptr, length, | PNG_HANDLE_CHUNK_AS_DEFAULT); | } | } | #endif /* SEQUENTIAL_READ */ |