From 53f9fbcfb7090372b781e1b73c1458174cc7c761 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Tue, 6 Sep 2016 09:11:10 -0400
Subject: add run time error checking to LLImageRaw::scale

---
 indra/llimage/llimage.cpp | 93 +++++++++++++++++++++--------------------------
 1 file changed, 42 insertions(+), 51 deletions(-)

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 91fa8c6ad1..02f1b223c2 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1401,7 +1401,12 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
 
 bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
 {
-	llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
+    S32 components = getComponents();
+	if (! ((1 == components) || (3 == components) || (4 == components) )
+    {
+        LL_WARNS() << "Invalid getComponents value (" << components << ")" << LL_ENDL;
+        return false;
+    }
 
 	S32 old_width = getWidth();
 	S32 old_height = getHeight();
@@ -1415,67 +1420,53 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
 
 	if (scale_image_data)
 	{
-		/*
-		S32 temp_data_size = old_width * new_height * getComponents();
-		llassert_always(temp_data_size > 0);
-		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 );
-		}
-
-		deleteData();
+		S32 new_data_size = new_width * new_height * components;
 
-		U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
+		if (new_data_size > 0)
+        {
+            U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size); 
+            if(NULL == new_data) 
+            {
+                return false; 
+            }
 
-		// Horizontal
-		for( S32 row = 0; row < new_height; row++ )
-		{
-			copyLineScaled( &temp_buffer[0] + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 );
-		}
-		*/
-
-		S32 new_data_size = new_width * new_height * getComponents();
-		llassert_always(new_data_size > 0);
-
-		U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size); 
-		if(NULL == new_data) 
-		{
-			return false; 
+            bilinear_scale(getData(), old_width, old_height, components, old_width*components, new_data, new_width, new_height, components, new_width*components);
+            setDataAndSize(new_data, new_width, new_height, components); 
 		}
-
-		bilinear_scale(getData(), old_width, old_height, getComponents(), old_width*getComponents(), new_data, new_width, new_height, getComponents(), new_width*getComponents());
-		setDataAndSize(new_data, new_width, new_height, getComponents()); 
 	}
 	else
 	{
 		// copy	out	existing image data
-		S32	temp_data_size = old_width * old_height	* getComponents();
+		S32	temp_data_size = old_width * old_height	* components;
 		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++ )
-		{
-			if (row	< old_height)
-			{
-				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)
-				{
-					// pad out rest	of row with	black
-					memset(new_buffer +	(getComponents() * ((new_width * row) +	old_width)), 0,	getComponents()	* (new_width - old_width));
-				}
-			}
-			else
-			{
-				// pad remaining rows with black
-				memset(new_buffer +	(new_width * row * getComponents()), 0,	new_width *	getComponents());
-			}
-		}
+		U8*	new_buffer = allocateDataSize(new_width, new_height, components);
+
+        if (!new_buffer)
+        {
+            LL_WARNS() << "Failed to allocate new image data buffer" << LL_ENDL;
+            return false;
+        }
+        
+        for( S32 row = 0; row <	new_height;	row++ )
+        {
+            if (row	< old_height)
+            {
+                memcpy(new_buffer +	(new_width * row * components), &temp_buffer[0] + (old_width *	row	* components),	components * llmin(old_width, new_width));
+                if (old_width <	new_width)
+                {
+                    // pad out rest	of row with	black
+                    memset(new_buffer +	(components * ((new_width * row) +	old_width)), 0,	components * (new_width - old_width));
+                }
+            }
+            else
+            {
+                // pad remaining rows with black
+                memset(new_buffer +	(new_width * row * components), 0,	new_width *	components);
+            }
+        }
 	}
 
 	return true ;
-- 
cgit v1.2.3