| 8689 | } |
| 8690 | |
| 8691 | bool basisu_lowlevel_etc1s_transcoder::transcode_image( |
| 8692 | transcoder_texture_format target_format, |
| 8693 | void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, |
| 8694 | const uint8_t* pCompressed_data, uint32_t compressed_data_length, |
| 8695 | uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index, |
| 8696 | uint32_t rgb_offset, uint32_t rgb_length, uint32_t alpha_offset, uint32_t alpha_length, |
| 8697 | uint32_t decode_flags, |
| 8698 | bool basis_file_has_alpha_slices, |
| 8699 | bool is_video, |
| 8700 | uint32_t output_row_pitch_in_blocks_or_pixels, |
| 8701 | basisu_transcoder_state* pState, |
| 8702 | uint32_t output_rows_in_pixels) |
| 8703 | { |
| 8704 | if (((uint64_t)rgb_offset + rgb_length) > (uint64_t)compressed_data_length) |
| 8705 | { |
| 8706 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: source data buffer too small (color)\n"); |
| 8707 | return false; |
| 8708 | } |
| 8709 | |
| 8710 | if (alpha_length) |
| 8711 | { |
| 8712 | if (((uint64_t)alpha_offset + alpha_length) > (uint64_t)compressed_data_length) |
| 8713 | { |
| 8714 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: source data buffer too small (alpha)\n"); |
| 8715 | return false; |
| 8716 | } |
| 8717 | } |
| 8718 | else |
| 8719 | { |
| 8720 | assert(!basis_file_has_alpha_slices); |
| 8721 | } |
| 8722 | |
| 8723 | if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGB) || (target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)) |
| 8724 | { |
| 8725 | if ((!basisu::is_pow2(num_blocks_x * 4)) || (!basisu::is_pow2(num_blocks_y * 4))) |
| 8726 | { |
| 8727 | // PVRTC1 only supports power of 2 dimensions |
| 8728 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: PVRTC1 only supports power of 2 dimensions\n"); |
| 8729 | return false; |
| 8730 | } |
| 8731 | } |
| 8732 | |
| 8733 | if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA) && (!basis_file_has_alpha_slices)) |
| 8734 | { |
| 8735 | // Switch to PVRTC1 RGB if the input doesn't have alpha. |
| 8736 | target_format = transcoder_texture_format::cTFPVRTC1_4_RGB; |
| 8737 | } |
| 8738 | |
| 8739 | const bool transcode_alpha_data_to_opaque_formats = (decode_flags & cDecodeFlagsTranscodeAlphaDataToOpaqueFormats) != 0; |
| 8740 | const uint32_t bytes_per_block_or_pixel = basis_get_bytes_per_block_or_pixel(target_format); |
| 8741 | const uint32_t total_slice_blocks = num_blocks_x * num_blocks_y; |
| 8742 | |
| 8743 | if (!basis_validate_output_buffer_size(target_format, output_blocks_buf_size_in_blocks_or_pixels, orig_width, orig_height, output_row_pitch_in_blocks_or_pixels, output_rows_in_pixels, total_slice_blocks)) |
| 8744 | { |
| 8745 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: output buffer size too small\n"); |
| 8746 | return false; |
| 8747 | } |
| 8748 |
no test coverage detected