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 
69 // -----------------------------------------------------------------------------
70 
71 /*! @brief Compresses a 4x4 block of pixels.
72 
73 	@param rgba		The rgba values of the 16 source pixels.
74 	@param mask		The valid pixel mask.
75 	@param block	Storage for the compressed DXT block.
76 	@param flags	Compression flags.
77 	@param metric	An optional perceptual metric.
78 
79 	The source pixels should be presented as a contiguous array of 16 rgba
80 	values, with each component as 1 byte each. In memory this should be:
81 
82 		{ r1, g1, b1, a1, .... , r16, g16, b16, a16 }
83 
84 	The mask parameter enables only certain pixels within the block. The lowest
85 	bit enables the first pixel and so on up to the 16th bit. Bits beyond the
86 	16th bit are ignored. Pixels that are not enabled are allowed to take
87 	arbitrary colours in the output block. An example of how this can be used
88 	is in the CompressImage function to disable pixels outside the bounds of
89 	the image when the width or height is not divisible by 4.
90 
91 	The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
92 	however, DXT1 will be used by default if none is specified. When using DXT1
93 	compression, 8 bytes of storage are required for the compressed DXT block.
94 	DXT3 and DXT5 compression require 16 bytes of storage per block.
95 
96 	The flags parameter can also specify a preferred colour compressor to use
97 	when fitting the RGB components of the data. Possible colour compressors
98 	are: kColourClusterFit (the default), kColourRangeFit (very fast, low
99 	quality) or kColourIterativeClusterFit (slowest, best quality).
100 
101 	When using kColourClusterFit or kColourIterativeClusterFit, an additional
102 	flag can be specified to weight the importance of each pixel by its alpha
103 	value. For images that are rendered using alpha blending, this can
104 	significantly increase the perceived quality.
105 
106 	The metric parameter can be used to weight the relative importance of each
107 	colour channel, or pass NULL to use the default uniform weight of
108 	{ 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
109 	allowed either uniform or "perceptual" weights with the fixed values
110 	{ 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
111 	contiguous array of 3 floats.
112 */
113 void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric = 0 );
114 
115 // -----------------------------------------------------------------------------
116 
117 /*! @brief Compresses a 4x4 block of pixels.
118 
119 	@param rgba		The rgba values of the 16 source pixels.
120 	@param block	Storage for the compressed DXT block.
121 	@param flags	Compression flags.
122 	@param metric	An optional perceptual metric.
123 
124 	The source pixels should be presented as a contiguous array of 16 rgba
125 	values, with each component as 1 byte each. In memory this should be:
126 
127 		{ r1, g1, b1, a1, .... , r16, g16, b16, a16 }
128 
129 	The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
130 	however, DXT1 will be used by default if none is specified. When using DXT1
131 	compression, 8 bytes of storage are required for the compressed DXT block.
132 	DXT3 and DXT5 compression require 16 bytes of storage per block.
133 
134 	The flags parameter can also specify a preferred colour compressor to use
135 	when fitting the RGB components of the data. Possible colour compressors
136 	are: kColourClusterFit (the default), kColourRangeFit (very fast, low
137 	quality) or kColourIterativeClusterFit (slowest, best quality).
138 
139 	When using kColourClusterFit or kColourIterativeClusterFit, an additional
140 	flag can be specified to weight the importance of each pixel by its alpha
141 	value. For images that are rendered using alpha blending, this can
142 	significantly increase the perceived quality.
143 
144 	The metric parameter can be used to weight the relative importance of each
145 	colour channel, or pass NULL to use the default uniform weight of
146 	{ 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
147 	allowed either uniform or "perceptual" weights with the fixed values
148 	{ 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
149 	contiguous array of 3 floats.
150 
151 	This method is an inline that calls CompressMasked with a mask of 0xffff,
152 	provided for compatibility with older versions of squish.
153 */
154 inline void Compress( u8 const* rgba, void* block, int flags, float* metric = 0 )
155 {
156 	CompressMasked( rgba, 0xffff, block, flags, metric );
157 }
158 
159 // -----------------------------------------------------------------------------
160 
161 /*! @brief Decompresses a 4x4 block of pixels.
162 
163 	@param rgba		Storage for the 16 decompressed pixels.
164 	@param block	The compressed DXT block.
165 	@param flags	Compression flags.
166 
167 	The decompressed pixels will be written as a contiguous array of 16 rgba
168 	values, with each component as 1 byte each. In memory this is:
169 
170 		{ r1, g1, b1, a1, .... , r16, g16, b16, a16 }
171 
172 	The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
173 	however, DXT1 will be used by default if none is specified. All other flags
174 	are ignored.
175 */
176 void Decompress( u8* rgba, void const* block, int flags );
177 
178 // -----------------------------------------------------------------------------
179 
180 /*! @brief Computes the amount of compressed storage required.
181 
182 	@param width	The width of the image.
183 	@param height	The height of the image.
184 	@param flags	Compression flags.
185 
186 	The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
187 	however, DXT1 will be used by default if none is specified. All other flags
188 	are ignored.
189 
190 	Most DXT images will be a multiple of 4 in each dimension, but this
191 	function supports arbitrary size images by allowing the outer blocks to
192 	be only partially used.
193 */
194 int GetStorageRequirements( int width, int height, int flags );
195 
196 // -----------------------------------------------------------------------------
197 
198 /*! @brief Compresses an image in memory.
199 
200 	@param rgba		The pixels of the source.
201 	@param width	The width of the source image.
202 	@param height	The height of the source image.
203 	@param blocks	Storage for the compressed output.
204 	@param flags	Compression flags.
205 	@param metric	An optional perceptual metric.
206 
207 	The source pixels should be presented as a contiguous array of width*height
208 	rgba values, with each component as 1 byte each. In memory this should be:
209 
210 		{ r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height
211 
212 	The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
213 	however, DXT1 will be used by default if none is specified. When using DXT1
214 	compression, 8 bytes of storage are required for each compressed DXT block.
215 	DXT3 and DXT5 compression require 16 bytes of storage per block.
216 
217 	The flags parameter can also specify a preferred colour compressor to use
218 	when fitting the RGB components of the data. Possible colour compressors
219 	are: kColourClusterFit (the default), kColourRangeFit (very fast, low
220 	quality) or kColourIterativeClusterFit (slowest, best quality).
221 
222 	When using kColourClusterFit or kColourIterativeClusterFit, an additional
223 	flag can be specified to weight the importance of each pixel by its alpha
224 	value. For images that are rendered using alpha blending, this can
225 	significantly increase the perceived quality.
226 
227 	The metric parameter can be used to weight the relative importance of each
228 	colour channel, or pass NULL to use the default uniform weight of
229 	{ 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that
230 	allowed either uniform or "perceptual" weights with the fixed values
231 	{ 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a
232 	contiguous array of 3 floats.
233 
234 	Internally this function calls squish::CompressMasked for each block, which
235 	allows for pixels outside the image to take arbitrary values. The function
236 	squish::GetStorageRequirements can be called to compute the amount of memory
237 	to allocate for the compressed output.
238 */
239 void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 );
240 
241 // -----------------------------------------------------------------------------
242 
243 /*! @brief Decompresses an image in memory.
244 
245 	@param rgba		Storage for the decompressed pixels.
246 	@param width	The width of the source image.
247 	@param height	The height of the source image.
248 	@param blocks	The compressed DXT blocks.
249 	@param flags	Compression flags.
250 
251 	The decompressed pixels will be written as a contiguous array of width*height
252 	16 rgba values, with each component as 1 byte each. In memory this is:
253 
254 		{ r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height
255 
256 	The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression,
257 	however, DXT1 will be used by default if none is specified. All other flags
258 	are ignored.
259 
260 	Internally this function calls squish::Decompress for each block.
261 */
262 void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags );
263 
264 // -----------------------------------------------------------------------------
265 
266 } // namespace squish
267 
268 #endif // ndef SQUISH_H
269 
270