summaryrefslogtreecommitdiff
path: root/indra/llimage/llimagedxt.h
blob: 1a297536b4174f5249dd02fa2aa93f850f177d9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/** 
 * @file llimagedxt.h
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 * 
 * Copyright (c) 2001-2009, Linden Research, Inc.
 * 
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 * 
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 * 
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 * 
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#ifndef LL_LLIMAGEDXT_H
#define LL_LLIMAGEDXT_H

#include "llimage.h"
#include "llpointer.h"

// This class decodes and encodes LL DXT files (which may unclude uncompressed RGB or RGBA mipped data)

class LLImageDXT : public LLImageFormatted
{
public:
	enum EFileFormat
	{ 
		FORMAT_UNKNOWN = 0,
		FORMAT_I8 = 1,
		FORMAT_A8,
		FORMAT_RGB8,
		FORMAT_RGBA8,
		FORMAT_DXT1,
		FORMAT_DXT2,
		FORMAT_DXT3,
		FORMAT_DXT4,
		FORMAT_DXT5,
		FORMAT_DXR1,
		FORMAT_DXR2,
		FORMAT_DXR3,
		FORMAT_DXR4,
		FORMAT_DXR5,
		FORMAT_NOFILE = 0xff,
	};
	
	struct dxtfile_header_old_t
	{
		S32 format;
		S32 maxlevel;
		S32 maxwidth;
		S32 maxheight;
	};

	struct dxtfile_header_t
	{
		S32 fourcc;
		// begin DDSURFACEDESC2 struct
		S32 header_size; // size of the header
		S32 flags; // flags - unused
		S32 maxheight;
		S32 maxwidth;
		S32 image_size; // size of the compressed image
		S32 depth;
		S32 num_mips;
		S32 reserved[11];
		struct pixel_format
		{
			S32 struct_size; // size of this structure
			S32 flags;
			S32 fourcc;
			S32 bit_count;
			S32 r_mask;
			S32 g_mask;
			S32 b_mask;
			S32 a_mask;
		} pixel_fmt;
		S32 caps[4];
		S32 reserved2;
	};

protected:
	/*virtual*/ ~LLImageDXT();

private:
	BOOL encodeDXT(const LLImageRaw* raw_image, F32 decode_time, bool explicit_mips);
	
public:
	LLImageDXT();

	/*virtual*/ std::string getExtension() { return std::string("dxt"); }
	/*virtual*/ BOOL updateData();

	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);

	/*virtual*/ S32 calcHeaderSize();
	/*virtual*/ S32 calcDataSize(S32 discard_level = 0);

	BOOL getMipData(LLPointer<LLImageRaw>& raw, S32 discard=-1);
	
	void setFormat();
	S32 getMipOffset(S32 discard);
	
	EFileFormat getFileFormat() { return mFileFormat; }
	bool isCompressed() { return (mFileFormat >= FORMAT_DXT1 && mFileFormat <= FORMAT_DXR5); }

	bool convertToDXR(); // convert from DXT to DXR
	
	static void checkMinWidthHeight(EFileFormat format, S32& width, S32& height);
	static S32 formatBits(EFileFormat format);
	static S32 formatBytes(EFileFormat format, S32 width, S32 height);
	static S32 formatOffset(EFileFormat format, S32 width, S32 height, S32 max_width, S32 max_height);
	static S32 formatComponents(EFileFormat format);
	
	static EFileFormat getFormat(S32 fourcc);
	static S32 getFourCC(EFileFormat format);

	static void calcDiscardWidthHeight(S32 discard_level, EFileFormat format, S32& width, S32& height);
	static S32 calcNumMips(S32 width, S32 height);

private:
	static void extractMip(const U8 *indata, U8* mipdata, int width, int height,
						   int mip_width, int mip_height, EFileFormat format);
	
private:
	EFileFormat mFileFormat;
	S32 mHeaderSize;
};

#endif