diff options
author | Merov Linden <merov@lindenlab.com> | 2012-03-20 20:19:47 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2012-03-20 20:19:47 -0700 |
commit | 1ebcb8039369175f7f43fc19956f32c923cfe1ba (patch) | |
tree | 231d7801a87702d42f5d51e642d9ba89600eefb7 | |
parent | 4c15635527800120f98aa1402d71baa4b9fbc932 (diff) | |
parent | 4f19eb3951366ca6a3db9de4a72cb0c1f8bc89d1 (diff) |
SH-3047 : Pull changes into viewer-thx1130 repo.
-rw-r--r-- | indra/integration_tests/llimage_libtest/llimage_libtest.cpp | 68 | ||||
-rw-r--r-- | indra/llimage/llimage.cpp | 18 | ||||
-rw-r--r-- | indra/llimage/llimage.h | 7 | ||||
-rw-r--r-- | indra/llimage/llimagej2c.cpp | 3 | ||||
-rw-r--r-- | indra/llkdu/llimagej2ckdu.cpp | 10 |
5 files changed, 86 insertions, 20 deletions
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 48e876429d..36c5b67826 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 file to load, in bytes." +" If (load == 0), it will load the whole file." +" If (load == -1), it will load the size relevant to reach the requested discard level (see -d)." +" Only valid for j2c images. Default is 0 (load whole file).\n" " -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" @@ -104,22 +109,52 @@ void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &fi // Print out some statistical data on the image std::cout << "Image stats for : " << filename << ", extension : " << image->getExtension() << std::endl; - std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl; - std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getDiscardLevel()) << std::endl; - std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl; + std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl; + std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getLevels()) << std::endl; + std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl; return; } // 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)) + // We support partial loading only for j2c images + if (image->getCodec() == IMG_CODEC_J2C) { - return NULL; + // Load the header + if (!image->load(src_filename, 600)) + { + return NULL; + } + S32 h = ((LLImageJ2C*)(image.get()))->calcHeaderSize(); + S32 d = (load_size > 0 ? ((LLImageJ2C*)(image.get()))->calcDiscardLevelBytes(load_size) : 0); + S8 r = ((LLImageJ2C*)(image.get()))->getRawDiscardLevel(); + std::cout << "Merov debug : header = " << h << ", load_size = " << load_size << ", discard level = " << d << ", raw discard level = " << r << std::endl; + for (d = 0; d < MAX_DISCARD_LEVEL; d++) + { + S32 data_size = ((LLImageJ2C*)(image.get()))->calcDataSize(d); + std::cout << "Merov debug : discard_level = " << d << ", data_size = " << data_size << std::endl; + } + if (load_size < 0) + { + load_size = (discard_level != -1 ? ((LLImageJ2C*)(image.get()))->calcDataSize(discard_level) : 0); + } + // Load the requested byte range + if (!image->load(src_filename, load_size)) + { + return NULL; + } + } + else + { + // This just loads the image file stream into a buffer. No decoding done. + if (!image->load(src_filename)) + { + return NULL; + } } if( (image->getComponents() != 3) && (image->getComponents() != 4) ) @@ -310,6 +345,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 +432,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 +562,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 56e01ac851..937655a22d 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1334,7 +1334,8 @@ LLImageFormatted::LLImageFormatted(S8 codec) mCodec(codec), mDecoding(0), mDecoded(0), - mDiscardLevel(-1) + mDiscardLevel(-1), + mLevels(0) { mMemType = LLMemType::MTYPE_IMAGEFORMATTED; } @@ -1561,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(); @@ -1580,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 4469c9e860..eba8362f1c 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -294,7 +294,7 @@ public: // 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 @@ -313,6 +313,8 @@ public: BOOL isDecoded() const { return mDecoded ? TRUE : FALSE; } void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; } S8 getDiscardLevel() const { return mDiscardLevel; } + S8 getLevels() const { return mLevels; } + void setLevels(S8 nlevels) { mLevels = nlevels; } // setLastError needs to be deferred for J2C images since it may be called from a DLL virtual void resetLastError(); @@ -325,7 +327,8 @@ protected: S8 mCodec; S8 mDecoding; S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC - S8 mDiscardLevel; + S8 mDiscardLevel; // Current resolution level worked on. 0 = full res, 1 = half res, 2 = quarter res, etc... + S8 mLevels; // Number of resolution levels in that image. Min is 1. 0 means unknown. public: static S32 sGlobalFormattedMemory; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index cc8cb66d73..fbf4b769e1 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -142,6 +142,7 @@ BOOL LLImageJ2C::updateData() BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region) { + setDiscardLevel(discard_level != -1 ? discard_level : 0); return mImpl->initDecode(*this,raw_image,discard_level,region); } @@ -286,6 +287,8 @@ S32 LLImageJ2C::calcHeaderSize() // calcDataSize() returns how many bytes to read // to load discard_level (including header and higher discard levels) +// *TODO: This is deeply wrong. That size should be taken from the image file header or other +// relevant infos. In any case, this is only an approximation. S32 LLImageJ2C::calcDataSize(S32 discard_level) { discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL); diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index c156ed0cef..eed4139f3f 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -291,8 +291,13 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod } } - base.setSize(dims.size.x, dims.size.y, components); + // Get the number of resolution levels in that image + mLevels = mCodeStreamp->get_min_dwt_levels(); + // Set the base dimensions + base.setSize(dims.size.x, dims.size.y, components); + base.setLevels(mLevels); + if (!keep_codestream) { mCodeStreamp->destroy(); @@ -394,12 +399,9 @@ 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 << "j2c image dimension: width = " << dims.size.x << ", height = " << dims.size.y << ", channels = " << channels << ", levels = " << levels << llendl; if (!mTileIndicesp) { |