| // basisu_dds_export.h |
| // Copyright (C) 2019-2025 Binomial LLC. All Rights Reserved. |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| // Basic DX10-style .DDS writer for basisu_tool's -dds command. It consumes the prepared source image |
| // slices from a basis_compressor that has been run in process_source_images() mode (so all the image |
| // loading, mipmap generation, and cubemap/array layout is done by the encoder), then packs each slice |
| // into the requested output format and writes a modern DX10 (DDS_HEADER_DXT10) .dds file. |
| // |
| // Supported -dds_format tokens (see parse_dds_output_format): |
| // Block compressed: bc1 bc2 bc3 bc4 bc5 bc7 |
| // Uncompressed: a8r8g8b8 r8 r8g8 r5g6b5 a1r5g5b5 a4r4g4b4 |
| // |
| // The sRGB-vs-UNORM DXGI variant is selected from the compressor's transfer function flag |
| // (m_ktx2_and_basis_srgb_transfer_function, set by -srgb/-photo/-linear); only bc1/bc2/bc3/bc7/a8r8g8b8/a8b8g8r8 |
| // have an sRGB DXGI variant, the rest are always written as UNORM. No transfer-function conversion is |
| // ever applied to the texel data - we only pick the format tag and pack the bytes as-is. |
| #pragma once |
| |
| #include <string> |
| #include "../transcoder/basisu.h" // for basisu::uint8_vec |
| |
| namespace basisu |
| { |
| class basis_compressor; |
| |
| // The output formats supported by the -dds command. |
| enum dds_output_format |
| { |
| cDDSFmtInvalid = -1, |
| |
| // Block compressed (packed with the real-time BC encoders). |
| cDDSFmtBC1, |
| cDDSFmtBC2, |
| cDDSFmtBC3, |
| cDDSFmtBC4, |
| cDDSFmtBC5, |
| cDDSFmtBC7, |
| |
| // Uncompressed (simple pixel format conversion). |
| cDDSFmtA8R8G8B8, // DXGI B8G8R8A8 (32bpp, BGRA in memory), has sRGB variant |
| cDDSFmtA8B8G8R8, // DXGI R8G8B8A8 (32bpp, RGBA in memory), has sRGB variant |
| cDDSFmtR8, // DXGI R8 (8bpp) |
| cDDSFmtR8G8, // DXGI R8G8 (16bpp), source R->R, source G->G (like BC5) |
| cDDSFmtR5G6B5, // DXGI B5G6R5 (16bpp) |
| cDDSFmtA1R5G5B5, // DXGI B5G5R5A1 (16bpp) |
| cDDSFmtA4R4G4B4, // DXGI B4G4R4A4 (16bpp) |
| |
| cDDSFmtTotal |
| }; |
| |
| // Parses a -dds_format token (case-insensitive) into a dds_output_format. Returns false (and sets |
| // fmt to cDDSFmtInvalid) on an unrecognized token. |
| bool parse_dds_output_format(const char* pToken, dds_output_format& fmt); |
| |
| // Returns the canonical token string for a format (for messages), or "?" if invalid. |
| const char* get_dds_output_format_string(dds_output_format fmt); |
| |
| // True if the format has a distinct sRGB DXGI variant (bc1/bc3/bc7/a8r8g8b8); false for the formats |
| // that are always written UNORM. Lets a caller report the actually-emitted variant accurately. |
| bool dds_output_format_has_srgb_variant(dds_output_format fmt); |
| |
| // Which BC7 base packer to use for bc7 output. (Eventually a third encoder may be added.) |
| enum dds_bc7_encoder |
| { |
| cDDSBC7Encoder_Default = -1, // "not specified" sentinel (CLI use); resolves to the dds_export_params default |
| cDDSBC7Encoder_BC7F = 0, // built-in fast real-time packer (basist::bc7f), default |
| cDDSBC7Encoder_BC7E_Scalar = 1 // higher-quality (slower) scalar bc7e encoder |
| }; |
| |
| // bc7f quality level -> which analytical mode flags the bc7f packer uses (higher = slower/better). |
| enum dds_bc7f_level |
| { |
| cDDSBC7FLevel_Analytical = 0, // cPackBC7FlagDefault |
| cDDSBC7FLevel_PartiallyAnalytical = 1, // cPackBC7FlagDefaultPartiallyAnalytical (default) |
| cDDSBC7FLevel_NonAnalytical = 2 // cPackBC7FlagDefaultNonAnalytical (slowest/best) |
| }; |
| |
| // Input parameters for build_dds(). Intended to grow as more -dds options are added (BC1 quality, etc.). |
| struct dds_export_params |
| { |
| dds_output_format m_format; |
| |
| // BC7-only knobs (ignored for non-bc7 formats): |
| dds_bc7_encoder m_bc7_encoder; // which BC7 base packer |
| int m_bc7f_level; // dds_bc7f_level [0,2]: analytical / partially / non analytical (bc7f only) |
| int m_bc7e_scalar_level; // bc7e_scalar quality level [0,6], 0=ultrafast..6=slowest (bc7e_scalar only) |
| |
| dds_export_params() |
| : m_format(cDDSFmtInvalid), |
| m_bc7_encoder(cDDSBC7Encoder_BC7F), |
| m_bc7f_level(cDDSBC7FLevel_PartiallyAnalytical), |
| m_bc7e_scalar_level(2) |
| { } |
| explicit dds_export_params(dds_output_format format) |
| : m_format(format), |
| m_bc7_encoder(cDDSBC7Encoder_BC7F), |
| m_bc7f_level(cDDSBC7FLevel_PartiallyAnalytical), |
| m_bc7e_scalar_level(2) |
| { } |
| }; |
| |
| // Builds an in-memory DX10 .dds file from the prepared slices of comp (which must have had a successful |
| // process_source_images() call) into dds_data (which is resize(0)'d first, then appended to). The caller |
| // is responsible for writing dds_data out (or using it however it likes). Picks the UNORM vs sRGB DXGI |
| // variant from comp's transfer function flag. On failure returns false and sets error_msg. On success, |
| // the optional out_* values report the texture's dimensions/structure (for a caller summary). |
| bool build_dds(uint8_vec& dds_data, const basis_compressor& comp, const dds_export_params& params, |
| std::string& error_msg, |
| uint32_t* pOut_width = nullptr, uint32_t* pOut_height = nullptr, |
| uint32_t* pOut_levels = nullptr, uint32_t* pOut_layers = nullptr, uint32_t* pOut_faces = nullptr); |
| |
| } // namespace basisu |