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.
30namespace squish {
31
32// -----------------------------------------------------------------------------
33
34//! Typedef a quantity that is a single unsigned byte.
35typedef unsigned char u8;
36
37// -----------------------------------------------------------------------------
38
39enum
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*/
116void 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*/
157inline 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*/
179void 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*/
197int 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*/
252void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric = 0 );
253void 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*/
277void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags );
278void 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*/
302void ComputeMSE(u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE);
303void 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