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 typedef enum e_image_codec
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 } EImageCodec;
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 ;
00105 U8 *getData() ;
00106 BOOL isBufferInvalid() ;
00107
00108 void setSize(S32 width, S32 height, S32 ncomponents);
00109 U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1);
00110
00111 protected:
00112
00113 void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; };
00114
00115 public:
00116 static const LLString& getLastError() {return sLastErrorMessage;};
00117 static void resetLastError() {sLastErrorMessage = LLString("No Error"); };
00118 static BOOL setLastError(const LLString& message, const LLString& filename = LLString());
00119
00120 static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
00121
00122
00123
00124 static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);
00125
00126 static void setSizeOverride(BOOL enabled) { sSizeOverride = enabled; }
00127
00128 static EImageCodec getCodecFromExtension(const LLString& exten);
00129
00130 private:
00131 U8 *mData;
00132 S32 mDataSize;
00133
00134 U16 mWidth;
00135 U16 mHeight;
00136
00137 S8 mComponents;
00138
00139 BOOL mBadBufferAllocation ;
00140
00141 public:
00142 S16 mMemType;
00143
00144 static LLString sLastErrorMessage;
00145
00146 static BOOL sSizeOverride;
00147 };
00148
00149
00150 class LLImageRaw : public LLImageBase
00151 {
00152 protected:
00153 ~LLImageRaw();
00154
00155 public:
00156 LLImageRaw();
00157 LLImageRaw(U16 width, U16 height, S8 components);
00158 LLImageRaw(U8 *data, U16 width, U16 height, S8 components);
00159
00160 LLImageRaw(const LLString& filename, bool j2c_lowest_mip_only = false);
00161
00162 void deleteData();
00163 U8* allocateData(S32 size = -1);
00164 U8* reallocateData(S32 size);
00165
00166 BOOL resize(U16 width, U16 height, S8 components);
00167
00168 U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const;
00169 BOOL setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
00170 const U8 *data, U32 stride = 0, BOOL reverse_y = FALSE);
00171
00172 void clear(U8 r=0, U8 g=0, U8 b=0, U8 a=255);
00173
00174 void verticalFlip();
00175
00176 void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
00177 void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
00178 void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
00179 void scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE );
00180
00181
00182 void fill( const LLColor4U& color );
00183
00184
00185
00186
00187 void copy( LLImageRaw* src );
00188
00189
00190 void copyUnscaled( LLImageRaw* src );
00191
00192
00193 void copyUnscaled4onto3( LLImageRaw* src );
00194
00195
00196 void copyUnscaled3onto4( LLImageRaw* src );
00197
00198
00199 void copyScaled( LLImageRaw* src );
00200
00201
00202 void copyScaled3onto4( LLImageRaw* src );
00203
00204
00205 void copyScaled4onto3( LLImageRaw* src );
00206
00207
00208
00209
00210
00211 void composite( LLImageRaw* src );
00212
00213
00214 void compositeScaled4onto3( LLImageRaw* src );
00215
00216
00217 void compositeUnscaled4onto3( LLImageRaw* src );
00218
00219 protected:
00220
00221 bool createFromFile(const LLString& filename, bool j2c_lowest_mip_only = false);
00222
00223 void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step );
00224 void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len );
00225
00226 U8 fastFractionalMult(U8 a,U8 b);
00227
00228 public:
00229 static S32 sGlobalRawMemory;
00230 static S32 sRawImageCount;
00231 };
00232
00233
00234
00235 class LLImageFormatted : public LLImageBase
00236 {
00237 public:
00238 static LLImageFormatted* createFromType(S8 codec);
00239 static LLImageFormatted* createFromExtension(const LLString& instring);
00240
00241 protected:
00242 ~LLImageFormatted();
00243
00244 public:
00245 LLImageFormatted(S8 codec);
00246
00247
00248 public:
00249 void deleteData();
00250 U8* allocateData(S32 size = -1);
00251 U8* reallocateData(S32 size);
00252
00253 void dump();
00254 void sanityCheck();
00255
00256
00257 public:
00258
00259
00260 virtual S32 calcHeaderSize() { return 0; };
00261
00262 virtual S32 calcDataSize(S32 discard_level);
00263
00264 virtual S32 calcDiscardLevelBytes(S32 bytes);
00265
00266 virtual S8 getRawDiscardLevel() { return mDiscardLevel; }
00267
00268 BOOL load(const LLString& filename);
00269 BOOL save(const LLString& filename);
00270
00271 virtual BOOL updateData() = 0;
00272 void setData(U8 *data, S32 size);
00273 void appendData(U8 *data, S32 size);
00274
00275
00276 virtual BOOL decode(LLImageRaw* raw_image, F32 decode_time) = 0;
00277
00278 virtual BOOL decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel);
00279
00280 virtual BOOL encode(const LLImageRaw* raw_image, F32 encode_time) = 0;
00281
00282 S8 getCodec() const;
00283 BOOL isDecoding() const { return mDecoding ? TRUE : FALSE; }
00284 BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; }
00285 void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
00286 S8 getDiscardLevel() const { return mDiscardLevel; }
00287
00288 protected:
00289 BOOL copyData(U8 *data, S32 size);
00290
00291 protected:
00292 S8 mCodec;
00293 S8 mDecoding;
00294 S8 mDecoded;
00295 S8 mDiscardLevel;
00296
00297 public:
00298 static S32 sGlobalFormattedMemory;
00299 };
00300
00301 #endif