diff options
Diffstat (limited to 'indra/llimage')
| -rw-r--r-- | indra/llimage/llimage.cpp | 133 | ||||
| -rw-r--r-- | indra/llimage/llimage.h | 73 | ||||
| -rw-r--r-- | indra/llimage/llimagebmp.cpp | 20 | ||||
| -rw-r--r-- | indra/llimage/llimagebmp.h | 8 | ||||
| -rw-r--r-- | indra/llimage/llimagedimensionsinfo.cpp | 2 | ||||
| -rw-r--r-- | indra/llimage/llimagedxt.cpp | 15 | ||||
| -rw-r--r-- | indra/llimage/llimagefilter.cpp | 4 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.cpp | 45 | ||||
| -rw-r--r-- | indra/llimage/llimagejpeg.cpp | 12 | ||||
| -rw-r--r-- | indra/llimage/llimagejpeg.h | 2 | ||||
| -rw-r--r-- | indra/llimage/llimagepng.cpp | 8 | ||||
| -rw-r--r-- | indra/llimage/llimagetga.cpp | 15 | ||||
| -rw-r--r-- | indra/llimage/llimageworker.cpp | 29 | ||||
| -rw-r--r-- | indra/llimage/llimageworker.h | 2 | ||||
| -rw-r--r-- | indra/llimage/llpngwrapper.cpp | 22 | ||||
| -rw-r--r-- | indra/llimage/llpngwrapper.h | 6 | ||||
| -rw-r--r-- | indra/llimage/tests/llimageworker_test.cpp | 4 | 
17 files changed, 288 insertions, 112 deletions
| diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index f9393dea54..281ae12491 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -614,7 +614,6 @@ const std::string& LLImage::getLastError()  //static  void LLImage::setLastError(const std::string& message)  { -	LLMutexLock m(sMutex);  	sLastErrorMessage = message;  } @@ -754,7 +753,7 @@ U8* LLImageBase::reallocateData(S32 size)  	return mData;  } -const U8* LLImageBase::getData() const	 +const U8* LLImageBase::getData() const  {   	if(mBadBufferAllocation)  	{ @@ -765,7 +764,7 @@ const U8* LLImageBase::getData() const  	return mData;   } // read only -U8* LLImageBase::getData()				 +U8* LLImageBase::getData()  {   	if(mBadBufferAllocation)  	{ @@ -778,7 +777,7 @@ U8* LLImageBase::getData()  bool LLImageBase::isBufferInvalid() const  { -	return mBadBufferAllocation || mData == NULL ; +	return mBadBufferAllocation || mData == NULL;  }  void LLImageBase::setSize(S32 width, S32 height, S32 ncomponents) @@ -854,6 +853,8 @@ LLImageRaw::~LLImageRaw()  // virtual  U8* LLImageRaw::allocateData(S32 size)  { +	LLImageDataLock lock(this); +  	U8* res = LLImageBase::allocateData(size);  	return res;  } @@ -861,12 +862,16 @@ U8* LLImageRaw::allocateData(S32 size)  // virtual  U8* LLImageRaw::reallocateData(S32 size)  { +	LLImageDataLock lock(this); +  	U8* res = LLImageBase::reallocateData(size);  	return res;  }  void LLImageRaw::releaseData()  { +    LLImageDataLock lock(this); +      LLImageBase::setSize(0, 0, 0);      LLImageBase::setDataAndSize(nullptr, 0);  } @@ -874,11 +879,15 @@ void LLImageRaw::releaseData()  // virtual  void LLImageRaw::deleteData()  { +	LLImageDataLock lock(this); +  	LLImageBase::deleteData();  }  void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)  -{  +{ +	LLImageDataLock lock(this); +  	if(data == getData())  	{  		return ; @@ -892,6 +901,8 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)  bool LLImageRaw::resize(U16 width, U16 height, S8 components)  { +	LLImageDataLock lock(this); +  	if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid())  	{  		return true; @@ -907,6 +918,8 @@ bool LLImageRaw::resize(U16 width, U16 height, S8 components)  bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,  							 const U8 *data, U32 stride, bool reverse_y)  { +	LLImageDataLock lock(this); +  	if (!getData())  	{  		return false; @@ -934,6 +947,9 @@ bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,  void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)  {  	llassert( getComponents() <= 4 ); + +	LLImageDataLock lock(this); +  	// This is fairly bogus, but it'll do for now.  	if (isBufferInvalid())  	{ @@ -974,6 +990,8 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)  // Reverses the order of the rows in the image  void LLImageRaw::verticalFlip()  { +	LLImageDataLock lock(this); +  	S32 row_bytes = getWidth() * getComponents();  	llassert(row_bytes > 0);  	std::vector<U8> line_buffer(row_bytes); @@ -991,6 +1009,8 @@ void LLImageRaw::verticalFlip()  bool LLImageRaw::optimizeAwayAlpha()  { +    LLImageDataLock lock(this); +      if (getComponents() == 4)      {          U8* data = getData(); @@ -1028,6 +1048,8 @@ bool LLImageRaw::optimizeAwayAlpha()  void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image)  { +	LLImageDataLock lock(this); +  	// Find new sizes  	S32 new_width  = expandDimToPowerOfTwo(getWidth(), max_dim);  	S32 new_height = expandDimToPowerOfTwo(getHeight(), max_dim); @@ -1037,6 +1059,8 @@ void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image)  void LLImageRaw::contractToPowerOfTwo(S32 max_dim, bool scale_image)  { +	LLImageDataLock lock(this); +  	// Find new sizes  	S32 new_width  = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE);  	S32 new_height = contractDimToPowerOfTwo(getHeight(), MIN_IMAGE_SIZE); @@ -1086,6 +1110,8 @@ S32 LLImageRaw::contractDimToPowerOfTwo(S32 curr_dim, S32 min_dim)  void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)  { +	LLImageDataLock lock(this); +  	// Find new sizes  	S32 new_width  = biasedDimToPowerOfTwo(getWidth(),max_dim);  	S32 new_height = biasedDimToPowerOfTwo(getHeight(),max_dim); @@ -1093,6 +1119,7 @@ void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)  	scale( new_width, new_height );  } +// static  // Calculates (U8)(255*(a/255.f)*(b/255.f) + 0.5f).  Thanks, Jim Blinn!  inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b )  { @@ -1101,10 +1128,13 @@ inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b )  } -void LLImageRaw::composite( LLImageRaw* src ) +void LLImageRaw::composite( const LLImageRaw* src )  {  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataSharedLock lockIn(src); +	LLImageDataLock lockOut(this); +  	if (!validateSrcAndDst("LLImageRaw::composite", src, dst))  	{  		return; @@ -1143,12 +1173,14 @@ void LLImageRaw::composite( LLImageRaw* src )  // Src and dst can be any size.  Src has 4 components.  Dst has 3 components. -void LLImageRaw::compositeScaled4onto3(LLImageRaw* src) +void LLImageRaw::compositeScaled4onto3(const LLImageRaw* src)  {  	LL_INFOS() << "compositeScaled4onto3" << LL_ENDL;  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataLock lock(this); +  	llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );  	S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents(); @@ -1170,14 +1202,16 @@ void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)  // Src and dst are same size.  Src has 4 components.  Dst has 3 components. -void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src ) +void LLImageRaw::compositeUnscaled4onto3( const LLImageRaw* src )  {  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataLock lock(this); +  	llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );  	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); -	U8* src_data = src->getData(); +	const U8* src_data = src->getData();  	U8* dst_data = dst->getData();  	S32 pixels = getWidth() * getHeight();  	while( pixels-- ) @@ -1207,10 +1241,13 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )  } -void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) +void LLImageRaw::copyUnscaledAlphaMask( const LLImageRaw* src, const LLColor4U& fill)  {  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataSharedLock lockIn(src); +	LLImageDataLock lockOut(this); +  	if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst))  	{  		return; @@ -1221,7 +1258,7 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)  	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );  	S32 pixels = getWidth() * getHeight(); -	U8* src_data = src->getData(); +	const U8* src_data = src->getData();  	U8* dst_data = dst->getData();  	for ( S32 i = 0; i < pixels; i++ )  	{ @@ -1238,6 +1275,8 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)  // Fill the buffer with a constant color  void LLImageRaw::fill( const LLColor4U& color )  { +	LLImageDataLock lock(this); +  	if (isBufferInvalid())  	{  		LL_WARNS() << "Invalid image buffer" << LL_ENDL; @@ -1275,16 +1314,21 @@ LLPointer<LLImageRaw> LLImageRaw::duplicate()  		return this; //nobody else refences to this image, no need to duplicate.  	} +	LLImageDataSharedLock lock(this); +  	//make a duplicate  	LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents());  	return dup;   }  // Src and dst can be any size.  Src and dst can each have 3 or 4 components. -void LLImageRaw::copy(LLImageRaw* src) +void LLImageRaw::copy(const LLImageRaw* src)  {  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataSharedLock lockIn(src); +	LLImageDataLock lockOut(this); +  	if (!validateSrcAndDst("LLImageRaw::copy", src, dst))  	{  		return; @@ -1330,10 +1374,12 @@ void LLImageRaw::copy(LLImageRaw* src)  }  // Src and dst are same size.  Src and dst have same number of components. -void LLImageRaw::copyUnscaled(LLImageRaw* src) +void LLImageRaw::copyUnscaled(const LLImageRaw* src)  {  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataLock lock(this); +  	llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );  	llassert( src->getComponents() == dst->getComponents() );  	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); @@ -1343,7 +1389,7 @@ void LLImageRaw::copyUnscaled(LLImageRaw* src)  // Src and dst can be any size.  Src has 3 components.  Dst has 4 components. -void LLImageRaw::copyScaled3onto4(LLImageRaw* src) +void LLImageRaw::copyScaled3onto4(const LLImageRaw* src)  {  	llassert( (3 == src->getComponents()) && (4 == getComponents()) ); @@ -1355,7 +1401,7 @@ void LLImageRaw::copyScaled3onto4(LLImageRaw* src)  // Src and dst can be any size.  Src has 4 components.  Dst has 3 components. -void LLImageRaw::copyScaled4onto3(LLImageRaw* src) +void LLImageRaw::copyScaled4onto3(const LLImageRaw* src)  {  	llassert( (4 == src->getComponents()) && (3 == getComponents()) ); @@ -1367,15 +1413,17 @@ void LLImageRaw::copyScaled4onto3(LLImageRaw* src)  // Src and dst are same size.  Src has 4 components.  Dst has 3 components. -void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src ) +void LLImageRaw::copyUnscaled4onto3( const LLImageRaw* src )  {  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataLock lock(this); +  	llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) );  	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );  	S32 pixels = getWidth() * getHeight(); -	U8* src_data = src->getData(); +	const U8* src_data = src->getData();  	U8* dst_data = dst->getData();  	for( S32 i=0; i<pixels; i++ )  	{ @@ -1389,15 +1437,18 @@ void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src )  // Src and dst are same size.  Src has 3 components.  Dst has 4 components. -void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src ) +void LLImageRaw::copyUnscaled3onto4( const LLImageRaw* src )  {  	LLImageRaw* dst = this;  // Just for clarity. + +	LLImageDataLock lock(this); +  	llassert( 3 == src->getComponents() );  	llassert( 4 == dst->getComponents() );  	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );  	S32 pixels = getWidth() * getHeight(); -	U8* src_data = src->getData(); +	const U8* src_data = src->getData();  	U8* dst_data = dst->getData();  	for( S32 i=0; i<pixels; i++ )  	{ @@ -1412,10 +1463,13 @@ void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )  // Src and dst can be any size.  Src and dst have same number of components. -void LLImageRaw::copyScaled( LLImageRaw* src ) +void LLImageRaw::copyScaled( const LLImageRaw* src )  {  	LLImageRaw* dst = this;  // Just for clarity. +	LLImageDataSharedLock lockIn(src); +	LLImageDataLock lockOut(this); +  	if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst))  	{  		return; @@ -1457,6 +1511,8 @@ void LLImageRaw::copyScaled( LLImageRaw* src )  bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )  { +    LLImageDataLock lock(this); +      S32 components = getComponents();      if (components != 1 && components != 3 && components != 4)      { @@ -1543,6 +1599,8 @@ LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height)  {      LLPointer<LLImageRaw> result; +    LLImageDataLock lock(this); +      S32 components = getComponents();      if (components != 1 && components != 3 && components != 4)      { @@ -1588,7 +1646,7 @@ LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height)      return result;  } -void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ) +void LLImageRaw::copyLineScaled( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step )  {  	const S32 components = getComponents();  	llassert( components >= 1 && components <= 4 ); @@ -1615,7 +1673,7 @@ void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixe  			S32 t0 = x * out_pixel_step * components;  			S32 t1 = index0 * in_pixel_step * components;  			U8* outp = out + t0; -			U8* inp = in + t1; +			const U8* inp = in + t1;  			for (S32 i = 0; i < components; ++i)  			{  				*outp = *inp; @@ -1703,7 +1761,7 @@ void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixe  	}  } -void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ) +void LLImageRaw::compositeRowScaled4onto3( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len )  {  	llassert( getComponents() == 3 ); @@ -1799,8 +1857,12 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3  	}  } -bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst) +// static +bool LLImageRaw::validateSrcAndDst(std::string func, const LLImageRaw* src, const LLImageRaw* dst)  { +	LLImageDataSharedLock lockIn(src); +	LLImageDataLock lockOut(dst); +  	if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())  	{  		LL_WARNS() << func << ": Source: "; @@ -2113,6 +2175,8 @@ bool LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32  decode_time, S3  // virtual  U8* LLImageFormatted::allocateData(S32 size)  { +	LLImageDataLock lock(this); +  	U8* res = LLImageBase::allocateData(size); // calls deleteData()  	sGlobalFormattedMemory += getDataSize();  	return res; @@ -2121,6 +2185,8 @@ U8* LLImageFormatted::allocateData(S32 size)  // virtual  U8* LLImageFormatted::reallocateData(S32 size)  { +	LLImageDataLock lock(this); +  	sGlobalFormattedMemory -= getDataSize();  	U8* res = LLImageBase::reallocateData(size);  	sGlobalFormattedMemory += getDataSize(); @@ -2130,6 +2196,12 @@ U8* LLImageFormatted::reallocateData(S32 size)  // virtual  void LLImageFormatted::deleteData()  { +    LLImageDataLock lock(this); + +    if (mDecoding) +    { +        LL_ERRS() << "LLImageFormatted::deleteData() is called during decoding" << LL_ENDL; +    }  	sGlobalFormattedMemory -= getDataSize();  	LLImageBase::deleteData();  } @@ -2155,6 +2227,8 @@ void LLImageFormatted::sanityCheck()  bool LLImageFormatted::copyData(U8 *data, S32 size)  { +	LLImageDataLock lock(this); +  	if ( data && ((data != getData()) || (size != getDataSize())) )  	{  		deleteData(); @@ -2167,6 +2241,8 @@ bool LLImageFormatted::copyData(U8 *data, S32 size)  // LLImageFormatted becomes the owner of data  void LLImageFormatted::setData(U8 *data, S32 size)  { +	LLImageDataLock lock(this); +  	if (data && data != getData())  	{  		deleteData(); @@ -2180,6 +2256,8 @@ void LLImageFormatted::appendData(U8 *data, S32 size)  {  	if (data)  	{ +		LLImageDataLock lock(this); +  		if (!getData())  		{  			setData(data, size); @@ -2221,6 +2299,9 @@ bool LLImageFormatted::load(const std::string &filename, int load_size)  	{  		load_size = file_size;  	} + +	LLImageDataLock lock(this); +  	bool res;  	U8 *data = allocateData(load_size);  	if (data) @@ -2258,7 +2339,9 @@ bool LLImageFormatted::save(const std::string &filename)  		setLastError("Unable to open file for writing", filename);  		return false;  	} -	 + +	LLImageDataSharedLock lock(this); +  	S32 result = outfile.write(getData(), getDataSize());  	outfile.close() ;      return (result != 0); diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 8f9e1b3c54..cc6a58f417 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -116,7 +116,11 @@ class LLImageBase  {  protected:  	virtual ~LLImageBase(); -	 + +	virtual void deleteData(); +	virtual U8* allocateData(S32 size = -1); +	virtual U8* reallocateData(S32 size = -1); +  public:  	LLImageBase(); @@ -126,10 +130,6 @@ public:  		TYPE_AVATAR_BAKE = 1,  	}; -	virtual void deleteData(); -	virtual U8* allocateData(S32 size = -1); -	virtual U8* reallocateData(S32 size = -1); -  	virtual void dump();  	virtual void sanityCheck(); @@ -171,10 +171,27 @@ private:  	S8 mComponents; -	bool mBadBufferAllocation ; -	bool mAllowOverSize ; +	bool mBadBufferAllocation; +	bool mAllowOverSize; + +private: +    mutable LLSharedMutex mDataMutex; + +public: +    template<bool SHARED> +    class DataLock : LLSharedMutexLockTemplate<SHARED> +    { +    public: +        DataLock(const LLImageBase* image) +        : LLSharedMutexLockTemplate<SHARED>(image ? &image->mDataMutex : nullptr) +        { +        } +    };  }; +using LLImageDataLock = LLImageBase::DataLock<false>; +using LLImageDataSharedLock = LLImageBase::DataLock<true>; +  // Raw representation of an image (used for textures, and other uncompressed formats  class LLImageRaw : public LLImageBase  { @@ -231,51 +248,51 @@ public:  	LLPointer<LLImageRaw> duplicate();  	// Src and dst can be any size.  Src and dst can each have 3 or 4 components. -	void copy( LLImageRaw* src ); +	void copy( const LLImageRaw* src );  	// Src and dst are same size.  Src and dst have same number of components. -	void copyUnscaled( LLImageRaw* src ); +	void copyUnscaled( const LLImageRaw* src );  	// Src and dst are same size.  Src has 4 components.  Dst has 3 components. -	void copyUnscaled4onto3( LLImageRaw* src ); +	void copyUnscaled4onto3( const LLImageRaw* src );  	// Src and dst are same size.  Src has 3 components.  Dst has 4 components. -	void copyUnscaled3onto4( LLImageRaw* src ); +	void copyUnscaled3onto4( const LLImageRaw* src );  	// Src and dst are same size.  Src has 1 component.  Dst has 4 components.  	// Alpha component is set to source alpha mask component.  	// RGB components are set to fill color. -	void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill); +	void copyUnscaledAlphaMask( const LLImageRaw* src, const LLColor4U& fill);  	// Src and dst can be any size.  Src and dst have same number of components. -	void copyScaled( LLImageRaw* src ); - -	// Src and dst can be any size.  Src has 3 components.  Dst has 4 components. -	void copyScaled3onto4( LLImageRaw* src ); - -	// Src and dst can be any size.  Src has 4 components.  Dst has 3 components. -	void copyScaled4onto3( LLImageRaw* src ); +	void copyScaled( const LLImageRaw* src );  	// Composite operations  	// Src and dst can be any size.  Src and dst can each have 3 or 4 components. -	void composite( LLImageRaw* src ); +	void composite( const LLImageRaw* src ); +protected:  	// Src and dst can be any size.  Src has 4 components.  Dst has 3 components. -	void compositeScaled4onto3( LLImageRaw* src ); +	void compositeScaled4onto3( const LLImageRaw* src );  	// Src and dst are same size.  Src has 4 components.  Dst has 3 components. -	void compositeUnscaled4onto3( LLImageRaw* src ); +	void compositeUnscaled4onto3( const LLImageRaw* src ); + +	// Src and dst can be any size.  Src has 3 components.  Dst has 4 components. +	void copyScaled3onto4( const LLImageRaw* src ); + +	// Src and dst can be any size.  Src has 4 components.  Dst has 3 components. +	void copyScaled4onto3( const LLImageRaw* src ); -protected:  	// Create an image from a local file (generally used in tools)  	//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false); -	void copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ); -	void compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ); +	void copyLineScaled( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ); +	void compositeRowScaled4onto3( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ); -	U8	fastFractionalMult(U8 a,U8 b); +	static U8 fastFractionalMult(U8 a, U8 b);  	void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ; @@ -283,7 +300,7 @@ public:  	static S32 sRawImageCount;  private: -	bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst); +	static bool validateSrcAndDst(std::string func, const LLImageRaw* src, const LLImageRaw* dst);  };  // Compressed representation of image. @@ -356,7 +373,7 @@ protected:  	S8 mDecoded;  // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC  	S8 mDiscardLevel;	// Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc...  	S8 mLevels;			// Number of resolution levels in that image. Min is 1. 0 means unknown. -	 +  public:  	static S32 sGlobalFormattedMemory;  }; diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index cdea0da68d..d0881bb9ff 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -96,6 +96,8 @@ bool LLImageBMP::updateData()  {  	resetLastError(); +	LLImageDataLock lock(this); +  	// Check to make sure that this instance has been initialized with data  	U8* mdata = getData();  	if (!mdata || (0 == getDataSize())) @@ -337,8 +339,11 @@ bool LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)  	resetLastError(); +	LLImageDataLock lockIn(this); +	LLImageDataLock lockOut(raw_image); +  	// Check to make sure that this instance has been initialized with data -	U8* mdata = getData(); +	const U8* mdata = getData();  	if (!mdata || (0 == getDataSize()))  	{  		setLastError("llimagebmp trying to decode an image with no data!"); @@ -351,7 +356,7 @@ bool LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)  		return false;  	} -	U8* src = mdata + mBitmapOffset; +	const U8* src = mdata + mBitmapOffset;  	U8* dst = raw_image->getData();  	bool success = false; @@ -398,7 +403,7 @@ U32 LLImageBMP::countTrailingZeros( U32 m )  } -bool LLImageBMP::decodeColorMask16( U8* dst, U8* src ) +bool LLImageBMP::decodeColorMask16( U8* dst, const U8* src )  {  	llassert( 16 == mBitsPerPixel ); @@ -434,7 +439,7 @@ bool LLImageBMP::decodeColorMask16( U8* dst, U8* src )  	return true;  } -bool LLImageBMP::decodeColorMask32( U8* dst, U8* src ) +bool LLImageBMP::decodeColorMask32( U8* dst, const U8* src )  {  	// Note: alpha is not supported @@ -478,7 +483,7 @@ bool LLImageBMP::decodeColorMask32( U8* dst, U8* src )  } -bool LLImageBMP::decodeColorTable8( U8* dst, U8* src ) +bool LLImageBMP::decodeColorTable8( U8* dst, const U8* src )  {  	llassert( (8 == mBitsPerPixel) && (mColorPaletteColors >= 256) ); @@ -508,7 +513,7 @@ bool LLImageBMP::decodeColorTable8( U8* dst, U8* src )  } -bool LLImageBMP::decodeTruecolor24( U8* dst, U8* src ) +bool LLImageBMP::decodeTruecolor24( U8* dst, const U8* src )  {  	llassert( 24 == mBitsPerPixel );  	llassert( 3 == getComponents() ); @@ -542,6 +547,9 @@ bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)  	resetLastError(); +	LLImageDataSharedLock lockIn(raw_image); +	LLImageDataLock lockOut(this); +  	S32 src_components = raw_image->getComponents();  	S32 dst_components =  ( src_components < 3 ) ? 1 : 3; diff --git a/indra/llimage/llimagebmp.h b/indra/llimage/llimagebmp.h index 6a5fa4697d..295f96e541 100644 --- a/indra/llimage/llimagebmp.h +++ b/indra/llimage/llimagebmp.h @@ -45,10 +45,10 @@ public:  	/*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time);  protected: -	bool		decodeColorTable8( U8* dst, U8* src ); -	bool		decodeColorMask16( U8* dst, U8* src ); -	bool		decodeTruecolor24( U8* dst, U8* src ); -	bool		decodeColorMask32( U8* dst, U8* src ); +	bool		decodeColorTable8( U8* dst, const U8* src ); +	bool		decodeColorMask16( U8* dst, const U8* src ); +	bool		decodeTruecolor24( U8* dst, const U8* src ); +	bool		decodeColorMask32( U8* dst, const U8* src );  	U32			countTrailingZeros( U32 m ); diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp index 9dd69ff132..c5e4b76012 100644 --- a/indra/llimage/llimagedimensionsinfo.cpp +++ b/indra/llimage/llimagedimensionsinfo.cpp @@ -201,7 +201,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()  	jpeg_create_decompress	(&cinfo);  	jpeg_stdio_src		(&cinfo, fp); -	jpeg_read_header	(&cinfo, TRUE); +	jpeg_read_header	(&cinfo, true);  	cinfo.out_color_space = JCS_RGB;  	jpeg_start_decompress	(&cinfo); diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index ae76c5243f..07e44c615c 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -176,6 +176,8 @@ bool LLImageDXT::updateData()  {  	resetLastError(); +	LLImageDataLock lock(this); +  	U8* data = getData();  	S32 data_size = getDataSize(); @@ -268,7 +270,10 @@ bool LLImageDXT::decode(LLImageRaw* raw_image, F32 time)  		LL_WARNS() << "Attempt to decode compressed LLImageDXT to Raw (unsupported)" << LL_ENDL;  		return false;  	} -	 + +	LLImageDataSharedLock lockIn(this); +	LLImageDataLock lockOut(raw_image); +  	S32 width = getWidth(), height = getHeight();  	S32 ncomponents = getComponents();  	U8* data = NULL; @@ -309,6 +314,9 @@ bool LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard)  	{  		LL_ERRS() << "Request for invalid discard level" << LL_ENDL;  	} + +	LLImageDataSharedLock lock(this); +  	U8* data = getData() + getMipOffset(discard);  	S32 width = 0;  	S32 height = 0; @@ -339,6 +347,8 @@ bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_  		return 0;  	} +	LLImageDataLock lock(this); +  	S32 width = raw_image->getWidth();  	S32 height = raw_image->getHeight(); @@ -430,6 +440,9 @@ bool LLImageDXT::convertToDXR()  		return false;  	}  	mFileFormat = newformat; + +	LLImageDataLock lock(this); +  	S32 width = getWidth(), height = getHeight();  	S32 nmips = calcNumMips(width,height);  	S32 total_bytes = getDataSize(); diff --git a/indra/llimage/llimagefilter.cpp b/indra/llimage/llimagefilter.cpp index 41adc7be9a..61c2e1d742 100644 --- a/indra/llimage/llimagefilter.cpp +++ b/indra/llimage/llimagefilter.cpp @@ -87,7 +87,9 @@ LLImageFilter::~LLImageFilter()  void LLImageFilter::executeFilter(LLPointer<LLImageRaw> raw_image)  {      mImage = raw_image; -     + +    LLImageDataLock lock(mImage); +  	//std::cout << "Filter : size = " << mFilterData.size() << std::endl;  	for (S32 i = 0; i < mFilterData.size(); ++i)  	{ diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 68598589b8..382da40dcf 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -107,6 +107,8 @@ bool LLImageJ2C::updateData()  	bool res = true;  	resetLastError(); +	LLImageDataLock lock(this); +  	// Check to make sure that this instance has been initialized with data  	if (!getData() || (getDataSize() < 16))  	{ @@ -157,36 +159,48 @@ bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	LLTimer elapsed; -	bool res = true; -	  	resetLastError(); -	// Check to make sure that this instance has been initialized with data -	if (!getData() || (getDataSize() < 16)) +	bool res;  	{ -		setLastError("LLImageJ2C uninitialized"); -		res = true; // done -	} -	else -	{ -		// Update the raw discard level -		updateRawDiscardLevel(); +		LLImageDataLock lock(this); +  		mDecoding = true; -		res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count); +		// Check to make sure that this instance has been initialized with data +		if (!getData() || (getDataSize() < 16)) +		{ +			setLastError("LLImageJ2C uninitialized"); +			res = true; // done +		} +		else +		{ +			// Update the raw discard level +			updateRawDiscardLevel(); +			res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count); +		}  	} -	 +  	if (res)  	{  		if (!mDecoding)  		{  			// Failed  			raw_imagep->deleteData(); +			res = false;  		}  		else  		{  			mDecoding = false;  		}  	} +	else +	{ +		if (mDecoding) +		{ +			LL_WARNS() << "decodeImpl failed but mDecoding is true" << LL_ENDL; +			mDecoding = false; +		} +	}  	if (!mLastError.empty())  	{ @@ -406,9 +420,10 @@ bool LLImageJ2C::loadAndValidate(const std::string &filename)  bool LLImageJ2C::validate(U8 *data, U32 file_size)  { -  	resetLastError(); -	 + +	LLImageDataLock lock(this); +  	setData(data, file_size);  	bool res = updateData(); diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index 32a5472ec8..a35171601a 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -50,6 +50,8 @@ bool LLImageJPEG::updateData()  {  	resetLastError(); +	LLImageDataLock lock(this); +  	// Check to make sure that this instance has been initialized with data  	if (!getData() || (0 == getDataSize()))  	{ @@ -188,7 +190,10 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)  	llassert_always(raw_image);  	resetLastError(); -	 + +	LLImageDataLock lockIn(this); +	LLImageDataLock lockOut(raw_image); +  	// Check to make sure that this instance has been initialized with data  	if (!getData() || (0 == getDataSize()))  	{ @@ -408,6 +413,8 @@ void LLImageJPEG::encodeTermDestination( j_compress_ptr cinfo )  {  	LLImageJPEG* self = (LLImageJPEG*) cinfo->client_data; +	LLImageDataLock lock(self); +  	S32 file_bytes = (S32)(self->mOutputBufferSize - cinfo->dest->free_in_buffer);  	self->allocateData(file_bytes); @@ -484,6 +491,9 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )  	resetLastError(); +	LLImageDataSharedLock lockIn(raw_image); +	LLImageDataLock lockOut(this); +  	switch( raw_image->getComponents() )  	{  	case 1: diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h index 7a849a8421..d674b40b8f 100644 --- a/indra/llimage/llimagejpeg.h +++ b/indra/llimage/llimagejpeg.h @@ -73,8 +73,6 @@ public:  	static void		errorEmitMessage(j_common_ptr cinfo, int msg_level);  	static void		errorOutputMessage(j_common_ptr cinfo); -	static bool		decompress(LLImageJPEG* imagep); -  protected:  	U8*				mOutputBuffer;		// temp buffer used during encoding  	S32				mOutputBufferSize;	// bytes in mOuputBuffer diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp index c4b98d8260..5d956bfb4e 100644 --- a/indra/llimage/llimagepng.cpp +++ b/indra/llimage/llimagepng.cpp @@ -51,6 +51,8 @@ bool LLImagePNG::updateData()  {      resetLastError(); +    LLImageDataLock lock(this); +      // Check to make sure that this instance has been initialized with data      if (!getData() || (0 == getDataSize()))      { @@ -87,6 +89,9 @@ bool LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)      resetLastError(); +    LLImageDataSharedLock lockIn(this); +    LLImageDataLock lockOut(raw_image); +      // Check to make sure that this instance has been initialized with data      if (!getData() || (0 == getDataSize()))      { @@ -119,6 +124,9 @@ bool LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)      resetLastError(); +	LLImageDataSharedLock lockIn(raw_image); +	LLImageDataLock lockOut(this); +  	// Image logical size  	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents()); diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp index 152a7f309c..0201cc6413 100644 --- a/indra/llimage/llimagetga.cpp +++ b/indra/llimage/llimagetga.cpp @@ -108,6 +108,8 @@ bool LLImageTGA::updateData()  {  	resetLastError(); +	LLImageDataLock lock(this); +  	// Check to make sure that this instance has been initialized with data  	if (!getData() || (0 == getDataSize()))  	{ @@ -327,7 +329,10 @@ bool LLImageTGA::updateData()  bool LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)  {  	llassert_always(raw_image); -	 + +	LLImageDataSharedLock lockIn(this); +	LLImageDataLock lockOut(raw_image); +  	// Check to make sure that this instance has been initialized with data  	if (!getData() || (0 == getDataSize()))  	{ @@ -643,7 +648,10 @@ bool LLImageTGA::decodeColorMap( LLImageRaw* raw_image, bool rle, bool flipped )  bool LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)  {  	llassert_always(raw_image); -	 + +	LLImageDataSharedLock lockIn(raw_image); +	LLImageDataLock lockOut(this); +  	deleteData();  	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents()); @@ -1062,6 +1070,9 @@ bool LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight  	// --+---Input--------------------------------  	//   | +	LLImageDataSharedLock lockIn(this); +	LLImageDataLock lockOut(raw_image); +  	if (!getData() || (0 == getDataSize()))  	{  		setLastError("LLImageTGA trying to decode an image with no data!"); diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index fd59daad3d..f97d991ca6 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -36,7 +36,7 @@ class ImageRequest  public:  	ImageRequest(const LLPointer<LLImageFormatted>& image,                   S32 discard, -                 BOOL needs_aux, +                 bool needs_aux,                   const LLPointer<LLImageDecodeThread::Responder>& responder,                   U32 request_id);  	virtual ~ImageRequest(); @@ -51,12 +51,12 @@ private:  	LLPointer<LLImageFormatted> mFormattedImage;  	S32 mDiscardLevel;      U32 mRequestId; -	BOOL mNeedsAux; +	bool mNeedsAux;  	// output  	LLPointer<LLImageRaw> mDecodedImageRaw;  	LLPointer<LLImageRaw> mDecodedImageAux; -	BOOL mDecodedRaw; -	BOOL mDecodedAux; +    bool mDecodedRaw; +    bool mDecodedAux;  	LLPointer<LLImageDecodeThread::Responder> mResponder;  }; @@ -91,7 +91,7 @@ size_t LLImageDecodeThread::getPending()  LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(      const LLPointer<LLImageFormatted>& image,       S32 discard, -    BOOL needs_aux, +    bool needs_aux,      const LLPointer<LLImageDecodeThread::Responder>& responder)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -127,14 +127,14 @@ LLImageDecodeThread::Responder::~Responder()  ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,                             S32 discard, -                           BOOL needs_aux, +                           bool needs_aux,                             const LLPointer<LLImageDecodeThread::Responder>& responder,                             U32 request_id)  	: mFormattedImage(image),  	  mDiscardLevel(discard),  	  mNeedsAux(needs_aux), -	  mDecodedRaw(FALSE), -	  mDecodedAux(FALSE), +	  mDecodedRaw(false), +	  mDecodedAux(false),  	  mResponder(responder),  	  mRequestId(request_id)  { @@ -154,9 +154,18 @@ ImageRequest::~ImageRequest()  bool ImageRequest::processRequest()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + +	if (mFormattedImage.isNull()) +		return true; +  	const F32 decode_time_slice = 0.f; //disable time slicing  	bool done = true; -	if (!mDecodedRaw && mFormattedImage.notNull()) + +	LLImageDataLock lockFormatted(mFormattedImage); +	LLImageDataLock lockDecodedRaw(mDecodedImageRaw); +	LLImageDataLock lockDecodedAux(mDecodedImageAux); + +	if (!mDecodedRaw)  	{  		// Decode primary channels  		if (mDecodedImageRaw.isNull()) @@ -182,7 +191,7 @@ bool ImageRequest::processRequest()  		// some decoders are removing data when task is complete and there were errors  		mDecodedRaw = done && mDecodedImageRaw->getData();  	} -	if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull()) +	if (done && mNeedsAux && !mDecodedAux)  	{  		// Decode aux channel  		if (!mDecodedImageAux) diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index b4ab9432e6..e7ad7ed4d0 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -49,7 +49,7 @@ public:  	// meant to resemble LLQueuedThread::handle_t  	typedef U32 handle_t;  	handle_t decodeImage(const LLPointer<LLImageFormatted>& image, -						 S32 discard, BOOL needs_aux, +						 S32 discard, bool needs_aux,  						 const LLPointer<Responder>& responder);  	size_t getPending();  	size_t update(F32 max_time_ms); diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index cad7c00042..baf1330011 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -70,7 +70,7 @@ LLPngWrapper::~LLPngWrapper()  }  // Checks the src for a valid PNG header -BOOL LLPngWrapper::isValidPng(U8* src) +bool LLPngWrapper::isValidPng(U8* src)  {  	const int PNG_BYTES_TO_CHECK = 8; @@ -78,10 +78,10 @@ BOOL LLPngWrapper::isValidPng(U8* src)  	if (sig != 0)  	{  		mErrorMessage = "Invalid or corrupt PNG file"; -		return FALSE; +		return false;  	} -	return TRUE; +	return true;  }  // Called by the libpng library when a fatal encoding or decoding error @@ -134,7 +134,7 @@ void LLPngWrapper::writeFlush(png_structp png_ptr)  // The scanline also begins at the bottom of  // the image (per SecondLife conventions) instead of at the top, so we  // must assign row-pointers in "reverse" order. -BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop) +bool LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop)  {  	try  	{ @@ -173,6 +173,8 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf  		// data space  		if (rawImage != NULL)  		{ +			LLImageDataLock lock(rawImage); +  			if (!rawImage->resize(static_cast<U16>(mWidth),  				static_cast<U16>(mHeight), mChannels))  			{ @@ -208,18 +210,18 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf  	{  		mErrorMessage = msg.what();  		releaseResources(); -		return (FALSE); +		return (false);  	}  	catch (std::bad_alloc&)  	{  		mErrorMessage = "LLPngWrapper";  		releaseResources(); -		return (FALSE); +		return (false);  	}  	// Clean up and return  	releaseResources(); -	return (TRUE); +	return (true);  }  // Do transformations to normalize the input to 8-bpp RGBA @@ -281,7 +283,7 @@ void LLPngWrapper::updateMetaData()  // Method to write raw image into PNG at dest. The raw scanline begins  // at the bottom of the image per SecondLife conventions. -BOOL LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest, size_t destSize) +bool LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest, size_t destSize)  {  	try  	{ @@ -362,11 +364,11 @@ BOOL LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest, size_t destSiz  	{  		mErrorMessage = msg.what();  		releaseResources(); -		return (FALSE); +		return (false);  	}  	releaseResources(); -	return TRUE; +	return true;  }  // Cleanup various internal structures diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index 8d42317b0f..b17e8d1f40 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -43,9 +43,9 @@ public:  		S8  mComponents;  	}; -	BOOL isValidPng(U8* src); -	BOOL readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop = NULL); -	BOOL writePng(const LLImageRaw* rawImage, U8* dst, size_t destSize); +    bool isValidPng(U8* src); +    bool readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop = NULL); +    bool writePng(const LLImageRaw* rawImage, U8* dst, size_t destSize);  	U32  getFinalSize();  	const std::string& getErrorMessage(); diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index 0a97b739b0..5bd884874b 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -98,7 +98,7 @@ namespace tut  				done = res;  				*done = false;  			} -			virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) +			virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id)  			{  				*done = true;  			} @@ -150,7 +150,7 @@ namespace tut  		ensure("LLImageDecodeThread: threaded constructor failed", mThread != NULL);  		// Insert something in the queue  		bool done = false; -		LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, FALSE, new responder_test(&done)); +		LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 0, false, new responder_test(&done));  		// Verifies we get back a valid handle  		ensure("LLImageDecodeThread:  threaded decodeImage(), returned handle is null", decodeHandle != 0);  		// Wait till the thread has time to handle the work order (though it doesn't do much per work order...) | 
