diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/integration_tests/llimage_libtest/llimage_libtest.cpp | 31 | ||||
| -rw-r--r-- | indra/llimage/llimage.h | 13 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.cpp | 4 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.h | 4 | ||||
| -rw-r--r-- | indra/llimagej2coj/llimagej2coj.cpp | 2 | ||||
| -rw-r--r-- | indra/llimagej2coj/llimagej2coj.h | 2 | ||||
| -rw-r--r-- | indra/llkdu/llimagej2ckdu.cpp | 37 | ||||
| -rw-r--r-- | indra/llkdu/llimagej2ckdu.h | 3 | ||||
| -rw-r--r-- | indra/llkdu/tests/llimagej2ckdu_test.cpp | 1 | 
9 files changed, 80 insertions, 17 deletions
| diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 60ddf63b21..976aae08bb 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -70,6 +70,10 @@ static const char USAGE[] = "\n"  "        be used. Blocks must be smaller than precincts. Like precincts, this option adds\n"  "        PLT, tile markers and uses RPCL.\n"  "        Only valid for output j2c images. Default is 64.\n" +" -l, --levels <n>\n" +"        Number of decomposition levels (aka discard levels) in the output image.\n" +"        The maximum number of levels authorized is 32.\n" +"        Only valid for output j2c images. Default is 5.\n"  " -rev, --reversible\n"  "        Set the compression to be lossless (reversible in j2c parlance).\n"  "        Only valid for output j2c images.\n" @@ -147,7 +151,7 @@ LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_le  }  // Save a raw image instance into a file -bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, int blocks_size, int precincts_size, bool reversible, bool output_stats) +bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, int blocks_size, int precincts_size, int levels, bool reversible, bool output_stats)  {  	LLPointer<LLImageFormatted> image = create_image(dest_filename); @@ -156,9 +160,9 @@ bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_imag  	{  		// That method doesn't exist (and likely, doesn't make sense) for any other image file format  		// hence the required cryptic cast. -		if ((blocks_size != -1) || (precincts_size != -1)) +		if ((blocks_size != -1) || (precincts_size != -1) || (levels != 0))  		{ -			((LLImageJ2C*)(image.get()))->initEncode(*raw_image, blocks_size, precincts_size); +			((LLImageJ2C*)(image.get()))->initEncode(*raw_image, blocks_size, precincts_size, levels);  		}  		((LLImageJ2C*)(image.get()))->setReversible(reversible);  	} @@ -306,6 +310,7 @@ int main(int argc, char** argv)  	int discard_level = -1;  	int precincts_size = -1;  	int blocks_size = -1; +	int levels = 0;  	bool reversible = false;  	// Init whatever is necessary @@ -403,7 +408,6 @@ int main(int argc, char** argv)  			else  			{  				precincts_size = atoi(value_str.c_str()); -				// *TODO: make sure precincts_size is a power of 2  			}  		}  		else if (!strcmp(argv[arg], "--blocks") || !strcmp(argv[arg], "-b")) @@ -420,7 +424,22 @@ int main(int argc, char** argv)  			else  			{  				blocks_size = atoi(value_str.c_str()); -				// *TODO: make sure blocks_size is a power of 2 +			} +		} +		else if (!strcmp(argv[arg], "--levels") || !strcmp(argv[arg], "-l")) +		{ +			std::string value_str; +			if ((arg + 1) < argc) +			{ +				value_str = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (value_str[0] == '-')) +			{ +				std::cout << "No valid --levels argument given, default (5) will be used" << std::endl; +			} +			else +			{ +				levels = atoi(value_str.c_str());  			}  		}  		else if (!strcmp(argv[arg], "--reversible") || !strcmp(argv[arg], "-rev")) @@ -499,7 +518,7 @@ int main(int argc, char** argv)  		// Save file  		if (out_file != out_end)  		{ -			if (!save_image(*out_file, raw_image, blocks_size, precincts_size, reversible, image_stats)) +			if (!save_image(*out_file, raw_image, blocks_size, precincts_size, levels, reversible, image_stats))  			{  				std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;  			} diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 18444f3934..c464c3b2b6 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -35,8 +35,21 @@  const S32 MIN_IMAGE_MIP =  2; // 4x4, only used for expand/contract power of 2  const S32 MAX_IMAGE_MIP = 11; // 2048x2048 + +// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number  +// of levels is read from the header's file, not inferred from its size.  const S32 MAX_DISCARD_LEVEL = 5; +// JPEG2000 size constraints +// Those are declared here as they are germane to other image constraints used in the viewer +// and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL. +const S32 MAX_DECOMPOSITION_LEVELS = 32;	// Number of decomposition levels cannot exceed 32 according to jpeg2000 spec +const S32 MIN_DECOMPOSITION_LEVELS = 5;		// the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is) +const S32 MAX_PRECINCT_SIZE = 2048;			// No reason to be bigger than MAX_IMAGE_SIZE  +const S32 MIN_PRECINCT_SIZE = 4;			// Can't be smaller than MIN_BLOCK_SIZE +const S32 MAX_BLOCK_SIZE = 64;				// Max total block size is 4096, hence 64x64 when using square blocks +const S32 MIN_BLOCK_SIZE = 4;				// Min block dim is 4 according to jpeg2000 spec +  const S32 MIN_IMAGE_SIZE = (1<<MIN_IMAGE_MIP); // 4, only used for expand/contract power of 2  const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048  const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index a90df0f1c1..44e6b89dd3 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -144,9 +144,9 @@ BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* regio  	return mImpl->initDecode(*this,raw_image,discard_level,region);  } -BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size) +BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)  { -	return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size); +	return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size,levels);  }  BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time) diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 6bba81aab5..914174fc57 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -57,7 +57,7 @@ public:  	/*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string());  	BOOL initDecode(LLImageRaw &raw_image, int discard_level, int* region); -	BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size); +	BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels);  	// Encode with comment text   	BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0); @@ -120,7 +120,7 @@ protected:  	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  							BOOL reversible=FALSE) = 0;  	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0; -	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1) = 0; +	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0) = 0;  	friend class LLImageJ2C;  }; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 8288fa1f5c..d15824ce5a 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -113,7 +113,7 @@ BOOL LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int disca  	return FALSE;  } -BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size) +BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)  {  	// No specific implementation for this method in the OpenJpeg case  	return FALSE; diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h index 9c7cc09fcb..40ad4edb00 100644 --- a/indra/llimagej2coj/llimagej2coj.h +++ b/indra/llimagej2coj/llimagej2coj.h @@ -40,7 +40,7 @@ protected:  	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  								BOOL reversible = FALSE);  	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); -	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1); +	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);  };  #endif diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index ae456a48be..f83accf356 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -29,6 +29,7 @@  #include "lltimer.h"  #include "llpointer.h" +#include "llmath.h"  #include "llkdumem.h" @@ -192,7 +193,8 @@ mTileIndicesp(NULL),  mRawImagep(NULL),  mDecodeState(NULL),  mBlocksSize(-1), -mPrecinctsSize(-1) +mPrecinctsSize(-1), +mLevels(0)  {  } @@ -328,10 +330,30 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int disc  	return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region);  } -BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size) +BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)  { -	mBlocksSize = blocks_size;  	mPrecinctsSize = precincts_size; +	if (mPrecinctsSize != -1) +	{ +		mPrecinctsSize = get_lower_power_two(mPrecinctsSize,MAX_PRECINCT_SIZE); +		mPrecinctsSize = llmax(mPrecinctsSize,MIN_PRECINCT_SIZE); +	} +	mBlocksSize = blocks_size; +	if (mBlocksSize != -1) +	{ +		mBlocksSize = get_lower_power_two(mBlocksSize,MAX_BLOCK_SIZE); +		mBlocksSize = llmax(mBlocksSize,MIN_BLOCK_SIZE); +		if (mPrecinctsSize != -1) +		{ +			mBlocksSize = llmin(mBlocksSize,mPrecinctsSize);	// blocks *must* be smaller than precincts +		} +	} +	mLevels = levels; +	if (mLevels != 0) +	{ +		mLevels = llmin(mLevels,MAX_DECOMPOSITION_LEVELS); +		mLevels = llmax(MIN_DECOMPOSITION_LEVELS,mLevels); +	}  	return TRUE;  } @@ -373,10 +395,12 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  		// Resize raw_image according to the image to be decoded  		kdu_dims dims; mCodeStreamp->get_dims(0,dims); +		// *TODO: Use the real number of levels read from the file throughout the code instead of relying on an infered value from dimensions +		//S32 levels = mCodeStreamp->get_min_dwt_levels();  		S32 channels = base.getComponents() - first_channel;  		channels = llmin(channels,max_channel_count);  		raw_image.resize(dims.size.x, dims.size.y, channels); -		//	llinfos << "Resizing raw_image to " << dims.size.x << ":" << dims.size.y << llendl; +		//llinfos << "j2c image dimension: width = " << dims.size.x << ", height = " << dims.size.y << ", channels = " << channels << ", levels = " << levels << llendl;  		if (!mTileIndicesp)  		{ @@ -653,6 +677,11 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  			std::string Parts_string = llformat("ORGtparts=R");  			codestream.access_siz()->parse_string(Parts_string.c_str());  		} +		if (mLevels != 0) +		{ +			std::string levels_string = llformat("Clevels=%d",mLevels); +			codestream.access_siz()->parse_string(levels_string.c_str()); +		}  		codestream.access_siz()->finalize_all();  		codestream.change_appearance(transpose,vflip,hflip); diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 9fce58b762..1489dbf704 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -59,7 +59,7 @@ protected:  	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  								BOOL reversible=FALSE);  	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); -	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1); +	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);  private:  	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL); @@ -73,6 +73,7 @@ private:  	kdu_dims *mTileIndicesp;  	int mBlocksSize;  	int mPrecinctsSize; +	int mLevels;  	// Temporary variables for in-progress decodes...  	LLImageRaw *mRawImagep; diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index 7ac24a969a..ab60ab6d50 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -134,6 +134,7 @@ kdu_params* kdu_params::access_cluster(const char*) { return NULL; }  void kdu_codestream::set_fast() { }  void kdu_codestream::set_fussy() { }  void kdu_codestream::get_dims(int, kdu_dims&, bool ) { } +int kdu_codestream::get_min_dwt_levels() { return 5; }  void kdu_codestream::change_appearance(bool, bool, bool) { }  void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { }  void kdu_codestream::destroy() { } | 
