summaryrefslogtreecommitdiff
path: root/indra/llimage/llimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llimage/llimage.cpp')
-rw-r--r--indra/llimage/llimage.cpp124
1 files changed, 104 insertions, 20 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index c4d7096036..b8b71cde53 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -773,7 +773,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)
@@ -849,6 +849,8 @@ LLImageRaw::~LLImageRaw()
// virtual
U8* LLImageRaw::allocateData(S32 size)
{
+ LLImageDataLock lock(this);
+
U8* res = LLImageBase::allocateData(size);
return res;
}
@@ -856,12 +858,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);
}
@@ -869,11 +875,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 ;
@@ -887,6 +897,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;
@@ -902,6 +914,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;
@@ -929,6 +943,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())
{
@@ -969,6 +986,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);
@@ -986,6 +1005,8 @@ void LLImageRaw::verticalFlip()
bool LLImageRaw::optimizeAwayAlpha()
{
+ LLImageDataLock lock(this);
+
if (getComponents() == 4)
{
U8* data = getData();
@@ -1023,6 +1044,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);
@@ -1032,6 +1055,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);
@@ -1081,6 +1106,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);
@@ -1088,6 +1115,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 )
{
@@ -1096,10 +1124,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;
@@ -1138,12 +1169,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();
@@ -1165,14 +1198,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-- )
@@ -1202,10 +1237,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;
@@ -1216,7 +1254,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++ )
{
@@ -1233,6 +1271,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;
@@ -1270,16 +1310,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;
@@ -1325,10 +1370,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()) );
@@ -1338,7 +1385,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()) );
@@ -1350,7 +1397,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()) );
@@ -1362,15 +1409,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++ )
{
@@ -1384,15 +1433,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++ )
{
@@ -1407,10 +1459,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;
@@ -1452,6 +1507,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)
{
@@ -1538,6 +1595,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)
{
@@ -1583,7 +1642,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 );
@@ -1610,7 +1669,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;
@@ -1698,7 +1757,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 );
@@ -1794,8 +1853,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: ";
@@ -2108,6 +2171,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;
@@ -2116,6 +2181,8 @@ U8* LLImageFormatted::allocateData(S32 size)
// virtual
U8* LLImageFormatted::reallocateData(S32 size)
{
+ LLImageDataLock lock(this);
+
sGlobalFormattedMemory -= getDataSize();
U8* res = LLImageBase::reallocateData(size);
sGlobalFormattedMemory += getDataSize();
@@ -2125,6 +2192,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();
}
@@ -2150,6 +2223,8 @@ void LLImageFormatted::sanityCheck()
bool LLImageFormatted::copyData(U8 *data, S32 size)
{
+ LLImageDataLock lock(this);
+
if ( data && ((data != getData()) || (size != getDataSize())) )
{
deleteData();
@@ -2162,6 +2237,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();
@@ -2175,6 +2252,8 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
{
if (data)
{
+ LLImageDataLock lock(this);
+
if (!getData())
{
setData(data, size);
@@ -2216,6 +2295,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)
@@ -2254,6 +2336,8 @@ bool LLImageFormatted::save(const std::string &filename)
return false;
}
+ LLImageDataSharedLock lock(this);
+
S32 result = outfile.write(getData(), getDataSize());
outfile.close() ;
return (result != 0);