Merge branch 'master' into sunshine
Conflicts: indra/llimage/llimage.cpp indra/llui/llui.cpp indra/newview/llvoavatar.cpp
This commit is contained in:
@@ -210,6 +210,19 @@ U8* LLImageBase::allocateData(S32 size)
|
||||
// virtual
|
||||
U8* LLImageBase::reallocateData(S32 size)
|
||||
{
|
||||
if (size == -1)
|
||||
{
|
||||
size = mWidth * mHeight * mComponents;
|
||||
if (size <= 0)
|
||||
{
|
||||
llerrs << llformat("LLImageBase::reallocateData called with bad dimensions: %dx%dx%d", mWidth, mHeight, (S32)mComponents) << llendl;
|
||||
}
|
||||
}
|
||||
else if (size <= 0 || (size > 4096 * 4096 * 16 && !mAllowOverSize))
|
||||
{
|
||||
llerrs << "LLImageBase::reallocateData: bad size: " << size << llendl;
|
||||
}
|
||||
|
||||
if(mData && (mDataSize == size))
|
||||
return mData;
|
||||
|
||||
@@ -304,6 +317,32 @@ LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)
|
||||
++sRawImageCount;
|
||||
}
|
||||
|
||||
LLImageRaw::LLImageRaw(LLImageRaw const* src, U16 width, U16 height, U16 crop_offset, bool crop_vertically) : mCacheEntries(0)
|
||||
{
|
||||
mMemType = LLMemType::MTYPE_IMAGERAW;
|
||||
llassert_always(src);
|
||||
S8 const components = src->getComponents();
|
||||
U8 const* const data = src->getData();
|
||||
if (allocateDataSize(width, height, components))
|
||||
{
|
||||
if (crop_vertically)
|
||||
{
|
||||
llassert_always(width == src->getWidth());
|
||||
memcpy(getData(), data + width * crop_offset * components, width * height * components);
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert_always(height == src->getHeight());
|
||||
U16 const src_width = src->getWidth();
|
||||
for (U16 row = 0; row < height; ++row)
|
||||
{
|
||||
memcpy(getData() + width * row * components, data + (src_width * row + crop_offset) * components, width * components);
|
||||
}
|
||||
}
|
||||
}
|
||||
++sRawImageCount;
|
||||
}
|
||||
|
||||
/*LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only)
|
||||
: LLImageBase(), mCacheEntries(0)
|
||||
{
|
||||
@@ -522,7 +561,7 @@ void LLImageRaw::contractToPowerOfTwo(S32 max_dim, BOOL scale_image)
|
||||
scale( new_width, new_height, scale_image );
|
||||
}
|
||||
|
||||
void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)
|
||||
void LLImageRaw::biasedScaleToPowerOfTwo(S32 target_width, S32 target_height, S32 max_dim)
|
||||
{
|
||||
// Strong bias towards rounding down (to save bandwidth)
|
||||
// No bias would mean THRESHOLD == 1.5f;
|
||||
@@ -531,22 +570,22 @@ void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)
|
||||
// Find new sizes
|
||||
S32 larger_w = max_dim; // 2^n >= mWidth
|
||||
S32 smaller_w = max_dim; // 2^(n-1) <= mWidth
|
||||
while( (smaller_w > getWidth()) && (smaller_w > MIN_IMAGE_SIZE) )
|
||||
while( (smaller_w > target_width) && (smaller_w > MIN_IMAGE_SIZE) )
|
||||
{
|
||||
larger_w = smaller_w;
|
||||
smaller_w >>= 1;
|
||||
}
|
||||
S32 new_width = ( (F32)getWidth() / smaller_w > THRESHOLD ) ? larger_w : smaller_w;
|
||||
S32 new_width = ( (F32)target_width / smaller_w > THRESHOLD ) ? larger_w : smaller_w;
|
||||
|
||||
|
||||
S32 larger_h = max_dim; // 2^m >= mHeight
|
||||
S32 smaller_h = max_dim; // 2^(m-1) <= mHeight
|
||||
while( (smaller_h > getHeight()) && (smaller_h > MIN_IMAGE_SIZE) )
|
||||
while( (smaller_h > target_height) && (smaller_h > MIN_IMAGE_SIZE) )
|
||||
{
|
||||
larger_h = smaller_h;
|
||||
smaller_h >>= 1;
|
||||
}
|
||||
S32 new_height = ( (F32)getHeight() / smaller_h > THRESHOLD ) ? larger_h : smaller_h;
|
||||
S32 new_height = ( (F32)target_height / smaller_h > THRESHOLD ) ? larger_h : smaller_h;
|
||||
|
||||
|
||||
scale( new_width, new_height );
|
||||
@@ -951,75 +990,66 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
|
||||
return TRUE; // Nothing to do.
|
||||
}
|
||||
|
||||
// Reallocate the data buffer.
|
||||
U8* old_buffer = NULL;
|
||||
U8* new_buffer;
|
||||
S32 const old_width_bytes = old_width * getComponents();
|
||||
S32 const new_width_bytes = new_width * getComponents();
|
||||
S32 const min_height = llmin(old_height, new_height);
|
||||
S32 const min_width_bytes = llmin(old_width_bytes, new_width_bytes);
|
||||
|
||||
if (scale_image_data)
|
||||
{
|
||||
S32 temp_data_size = old_width * new_height * getComponents();
|
||||
llassert_always(temp_data_size > 0);
|
||||
try
|
||||
if (new_height != old_height)
|
||||
{
|
||||
std::vector<U8> temp_buffer(temp_data_size);
|
||||
|
||||
// Vertical
|
||||
for( S32 col = 0; col < old_width; col++ )
|
||||
{
|
||||
copyLineScaled( getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), old_height, new_height, old_width, old_width );
|
||||
// Resize vertically.
|
||||
old_buffer = LLImageBase::release();
|
||||
new_buffer = allocateDataSize(old_width, new_height, getComponents());
|
||||
for (S32 col = 0; col < old_width; ++col)
|
||||
{
|
||||
copyLineScaled(old_buffer + getComponents() * col, new_buffer + getComponents() * col, old_height, new_height, old_width, old_width);
|
||||
}
|
||||
LLImageBase::deleteData(old_buffer);
|
||||
}
|
||||
|
||||
deleteData();
|
||||
|
||||
U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
|
||||
|
||||
// Horizontal
|
||||
for( S32 row = 0; row < new_height; row++ )
|
||||
if (new_width != old_width)
|
||||
{
|
||||
copyLineScaled( &temp_buffer[0] + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 );
|
||||
}
|
||||
}
|
||||
catch(std::bad_alloc)
|
||||
{
|
||||
llerrs << "Out of memory in LLImageRaw::scale()" << llendl;
|
||||
// Resize horizontally.
|
||||
old_buffer = LLImageBase::release();
|
||||
new_buffer = allocateDataSize(new_width, new_height, getComponents());
|
||||
for (S32 row = 0; row < new_height; ++row)
|
||||
{
|
||||
copyLineScaled(old_buffer + old_width_bytes * row, new_buffer + new_width_bytes * row, old_width, new_width, 1, 1);
|
||||
}
|
||||
LLImageBase::deleteData(old_buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy out existing image data
|
||||
S32 temp_data_size = old_width * old_height * getComponents();
|
||||
try
|
||||
if (new_width == old_width)
|
||||
{
|
||||
std::vector<U8> temp_buffer(temp_data_size);
|
||||
memcpy(&temp_buffer[0], getData(), temp_data_size);
|
||||
|
||||
// allocate new image data, will delete old data
|
||||
U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
|
||||
|
||||
for( S32 row = 0; row < new_height; row++ )
|
||||
setSize(new_width, new_height, getComponents());
|
||||
new_buffer = reallocateData();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (row < old_height)
|
||||
old_buffer = LLImageBase::release();
|
||||
new_buffer = allocateDataSize(new_width, new_height, getComponents());
|
||||
for (S32 row = 0; row < min_height; ++row)
|
||||
{
|
||||
memcpy(new_buffer + (new_width * row * getComponents()), &temp_buffer[0] + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width));
|
||||
if (old_width < new_width)
|
||||
memcpy(new_buffer + row * new_width_bytes, old_buffer + row * old_width_bytes, min_width_bytes);
|
||||
if (new_width_bytes > old_width_bytes)
|
||||
{
|
||||
// pad out rest of row with black
|
||||
memset(new_buffer + (getComponents() * ((new_width * row) + old_width)), 0, getComponents() * (new_width - old_width));
|
||||
// Pad out rest of row with black.
|
||||
memset(new_buffer + new_width_bytes * row + old_width_bytes, 0, new_width_bytes - old_width_bytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pad remaining rows with black
|
||||
memset(new_buffer + (new_width * row * getComponents()), 0, new_width * getComponents());
|
||||
}
|
||||
LLImageBase::deleteData(old_buffer);
|
||||
}
|
||||
}
|
||||
catch(std::bad_alloc)
|
||||
if (new_height > old_height)
|
||||
{
|
||||
llwarns << "Out of memory in LLImageRaw::scale: old (w, h, c) = (" << old_width << ", " << old_height << ", " << (S32)getComponents() <<
|
||||
") ; new (w, h, c) = (" << new_width << ", " << new_height << ", " << (S32)getComponents() << ")" << llendl;
|
||||
return FALSE ;
|
||||
// Pad remaining rows with black.
|
||||
memset(new_buffer + new_width_bytes * min_height, 0, new_width_bytes * (new_height - old_height));
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user