OpenJPEG experiment, PCH circumcision

This commit is contained in:
siana
2011-03-20 04:44:58 +01:00
parent e70a91311f
commit baac16b5d2
13 changed files with 85 additions and 63 deletions

View File

@@ -196,6 +196,13 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
}
mImpl = j2cimpl_create_func();
// Clear data size table
for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++)
{ // Array size is MAX_DISCARD_LEVEL+1
mDataSizes[i] = 0;
}
}
// virtual
@@ -371,9 +378,44 @@ S32 LLImageJ2C::calcHeaderSize()
return calcHeaderSizeJ2C();
}
// calcDataSize() returns how many bytes to read
// to load discard_level (including header and higher discard levels)
S32 LLImageJ2C::calcDataSize(S32 discard_level)
{
return calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), discard_level, mRate);
discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL);
if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth())
|| mDataSizes[0] == 0)
{
mAreaUsedForDataSizeCalcs = getHeight() * getWidth();
S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
while ( level >= 0 )
{
mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
level--;
}
/* This is technically a more correct way to calculate the size required
for each discard level, since they should include the size needed for
lower levels. Unfortunately, this doesn't work well and will lead to
download stalls. The true correct way is to parse the header. This will
all go away with http textures at some point.
// Calculate the size for each discard level. Lower levels (higher quality)
// contain the cumulative size of higher levels
S32 total_size = calcHeaderSizeJ2C();
S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
while ( level >= 0 )
{ // Add in this discard level and all before it
total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
mDataSizes[level] = total_size;
level--;
}
*/
}
return mDataSizes[discard_level];
}
S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)

View File

@@ -87,6 +87,8 @@ protected:
void updateRawDiscardLevel();
S32 mMaxBytes; // Maximum number of bytes of data to use...
S32 mDataSizes[MAX_DISCARD_LEVEL+1]; // Size of data required to reach a given level
U32 mAreaUsedForDataSizeCalcs; // Height * width used to calculate mDataSizes
S8 mRawDiscardLevel;
F32 mRate;
BOOL mReversible;

View File

@@ -151,13 +151,8 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
/* decode the stream and fill the image structure, also fill in an additional
structure to get the decoding result. This structure is a bit unusual in that
it is not received through opj, but still has some dynamically allocated fields
that need to be cleared up at the end by calling a destroy function. */
opj_codestream_info_t cinfo;
memset(&cinfo, 0, sizeof(opj_codestream_info_t));
image = opj_decode_with_info(dinfo, cio, &cinfo);
/* decode the stream and fill the image structure */
image = opj_decode(dinfo, cio);
/* close the byte stream */
opj_cio_close(cio);
@@ -171,70 +166,45 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
// The image decode failed if the return was NULL or the component
// count was zero. The latter is just a sanity check before we
// dereference the array.
if(!image)
if(!image || !image->numcomps)
{
LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL;
return TRUE; // done
}
S32 img_components = image->numcomps;
if( !img_components ) // < 1 ||img_components > 4 )
{
LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL;
llwarns << "ERROR -> decodeImpl: failed to decode image!" << llendl;
if (image)
{
opj_destroy_cstr_info(&cinfo);
opj_image_destroy(image);
}
base.decodeFailed();
return TRUE; // done
}
// sometimes we get bad data out of the cache - check to see if the decode succeeded
int decompdifference = 0;
if (cinfo.numdecompos) // sanity
for (S32 i = 0; i < image->numcomps; i++)
{
for (int comp = 0; comp < image->numcomps; comp++)
{ /* get maximum decomposition level difference, first field is from the COD header and the second
is what is actually met in the codestream, NB: if everything was ok, this calculation will
return what was set in the cp_reduce value! */
decompdifference = llmax(decompdifference, cinfo.numdecompos[comp] - image->comps[comp].resno_decoded);
}
if (decompdifference < 0) // sanity
if (image->comps[i].factor != base.getRawDiscardLevel())
{
decompdifference = 0;
// if we didn't get the discard level we're expecting, fail
opj_image_destroy(image);
base.decodeFailed();
return TRUE;
}
}
/* if OpenJPEG failed to decode all requested decomposition levels
the difference will be greater than this level */
if (decompdifference > base.getRawDiscardLevel())
if(image->numcomps <= first_channel)
{
llwarns << "not enough data for requested discard level, setting mDecoding to FALSE, difference: " << (decompdifference - base.getRawDiscardLevel()) << llendl;
opj_destroy_cstr_info(&cinfo);
opj_image_destroy(image);
base.mDecoding = FALSE;
return TRUE;
}
if(img_components <= first_channel)
{
// sanity
LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL;
llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl;
if (image)
{
opj_destroy_cstr_info(&cinfo);
opj_image_destroy(image);
}
base.decodeFailed();
return TRUE;
}
// Copy image data into our raw image format (instead of the separate channel format
S32 img_components = image->numcomps;
S32 channels = img_components - first_channel;
if( channels > max_channel_count )
channels = max_channel_count;
@@ -274,19 +244,15 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
else // Some rare OpenJPEG versions have this bug.
{
llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl;
opj_destroy_cstr_info(&cinfo);
opj_image_destroy(image);
base.decodeFailed();
return TRUE; // done
}
}
/* free opj data structures */
if (image)
{
opj_destroy_cstr_info(&cinfo);
opj_image_destroy(image);
}
/* free image data structure */
opj_image_destroy(image);
return TRUE; // done
}
@@ -349,7 +315,7 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
opj_image_cmptparm_t cmptparm[MAX_COMPS];
opj_image_t * image = NULL;
S32 numcomps = llmin((S32)raw_image.getComponents(),(S32)MAX_COMPS);
S32 numcomps = llmin((S32)raw_image.getComponents(), MAX_COMPS);
S32 width = raw_image.getWidth();
S32 height = raw_image.getHeight();

View File

@@ -75,6 +75,7 @@
#include "llfirstuse.h"
#include "llrender.h"
#include "llfont.h"
#include "llimagej2c.h"
#include "llweb.h"
#include "llsecondlifeurls.h"

View File

@@ -22,6 +22,7 @@
#include "lltexturecache.h"
#include "llimage.h"
#include "llappviewer.h"
#include "llimagej2c.h"
std::vector<LLFloaterExport*> LLFloaterExport::instances;

View File

@@ -38,6 +38,7 @@
#include "llmemory.h"
#include "llimagegl.h"
#include "llimagejpeg.h"
class LLTextEditor;
class LLLineEditor;

View File

@@ -43,6 +43,7 @@
#include "llfontgl.h"
#include "llgl.h" // for renderer
#include "llinventory.h"
#include "llimagej2c.h"
#include "llstring.h"
#include "llsys.h"
#include "llversionviewer.h"

View File

@@ -10,6 +10,7 @@
#include "llassetconverter.h"
#include "llviewerimagelist.h"
#include "llviewerimage.h"
#include "llimagej2c.h"
LLFloaterVFS* LLFloaterVFS::sInstance;
std::list<LLFloaterVFS::entry> LLFloaterVFS::mFiles;

View File

@@ -24,6 +24,7 @@
#include "llfloaterperms.h"
#include "llviewerregion.h"
#include "llviewerobjectlist.h"
#include "llimagej2c.h"
// static vars
bool LLXmlImport::sImportInProgress = false;

View File

@@ -13,6 +13,7 @@
#include "llfloater.h"
#include "lluictrlfactory.h"
#include "llscrolllistctrl.h"
#include "llimagetga.h"
std::list<LLFloaterInventoryBackup*> LLFloaterInventoryBackup::sInstances;

View File

@@ -56,6 +56,7 @@ const BOOL IMMEDIATE_NO = FALSE;
class LLMessageSystem;
class LLViewerImage;
class LLTextureView;
class LLImageJ2C;
typedef void (*LLImageCallback)(BOOL success,
LLViewerImage *src_vi,

View File

@@ -81,6 +81,10 @@
#include "lluuid.h"
#include "llvorbisencode.h"
#include "llimagejpeg.h"
#include "llimagepng.h"
#include "llimagebmp.h"
// system libraries
#include <boost/tokenizer.hpp>

View File

@@ -114,13 +114,13 @@
// Library includes from llimage
//#include "llblockdata.h"
#include "llimage.h"
#include "llimagebmp.h"
#include "llimagepng.h"
#include "llimagej2c.h"
#include "llimagejpeg.h"
#include "llimagetga.h"
#include "llmapimagetype.h"
//#include "llimage.h"
//#include "llimagebmp.h"
//#include "llimagepng.h"
//#include "llimagej2c.h"
//#include "llimagejpeg.h"
//#include "llimagetga.h"
//#include "llmapimagetype.h"
// Library includes from llmath project
//#include "camera.h"