| 1 | /* ----------------------------------------------------------------------------- |
| 2 | |
| 3 | Copyright (c) 2006 Simon Brown si@sjbrown.co.uk |
| 4 | |
| 5 | Permission is hereby granted, free of charge, to any person obtaining |
| 6 | a copy of this software and associated documentation files (the |
| 7 | "Software"), to deal in the Software without restriction, including |
| 8 | without limitation the rights to use, copy, modify, merge, publish, |
| 9 | distribute, sublicense, and/or sell copies of the Software, and to |
| 10 | permit persons to whom the Software is furnished to do so, subject to |
| 11 | the following conditions: |
| 12 | |
| 13 | The above copyright notice and this permission notice shall be included |
| 14 | in all copies or substantial portions of the Software. |
| 15 | |
| 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 17 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 23 | |
| 24 | -------------------------------------------------------------------------- */ |
| 25 | |
| 26 | #ifndef SQUISH_H |
| 27 | #define SQUISH_H |
| 28 | |
| 29 | //! All squish API functions live in this namespace. |
| 30 | namespace squish { |
| 31 | |
| 32 | // ----------------------------------------------------------------------------- |
| 33 | |
| 34 | //! Typedef a quantity that is a single unsigned byte. |
| 35 | typedef unsigned char u8; |
| 36 | |
| 37 | // ----------------------------------------------------------------------------- |
| 38 | |
| 39 | enum |
| 40 | { |
| 41 | //! Use DXT1 compression. |
| 42 | kDxt1 = ( 1 << 0 ), |
| 43 | |
| 44 | //! Use DXT3 compression. |
| 45 | kDxt3 = ( 1 << 1 ), |
| 46 | |
| 47 | //! Use DXT5 compression. |
| 48 | kDxt5 = ( 1 << 2 ), |
| 49 | |
| 50 | //! Use BC4 compression. |
| 51 | kBc4 = ( 1 << 3 ), |
| 52 | |
| 53 | //! Use BC5 compression. |
| 54 | kBc5 = ( 1 << 4 ), |
| 55 | |
| 56 | //! Use a slow but high quality colour compressor (the default). |
| 57 | kColourClusterFit = ( 1 << 5 ), |
| 58 | |
| 59 | //! Use a fast but low quality colour compressor. |
| 60 | kColourRangeFit = ( 1 << 6 ), |
| 61 | |
| 62 | //! Weight the colour by alpha during cluster fit (disabled by default). |
| 63 | kWeightColourByAlpha = ( 1 << 7 ), |
| 64 | |
| 65 | //! Use a very slow but very high quality colour compressor. |
| 66 | kColourIterativeClusterFit = ( 1 << 8 ), |
| 67 | |
| 68 | //! Source is BGRA rather than RGBA |
| 69 | kSourceBGRA = ( 1 << 9 ) |
| 70 | }; |
| 71 | |
| 72 | // ----------------------------------------------------------------------------- |
| 73 | |
| 74 | /*! @brief Compresses a 4x4 block of pixels. |
| 75 | |
| 76 | @param rgba The rgba values of the 16 source pixels. |
| 77 | @param mask The valid pixel mask. |
| 78 | @param block Storage for the compressed DXT block. |
| 79 | @param flags Compression flags. |
| 80 | @param metric An optional perceptual metric. |
| 81 | |
| 82 | The source pixels should be presented as a contiguous array of 16 rgba |
| 83 | values, with each component as 1 byte each. In memory this should be: |
| 84 | |
| 85 | { r1, g1, b1, a1, .... , r16, g16, b16, a16 } |
| 86 | |
| 87 | The mask parameter enables only certain pixels within the block. The lowest |
| 88 | bit enables the first pixel and so on up to the 16th bit. Bits beyond the |
| 89 | 16th bit are ignored. Pixels that are not enabled are allowed to take |
| 90 | arbitrary colours in the output block. An example of how this can be used |
| 91 | is in the CompressImage function to disable pixels outside the bounds of |
| 92 | the image when the width or height is not divisible by 4. |
| 93 | |
| 94 | The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, |
| 95 | however, DXT1 will be used by default if none is specified. When using DXT1 |
| 96 | compression, 8 bytes of storage are required for the compressed DXT block. |
| 97 | DXT3 and DXT5 compression require 16 bytes of storage per block. |
| 98 | |
| 99 | The flags parameter can also specify a preferred colour compressor to use |
| 100 | when fitting the RGB components of the data. Possible colour compressors |
| 101 | are: kColourClusterFit (the default), kColourRangeFit (very fast, low |
| 102 | quality) or kColourIterativeClusterFit (slowest, best quality). |
| 103 | |
| 104 | When using kColourClusterFit or kColourIterativeClusterFit, an additional |
| 105 | flag can be specified to weight the importance of each pixel by its alpha |
| 106 | value. For images that are rendered using alpha blending, this can |
| 107 | significantly increase the perceived quality. |
| 108 | |
| 109 | The metric parameter can be used to weight the relative importance of each |
| 110 | colour channel, or pass NULL to use the default uniform weight of |
| 111 | { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that |
| 112 | allowed either uniform or "perceptual" weights with the fixed values |
| 113 | { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a |
| 114 | contiguous array of 3 floats. |
| 115 | */ |
| 116 | void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric = 0 ); |
| 117 | |
| 118 | // ----------------------------------------------------------------------------- |
| 119 | |
| 120 | /*! @brief Compresses a 4x4 block of pixels. |
| 121 | |
| 122 | @param rgba The rgba values of the 16 source pixels. |
| 123 | @param block Storage for the compressed DXT block. |
| 124 | @param flags Compression flags. |
| 125 | @param metric An optional perceptual metric. |
| 126 | |
| 127 | The source pixels should be presented as a contiguous array of 16 rgba |
| 128 | values, with each component as 1 byte each. In memory this should be: |
| 129 | |
| 130 | { r1, g1, b1, a1, .... , r16, g16, b16, a16 } |
| 131 | |
| 132 | The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, |
| 133 | however, DXT1 will be used by default if none is specified. When using DXT1 |
| 134 | compression, 8 bytes of storage are required for the compressed DXT block. |
| 135 | DXT3 and DXT5 compression require 16 bytes of storage per block. |
| 136 | |
| 137 | The flags parameter can also specify a preferred colour compressor to use |
| 138 | when fitting the RGB components of the data. Possible colour compressors |
| 139 | are: kColourClusterFit (the default), kColourRangeFit (very fast, low |
| 140 | quality) or kColourIterativeClusterFit (slowest, best quality). |
| 141 | |
| 142 | When using kColourClusterFit or kColourIterativeClusterFit, an additional |
| 143 | flag can be specified to weight the importance of each pixel by its alpha |
| 144 | value. For images that are rendered using alpha blending, this can |
| 145 | significantly increase the perceived quality. |
| 146 | |
| 147 | The metric parameter can be used to weight the relative importance of each |
| 148 | colour channel, or pass NULL to use the default uniform weight of |
| 149 | { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that |
| 150 | allowed either uniform or "perceptual" weights with the fixed values |
| 151 | { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a |
| 152 | contiguous array of 3 floats. |
| 153 | |
| 154 | This method is an inline that calls CompressMasked with a mask of 0xffff, |
| 155 | provided for compatibility with older versions of squish. |
| 156 | */ |
| 157 | inline void Compress( u8 const* rgba, void* block, int flags, float* metric = 0 ) |
| 158 | { |
| 159 | CompressMasked( rgba, 0xffff, block, flags, metric ); |
| 160 | } |
| 161 | |
| 162 | // ----------------------------------------------------------------------------- |
| 163 | |
| 164 | /*! @brief Decompresses a 4x4 block of pixels. |
| 165 | |
| 166 | @param rgba Storage for the 16 decompressed pixels. |
| 167 | @param block The compressed DXT block. |
| 168 | @param flags Compression flags. |
| 169 | |
| 170 | The decompressed pixels will be written as a contiguous array of 16 rgba |
| 171 | values, with each component as 1 byte each. In memory this is: |
| 172 | |
| 173 | { r1, g1, b1, a1, .... , r16, g16, b16, a16 } |
| 174 | |
| 175 | The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, |
| 176 | however, DXT1 will be used by default if none is specified. All other flags |
| 177 | are ignored. |
| 178 | */ |
| 179 | void Decompress( u8* rgba, void const* block, int flags ); |
| 180 | |
| 181 | // ----------------------------------------------------------------------------- |
| 182 | |
| 183 | /*! @brief Computes the amount of compressed storage required. |
| 184 | |
| 185 | @param width The width of the image. |
| 186 | @param height The height of the image. |
| 187 | @param flags Compression flags. |
| 188 | |
| 189 | The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, |
| 190 | however, DXT1 will be used by default if none is specified. All other flags |
| 191 | are ignored. |
| 192 | |
| 193 | Most DXT images will be a multiple of 4 in each dimension, but this |
| 194 | function supports arbitrary size images by allowing the outer blocks to |
| 195 | be only partially used. |
| 196 | */ |
| 197 | int GetStorageRequirements( int width, int height, int flags ); |
| 198 | |
| 199 | // ----------------------------------------------------------------------------- |
| 200 | |
| 201 | /*! @brief Compresses an image in memory. |
| 202 | |
| 203 | @param rgba The pixels of the source. |
| 204 | @param width The width of the source image. |
| 205 | @param height The height of the source image. |
| 206 | @param pitch The pitch of the source image. |
| 207 | @param blocks Storage for the compressed output. |
| 208 | @param flags Compression flags. |
| 209 | @param metric An optional perceptual metric. |
| 210 | |
| 211 | The source pixels should be presented as a contiguous array of width*height |
| 212 | rgba values, with each component as 1 byte each. In memory this should be: |
| 213 | |
| 214 | { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height |
| 215 | |
| 216 | The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, |
| 217 | however, DXT1 will be used by default if none is specified. When using DXT1 |
| 218 | compression, 8 bytes of storage are required for each compressed DXT block. |
| 219 | DXT3 and DXT5 compression require 16 bytes of storage per block. |
| 220 | |
| 221 | The flags parameter can also specify a preferred colour compressor to use |
| 222 | when fitting the RGB components of the data. Possible colour compressors |
| 223 | are: kColourClusterFit (the default), kColourRangeFit (very fast, low |
| 224 | quality) or kColourIterativeClusterFit (slowest, best quality). |
| 225 | |
| 226 | When using kColourClusterFit or kColourIterativeClusterFit, an additional |
| 227 | flag can be specified to weight the importance of each pixel by its alpha |
| 228 | value. For images that are rendered using alpha blending, this can |
| 229 | significantly increase the perceived quality. |
| 230 | |
| 231 | The metric parameter can be used to weight the relative importance of each |
| 232 | colour channel, or pass NULL to use the default uniform weight of |
| 233 | { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that |
| 234 | allowed either uniform or "perceptual" weights with the fixed values |
| 235 | { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a |
| 236 | contiguous array of 3 floats. |
| 237 | |
| 238 | Internally this function calls squish::CompressMasked for each block, which |
| 239 | allows for pixels outside the image to take arbitrary values. The function |
| 240 | squish::GetStorageRequirements can be called to compute the amount of memory |
| 241 | to allocate for the compressed output. |
| 242 | |
| 243 | Note on compression quality: When compressing textures with |
| 244 | libsquish it is recommended to apply a gamma-correction |
| 245 | beforehand. This will reduce the blockiness in dark areas. The |
| 246 | level of necessary gamma-correction is platform dependent. For |
| 247 | example, a gamma correction with gamma = 0.5 before compression |
| 248 | and gamma = 2.0 after decompression yields good results on the |
| 249 | Windows platform but for other platforms like MacOS X a different |
| 250 | gamma value may be more suitable. |
| 251 | */ |
| 252 | void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric = 0 ); |
| 253 | void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 ); |
| 254 | |
| 255 | // ----------------------------------------------------------------------------- |
| 256 | |
| 257 | /*! @brief Decompresses an image in memory. |
| 258 | |
| 259 | @param rgba Storage for the decompressed pixels. |
| 260 | @param width The width of the source image. |
| 261 | @param height The height of the source image. |
| 262 | @param pitch The pitch of the decompressed pixels. |
| 263 | @param blocks The compressed DXT blocks. |
| 264 | @param flags Compression flags. |
| 265 | |
| 266 | The decompressed pixels will be written as a contiguous array of width*height |
| 267 | 16 rgba values, with each component as 1 byte each. In memory this is: |
| 268 | |
| 269 | { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height |
| 270 | |
| 271 | The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, |
| 272 | however, DXT1 will be used by default if none is specified. All other flags |
| 273 | are ignored. |
| 274 | |
| 275 | Internally this function calls squish::Decompress for each block. |
| 276 | */ |
| 277 | void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags ); |
| 278 | void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ); |
| 279 | |
| 280 | // ----------------------------------------------------------------------------- |
| 281 | |
| 282 | /*! @brief Computes MSE of an compressed image in memory. |
| 283 | |
| 284 | @param rgba The original image pixels. |
| 285 | @param width The width of the source image. |
| 286 | @param height The height of the source image. |
| 287 | @param pitch The pitch of the source image. |
| 288 | @param dxt The compressed dxt blocks |
| 289 | @param flags Compression flags. |
| 290 | @param colourMSE The MSE of the colour values. |
| 291 | @param alphaMSE The MSE of the alpha values. |
| 292 | |
| 293 | The colour MSE and alpha MSE are computed across all pixels. The colour MSE is |
| 294 | averaged across all rgb values (i.e. colourMSE = sum sum_k ||dxt.k - rgba.k||/3) |
| 295 | |
| 296 | The flags parameter should specify kDxt1, kDxt3, kDxt5, kBc4, or kBc5 compression, |
| 297 | however, DXT1 will be used by default if none is specified. All other flags |
| 298 | are ignored. |
| 299 | |
| 300 | Internally this function calls squish::Decompress for each block. |
| 301 | */ |
| 302 | void ComputeMSE(u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE); |
| 303 | void ComputeMSE(u8 const *rgba, int width, int height, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE); |
| 304 | |
| 305 | // ----------------------------------------------------------------------------- |
| 306 | |
| 307 | } // namespace squish |
| 308 | |
| 309 | #endif // ndef SQUISH_H |
| 310 | |