Skip to content

Commit 1014841

Browse files
committed
Feature Request: Repair Uploaded by functionality
Clean up llviewertexture a bit while doing so. Sync LLImage Thanks to Cinder and the Alchemy Team for this buncha code.
1 parent dd49033 commit 1014841

8 files changed

Lines changed: 235 additions & 328 deletions

File tree

indra/llimage/llimage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ class LLImageRaw : public LLImageBase
244244

245245
// Src and dst are same size. Src has 4 components. Dst has 3 components.
246246
void compositeUnscaled4onto3( LLImageRaw* src );
247+
248+
std::string getComment() const { return mComment; }
249+
std::string mComment;
247250

248251
protected:
249252
// Create an image from a local file (generally used in tools)

indra/llimage/llimagebmp.cpp

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
/**
22
* @file llimagebmp.cpp
33
*
4-
* $LicenseInfo:firstyear=2001&license=viewergpl$
5-
*
6-
* Copyright (c) 2001-2009, Linden Research, Inc.
7-
*
4+
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
85
* Second Life Viewer Source Code
9-
* The source code in this file ("Source Code") is provided by Linden Lab
10-
* to you under the terms of the GNU General Public License, version 2.0
11-
* ("GPL"), unless you have obtained a separate licensing agreement
12-
* ("Other License"), formally executed by you and Linden Lab. Terms of
13-
* the GPL can be found in doc/GPL-license.txt in this distribution, or
14-
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
15-
*
16-
* There are special exceptions to the terms and conditions of the GPL as
17-
* it is applied to this Source Code. View the full text of the exception
18-
* in the file doc/FLOSS-exception.txt in this software distribution, or
19-
* online at
20-
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
21-
*
22-
* By copying, modifying or distributing this software, you acknowledge
23-
* that you have read and understood your obligations described above,
24-
* and agree to abide by those obligations.
6+
* Copyright (C) 2010, Linden Research, Inc.
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation;
11+
* version 2.1 of the License only.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2521
*
26-
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27-
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28-
* COMPLETENESS OR PERFORMANCE.
22+
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
2923
* $/LicenseInfo$
3024
*/
3125

@@ -81,7 +75,7 @@ LLImageBMP::LLImageBMP()
8175
:
8276
LLImageFormatted(IMG_CODEC_BMP),
8377
mColorPaletteColors( 0 ),
84-
mColorPalette( NULL ),
78+
mColorPalette(nullptr ),
8579
mBitmapOffset( 0 ),
8680
mBitsPerPixel( 0 ),
8781
mOriginAtTop( FALSE )
@@ -324,10 +318,13 @@ BOOL LLImageBMP::updateData()
324318

325319
if( 0 != mColorPaletteColors )
326320
{
327-
mColorPalette = new U8[color_palette_size];
328-
if (!mColorPalette)
321+
try
322+
{
323+
mColorPalette = new U8[color_palette_size];
324+
}
325+
catch (const std::bad_alloc& e)
329326
{
330-
LL_ERRS() << "Out of memory in LLImageBMP::updateData()" << LL_ENDL;
327+
LL_WARNS() << "Failed to allocate bmp color date with exception: " << e.what() << LL_ENDL;
331328
return FALSE;
332329
}
333330
memcpy( mColorPalette, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE + extension_size, color_palette_size ); /* Flawfinder: ignore */

indra/llimage/llimagedxt.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
271271

272272
S32 width = getWidth(), height = getHeight();
273273
S32 ncomponents = getComponents();
274-
U8* data = NULL;
274+
U8* data = nullptr;
275275
if (mDiscardLevel >= 0)
276276
{
277277
data = getData() + getMipOffset(mDiscardLevel);
@@ -332,7 +332,7 @@ BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
332332
break;
333333
default:
334334
LL_ERRS() << "LLImageDXT::encode: Unhandled channel number: " << ncomponents << LL_ENDL;
335-
return 0;
335+
return false;
336336
}
337337

338338
S32 width = raw_image->getWidth();
@@ -371,7 +371,7 @@ BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
371371
header->maxwidth = width;
372372
header->maxheight = height;
373373

374-
U8* prev_mipdata = 0;
374+
U8* prev_mipdata = nullptr;
375375
w = width, h = height;
376376
for (S32 mip=0; mip<nmips; mip++)
377377
{

indra/llimagej2coj/llimagej2coj.cpp

Lines changed: 75 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,7 @@
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
4237
LLImageJ2CImpl* 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
5456
static std::string chomp(const char* msg)
5557
{
@@ -108,22 +110,57 @@ LLImageJ2COJ::~LLImageJ2COJ()
108110

109111
BOOL 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, &parameters);
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

Comments
 (0)