1 : // File: crnlib.h - Advanced DXTn texture compression library.
2 : // Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC
3 : // See copyright notice and license at the end of this file.
4 : //
5 : // This header file contains the public crnlib declarations for DXTn,
6 : // clustered DXTn, and CRN compression/decompression.
7 : //
8 : // Note: This library does NOT need to be linked into your game executable if
9 : // all you want to do is transcode .CRN files to raw DXTn bits at run-time.
10 : // The crn_decomp.h header file library contains all the code necessary for
11 : // decompression.
12 : //
13 : // Important: If compiling with gcc, be sure strict aliasing is disabled: -fno-strict-aliasing
14 : #ifndef CRNLIB_H
15 : #define CRNLIB_H
16 :
17 : #ifdef _MSC_VER
18 : #pragma warning (disable: 4127) // conditional expression is constant
19 : #endif
20 :
21 : #define CRNLIB_VERSION 104
22 :
23 : #define CRNLIB_SUPPORT_ATI_COMPRESS 0
24 : #define CRNLIB_SUPPORT_SQUISH 0
25 :
26 : typedef unsigned char crn_uint8;
27 : typedef unsigned short crn_uint16;
28 : typedef unsigned int crn_uint32;
29 : typedef signed char crn_int8;
30 : typedef signed short crn_int16;
31 : typedef signed int crn_int32;
32 : typedef unsigned int crn_bool;
33 :
34 : // crnlib can compress to these file types.
35 : enum crn_file_type
36 : {
37 : // .CRN
38 : cCRNFileTypeCRN = 0,
39 :
40 : // .DDS using regular DXT or clustered DXT
41 : cCRNFileTypeDDS,
42 :
43 : cCRNFileTypeForceDWORD = 0xFFFFFFFF
44 : };
45 :
46 : // Supported compressed pixel formats.
47 : // Basically all the standard DX9 formats, with some swizzled DXT5 formats
48 : // (most of them supported by ATI's Compressonator), along with some ATI/X360 GPU specific formats.
49 : enum crn_format
50 : {
51 : cCRNFmtInvalid = -1,
52 :
53 : cCRNFmtDXT1 = 0,
54 :
55 : cCRNFmtFirstValid = cCRNFmtDXT1,
56 :
57 : // cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS.
58 : cCRNFmtDXT3,
59 :
60 : cCRNFmtDXT5,
61 :
62 : // Various DXT5 derivatives
63 : cCRNFmtDXT5_CCxY, // Luma-chroma
64 : cCRNFmtDXT5_xGxR, // Swizzled 2-component
65 : cCRNFmtDXT5_xGBR, // Swizzled 3-component
66 : cCRNFmtDXT5_AGBR, // Swizzled 4-component
67 :
68 : // ATI 3DC and X360 DXN
69 : cCRNFmtDXN_XY,
70 : cCRNFmtDXN_YX,
71 :
72 : // DXT5 alpha blocks only
73 : cCRNFmtDXT5A,
74 :
75 : cCRNFmtETC1,
76 :
77 : cCRNFmtTotal,
78 :
79 : cCRNFmtForceDWORD = 0xFFFFFFFF
80 : };
81 :
82 : // Various library/file format limits.
83 : enum crn_limits
84 : {
85 : // Max. mipmap level resolution on any axis.
86 : cCRNMaxLevelResolution = 4096,
87 :
88 : cCRNMinPaletteSize = 8,
89 : cCRNMaxPaletteSize = 8192,
90 :
91 : cCRNMaxFaces = 6,
92 : cCRNMaxLevels = 16,
93 :
94 : cCRNMaxHelperThreads = 16,
95 :
96 : cCRNMinQualityLevel = 0,
97 : cCRNMaxQualityLevel = 255
98 : };
99 :
100 : // CRN/DDS compression flags.
101 : // See the m_flags member in the crn_comp_params struct, below.
102 : enum crn_comp_flags
103 : {
104 : // Enables perceptual colorspace distance metrics if set.
105 : // Important: Be sure to disable this when compressing non-sRGB colorspace images, like normal maps!
106 : // Default: Set
107 : cCRNCompFlagPerceptual = 1,
108 :
109 : // Enables (up to) 8x8 macroblock usage if set. If disabled, only 4x4 blocks are allowed.
110 : // Compression ratio will be lower when disabled, but may cut down on blocky artifacts because the process used to determine
111 : // where large macroblocks can be used without artifacts isn't perfect.
112 : // Default: Set.
113 : cCRNCompFlagHierarchical = 2,
114 :
115 : // cCRNCompFlagQuick disables several output file optimizations - intended for things like quicker previews.
116 : // Default: Not set.
117 : cCRNCompFlagQuick = 4,
118 :
119 : // DXT1: OK to use DXT1 alpha blocks for better quality or DXT1A transparency.
120 : // DXT5: OK to use both DXT5 block types.
121 : // Currently only used when writing to .DDS files, as .CRN uses only a subset of the possible DXTn block types.
122 : // Default: Set.
123 : cCRNCompFlagUseBothBlockTypes = 8,
124 :
125 : // OK to use DXT1A transparent indices to encode black (assumes pixel shader ignores fetched alpha).
126 : // Currently only used when writing to .DDS files, .CRN never uses alpha blocks.
127 : // Default: Not set.
128 : cCRNCompFlagUseTransparentIndicesForBlack = 16,
129 :
130 : // Disables endpoint caching, for more deterministic output.
131 : // Currently only used when writing to .DDS files.
132 : // Default: Not set.
133 : cCRNCompFlagDisableEndpointCaching = 32,
134 :
135 : // If enabled, use the cCRNColorEndpointPaletteSize, etc. params to control the CRN palette sizes. Only useful when writing to .CRN files.
136 : // Default: Not set.
137 : cCRNCompFlagManualPaletteSizes = 64,
138 :
139 : // If enabled, DXT1A alpha blocks are used to encode single bit transparency.
140 : // Default: Not set.
141 : cCRNCompFlagDXT1AForTransparency = 128,
142 :
143 : // If enabled, the DXT1 compressor's color distance metric assumes the pixel shader will be converting the fetched RGB results to luma (Y part of YCbCr).
144 : // This increases quality when compressing grayscale images, because the compressor can spread the luma error amoung all three channels (i.e. it can generate blocks
145 : // with some chroma present if doing so will ultimately lead to lower luma error).
146 : // Only enable on grayscale source images.
147 : // Default: Not set.
148 : cCRNCompFlagGrayscaleSampling = 256,
149 :
150 : // If enabled, debug information will be output during compression.
151 : // Default: Not set.
152 : cCRNCompFlagDebugging = 0x80000000,
153 :
154 : cCRNCompFlagForceDWORD = 0xFFFFFFFF
155 : };
156 :
157 : // Controls DXTn quality vs. speed control - only used when compressing to .DDS.
158 : enum crn_dxt_quality
159 : {
160 : cCRNDXTQualitySuperFast,
161 : cCRNDXTQualityFast,
162 : cCRNDXTQualityNormal,
163 : cCRNDXTQualityBetter,
164 : cCRNDXTQualityUber,
165 :
166 : cCRNDXTQualityTotal,
167 :
168 : cCRNDXTQualityForceDWORD = 0xFFFFFFFF
169 : };
170 :
171 : // Which DXTn compressor to use when compressing to plain (non-clustered) .DDS.
172 : enum crn_dxt_compressor_type
173 : {
174 : cCRNDXTCompressorCRN, // Use crnlib's ETC1 or DXTc block compressor (default, highest quality, comparable or better than ati_compress or squish, and crnlib's ETC1 is a lot fasterw with similiar quality to Erricson's)
175 : cCRNDXTCompressorCRNF, // Use crnlib's "fast" DXTc block compressor
176 : cCRNDXTCompressorRYG, // Use RYG's DXTc block compressor (low quality, but very fast)
177 :
178 : #if CRNLIB_SUPPORT_ATI_COMPRESS
179 : cCRNDXTCompressorATI,
180 : #endif
181 :
182 : #if CRNLIB_SUPPORT_SQUISH
183 : cCRNDXTCompressorSquish,
184 : #endif
185 :
186 : cCRNTotalDXTCompressors,
187 :
188 : cCRNDXTCompressorForceDWORD = 0xFFFFFFFF
189 : };
190 :
191 : // Progress callback function.
192 : // Processing will stop prematurely (and fail) if the callback returns false.
193 : // phase_index, total_phases - high level progress
194 : // subphase_index, total_subphases - progress within current phase
195 : typedef crn_bool (*crn_progress_callback_func)(crn_uint32 phase_index, crn_uint32 total_phases, crn_uint32 subphase_index, crn_uint32 total_subphases, void* pUser_data_ptr);
196 :
197 : // CRN/DDS compression parameters struct.
198 : struct crn_comp_params
199 : {
200 2 : inline crn_comp_params() { clear(); }
201 :
202 : // Clear struct to default parameters.
203 2 : inline void clear()
204 : {
205 2 : m_size_of_obj = sizeof(*this);
206 2 : m_file_type = cCRNFileTypeCRN;
207 2 : m_faces = 1;
208 2 : m_width = 0;
209 2 : m_height = 0;
210 2 : m_levels = 1;
211 2 : m_format = cCRNFmtDXT1;
212 2 : m_flags = cCRNCompFlagPerceptual | cCRNCompFlagHierarchical | cCRNCompFlagUseBothBlockTypes;
213 :
214 14 : for (crn_uint32 f = 0; f < cCRNMaxFaces; f++)
215 204 : for (crn_uint32 l = 0; l < cCRNMaxLevels; l++)
216 192 : m_pImages[f][l] = NULL;
217 :
218 2 : m_target_bitrate = 0.0f;
219 2 : m_quality_level = cCRNMaxQualityLevel;
220 2 : m_dxt1a_alpha_threshold = 128;
221 2 : m_dxt_quality = cCRNDXTQualityUber;
222 2 : m_dxt_compressor_type = cCRNDXTCompressorCRN;
223 2 : m_alpha_component = 3;
224 :
225 2 : m_crn_adaptive_tile_color_psnr_derating = 2.0f;
226 2 : m_crn_adaptive_tile_alpha_psnr_derating = 2.0f;
227 2 : m_crn_color_endpoint_palette_size = 0;
228 2 : m_crn_color_selector_palette_size = 0;
229 2 : m_crn_alpha_endpoint_palette_size = 0;
230 2 : m_crn_alpha_selector_palette_size = 0;
231 :
232 2 : m_num_helper_threads = 0;
233 2 : m_userdata0 = 0;
234 2 : m_userdata1 = 0;
235 2 : m_pProgress_func = NULL;
236 2 : m_pProgress_func_data = NULL;
237 2 : }
238 :
239 : inline bool operator== (const crn_comp_params& rhs) const
240 : {
241 : #define CRNLIB_COMP(x) do { if ((x) != (rhs.x)) return false; } while(0)
242 : CRNLIB_COMP(m_size_of_obj);
243 : CRNLIB_COMP(m_file_type);
244 : CRNLIB_COMP(m_faces);
245 : CRNLIB_COMP(m_width);
246 : CRNLIB_COMP(m_height);
247 : CRNLIB_COMP(m_levels);
248 : CRNLIB_COMP(m_format);
249 : CRNLIB_COMP(m_flags);
250 : CRNLIB_COMP(m_target_bitrate);
251 : CRNLIB_COMP(m_quality_level);
252 : CRNLIB_COMP(m_dxt1a_alpha_threshold);
253 : CRNLIB_COMP(m_dxt_quality);
254 : CRNLIB_COMP(m_dxt_compressor_type);
255 : CRNLIB_COMP(m_alpha_component);
256 : CRNLIB_COMP(m_crn_adaptive_tile_color_psnr_derating);
257 : CRNLIB_COMP(m_crn_adaptive_tile_alpha_psnr_derating);
258 : CRNLIB_COMP(m_crn_color_endpoint_palette_size);
259 : CRNLIB_COMP(m_crn_color_selector_palette_size);
260 : CRNLIB_COMP(m_crn_alpha_endpoint_palette_size);
261 : CRNLIB_COMP(m_crn_alpha_selector_palette_size);
262 : CRNLIB_COMP(m_num_helper_threads);
263 : CRNLIB_COMP(m_userdata0);
264 : CRNLIB_COMP(m_userdata1);
265 : CRNLIB_COMP(m_pProgress_func);
266 : CRNLIB_COMP(m_pProgress_func_data);
267 :
268 : for (crn_uint32 f = 0; f < cCRNMaxFaces; f++)
269 : for (crn_uint32 l = 0; l < cCRNMaxLevels; l++)
270 : CRNLIB_COMP(m_pImages[f][l]);
271 :
272 : #undef CRNLIB_COMP
273 : return true;
274 : }
275 :
276 : // Returns true if the input parameters are reasonable.
277 : inline bool check() const
278 : {
279 : if ( (m_file_type > cCRNFileTypeDDS) ||
280 : (((int)m_quality_level < (int)cCRNMinQualityLevel) || ((int)m_quality_level > (int)cCRNMaxQualityLevel)) ||
281 : (m_dxt1a_alpha_threshold > 255) ||
282 : ((m_faces != 1) && (m_faces != 6)) ||
283 : ((m_width < 1) || (m_width > cCRNMaxLevelResolution)) ||
284 : ((m_height < 1) || (m_height > cCRNMaxLevelResolution)) ||
285 : ((m_levels < 1) || (m_levels > cCRNMaxLevels)) ||
286 : ((m_format < cCRNFmtDXT1) || (m_format >= cCRNFmtTotal)) ||
287 : ((m_crn_color_endpoint_palette_size) && ((m_crn_color_endpoint_palette_size < cCRNMinPaletteSize) || (m_crn_color_endpoint_palette_size > cCRNMaxPaletteSize))) ||
288 : ((m_crn_color_selector_palette_size) && ((m_crn_color_selector_palette_size < cCRNMinPaletteSize) || (m_crn_color_selector_palette_size > cCRNMaxPaletteSize))) ||
289 : ((m_crn_alpha_endpoint_palette_size) && ((m_crn_alpha_endpoint_palette_size < cCRNMinPaletteSize) || (m_crn_alpha_endpoint_palette_size > cCRNMaxPaletteSize))) ||
290 : ((m_crn_alpha_selector_palette_size) && ((m_crn_alpha_selector_palette_size < cCRNMinPaletteSize) || (m_crn_alpha_selector_palette_size > cCRNMaxPaletteSize))) ||
291 : (m_alpha_component > 3) ||
292 : (m_num_helper_threads > cCRNMaxHelperThreads) ||
293 : (m_dxt_quality > cCRNDXTQualityUber) ||
294 : (m_dxt_compressor_type >= cCRNTotalDXTCompressors) )
295 : {
296 : return false;
297 : }
298 : return true;
299 : }
300 :
301 : // Helper to set/get flags from m_flags member.
302 : inline bool get_flag(crn_comp_flags flag) const { return (m_flags & flag) != 0; }
303 4 : inline void set_flag(crn_comp_flags flag, bool val) { m_flags &= ~flag; if (val) m_flags |= flag; }
304 :
305 : crn_uint32 m_size_of_obj;
306 :
307 : crn_file_type m_file_type; // Output file type: cCRNFileTypeCRN or cCRNFileTypeDDS.
308 :
309 : crn_uint32 m_faces; // 1 (2D map) or 6 (cubemap)
310 : crn_uint32 m_width; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK
311 : crn_uint32 m_height; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK
312 : crn_uint32 m_levels; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK
313 :
314 : crn_format m_format; // Output pixel format.
315 :
316 : crn_uint32 m_flags; // see crn_comp_flags enum
317 :
318 : // Array of pointers to 32bpp input images.
319 : const crn_uint32* m_pImages[cCRNMaxFaces][cCRNMaxLevels];
320 :
321 : // Target bitrate - if non-zero, the compressor will use an interpolative search to find the
322 : // highest quality level that is <= the target bitrate. If it fails to find a bitrate high enough, it'll
323 : // try disabling adaptive block sizes (cCRNCompFlagHierarchical flag) and redo the search. This process can be pretty slow.
324 : float m_target_bitrate;
325 :
326 : // Desired quality level.
327 : // Currently, CRN and DDS quality levels are not compatible with eachother from an image quality standpoint.
328 : crn_uint32 m_quality_level; // [cCRNMinQualityLevel, cCRNMaxQualityLevel]
329 :
330 : // DXTn compression parameters.
331 : crn_uint32 m_dxt1a_alpha_threshold;
332 : crn_dxt_quality m_dxt_quality;
333 : crn_dxt_compressor_type m_dxt_compressor_type;
334 :
335 : // Alpha channel's component. Defaults to 3.
336 : crn_uint32 m_alpha_component;
337 :
338 : // Various low-level CRN specific parameters.
339 : float m_crn_adaptive_tile_color_psnr_derating;
340 : float m_crn_adaptive_tile_alpha_psnr_derating;
341 :
342 : crn_uint32 m_crn_color_endpoint_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize]
343 : crn_uint32 m_crn_color_selector_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize]
344 :
345 : crn_uint32 m_crn_alpha_endpoint_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize]
346 : crn_uint32 m_crn_alpha_selector_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize]
347 :
348 : // Number of helper threads to create during compression. 0=no threading.
349 : crn_uint32 m_num_helper_threads;
350 :
351 : // CRN userdata0 and userdata1 members, which are written directly to the header of the output file.
352 : crn_uint32 m_userdata0;
353 : crn_uint32 m_userdata1;
354 :
355 : // User provided progress callback.
356 : crn_progress_callback_func m_pProgress_func;
357 : void* m_pProgress_func_data;
358 : };
359 :
360 : // Mipmap generator's mode.
361 : enum crn_mip_mode
362 : {
363 : cCRNMipModeUseSourceOrGenerateMips, // Use source texture's mipmaps if it has any, otherwise generate new mipmaps
364 : cCRNMipModeUseSourceMips, // Use source texture's mipmaps if it has any, otherwise the output has no mipmaps
365 : cCRNMipModeGenerateMips, // Always generate new mipmaps
366 : cCRNMipModeNoMips, // Output texture has no mipmaps
367 :
368 : cCRNMipModeTotal,
369 :
370 : cCRNModeForceDWORD = 0xFFFFFFFF
371 : };
372 :
373 : const char* crn_get_mip_mode_desc(crn_mip_mode m);
374 : const char* crn_get_mip_mode_name(crn_mip_mode m);
375 :
376 : // Mipmap generator's filter kernel.
377 : enum crn_mip_filter
378 : {
379 : cCRNMipFilterBox,
380 : cCRNMipFilterTent,
381 : cCRNMipFilterLanczos4,
382 : cCRNMipFilterMitchell,
383 : cCRNMipFilterKaiser, // Kaiser=default mipmap filter
384 :
385 : cCRNMipFilterTotal,
386 :
387 : cCRNMipFilterForceDWORD = 0xFFFFFFFF
388 : };
389 :
390 : const char* crn_get_mip_filter_name(crn_mip_filter f);
391 :
392 : // Mipmap generator's scale mode.
393 : enum crn_scale_mode
394 : {
395 : cCRNSMDisabled,
396 : cCRNSMAbsolute,
397 : cCRNSMRelative,
398 : cCRNSMLowerPow2,
399 : cCRNSMNearestPow2,
400 : cCRNSMNextPow2,
401 :
402 : cCRNSMTotal,
403 :
404 : cCRNSMForceDWORD = 0xFFFFFFFF
405 : };
406 :
407 : const char* crn_get_scale_mode_desc(crn_scale_mode sm);
408 :
409 : // Mipmap generator parameters.
410 : struct crn_mipmap_params
411 : {
412 : inline crn_mipmap_params() { clear(); }
413 :
414 : inline void clear()
415 : {
416 : m_size_of_obj = sizeof(*this);
417 : m_mode = cCRNMipModeUseSourceOrGenerateMips;
418 : m_filter = cCRNMipFilterKaiser;
419 : m_gamma_filtering = true;
420 : m_gamma = 2.2f;
421 : // Default "blurriness" factor of .9 actually sharpens the output a little.
422 : m_blurriness = .9f;
423 : m_renormalize = false;
424 : m_tiled = false;
425 : m_max_levels = cCRNMaxLevels;
426 : m_min_mip_size = 1;
427 :
428 : m_scale_mode = cCRNSMDisabled;
429 : m_scale_x = 1.0f;
430 : m_scale_y = 1.0f;
431 :
432 : m_window_left = 0;
433 : m_window_top = 0;
434 : m_window_right = 0;
435 : m_window_bottom = 0;
436 :
437 : m_clamp_scale = false;
438 : m_clamp_width = 0;
439 : m_clamp_height = 0;
440 : }
441 :
442 : inline bool check() const { return true; }
443 :
444 : inline bool operator== (const crn_mipmap_params& rhs) const
445 : {
446 : #define CRNLIB_COMP(x) do { if ((x) != (rhs.x)) return false; } while(0)
447 : CRNLIB_COMP(m_size_of_obj);
448 : CRNLIB_COMP(m_mode);
449 : CRNLIB_COMP(m_filter);
450 : CRNLIB_COMP(m_gamma_filtering);
451 : CRNLIB_COMP(m_gamma);
452 : CRNLIB_COMP(m_blurriness);
453 : CRNLIB_COMP(m_renormalize);
454 : CRNLIB_COMP(m_tiled);
455 : CRNLIB_COMP(m_max_levels);
456 : CRNLIB_COMP(m_min_mip_size);
457 : CRNLIB_COMP(m_scale_mode);
458 : CRNLIB_COMP(m_scale_x);
459 : CRNLIB_COMP(m_scale_y);
460 : CRNLIB_COMP(m_window_left);
461 : CRNLIB_COMP(m_window_top);
462 : CRNLIB_COMP(m_window_right);
463 : CRNLIB_COMP(m_window_bottom);
464 : CRNLIB_COMP(m_clamp_scale);
465 : CRNLIB_COMP(m_clamp_width);
466 : CRNLIB_COMP(m_clamp_height);
467 : return true;
468 : #undef CRNLIB_COMP
469 : }
470 : crn_uint32 m_size_of_obj;
471 :
472 : crn_mip_mode m_mode;
473 : crn_mip_filter m_filter;
474 :
475 : crn_bool m_gamma_filtering;
476 : float m_gamma;
477 :
478 : float m_blurriness;
479 :
480 : crn_uint32 m_max_levels;
481 : crn_uint32 m_min_mip_size;
482 :
483 : crn_bool m_renormalize;
484 : crn_bool m_tiled;
485 :
486 : crn_scale_mode m_scale_mode;
487 : float m_scale_x;
488 : float m_scale_y;
489 :
490 : crn_uint32 m_window_left;
491 : crn_uint32 m_window_top;
492 : crn_uint32 m_window_right;
493 : crn_uint32 m_window_bottom;
494 :
495 : crn_bool m_clamp_scale;
496 : crn_uint32 m_clamp_width;
497 : crn_uint32 m_clamp_height;
498 : };
499 :
500 : // -------- High-level helper function definitions for CDN/DDS compression.
501 :
502 : #ifndef CRNLIB_MIN_ALLOC_ALIGNMENT
503 : #define CRNLIB_MIN_ALLOC_ALIGNMENT sizeof(size_t) * 2
504 : #endif
505 :
506 : // Function to set an optional user provided memory allocation/reallocation/msize routines.
507 : // By default, crnlib just uses malloc(), free(), etc. for all allocations.
508 : typedef void* (*crn_realloc_func)(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data);
509 : typedef size_t (*crn_msize_func)(void* p, void* pUser_data);
510 : void crn_set_memory_callbacks(crn_realloc_func pRealloc, crn_msize_func pMSize, void* pUser_data);
511 :
512 : // Frees memory blocks allocated by crn_compress(), crn_decompress_crn_to_dds(), or crn_decompress_dds_to_images().
513 : void crn_free_block(void *pBlock);
514 :
515 : // Compresses a 32-bit/pixel texture to either: a regular DX9 DDS file, a "clustered" (or reduced entropy) DX9 DDS file, or a CRN file in memory.
516 : // Input parameters:
517 : // comp_params is the compression parameters struct, defined above.
518 : // compressed_size will be set to the size of the returned memory block containing the output file.
519 : // The returned block must be freed by calling crn_free_block().
520 : // *pActual_quality_level will be set to the actual quality level used to compress the image. May be NULL.
521 : // *pActual_bitrate will be set to the output file's effective bitrate, possibly taking into account LZMA compression. May be NULL.
522 : // Return value:
523 : // The compressed file data, or NULL on failure.
524 : // compressed_size will be set to the size of the returned memory buffer.
525 : // Notes:
526 : // A "regular" DDS file is compressed using normal DXTn compression at the specified DXT quality level.
527 : // A "clustered" DDS file is compressed using clustered DXTn compression to either the target bitrate or the specified integer quality factor.
528 : // The output file is a standard DX9 format DDS file, except the compressor assumes you will be later losslessly compressing the DDS output file using the LZMA algorithm.
529 : // A texture is defined as an array of 1 or 6 "faces" (6 faces=cubemap), where each "face" consists of between [1,cCRNMaxLevels] mipmap levels.
530 : // Mipmap levels are simple 32-bit 2D images with a pitch of width*sizeof(uint32), arranged in the usual raster order (top scanline first).
531 : // The image pixels may be grayscale (YYYX bytes in memory), grayscale/alpha (YYYA in memory), 24-bit (RGBX in memory), or 32-bit (RGBA) colors (where "X"=don't care).
532 : // RGB color data is generally assumed to be in the sRGB colorspace. If not, be sure to clear the "cCRNCompFlagPerceptual" in the crn_comp_params struct!
533 : void *crn_compress(const crn_comp_params &comp_params, crn_uint32 &compressed_size, crn_uint32 *pActual_quality_level = NULL, float *pActual_bitrate = NULL);
534 :
535 : // Like the above function, except this function can also do things like generate mipmaps, and resize or crop the input texture before compression.
536 : // The actual operations performed are controlled by the crn_mipmap_params struct members.
537 : // Be sure to set the "m_gamma_filtering" member of crn_mipmap_params to false if the input texture is not sRGB.
538 : void *crn_compress(const crn_comp_params &comp_params, const crn_mipmap_params &mip_params, crn_uint32 &compressed_size, crn_uint32 *pActual_quality_level = NULL, float *pActual_bitrate = NULL);
539 :
540 : // Transcodes an entire CRN file to DDS using the crn_decomp.h header file library to do most of the heavy lifting.
541 : // The output DDS file's format is guaranteed to be one of the DXTn formats in the crn_format enum.
542 : // This is a fast operation, because the CRN format is explicitly designed to be efficiently transcodable to DXTn.
543 : // For more control over decompression, see the lower-level helper functions in crn_decomp.h, which do not depend at all on crnlib.
544 : void *crn_decompress_crn_to_dds(const void *pCRN_file_data, crn_uint32 &file_size);
545 :
546 : // Decompresses an entire DDS file in any supported format to uncompressed 32-bit/pixel image(s).
547 : // See the crnlib::pixel_format enum in inc/dds_defs.h for a list of the supported DDS formats.
548 : // You are responsible for freeing each image block, either by calling crn_free_all_images() or manually calling crn_free_block() on each image pointer.
549 : struct crn_texture_desc
550 : {
551 : crn_uint32 m_faces;
552 : crn_uint32 m_width;
553 : crn_uint32 m_height;
554 : crn_uint32 m_levels;
555 : crn_uint32 m_fmt_fourcc; // Same as crnlib::pixel_format
556 : };
557 : bool crn_decompress_dds_to_images(const void *pDDS_file_data, crn_uint32 dds_file_size, crn_uint32 **ppImages, crn_texture_desc &tex_desc);
558 :
559 : // Frees all images allocated by crn_decompress_dds_to_images().
560 : void crn_free_all_images(crn_uint32 **ppImages, const crn_texture_desc &desc);
561 :
562 : // -------- crn_format related helpers functions.
563 :
564 : // Returns the FOURCC format equivalent to the specified crn_format.
565 : crn_uint32 crn_get_format_fourcc(crn_format fmt);
566 :
567 : // Returns the crn_format's bits per texel.
568 : crn_uint32 crn_get_format_bits_per_texel(crn_format fmt);
569 :
570 : // Returns the crn_format's number of bytes per block.
571 : crn_uint32 crn_get_bytes_per_dxt_block(crn_format fmt);
572 :
573 : // Returns the non-swizzled, basic DXTn version of the specified crn_format.
574 : // This is the format you would supply D3D or OpenGL.
575 : crn_format crn_get_fundamental_dxt_format(crn_format fmt);
576 :
577 : // -------- String helpers.
578 :
579 : // Converts a crn_file_type to a string.
580 : const char* crn_get_file_type_ext(crn_file_type file_type);
581 :
582 : // Converts a crn_format to a string.
583 : const char* crn_get_format_string(crn_format fmt);
584 :
585 : // Converts a crn_dxt_quality to a string.
586 : const char* crn_get_dxt_quality_string(crn_dxt_quality q);
587 :
588 : // -------- Low-level DXTn 4x4 block compressor API
589 :
590 : // crnlib's DXTn endpoint optimizer actually supports any number of source pixels (i.e. from 1 to thousands, not just 16),
591 : // but for simplicity this API only supports 4x4 texel blocks.
592 : typedef void *crn_block_compressor_context_t;
593 :
594 : // Create a DXTn block compressor.
595 : // This function only supports the basic/nonswizzled "fundamental" formats: DXT1, DXT3, DXT5, DXT5A, DXN_XY and DXN_YX.
596 : // Avoid calling this multiple times if you intend on compressing many blocks, because it allocates some memory.
597 : crn_block_compressor_context_t crn_create_block_compressor(const crn_comp_params ¶ms);
598 :
599 : // Compresses a block of 16 pixels to the destination DXTn block.
600 : // pDst_block should be 8 (for DXT1/DXT5A) or 16 bytes (all the others).
601 : // pPixels should be an array of 16 crn_uint32's. Each crn_uint32 must be r,g,b,a (r is always first) in memory.
602 : void crn_compress_block(crn_block_compressor_context_t pContext, const crn_uint32 *pPixels, void *pDst_block);
603 :
604 : // Frees a DXTn block compressor.
605 : void crn_free_block_compressor(crn_block_compressor_context_t pContext);
606 :
607 : // Unpacks a compressed block to pDst_pixels.
608 : // pSrc_block should be 8 (for DXT1/DXT5A) or 16 bytes (all the others).
609 : // pDst_pixel should be an array of 16 crn_uint32's. Each uint32 will be r,g,b,a (r is always first) in memory.
610 : // crn_fmt should be one of the "fundamental" formats: DXT1, DXT3, DXT5, DXT5A, DXN_XY and DXN_YX.
611 : // The various swizzled DXT5 formats (such as cCRNFmtDXT5_xGBR, etc.) will be unpacked as if they where plain DXT5.
612 : // Returns false if the crn_fmt is invalid.
613 : bool crn_decompress_block(const void *pSrc_block, crn_uint32 *pDst_pixels, crn_format crn_fmt);
614 :
615 : #endif // CRNLIB_H
616 :
617 : //------------------------------------------------------------------------------
618 : //
619 : // crnlib uses the ZLIB license:
620 : // http://opensource.org/licenses/Zlib
621 : //
622 : // Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC
623 : //
624 : // This software is provided 'as-is', without any express or implied
625 : // warranty. In no event will the authors be held liable for any damages
626 : // arising from the use of this software.
627 : //
628 : // Permission is granted to anyone to use this software for any purpose,
629 : // including commercial applications, and to alter it and redistribute it
630 : // freely, subject to the following restrictions:
631 : //
632 : // 1. The origin of this software must not be misrepresented; you must not
633 : // claim that you wrote the original software. If you use this software
634 : // in a product, an acknowledgment in the product documentation would be
635 : // appreciated but is not required.
636 : //
637 : // 2. Altered source versions must be plainly marked as such, and must not be
638 : // misrepresented as being the original software.
639 : //
640 : // 3. This notice may not be removed or altered from any source distribution.
641 : //
642 : //------------------------------------------------------------------------------
|