| 8648 | } |
| 8649 | |
| 8650 | bool basisu_lowlevel_etc1s_transcoder::transcode_image( |
| 8651 | transcoder_texture_format target_format, |
| 8652 | void* pOutput_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels, |
| 8653 | const uint8_t* pCompressed_data, uint32_t compressed_data_length, |
| 8654 | uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index, |
| 8655 | uint32_t rgb_offset, uint32_t rgb_length, uint32_t alpha_offset, uint32_t alpha_length, |
| 8656 | uint32_t decode_flags, |
| 8657 | bool basis_file_has_alpha_slices, |
| 8658 | bool is_video, |
| 8659 | uint32_t output_row_pitch_in_blocks_or_pixels, |
| 8660 | basisu_transcoder_state* pState, |
| 8661 | uint32_t output_rows_in_pixels) |
| 8662 | { |
| 8663 | if (((uint64_t)rgb_offset + rgb_length) > (uint64_t)compressed_data_length) |
| 8664 | { |
| 8665 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: source data buffer too small (color)\n"); |
| 8666 | return false; |
| 8667 | } |
| 8668 | |
| 8669 | if (alpha_length) |
| 8670 | { |
| 8671 | if (((uint64_t)alpha_offset + alpha_length) > (uint64_t)compressed_data_length) |
| 8672 | { |
| 8673 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: source data buffer too small (alpha)\n"); |
| 8674 | return false; |
| 8675 | } |
| 8676 | } |
| 8677 | else |
| 8678 | { |
| 8679 | assert(!basis_file_has_alpha_slices); |
| 8680 | } |
| 8681 | |
| 8682 | if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGB) || (target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA)) |
| 8683 | { |
| 8684 | if ((!basisu::is_pow2(num_blocks_x * 4)) || (!basisu::is_pow2(num_blocks_y * 4))) |
| 8685 | { |
| 8686 | // PVRTC1 only supports power of 2 dimensions |
| 8687 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: PVRTC1 only supports power of 2 dimensions\n"); |
| 8688 | return false; |
| 8689 | } |
| 8690 | } |
| 8691 | |
| 8692 | if ((target_format == transcoder_texture_format::cTFPVRTC1_4_RGBA) && (!basis_file_has_alpha_slices)) |
| 8693 | { |
| 8694 | // Switch to PVRTC1 RGB if the input doesn't have alpha. |
| 8695 | target_format = transcoder_texture_format::cTFPVRTC1_4_RGB; |
| 8696 | } |
| 8697 | |
| 8698 | const bool transcode_alpha_data_to_opaque_formats = (decode_flags & cDecodeFlagsTranscodeAlphaDataToOpaqueFormats) != 0; |
| 8699 | const uint32_t bytes_per_block_or_pixel = basis_get_bytes_per_block_or_pixel(target_format); |
| 8700 | const uint32_t total_slice_blocks = num_blocks_x * num_blocks_y; |
| 8701 | |
| 8702 | 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)) |
| 8703 | { |
| 8704 | BASISU_DEVEL_ERROR("basisu_lowlevel_etc1s_transcoder::transcode_image: output buffer size too small\n"); |
| 8705 | return false; |
| 8706 | } |
| 8707 |
no test coverage detected