From fe7a4d0183bfb19784b61124ef4c377c9a5d42d2 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 15 Mar 2012 14:07:54 -0700
Subject: [PATCH] SH-3047 : Add a load_size argument to llimage_libtest and
 allow partial image file to be loaded.

---
 .../llimage_libtest/llimage_libtest.cpp       | 28 +++++++++++++++++--
 indra/llimage/llimage.cpp                     | 15 ++++++----
 indra/llimage/llimage.h                       |  2 +-
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index 9d524367ed7..50dde971af8 100644
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -54,6 +54,11 @@ static const char USAGE[] = "\n"
 " -o, --output <file1 .. file2> OR <type>\n"
 "        List of image files to create (assumes same order as for input files)\n"
 "        OR 3 letters file type extension to convert each input file into.\n"
+" -load, --load_size <n>\n"
+"        Portion of the input image to load, in bytes."
+"        Will load the whole image if 0 or if the size requested is more than the file size."
+"        This parameter will be applied to any input image type but really makes sense only"
+"        for j2c images."
 " -r, --region <x0, y0, x1, y1>\n"
 "        Crop region applied to the input files in pixels.\n"
 "        Only used for j2c images. Default is no region cropping.\n"
@@ -112,12 +117,12 @@ void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &fi
 }
 
 // Load an image from file and return a raw (decompressed) instance of its data
-LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, bool output_stats)
+LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, int load_size, bool output_stats)
 {
 	LLPointer<LLImageFormatted> image = create_image(src_filename);
 	
 	// This just loads the image file stream into a buffer. No decoding done.
-	if (!image->load(src_filename))
+	if (!image->load(src_filename, load_size))
 	{
 		return NULL;
 	}
@@ -310,6 +315,7 @@ int main(int argc, char** argv)
 	bool image_stats = false;
 	int* region = NULL;
 	int discard_level = -1;
+	int load_size = 0;
 	int precincts_size = -1;
 	int blocks_size = -1;
 	int levels = 0;
@@ -396,6 +402,22 @@ int main(int argc, char** argv)
 				discard_level = llclamp(discard_level,0,5);
 			}
 		}
+		else if (!strcmp(argv[arg], "--load_size") || !strcmp(argv[arg], "-load"))
+		{
+			std::string value_str;
+			if ((arg + 1) < argc)
+			{
+				value_str = argv[arg+1];
+			}
+			if (((arg + 1) >= argc) || (value_str[0] == '-'))
+			{
+				std::cout << "No valid --load_size argument given, load_size ignored" << std::endl;
+			}
+			else
+			{
+				load_size = atoi(value_str.c_str());
+			}
+		}
 		else if (!strcmp(argv[arg], "--precincts") || !strcmp(argv[arg], "-p"))
 		{
 			std::string value_str;
@@ -510,7 +532,7 @@ int main(int argc, char** argv)
 	for (; in_file != in_end; ++in_file, ++out_file)
 	{
 		// Load file
-		LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, image_stats);
+		LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, load_size, image_stats);
 		if (!raw_image)
 		{
 			std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 091e78e358a..937655a22d7 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1562,7 +1562,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
 
 //----------------------------------------------------------------------------
 
-BOOL LLImageFormatted::load(const std::string &filename)
+BOOL LLImageFormatted::load(const std::string &filename, int load_size)
 {
 	resetLastError();
 
@@ -1581,14 +1581,19 @@ BOOL LLImageFormatted::load(const std::string &filename)
 		return FALSE;
 	}
 
+	// Constrain the load size to acceptable values
+	if ((load_size == 0) || (load_size > file_size))
+	{
+		load_size = file_size;
+	}
 	BOOL res;
-	U8 *data = allocateData(file_size);
-	apr_size_t bytes_read = file_size;
+	U8 *data = allocateData(load_size);
+	apr_size_t bytes_read = load_size;
 	apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
-	if (s != APR_SUCCESS || (S32) bytes_read != file_size)
+	if (s != APR_SUCCESS || (S32) bytes_read != load_size)
 	{
 		deleteData();
-		setLastError("Unable to read entire file",filename);
+		setLastError("Unable to read file",filename);
 		res = FALSE;
 	}
 	else
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 847ba8c11c1..eba8362f1c1 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -294,7 +294,7 @@ class LLImageFormatted : public LLImageBase
 	// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
 	virtual S8  getRawDiscardLevel() { return mDiscardLevel; }
 	
-	BOOL load(const std::string& filename);
+	BOOL load(const std::string& filename, int load_size = 0);
 	BOOL save(const std::string& filename);
 
 	virtual BOOL updateData() = 0; // pure virtual
-- 
GitLab