00001
00032 #ifndef LL_LLIMAGE_H
00033 #define LL_LLIMAGE_H
00034
00035 #include "lluuid.h"
00036 #include "llstring.h"
00037 #include "llmemory.h"
00038 #include "llthread.h"
00039
00040 const S32 MIN_IMAGE_MIP = 2;
00041 const S32 MAX_IMAGE_MIP = 11;
00042 const S32 MAX_DISCARD_LEVEL = 5;
00043
00044 const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP);
00045 const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP);
00046 const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE;
00047 const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE;
00048 const S32 MAX_IMAGE_COMPONENTS = 8;
00049 const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS;
00050
00051
00052 const S32 FIRST_PACKET_SIZE = 600;
00053 const S32 MAX_IMG_PACKET_SIZE = 1000;
00054
00055
00056
00057
00058
00059 class LLImageFormatted;
00060 class LLImageRaw;
00061 class LLColor4U;
00062
00063 enum
00064 {
00065 IMG_CODEC_INVALID = 0,
00066 IMG_CODEC_RGB = 1,
00067 IMG_CODEC_J2C = 2,
00068 IMG_CODEC_BMP = 3,
00069 IMG_CODEC_TGA = 4,
00070 IMG_CODEC_JPEG = 5,
00071 IMG_CODEC_DXT = 6,
00072 IMG_CODEC_PNG = 7,
00073 IMG_CODEC_EOF = 8
00074 };
00075
00076
00077
00078 class LLImageBase : public LLThreadSafeRefCount
00079 {
00080 protected:
00081 virtual ~LLImageBase();
00082
00083 public:
00084 LLImageBase();
00085
00086 enum
00087 {
00088 TYPE_NORMAL = 0,
00089 TYPE_AVATAR_BAKE = 1,
00090 };
00091
00092 virtual void deleteData();
00093 virtual U8* allocateData(S32 size = -1);
00094 virtual U8* reallocateData(S32 size = -1);
00095
00096 virtual void dump();
00097 virtual void sanityCheck();
00098
00099 U16 getWidth() const { return mWidth; }
00100 U16 getHeight() const { return mHeight; }
00101 S8 getComponents() const { return mComponents; }
00102 S32 getDataSize() const { return mDataSize; }
00103
00104 const U8 *getData() const { return mData; }
00105 U8 *getData() { return mData; }
00106
00107 void setSize(S32 width, S32 height, S32 ncomponents);
00108 U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1);
00109
00110 protected:
00111
00112 void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; };
00113
00114 public:
00115 static const LLString& getLastError() {return sLastErrorMessage;};
00116 static void resetLastError() {sLastErrorMessage = LLString("No Error"); };
00117 static BOOL setLastError(const LLString& message, const LLString& filename = LLString());
00118
00119 static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
00120
00121
00122
00123 static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);
00124
00125 static void setSizeOverride(BOOL enabled) { sSizeOverride = enabled; }
00126
00127 private:
00128 U8 *mData;
00129 S32 mDataSize;
00130
00131 U16 mWidth;
00132 U16 mHeight;
00133
00134 S8 mComponents;
00135
00136 public:
00137 S16 mMemType;
00138
00139 static LLString sLastErrorMessage;
00140
00141 static BOOL sSizeOverride;
00142 };
00143
00144
00145 class LLImageRaw : public LLImageBase
00146 {
00147 protected:
00148 ~LLImageRaw();
00149
00150 public:
00151 LLImageRaw();
00152 LLImageRaw(U16 width, U16 height, S8 components);
00153 LLImageRaw(U8 *data, U16 width, U16 height, S8 components);
00154
00155 LLImageRaw(const LLString& filename, bool j2c_lowest_mip_only = false);
00156
00157 void deleteData();
00158 U8* allocateData(S32 size = -1);
00159 U8* reallocateData(S32 size);
00160
00161 BOOL resize(U16 width, U16 height, S8 components);
00162
00163 U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const;
00164 BOOL setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
00165 const U8 *data, U32 stride = 0, BOOL reverse_y = FALSE);
00166
00167 void clear(U8 r=0, U8 g=0, U8 b=0, U8 a=255);
00168
00169 void verticalFlip();
00170
00171 void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
00172 void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
00173 void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
00174 void scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE );
00175
00176
00177 void fill( const LLColor4U& color );
00178
00179
00180
00181
00182 void copy( LLImageRaw* src );
00183
00184
00185 void copyUnscaled( LLImageRaw* src );
00186
00187
00188 void copyUnscaled4onto3( LLImageRaw* src );
00189
00190
00191 void copyUnscaled3onto4( LLImageRaw* src );
00192
00193
00194 void copyScaled( LLImageRaw* src );
00195
00196
00197 void copyScaled3onto4( LLImageRaw* src );
00198
00199
00200 void copyScaled4onto3( LLImageRaw* src );
00201
00202
00203
00204
00205
00206 void composite( LLImageRaw* src );
00207
00208
00209 void compositeScaled4onto3( LLImageRaw* src );
00210
00211
00212 void compositeUnscaled4onto3( LLImageRaw* src );
00213
00214 protected:
00215
00216 bool createFromFile(const LLString& filename, bool j2c_lowest_mip_only = false);
00217
00218 void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );
00219 void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len );
00220
00221 U8 fastFractionalMult(U8 a,U8 b);
00222
00223 public:
00224 static S32 sGlobalRawMemory;
00225 static S32 sRawImageCount;
00226 };
00227
00228
00229
00230 class LLImageFormatted : public LLImageBase
00231 {
00232 public:
00233 static LLImageFormatted* createFromType(S8 codec);
00234 static LLImageFormatted* createFromExtension(const LLString& instring);
00235
00236 protected:
00237 ~LLImageFormatted();
00238
00239 public:
00240 LLImageFormatted(S8 codec);
00241
00242
00243 public:
00244 void deleteData();
00245 U8* allocateData(S32 size = -1);
00246 U8* reallocateData(S32 size);
00247
00248 void dump();
00249 void sanityCheck();
00250
00251
00252 public:
00253
00254
00255 virtual S32 calcHeaderSize() { return 0; };
00256
00257 virtual S32 calcDataSize(S32 discard_level);
00258
00259 virtual S32 calcDiscardLevelBytes(S32 bytes);
00260
00261 virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
00262
00263 BOOL load(const LLString& filename);
00264 BOOL save(const LLString& filename);
00265
00266 virtual BOOL updateData() = 0;
00267 void setData(U8 *data, S32 size);
00268 void appendData(U8 *data, S32 size);
00269
00270
00271 virtual BOOL decode(LLImageRaw* raw_image, F32 decode_time=0.0) = 0;
00272
00273 virtual BOOL decode(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel);
00274
00275 virtual BOOL encode(const LLImageRaw* raw_image, F32 encode_time=0.0) = 0;
00276
00277 S8 getCodec() const;
00278 BOOL isDecoding() const { return mDecoding ? TRUE : FALSE; }
00279 BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; }
00280 void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
00281 S8 getDiscardLevel() const { return mDiscardLevel; }
00282
00283 protected:
00284 BOOL copyData(U8 *data, S32 size);
00285
00286 protected:
00287 S8 mCodec;
00288 S8 mDecoding;
00289 S8 mDecoded;
00290 S8 mDiscardLevel;
00291
00292 public:
00293 static S32 sGlobalFormattedMemory;
00294 };
00295
00296 #endif