diff options
Diffstat (limited to 'linden/indra/llimage/llimage.h')
-rw-r--r-- | linden/indra/llimage/llimage.h | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/linden/indra/llimage/llimage.h b/linden/indra/llimage/llimage.h new file mode 100644 index 0000000..eb1805a --- /dev/null +++ b/linden/indra/llimage/llimage.h | |||
@@ -0,0 +1,317 @@ | |||
1 | /** | ||
2 | * @file llimage.h | ||
3 | * @brief Object for managing images and their textures. | ||
4 | * | ||
5 | * Copyright (c) 2000-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #ifndef LL_LLIMAGE_H | ||
29 | #define LL_LLIMAGE_H | ||
30 | |||
31 | #include "stdtypes.h" | ||
32 | #include "lluuid.h" | ||
33 | #include "llstring.h" | ||
34 | #include "llmemory.h" | ||
35 | #include "llworkerthread.h" | ||
36 | |||
37 | const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2 | ||
38 | const S32 MAX_IMAGE_MIP = 11; // 2048x2048 | ||
39 | const S32 MAX_DISCARD_LEVEL = 5; | ||
40 | |||
41 | const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2 | ||
42 | const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048 | ||
43 | const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE; | ||
44 | const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE; | ||
45 | const S32 MAX_IMAGE_COMPONENTS = 8; | ||
46 | const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; | ||
47 | |||
48 | // Note! These CANNOT be changed without invalidating the viewer VFS files, I think? | ||
49 | const S32 FIRST_PACKET_SIZE = 600; | ||
50 | const S32 MAX_IMG_PACKET_SIZE = 1000; | ||
51 | |||
52 | // Base classes for images. | ||
53 | // There are two major parts for the image: | ||
54 | // The compressed representation, and the decompressed representation. | ||
55 | |||
56 | class LLImageFormatted; | ||
57 | class LLImageRaw; | ||
58 | class LLColor4U; | ||
59 | |||
60 | enum | ||
61 | { | ||
62 | IMG_CODEC_INVALID = 0, | ||
63 | IMG_CODEC_RGB = 1, | ||
64 | IMG_CODEC_J2C = 2, | ||
65 | IMG_CODEC_BMP = 3, | ||
66 | IMG_CODEC_TGA = 4, | ||
67 | IMG_CODEC_JPEG = 5, | ||
68 | IMG_CODEC_DXT = 6, | ||
69 | IMG_CODEC_EOF = 7 | ||
70 | }; | ||
71 | |||
72 | //============================================================================ | ||
73 | |||
74 | class LLImageBase : public LLThreadSafeRefCount | ||
75 | { | ||
76 | protected: | ||
77 | virtual ~LLImageBase(); | ||
78 | |||
79 | public: | ||
80 | LLImageBase(); | ||
81 | |||
82 | enum | ||
83 | { | ||
84 | TYPE_NORMAL = 0, | ||
85 | TYPE_AVATAR_BAKE = 1, | ||
86 | }; | ||
87 | |||
88 | virtual void deleteData(); | ||
89 | virtual U8* allocateData(S32 size = -1); | ||
90 | virtual U8* reallocateData(S32 size = -1); | ||
91 | |||
92 | virtual void dump(); | ||
93 | virtual void sanityCheck(); | ||
94 | |||
95 | U16 getWidth() const { return mWidth; } | ||
96 | U16 getHeight() const { return mHeight; } | ||
97 | S8 getComponents() const { return mComponents; } | ||
98 | S32 getDataSize() const { return mDataSize; } | ||
99 | |||
100 | const U8 *getData() const { return mData; } // read only | ||
101 | U8 *getData() { return mData; } | ||
102 | |||
103 | void setSize(S32 width, S32 height, S32 ncomponents); | ||
104 | U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1); // setSize() + allocateData() | ||
105 | |||
106 | protected: | ||
107 | // special accessor to allow direct setting of mData and mDataSize by LLImageFormatted | ||
108 | void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }; | ||
109 | |||
110 | public: | ||
111 | static const LLString& getLastError() {return sLastErrorMessage;}; | ||
112 | static void resetLastError() {sLastErrorMessage = LLString("No Error"); }; | ||
113 | static BOOL setLastError(const LLString& message, const LLString& filename = ""); // returns FALSE | ||
114 | |||
115 | static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels); | ||
116 | |||
117 | // Function for calculating the download priority for textes | ||
118 | // <= 0 priority means that there's no need for more data. | ||
119 | static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent); | ||
120 | |||
121 | static void setSizeOverride(BOOL enabled) { sSizeOverride = enabled; } | ||
122 | |||
123 | private: | ||
124 | U8 *mData; | ||
125 | S32 mDataSize; | ||
126 | |||
127 | U16 mWidth; | ||
128 | U16 mHeight; | ||
129 | |||
130 | S8 mComponents; | ||
131 | |||
132 | public: | ||
133 | S16 mMemType; // debug | ||
134 | |||
135 | static LLString sLastErrorMessage; | ||
136 | |||
137 | static BOOL sSizeOverride; | ||
138 | }; | ||
139 | |||
140 | // Raw representation of an image (used for textures, and other uncompressed formats | ||
141 | class LLImageRaw : public LLImageBase | ||
142 | { | ||
143 | protected: | ||
144 | /*virtual*/ ~LLImageRaw(); | ||
145 | |||
146 | public: | ||
147 | LLImageRaw(); | ||
148 | LLImageRaw(U16 width, U16 height, S8 components); | ||
149 | LLImageRaw(U8 *data, U16 width, U16 height, S8 components); | ||
150 | // Construct using createFromFile (used by tools) | ||
151 | LLImageRaw(const LLString& filename, bool j2c_lowest_mip_only = false); | ||
152 | |||
153 | /*virtual*/ void deleteData(); | ||
154 | /*virtual*/ U8* allocateData(S32 size = -1); | ||
155 | /*virtual*/ U8* reallocateData(S32 size); | ||
156 | |||
157 | BOOL copyData(U8 *data, U16 width, U16 height, S8 components); | ||
158 | |||
159 | BOOL resize(U16 width, U16 height, S8 components); | ||
160 | |||
161 | U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const; | ||
162 | BOOL setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, | ||
163 | const U8 *data, U32 stride = 0, BOOL reverse_y = FALSE); | ||
164 | |||
165 | void clear(U8 r=0, U8 g=0, U8 b=0, U8 a=255); | ||
166 | |||
167 | void verticalFlip(); | ||
168 | |||
169 | void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE); | ||
170 | void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE); | ||
171 | void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE); | ||
172 | void scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE ); | ||
173 | |||
174 | // Fill the buffer with a constant color | ||
175 | void fill( const LLColor4U& color ); | ||
176 | |||
177 | // Copy operations | ||
178 | |||
179 | // Src and dst can be any size. Src and dst can each have 3 or 4 components. | ||
180 | void copy( LLImageRaw* src ); | ||
181 | |||
182 | // Src and dst are same size. Src and dst have same number of components. | ||
183 | void copyUnscaled( LLImageRaw* src ); | ||
184 | |||
185 | // Src and dst are same size. Src has 4 components. Dst has 3 components. | ||
186 | void copyUnscaled4onto3( LLImageRaw* src ); | ||
187 | |||
188 | // Src and dst are same size. Src has 3 components. Dst has 4 components. | ||
189 | void copyUnscaled3onto4( LLImageRaw* src ); | ||
190 | |||
191 | // Src and dst can be any size. Src and dst have same number of components. | ||
192 | void copyScaled( LLImageRaw* src ); | ||
193 | |||
194 | // Src and dst can be any size. Src has 3 components. Dst has 4 components. | ||
195 | void copyScaled3onto4( LLImageRaw* src ); | ||
196 | |||
197 | // Src and dst can be any size. Src has 4 components. Dst has 3 components. | ||
198 | void copyScaled4onto3( LLImageRaw* src ); | ||
199 | |||
200 | |||
201 | // Composite operations | ||
202 | |||
203 | // Src and dst can be any size. Src and dst can each have 3 or 4 components. | ||
204 | void composite( LLImageRaw* src ); | ||
205 | |||
206 | // Src and dst can be any size. Src has 4 components. Dst has 3 components. | ||
207 | void compositeScaled4onto3( LLImageRaw* src ); | ||
208 | |||
209 | // Src and dst are same size. Src has 4 components. Dst has 3 components. | ||
210 | void compositeUnscaled4onto3( LLImageRaw* src ); | ||
211 | |||
212 | protected: | ||
213 | // Create an image from a local file (generally used in tools) | ||
214 | bool createFromFile(const LLString& filename, bool j2c_lowest_mip_only = false); | ||
215 | |||
216 | void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ); | ||
217 | void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ); | ||
218 | |||
219 | U8 fastFractionalMult(U8 a,U8 b); | ||
220 | |||
221 | public: | ||
222 | static S32 sGlobalRawMemory; | ||
223 | static S32 sRawImageCount; | ||
224 | }; | ||
225 | |||
226 | // Compressed representation of image. | ||
227 | // Subclass from this class for the different representations (J2C, bmp) | ||
228 | class LLImageFormatted : public LLImageBase, public LLWorkerClass | ||
229 | { | ||
230 | public: | ||
231 | static void initClass(bool threaded = true, bool run_always = true); | ||
232 | static void cleanupClass(); | ||
233 | static LLImageFormatted* createFromExtension(const LLString& instring); | ||
234 | |||
235 | protected: | ||
236 | /*virtual*/ ~LLImageFormatted(); | ||
237 | |||
238 | public: | ||
239 | LLImageFormatted(S8 codec); | ||
240 | |||
241 | // LLImageBase | ||
242 | public: | ||
243 | /*virtual*/ void deleteData(); | ||
244 | /*virtual*/ U8* allocateData(S32 size = -1); | ||
245 | /*virtual*/ U8* reallocateData(S32 size); | ||
246 | |||
247 | /*virtual*/ void dump(); | ||
248 | /*virtual*/ void sanityCheck(); | ||
249 | |||
250 | // LLWorkerThread | ||
251 | public: | ||
252 | // called from WORKER THREAD, returns TRUE if done | ||
253 | /*virtual*/ bool doWork(S32 param); | ||
254 | private: | ||
255 | // called from MAIN THREAD | ||
256 | /*virtual*/ void startWork(S32 param); // called from addWork() | ||
257 | /*virtual*/ void endWork(S32 param, bool aborted); // called from doWork() | ||
258 | |||
259 | // New methods | ||
260 | public: | ||
261 | // calcHeaderSize() returns the maximum size of header; | ||
262 | // 0 indicates we don't know have a header and have to lead the entire file | ||
263 | virtual S32 calcHeaderSize() { return 0; }; | ||
264 | // readHeader() reads size bytes into mData, and sets width/height/ncomponents | ||
265 | virtual void readHeader(U8* data, S32 size); | ||
266 | // calcDataSize() returns how many bytes to read to load discard_level (including header) | ||
267 | virtual S32 calcDataSize(S32 discard_level); | ||
268 | // calcDiscardLevelBytes() returns the smallest valid discard level based on the number of input bytes | ||
269 | virtual S32 calcDiscardLevelBytes(S32 bytes); | ||
270 | // getRawDiscardLevel()by default returns mDiscardLevel, but may be overridden (LLImageJ2C) | ||
271 | virtual S8 getRawDiscardLevel() { return mDiscardLevel; } | ||
272 | |||
273 | BOOL load(const LLString& filename); | ||
274 | BOOL save(const LLString& filename); | ||
275 | // BOOL save(LLVFS *vfs, const LLUUID &uuid, const LLAssetType::EType type); | ||
276 | // Depricated to remove VFS dependency (see .cpp for replacement): | ||
277 | |||
278 | virtual BOOL updateData() = 0; // pure virtual | ||
279 | BOOL copyData(U8 *data, S32 size); // calls updateData() | ||
280 | BOOL setData(U8 *data, S32 size); // calls updateData() | ||
281 | BOOL appendData(U8 *data, S32 size); // use if some data (e.g header) is already loaded, calls updateData() | ||
282 | |||
283 | // Loads first 4 channels. | ||
284 | virtual BOOL decode(LLImageRaw* raw_image, F32 decode_time=0.0) = 0; | ||
285 | // Subclasses that can handle more than 4 channels should override this function. | ||
286 | virtual BOOL decode(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel); | ||
287 | |||
288 | // Decode methods to return a pointer to raw data for purposes of passing to | ||
289 | // opengl or such. This class tracks the decoded data and keeps it alive until | ||
290 | // destroyed or releaseDecodedData() is called. | ||
291 | virtual BOOL requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard = -1, F32 decode_time=0.0); | ||
292 | virtual BOOL requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, | ||
293 | S32 discard = -1, F32 decode_time=0.0); | ||
294 | virtual void releaseDecodedData(); | ||
295 | |||
296 | virtual BOOL encode(const LLImageRaw* raw_image, F32 encode_time=0.0) = 0; | ||
297 | |||
298 | S8 getCodec() const; | ||
299 | BOOL isDecoding() const { return mDecoding ? TRUE : FALSE; } | ||
300 | BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; } | ||
301 | void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; } | ||
302 | S8 getDiscardLevel() const { return mDiscardLevel; } | ||
303 | |||
304 | protected: | ||
305 | S8 mCodec; | ||
306 | S8 mDecoding; | ||
307 | S8 mDecoded; | ||
308 | S8 mDiscardLevel; | ||
309 | |||
310 | LLPointer<LLImageRaw> mDecodedImage; | ||
311 | |||
312 | public: | ||
313 | static S32 sGlobalFormattedMemory; | ||
314 | static LLWorkerThread* sWorkerThread; | ||
315 | }; | ||
316 | |||
317 | #endif | ||