3333#include " lltimer.h"
3434// #include "llmemory.h"
3535
36- const char * fallbackEngineInfoLLImageJ2CImpl ()
37- {
38- static std::string version_string = std::string (" OpenJPEG: " ) + opj_version ();
39- return version_string.c_str ();
40- }
41-
36+ // Factory function: see declaration in llimagej2c.cpp
4237LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl ()
4338{
4439 return new LLImageJ2COJ ();
@@ -50,6 +45,13 @@ void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
5045 impl = NULL ;
5146}
5247
48+ const char * fallbackEngineInfoLLImageJ2CImpl ()
49+ {
50+ static std::string version_string = std::string (" OpenJPEG: " )
51+ + opj_version ();
52+ return version_string.c_str ();
53+ }
54+
5355// Return string from message, eliminating final \n if present
5456static std::string chomp (const char * msg)
5557{
@@ -108,22 +110,57 @@ LLImageJ2COJ::~LLImageJ2COJ()
108110
109111BOOL LLImageJ2COJ::decodeImpl (LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
110112{
111- //
112- // FIXME: Get the comment field out of the texture
113- //
114-
115113 LLTimer decode_timer;
116114
115+ /* Extract metadata */
116+ /* ---------------- */
117+ U8* c_data = base.getData ();
118+ size_t c_size = base.getDataSize ();
119+ size_t position = 0 ;
120+
121+ while (position < 1024 && position < (c_size - 7 )) // the comment field should be in the first 1024 bytes.
122+ {
123+ if (c_data[position] == 0xff && c_data[position + 1 ] == 0x64 )
124+ {
125+ U8 high_byte = c_data[position + 2 ];
126+ U8 low_byte = c_data[position + 3 ];
127+ S32 c_length = (high_byte * 256 ) + low_byte; // This size also counts the markers, 00 01 and itself
128+ if (c_length > 200 ) // sanity check
129+ {
130+ // While comments can be very long, anything longer then 200 is suspect.
131+ break ;
132+ }
133+
134+ if (position + 2 + c_length > c_size)
135+ {
136+ // comment extends past end of data, corruption, or all data not retrived yet.
137+ break ;
138+ }
139+
140+ // if the comment block does not end at the end of data, check to see if the next
141+ // block starts with 0xFF
142+ if (position + 2 + c_length < c_size && c_data[position + 2 + c_length] != 0xff )
143+ {
144+ // invalied comment block
145+ break ;
146+ }
147+
148+ // extract the comment minus the markers, 00 01
149+ raw_image.mComment .assign ((char *)c_data + position + 6 , c_length - 4 );
150+ break ;
151+ }
152+ ++position;
153+ }
154+
117155 opj_dparameters_t parameters; /* decompression parameters */
118- opj_event_mgr_t event_mgr; /* event manager */
119- opj_image_t *image = NULL ;
156+ opj_event_mgr_t event_mgr = { } ; /* event manager */
157+ opj_image_t *image = nullptr ;
120158
121- opj_dinfo_t * dinfo = NULL ; /* handle to a decompressor */
122- opj_cio_t *cio = NULL ;
159+ opj_dinfo_t * dinfo = nullptr ; /* handle to a decompressor */
160+ opj_cio_t *cio = nullptr ;
123161
124162
125163 /* configure the event callbacks (not required) */
126- memset (&event_mgr, 0 , sizeof (opj_event_mgr_t ));
127164 event_mgr.error_handler = error_callback;
128165 event_mgr.warning_handler = warning_callback;
129166 event_mgr.info_handler = info_callback;
@@ -168,19 +205,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
168205 opj_setup_decoder (dinfo, ¶meters);
169206
170207 /* open a byte stream */
171- #if 0
172- std::vector<U8> data(base.getData(), base.getData()+base.getDataSize());
173- S32 size = data.size();
174- if (data[size-1] == 0xFF) {
175- data.push_back((U8)0xD9);
176- } else if (data[size-2] != 0xFF || data[size-1] != 0xD9) {
177- data.push_back((U8)0xFF);
178- data.push_back((U8)0xD9);
179- }
180- cio = opj_cio_open((opj_common_ptr)dinfo, &data[0], data.size());
181- #else
182208 cio = opj_cio_open ((opj_common_ptr)dinfo, base.getData (), base.getDataSize ());
183- #endif
184209
185210 /* decode the stream and fill the image structure */
186211 image = opj_decode (dinfo, cio);
@@ -199,20 +224,11 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
199224 // dereference the array.
200225 if (!image || !image->numcomps )
201226 {
202- LL_WARNS (" Texture" ) << " ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
227+ LL_DEBUGS (" Texture" ) << " ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
203228 if (image)
204229 {
205230 opj_image_destroy (image);
206231 }
207- #if 0
208- std::stringstream filename;
209- filename << "err" << (int)base.getRawDiscardLevel() << "_" << rand() << ".jp2";
210- FILE* file = fopen(filename.str().c_str(), "wb");
211- if (file) {
212- fwrite(base.getData(), base.getDataSize(), 1, file);
213- fclose(file);
214- }
215- #endif
216232 base.decodeFailed ();
217233 return TRUE ; // done
218234 }
@@ -222,7 +238,6 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
222238 {
223239 if (image->comps [i].factor != base.getRawDiscardLevel ())
224240 {
225- LL_WARNS (" Texture" ) << " Expected discard level not reached!" << LL_ENDL;
226241 // if we didn't get the discard level we're expecting, fail
227242 opj_image_destroy (image);
228243 base.decodeFailed ();
@@ -262,6 +277,13 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
262277 S32 height = ceildivpow2 (image->y1 - image->y0 , f);
263278 raw_image.resize (width, height, channels);
264279 U8 *rawp = raw_image.getData ();
280+ if (!rawp)
281+ {
282+ opj_image_destroy (image);
283+ base.setLastError (" Memory error" );
284+ base.decodeFailed ();
285+ return true ; // done
286+ }
265287
266288 // first_channel is what channel to start copying from
267289 // dest is what channel to copy to. first_channel comes from the
@@ -283,9 +305,11 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
283305 }
284306 else // Some rare OpenJPEG versions have this bug.
285307 {
286- LL_WARNS (" Texture" ) << " ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
287- opj_image_destroy (image);
288-
308+ LL_DEBUGS (" Texture" ) << " ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
309+ if (image)
310+ {
311+ opj_image_destroy (image);
312+ }
289313 base.decodeFailed ();
290314 return TRUE ; // done
291315 }
@@ -302,14 +326,13 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
302326{
303327 const S32 MAX_COMPS = 5 ;
304328 opj_cparameters_t parameters; /* compression parameters */
305- opj_event_mgr_t event_mgr; /* event manager */
329+ opj_event_mgr_t event_mgr = { } ; /* event manager */
306330
307331
308332 /*
309333 configure the event callbacks (not required)
310334 setting of each callback is optional
311335 */
312- memset (&event_mgr, 0 , sizeof (opj_event_mgr_t ));
313336 event_mgr.error_handler = error_callback;
314337 event_mgr.warning_handler = warning_callback;
315338 event_mgr.info_handler = info_callback;
@@ -354,7 +377,7 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
354377 //
355378 OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
356379 opj_image_cmptparm_t cmptparm[MAX_COMPS];
357- opj_image_t * image = NULL ;
380+ opj_image_t * image = nullptr ;
358381 S32 numcomps = llmin ((S32)raw_image.getComponents (), MAX_COMPS);
359382 S32 width = raw_image.getWidth ();
360383 S32 height = raw_image.getHeight ();
@@ -398,7 +421,7 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
398421 /* ---------------------------- */
399422
400423 int codestream_length;
401- opj_cio_t *cio = NULL ;
424+ opj_cio_t *cio = nullptr ;
402425
403426 /* get a J2K compressor handle */
404427 opj_cinfo_t * cinfo = opj_create_compress (CODEC_J2K);
@@ -411,14 +434,14 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
411434
412435 /* open a byte stream for writing */
413436 /* allocate memory for all tiles */
414- cio = opj_cio_open ((opj_common_ptr)cinfo, NULL , 0 );
437+ cio = opj_cio_open ((opj_common_ptr)cinfo, nullptr , 0 );
415438
416439 /* encode the image */
417- bool bSuccess = opj_encode (cinfo, cio, image, NULL );
440+ bool bSuccess = opj_encode (cinfo, cio, image, nullptr );
418441 if (!bSuccess)
419442 {
420443 opj_cio_close (cio);
421- LL_WARNS (" Texture" ) << " Failed to encode image." << LL_ENDL;
444+ LL_DEBUGS (" Texture" ) << " Failed to encode image." << LL_ENDL;
422445 return FALSE ;
423446 }
424447 codestream_length = cio_tell (cio);
@@ -520,15 +543,14 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
520543 // Do it the old and slow way, decode the image with openjpeg
521544
522545 opj_dparameters_t parameters; /* decompression parameters */
523- opj_event_mgr_t event_mgr; /* event manager */
524- opj_image_t *image = NULL ;
546+ opj_event_mgr_t event_mgr = { } ; /* event manager */
547+ opj_image_t *image = nullptr ;
525548
526- opj_dinfo_t * dinfo = NULL ; /* handle to a decompressor */
527- opj_cio_t *cio = NULL ;
549+ opj_dinfo_t * dinfo = nullptr ; /* handle to a decompressor */
550+ opj_cio_t *cio = nullptr ;
528551
529552
530553 /* configure the event callbacks (not required) */
531- memset (&event_mgr, 0 , sizeof (opj_event_mgr_t ));
532554 event_mgr.error_handler = error_callback;
533555 event_mgr.warning_handler = warning_callback;
534556 event_mgr.info_handler = info_callback;
0 commit comments