OpenJPEG experiment, PCH circumcision
This commit is contained in:
@@ -196,6 +196,13 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
|
|||||||
}
|
}
|
||||||
|
|
||||||
mImpl = j2cimpl_create_func();
|
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
|
// virtual
|
||||||
@@ -371,9 +378,44 @@ S32 LLImageJ2C::calcHeaderSize()
|
|||||||
return calcHeaderSizeJ2C();
|
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)
|
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)
|
S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ protected:
|
|||||||
void updateRawDiscardLevel();
|
void updateRawDiscardLevel();
|
||||||
|
|
||||||
S32 mMaxBytes; // Maximum number of bytes of data to use...
|
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;
|
S8 mRawDiscardLevel;
|
||||||
F32 mRate;
|
F32 mRate;
|
||||||
BOOL mReversible;
|
BOOL mReversible;
|
||||||
|
|||||||
@@ -151,13 +151,8 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
/* open a byte stream */
|
/* open a byte stream */
|
||||||
cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
|
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
|
/* decode the stream and fill the image structure */
|
||||||
structure to get the decoding result. This structure is a bit unusual in that
|
image = opj_decode(dinfo, cio);
|
||||||
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);
|
|
||||||
|
|
||||||
/* close the byte stream */
|
/* close the byte stream */
|
||||||
opj_cio_close(cio);
|
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
|
// The image decode failed if the return was NULL or the component
|
||||||
// count was zero. The latter is just a sanity check before we
|
// count was zero. The latter is just a sanity check before we
|
||||||
// dereference the array.
|
// dereference the array.
|
||||||
if(!image)
|
if(!image || !image->numcomps)
|
||||||
{
|
{
|
||||||
LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL;
|
llwarns << "ERROR -> decodeImpl: failed to decode image!" << llendl;
|
||||||
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;
|
|
||||||
if (image)
|
if (image)
|
||||||
{
|
{
|
||||||
opj_destroy_cstr_info(&cinfo);
|
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base.decodeFailed();
|
||||||
return TRUE; // done
|
return TRUE; // done
|
||||||
}
|
}
|
||||||
|
|
||||||
// sometimes we get bad data out of the cache - check to see if the decode succeeded
|
// sometimes we get bad data out of the cache - check to see if the decode succeeded
|
||||||
int decompdifference = 0;
|
for (S32 i = 0; i < image->numcomps; i++)
|
||||||
if (cinfo.numdecompos) // sanity
|
|
||||||
{
|
{
|
||||||
for (int comp = 0; comp < image->numcomps; comp++)
|
if (image->comps[i].factor != base.getRawDiscardLevel())
|
||||||
{ /* 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
|
|
||||||
{
|
{
|
||||||
decompdifference = 0;
|
// if we didn't get the discard level we're expecting, fail
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* if OpenJPEG failed to decode all requested decomposition levels
|
|
||||||
the difference will be greater than this level */
|
|
||||||
if (decompdifference > base.getRawDiscardLevel())
|
|
||||||
{
|
|
||||||
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);
|
opj_image_destroy(image);
|
||||||
base.mDecoding = FALSE;
|
base.decodeFailed();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(img_components <= first_channel)
|
if(image->numcomps <= first_channel)
|
||||||
{
|
{
|
||||||
// sanity
|
llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl;
|
||||||
LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL;
|
|
||||||
if (image)
|
if (image)
|
||||||
{
|
{
|
||||||
opj_destroy_cstr_info(&cinfo);
|
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base.decodeFailed();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy image data into our raw image format (instead of the separate channel format
|
// 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;
|
S32 channels = img_components - first_channel;
|
||||||
if( channels > max_channel_count )
|
if( channels > max_channel_count )
|
||||||
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.
|
else // Some rare OpenJPEG versions have this bug.
|
||||||
{
|
{
|
||||||
llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl;
|
llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl;
|
||||||
opj_destroy_cstr_info(&cinfo);
|
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
|
|
||||||
|
base.decodeFailed();
|
||||||
return TRUE; // done
|
return TRUE; // done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free opj data structures */
|
/* free image data structure */
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
opj_destroy_cstr_info(&cinfo);
|
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE; // done
|
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_COLOR_SPACE color_space = CLRSPC_SRGB;
|
||||||
opj_image_cmptparm_t cmptparm[MAX_COMPS];
|
opj_image_cmptparm_t cmptparm[MAX_COMPS];
|
||||||
opj_image_t * image = NULL;
|
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 width = raw_image.getWidth();
|
||||||
S32 height = raw_image.getHeight();
|
S32 height = raw_image.getHeight();
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@
|
|||||||
#include "llfirstuse.h"
|
#include "llfirstuse.h"
|
||||||
#include "llrender.h"
|
#include "llrender.h"
|
||||||
#include "llfont.h"
|
#include "llfont.h"
|
||||||
|
#include "llimagej2c.h"
|
||||||
|
|
||||||
#include "llweb.h"
|
#include "llweb.h"
|
||||||
#include "llsecondlifeurls.h"
|
#include "llsecondlifeurls.h"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "lltexturecache.h"
|
#include "lltexturecache.h"
|
||||||
#include "llimage.h"
|
#include "llimage.h"
|
||||||
#include "llappviewer.h"
|
#include "llappviewer.h"
|
||||||
|
#include "llimagej2c.h"
|
||||||
|
|
||||||
std::vector<LLFloaterExport*> LLFloaterExport::instances;
|
std::vector<LLFloaterExport*> LLFloaterExport::instances;
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
#include "llmemory.h"
|
#include "llmemory.h"
|
||||||
#include "llimagegl.h"
|
#include "llimagegl.h"
|
||||||
|
#include "llimagejpeg.h"
|
||||||
|
|
||||||
class LLTextEditor;
|
class LLTextEditor;
|
||||||
class LLLineEditor;
|
class LLLineEditor;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "llfontgl.h"
|
#include "llfontgl.h"
|
||||||
#include "llgl.h" // for renderer
|
#include "llgl.h" // for renderer
|
||||||
#include "llinventory.h"
|
#include "llinventory.h"
|
||||||
|
#include "llimagej2c.h"
|
||||||
#include "llstring.h"
|
#include "llstring.h"
|
||||||
#include "llsys.h"
|
#include "llsys.h"
|
||||||
#include "llversionviewer.h"
|
#include "llversionviewer.h"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "llassetconverter.h"
|
#include "llassetconverter.h"
|
||||||
#include "llviewerimagelist.h"
|
#include "llviewerimagelist.h"
|
||||||
#include "llviewerimage.h"
|
#include "llviewerimage.h"
|
||||||
|
#include "llimagej2c.h"
|
||||||
|
|
||||||
LLFloaterVFS* LLFloaterVFS::sInstance;
|
LLFloaterVFS* LLFloaterVFS::sInstance;
|
||||||
std::list<LLFloaterVFS::entry> LLFloaterVFS::mFiles;
|
std::list<LLFloaterVFS::entry> LLFloaterVFS::mFiles;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "llfloaterperms.h"
|
#include "llfloaterperms.h"
|
||||||
#include "llviewerregion.h"
|
#include "llviewerregion.h"
|
||||||
#include "llviewerobjectlist.h"
|
#include "llviewerobjectlist.h"
|
||||||
|
#include "llimagej2c.h"
|
||||||
|
|
||||||
// static vars
|
// static vars
|
||||||
bool LLXmlImport::sImportInProgress = false;
|
bool LLXmlImport::sImportInProgress = false;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "llfloater.h"
|
#include "llfloater.h"
|
||||||
#include "lluictrlfactory.h"
|
#include "lluictrlfactory.h"
|
||||||
#include "llscrolllistctrl.h"
|
#include "llscrolllistctrl.h"
|
||||||
|
#include "llimagetga.h"
|
||||||
|
|
||||||
|
|
||||||
std::list<LLFloaterInventoryBackup*> LLFloaterInventoryBackup::sInstances;
|
std::list<LLFloaterInventoryBackup*> LLFloaterInventoryBackup::sInstances;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ const BOOL IMMEDIATE_NO = FALSE;
|
|||||||
class LLMessageSystem;
|
class LLMessageSystem;
|
||||||
class LLViewerImage;
|
class LLViewerImage;
|
||||||
class LLTextureView;
|
class LLTextureView;
|
||||||
|
class LLImageJ2C;
|
||||||
|
|
||||||
typedef void (*LLImageCallback)(BOOL success,
|
typedef void (*LLImageCallback)(BOOL success,
|
||||||
LLViewerImage *src_vi,
|
LLViewerImage *src_vi,
|
||||||
|
|||||||
@@ -81,6 +81,10 @@
|
|||||||
#include "lluuid.h"
|
#include "lluuid.h"
|
||||||
#include "llvorbisencode.h"
|
#include "llvorbisencode.h"
|
||||||
|
|
||||||
|
#include "llimagejpeg.h"
|
||||||
|
#include "llimagepng.h"
|
||||||
|
#include "llimagebmp.h"
|
||||||
|
|
||||||
// system libraries
|
// system libraries
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -114,13 +114,13 @@
|
|||||||
|
|
||||||
// Library includes from llimage
|
// Library includes from llimage
|
||||||
//#include "llblockdata.h"
|
//#include "llblockdata.h"
|
||||||
#include "llimage.h"
|
//#include "llimage.h"
|
||||||
#include "llimagebmp.h"
|
//#include "llimagebmp.h"
|
||||||
#include "llimagepng.h"
|
//#include "llimagepng.h"
|
||||||
#include "llimagej2c.h"
|
//#include "llimagej2c.h"
|
||||||
#include "llimagejpeg.h"
|
//#include "llimagejpeg.h"
|
||||||
#include "llimagetga.h"
|
//#include "llimagetga.h"
|
||||||
#include "llmapimagetype.h"
|
//#include "llmapimagetype.h"
|
||||||
|
|
||||||
// Library includes from llmath project
|
// Library includes from llmath project
|
||||||
//#include "camera.h"
|
//#include "camera.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user