From f1d2a1a4957ff6ee76d98f307bd682a36fe94038 Mon Sep 17 00:00:00 2001
From: ruslantproductengine <ruslantproductengine@lindenlab.com>
Date: Mon, 15 Sep 2014 20:26:28 +0300
Subject: MAINT-3562 FIXED Viewer crashes when updating local textures using
 Substance Designer : add code for control input buffer size

---
 indra/llimage/llimagepng.cpp   | 4 ++--
 indra/llimage/llpngwrapper.cpp | 9 ++++++++-
 indra/llimage/llpngwrapper.h   | 3 ++-
 3 files changed, 12 insertions(+), 4 deletions(-)

(limited to 'indra/llimage')

diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index 294f68b122..7735dc1379 100755
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
@@ -67,7 +67,7 @@ BOOL LLImagePNG::updateData()
 	}
 
 	LLPngWrapper::ImageInfo infop;
-	if (! pngWrapper.readPng(getData(), NULL, &infop))
+	if (! pngWrapper.readPng(getData(), getDataSize(), NULL, &infop))
 	{
 		setLastError(pngWrapper.getErrorMessage());
 		return FALSE;
@@ -102,7 +102,7 @@ BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
 		return FALSE;
 	}
 
-	if (! pngWrapper.readPng(getData(), raw_image))
+	if (! pngWrapper.readPng(getData(), getDataSize(), raw_image))
 	{
 		setLastError(pngWrapper.getErrorMessage());
 		return FALSE;
diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp
index 2cc7d3c460..aad139f570 100755
--- a/indra/llimage/llpngwrapper.cpp
+++ b/indra/llimage/llpngwrapper.cpp
@@ -87,6 +87,12 @@ void LLPngWrapper::errorHandler(png_structp png_ptr, png_const_charp msg)
 void LLPngWrapper::readDataCallback(png_structp png_ptr, png_bytep dest, png_size_t length)
 {
 	PngDataInfo *dataInfo = (PngDataInfo *) png_get_io_ptr(png_ptr);
+	if(dataInfo->mOffset + length > dataInfo->mDataSize)
+	{
+		png_error(png_ptr, "Data read error. Requested data size exceeds available data size.");
+		return;
+	}
+
 	U8 *src = &dataInfo->mData[dataInfo->mOffset];
 	memcpy(dest, src, length);
 	dataInfo->mOffset += static_cast<U32>(length);
@@ -114,7 +120,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, LLImageRaw* rawImage, ImageInfo *infop)
+BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop)
 {
 	try
 	{
@@ -133,6 +139,7 @@ BOOL LLPngWrapper::readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop)
 		PngDataInfo dataPtr;
 		dataPtr.mData = src;
 		dataPtr.mOffset = 0;
+		dataPtr.mDataSize = dataSize;
 
 		png_set_read_fn(mReadPngPtr, &dataPtr, &readDataCallback);
 		png_set_sig_bytes(mReadPngPtr, 0);
diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h
index 739f435996..27d7df3bef 100755
--- a/indra/llimage/llpngwrapper.h
+++ b/indra/llimage/llpngwrapper.h
@@ -44,7 +44,7 @@ public:
 	};
 
 	BOOL isValidPng(U8* src);
-	BOOL readPng(U8* src, LLImageRaw* rawImage, ImageInfo *infop = NULL);
+	BOOL readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop = NULL);
 	BOOL writePng(const LLImageRaw* rawImage, U8* dst);
 	U32  getFinalSize();
 	const std::string& getErrorMessage();
@@ -61,6 +61,7 @@ private:
 	{
 		U8 *mData;
 		U32 mOffset;
+		S32 mDataSize;
 	};
 
 	static void writeFlush(png_structp png_ptr);
-- 
cgit v1.2.3


From 41170b5603f9d6e6d6a9ec598ab60b9b74315b32 Mon Sep 17 00:00:00 2001
From: ruslantproductengine <ruslantproductengine@lindenlab.com>
Date: Thu, 25 Sep 2014 21:19:17 +0300
Subject: MAINT-4329 FIXED scales each image *twice* for no apparent reason :
 patchset #2

---
 indra/llimage/llimage.cpp | 66 +++++++++++------------------------------------
 indra/llimage/llimage.h   | 10 +++----
 2 files changed, 20 insertions(+), 56 deletions(-)

(limited to 'indra/llimage')

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index d336eeaabc..eaac6806ab 100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -524,7 +524,7 @@ 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.
 
@@ -560,7 +560,7 @@ 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;
 
@@ -568,26 +568,12 @@ void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
 
 	llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
 
-	S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
-	llassert_always(temp_data_size > 0);
-	std::vector<U8> temp_buffer(temp_data_size);
-
-	// Vertical: scale but no composite
-	for( S32 col = 0; col < src->getWidth(); col++ )
-	{
-		copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
-	}
-
-	// Horizontal: scale and composite
-	for( S32 row = 0; row < dst->getHeight(); row++ )
-	{
-		compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
-	}
+	ll_nn2d_interpolation(src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents());
 }
 
 
 // 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 )
 {
 	/*
 	//test fastFractionalMult()
@@ -610,7 +596,7 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
 	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-- )
@@ -751,7 +737,7 @@ 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.
 
@@ -833,7 +819,7 @@ 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.
 
@@ -846,21 +832,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
 		return;
 	}
 
-	S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents();
-	llassert_always(temp_data_size > 0);
-	std::vector<U8> temp_buffer(temp_data_size);
-
-	// Vertical
-	for( S32 col = 0; col < src->getWidth(); col++ )
-	{
-		copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
-	}
-
-	// Horizontal
-	for( S32 row = 0; row < dst->getHeight(); row++ )
-	{
-		copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 );
-	}
+	ll_nn2d_interpolation(src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents());
 }
 
 
@@ -880,25 +852,17 @@ 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);
+		S32 new_data_size = new_width * new_height * getComponents();
+		llassert_always(new_data_size > 0);
 
-		// Vertical
-		for( S32 col = 0; col < old_width; col++ )
+		U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size); 
+		if(NULL == new_data) 
 		{
-			copyLineScaled( getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), old_height, new_height, old_width, old_width );
+			return FALSE; 
 		}
 
-		deleteData();
-
-		U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
-
-		// 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 );
-		}
+		ll_nn2d_interpolation(getData(), old_width, old_height, getComponents(), new_data, new_width, new_height, getComponents());
+		setDataAndSize(new_data, new_width, new_height, getComponents());
 	}
 	else
 	{
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index cd3f76f1fd..eeb8e6de53 100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -229,7 +229,7 @@ public:
 	void copy( 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 );
@@ -243,7 +243,7 @@ public:
 	void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
 
 	// Src and dst can be any size.  Src and dst have same number of components.
-	void copyScaled( LLImageRaw* src );
+	void copyScaled( const LLImageRaw* src );
 
 	// Src and dst can be any size.  Src has 3 components.  Dst has 4 components.
 	void copyScaled3onto4( LLImageRaw* src );
@@ -255,13 +255,13 @@ public:
 	// 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 );
 
 	// 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 );
 
 protected:
 	// Create an image from a local file (generally used in tools)
-- 
cgit v1.2.3


From 96e5fc9f9b185f846b978984c673f0114409513d Mon Sep 17 00:00:00 2001
From: ruslantproductengine <ruslantproductengine@lindenlab.com>
Date: Sat, 14 Feb 2015 00:08:39 +0200
Subject: MAINT-4329 Backed out changeset: fd3a4d5c2cf5

---
 indra/llimage/llimage.cpp | 66 ++++++++++++++++++++++++++++++++++++-----------
 indra/llimage/llimage.h   | 10 +++----
 2 files changed, 56 insertions(+), 20 deletions(-)

(limited to 'indra/llimage')

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index eaac6806ab..d336eeaabc 100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -524,7 +524,7 @@ inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b )
 }
 
 
-void LLImageRaw::composite( const LLImageRaw* src )
+void LLImageRaw::composite( LLImageRaw* src )
 {
 	LLImageRaw* dst = this;  // Just for clarity.
 
@@ -560,7 +560,7 @@ void LLImageRaw::composite( const LLImageRaw* src )
 }
 
 // Src and dst can be any size.  Src has 4 components.  Dst has 3 components.
-void LLImageRaw::compositeScaled4onto3(const LLImageRaw* src)
+void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
 {
 	LL_INFOS() << "compositeScaled4onto3" << LL_ENDL;
 
@@ -568,12 +568,26 @@ void LLImageRaw::compositeScaled4onto3(const LLImageRaw* src)
 
 	llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
 
-	ll_nn2d_interpolation(src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents());
+	S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
+	llassert_always(temp_data_size > 0);
+	std::vector<U8> temp_buffer(temp_data_size);
+
+	// Vertical: scale but no composite
+	for( S32 col = 0; col < src->getWidth(); col++ )
+	{
+		copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
+	}
+
+	// Horizontal: scale and composite
+	for( S32 row = 0; row < dst->getHeight(); row++ )
+	{
+		compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
+	}
 }
 
 
 // Src and dst are same size.  Src has 4 components.  Dst has 3 components.
-void LLImageRaw::compositeUnscaled4onto3( const LLImageRaw* src )
+void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
 {
 	/*
 	//test fastFractionalMult()
@@ -596,7 +610,7 @@ void LLImageRaw::compositeUnscaled4onto3( const LLImageRaw* src )
 	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
 
 
-	const U8* src_data = src->getData();
+	U8* src_data = src->getData();
 	U8* dst_data = dst->getData();
 	S32 pixels = getWidth() * getHeight();
 	while( pixels-- )
@@ -737,7 +751,7 @@ void LLImageRaw::copy(LLImageRaw* src)
 }
 
 // Src and dst are same size.  Src and dst have same number of components.
-void LLImageRaw::copyUnscaled(const LLImageRaw* src)
+void LLImageRaw::copyUnscaled(LLImageRaw* src)
 {
 	LLImageRaw* dst = this;  // Just for clarity.
 
@@ -819,7 +833,7 @@ void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
 
 
 // Src and dst can be any size.  Src and dst have same number of components.
-void LLImageRaw::copyScaled( const LLImageRaw* src )
+void LLImageRaw::copyScaled( LLImageRaw* src )
 {
 	LLImageRaw* dst = this;  // Just for clarity.
 
@@ -832,7 +846,21 @@ void LLImageRaw::copyScaled( const LLImageRaw* src )
 		return;
 	}
 
-	ll_nn2d_interpolation(src->getData(), src->getWidth(), src->getHeight(), src->getComponents(), dst->getData(), dst->getWidth(), dst->getHeight(), dst->getComponents());
+	S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents();
+	llassert_always(temp_data_size > 0);
+	std::vector<U8> temp_buffer(temp_data_size);
+
+	// Vertical
+	for( S32 col = 0; col < src->getWidth(); col++ )
+	{
+		copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
+	}
+
+	// Horizontal
+	for( S32 row = 0; row < dst->getHeight(); row++ )
+	{
+		copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 );
+	}
 }
 
 
@@ -852,17 +880,25 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
 
 	if (scale_image_data)
 	{
-		S32 new_data_size = new_width * new_height * getComponents();
-		llassert_always(new_data_size > 0);
+		S32 temp_data_size = old_width * new_height * getComponents();
+		llassert_always(temp_data_size > 0);
+		std::vector<U8> temp_buffer(temp_data_size);
 
-		U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size); 
-		if(NULL == new_data) 
+		// Vertical
+		for( S32 col = 0; col < old_width; col++ )
 		{
-			return FALSE; 
+			copyLineScaled( getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), old_height, new_height, old_width, old_width );
 		}
 
-		ll_nn2d_interpolation(getData(), old_width, old_height, getComponents(), new_data, new_width, new_height, getComponents());
-		setDataAndSize(new_data, new_width, new_height, getComponents());
+		deleteData();
+
+		U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
+
+		// 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 );
+		}
 	}
 	else
 	{
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index eeb8e6de53..cd3f76f1fd 100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -229,7 +229,7 @@ public:
 	void copy( LLImageRaw* src );
 
 	// Src and dst are same size.  Src and dst have same number of components.
-	void copyUnscaled( const LLImageRaw* src );
+	void copyUnscaled( LLImageRaw* src );
 	
 	// Src and dst are same size.  Src has 4 components.  Dst has 3 components.
 	void copyUnscaled4onto3( LLImageRaw* src );
@@ -243,7 +243,7 @@ public:
 	void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
 
 	// Src and dst can be any size.  Src and dst have same number of components.
-	void copyScaled( const LLImageRaw* src );
+	void copyScaled( LLImageRaw* src );
 
 	// Src and dst can be any size.  Src has 3 components.  Dst has 4 components.
 	void copyScaled3onto4( LLImageRaw* src );
@@ -255,13 +255,13 @@ public:
 	// Composite operations
 
 	// Src and dst can be any size.  Src and dst can each have 3 or 4 components.
-	void composite( const LLImageRaw* src );
+	void composite( LLImageRaw* src );
 
 	// Src and dst can be any size.  Src has 4 components.  Dst has 3 components.
-	void compositeScaled4onto3( const LLImageRaw* src );
+	void compositeScaled4onto3( LLImageRaw* src );
 
 	// Src and dst are same size.  Src has 4 components.  Dst has 3 components.
-	void compositeUnscaled4onto3( const LLImageRaw* src );
+	void compositeUnscaled4onto3( LLImageRaw* src );
 
 protected:
 	// Create an image from a local file (generally used in tools)
-- 
cgit v1.2.3