Borrowed j2c bridge from Impru. THANKIES <3
This commit is contained in:
@@ -99,6 +99,7 @@ void info_callback(const char* msg, void*)
|
|||||||
|
|
||||||
LLImageJ2COJ::LLImageJ2COJ() : LLImageJ2CImpl()
|
LLImageJ2COJ::LLImageJ2COJ() : LLImageJ2CImpl()
|
||||||
{
|
{
|
||||||
|
mRawImagep=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,10 +113,6 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
//
|
//
|
||||||
// FIXME: Get the comment field out of the texture
|
// FIXME: Get the comment field out of the texture
|
||||||
//
|
//
|
||||||
if (!base.getData()) return FALSE;
|
|
||||||
if (!base.getDataSize()) return FALSE;
|
|
||||||
if (!raw_image.getData()) return FALSE;
|
|
||||||
if (!raw_image.getDataSize()) return FALSE;
|
|
||||||
|
|
||||||
LLTimer decode_timer;
|
LLTimer decode_timer;
|
||||||
|
|
||||||
@@ -155,11 +152,13 @@ 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 */
|
/* decode the stream and fill the image structure, also fill in an additional
|
||||||
if (!cio) return FALSE;
|
structure to get the decoding result. This structure is a bit unusual in that
|
||||||
if (cio->bp == NULL) return FALSE;
|
it is not received through opj, but still has some dynamically allocated fields
|
||||||
if (!dinfo) return FALSE;
|
that need to be cleared up at the end by calling a destroy function. */
|
||||||
image = opj_decode(dinfo, cio);
|
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);
|
||||||
@@ -173,19 +172,20 @@ 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)
|
||||||
{
|
{
|
||||||
LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL;
|
LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL;
|
||||||
return TRUE; // done
|
return TRUE; // done
|
||||||
}
|
}
|
||||||
|
|
||||||
S32 img_components = image->numcomps;
|
S32 img_components = image->numcomps;
|
||||||
|
|
||||||
if( !img_components ) // < 1 ||img_components > 4 )
|
if( !img_components ) // < 1 ||img_components > 4 )
|
||||||
{
|
{
|
||||||
LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,23 +193,40 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
for (S32 i = 0; i < img_components; i++)
|
int decompdifference = 0;
|
||||||
|
if (cinfo.numdecompos) // sanity
|
||||||
{
|
{
|
||||||
if (image->comps[i].factor != base.getRawDiscardLevel())
|
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 we didn't get the discard level we're expecting, fail
|
decompdifference = 0;
|
||||||
if (image) //anyway somthing odd with the image, better check than crash
|
|
||||||
opj_image_destroy(image);
|
|
||||||
base.mDecoding = FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
base.mDecoding = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if(img_components <= first_channel)
|
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;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +235,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
|
|
||||||
// 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 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;
|
||||||
@@ -257,15 +275,17 @@ 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);
|
||||||
|
|
||||||
return TRUE; // done
|
return TRUE; // done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free image data structure */
|
/* free opj data structures */
|
||||||
if (image)
|
if (image)
|
||||||
{
|
{
|
||||||
|
opj_destroy_cstr_info(&cinfo);
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +350,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); //Clamp avoid overrunning buffer -Shyotl
|
S32 numcomps = raw_image.getComponents();
|
||||||
S32 width = raw_image.getWidth();
|
S32 width = raw_image.getWidth();
|
||||||
S32 height = raw_image.getHeight();
|
S32 height = raw_image.getHeight();
|
||||||
|
|
||||||
@@ -421,8 +441,6 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
|
|||||||
//
|
//
|
||||||
// FIXME: We get metadata by decoding the ENTIRE image.
|
// FIXME: We get metadata by decoding the ENTIRE image.
|
||||||
//
|
//
|
||||||
if (!base.getData()) return FALSE;
|
|
||||||
if (!base.getDataSize()) return FALSE;
|
|
||||||
|
|
||||||
// Update the raw discard level
|
// Update the raw discard level
|
||||||
base.updateRawDiscardLevel();
|
base.updateRawDiscardLevel();
|
||||||
@@ -467,9 +485,6 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
|
|||||||
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 */
|
/* decode the stream and fill the image structure */
|
||||||
if (!cio) return FALSE;
|
|
||||||
if (cio->bp == NULL) return FALSE;
|
|
||||||
if (!dinfo) return FALSE;
|
|
||||||
image = opj_decode(dinfo, cio);
|
image = opj_decode(dinfo, cio);
|
||||||
|
|
||||||
/* close the byte stream */
|
/* close the byte stream */
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ protected:
|
|||||||
// Divide a by b to the power of 2 and round upwards.
|
// Divide a by b to the power of 2 and round upwards.
|
||||||
return (a + (1 << b) - 1) >> b;
|
return (a + (1 << b) - 1) >> b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temporary variables for in-progress decodes...
|
||||||
|
LLImageRaw *mRawImagep;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user