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.
This commit is contained in:
@@ -244,6 +244,9 @@ public:
|
|||||||
|
|
||||||
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
// Src and dst are same size. Src has 4 components. Dst has 3 components.
|
||||||
void compositeUnscaled4onto3( LLImageRaw* src );
|
void compositeUnscaled4onto3( LLImageRaw* src );
|
||||||
|
|
||||||
|
std::string getComment() const { return mComment; }
|
||||||
|
std::string mComment;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Create an image from a local file (generally used in tools)
|
// Create an image from a local file (generally used in tools)
|
||||||
|
|||||||
@@ -1,31 +1,25 @@
|
|||||||
/**
|
/**
|
||||||
* @file llimagebmp.cpp
|
* @file llimagebmp.cpp
|
||||||
*
|
*
|
||||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||||
*
|
|
||||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
|
||||||
*
|
|
||||||
* Second Life Viewer Source Code
|
* Second Life Viewer Source Code
|
||||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
* to you under the terms of the GNU General Public License, version 2.0
|
*
|
||||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
* This library is free software; you can redistribute it and/or
|
||||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
* License as published by the Free Software Foundation;
|
||||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
*
|
||||||
* There are special exceptions to the terms and conditions of the GPL as
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
* it is applied to this Source Code. View the full text of the exception
|
|
||||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
|
||||||
* online at
|
|
||||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
||||||
*
|
|
||||||
* By copying, modifying or distributing this software, you acknowledge
|
|
||||||
* that you have read and understood your obligations described above,
|
|
||||||
* and agree to abide by those obligations.
|
|
||||||
*
|
|
||||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
|
||||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
|
||||||
* COMPLETENESS OR PERFORMANCE.
|
|
||||||
* $/LicenseInfo$
|
* $/LicenseInfo$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -81,7 +75,7 @@ LLImageBMP::LLImageBMP()
|
|||||||
:
|
:
|
||||||
LLImageFormatted(IMG_CODEC_BMP),
|
LLImageFormatted(IMG_CODEC_BMP),
|
||||||
mColorPaletteColors( 0 ),
|
mColorPaletteColors( 0 ),
|
||||||
mColorPalette( NULL ),
|
mColorPalette(nullptr ),
|
||||||
mBitmapOffset( 0 ),
|
mBitmapOffset( 0 ),
|
||||||
mBitsPerPixel( 0 ),
|
mBitsPerPixel( 0 ),
|
||||||
mOriginAtTop( FALSE )
|
mOriginAtTop( FALSE )
|
||||||
@@ -324,10 +318,13 @@ BOOL LLImageBMP::updateData()
|
|||||||
|
|
||||||
if( 0 != mColorPaletteColors )
|
if( 0 != mColorPaletteColors )
|
||||||
{
|
{
|
||||||
mColorPalette = new U8[color_palette_size];
|
try
|
||||||
if (!mColorPalette)
|
|
||||||
{
|
{
|
||||||
LL_ERRS() << "Out of memory in LLImageBMP::updateData()" << LL_ENDL;
|
mColorPalette = new U8[color_palette_size];
|
||||||
|
}
|
||||||
|
catch (const std::bad_alloc& e)
|
||||||
|
{
|
||||||
|
LL_WARNS() << "Failed to allocate bmp color date with exception: " << e.what() << LL_ENDL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
memcpy( mColorPalette, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE + extension_size, color_palette_size ); /* Flawfinder: ignore */
|
memcpy( mColorPalette, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE + extension_size, color_palette_size ); /* Flawfinder: ignore */
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
|
|||||||
|
|
||||||
S32 width = getWidth(), height = getHeight();
|
S32 width = getWidth(), height = getHeight();
|
||||||
S32 ncomponents = getComponents();
|
S32 ncomponents = getComponents();
|
||||||
U8* data = NULL;
|
U8* data = nullptr;
|
||||||
if (mDiscardLevel >= 0)
|
if (mDiscardLevel >= 0)
|
||||||
{
|
{
|
||||||
data = getData() + getMipOffset(mDiscardLevel);
|
data = getData() + getMipOffset(mDiscardLevel);
|
||||||
@@ -332,7 +332,7 @@ BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LL_ERRS() << "LLImageDXT::encode: Unhandled channel number: " << ncomponents << LL_ENDL;
|
LL_ERRS() << "LLImageDXT::encode: Unhandled channel number: " << ncomponents << LL_ENDL;
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
S32 width = raw_image->getWidth();
|
S32 width = raw_image->getWidth();
|
||||||
@@ -371,7 +371,7 @@ BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
|
|||||||
header->maxwidth = width;
|
header->maxwidth = width;
|
||||||
header->maxheight = height;
|
header->maxheight = height;
|
||||||
|
|
||||||
U8* prev_mipdata = 0;
|
U8* prev_mipdata = nullptr;
|
||||||
w = width, h = height;
|
w = width, h = height;
|
||||||
for (S32 mip=0; mip<nmips; mip++)
|
for (S32 mip=0; mip<nmips; mip++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,12 +33,7 @@
|
|||||||
#include "lltimer.h"
|
#include "lltimer.h"
|
||||||
//#include "llmemory.h"
|
//#include "llmemory.h"
|
||||||
|
|
||||||
const char* fallbackEngineInfoLLImageJ2CImpl()
|
// Factory function: see declaration in llimagej2c.cpp
|
||||||
{
|
|
||||||
static std::string version_string = std::string("OpenJPEG: ") + opj_version();
|
|
||||||
return version_string.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
|
LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
|
||||||
{
|
{
|
||||||
return new LLImageJ2COJ();
|
return new LLImageJ2COJ();
|
||||||
@@ -50,6 +45,13 @@ void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
|
|||||||
impl = NULL;
|
impl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* fallbackEngineInfoLLImageJ2CImpl()
|
||||||
|
{
|
||||||
|
static std::string version_string = std::string("OpenJPEG: ")
|
||||||
|
+ opj_version();
|
||||||
|
return version_string.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
// Return string from message, eliminating final \n if present
|
// Return string from message, eliminating final \n if present
|
||||||
static std::string chomp(const char* msg)
|
static std::string chomp(const char* msg)
|
||||||
{
|
{
|
||||||
@@ -108,22 +110,57 @@ LLImageJ2COJ::~LLImageJ2COJ()
|
|||||||
|
|
||||||
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
|
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// FIXME: Get the comment field out of the texture
|
|
||||||
//
|
|
||||||
|
|
||||||
LLTimer decode_timer;
|
LLTimer decode_timer;
|
||||||
|
|
||||||
|
/* Extract metadata */
|
||||||
|
/* ---------------- */
|
||||||
|
U8* c_data = base.getData();
|
||||||
|
size_t c_size = base.getDataSize();
|
||||||
|
size_t position = 0;
|
||||||
|
|
||||||
|
while (position < 1024 && position < (c_size - 7)) // the comment field should be in the first 1024 bytes.
|
||||||
|
{
|
||||||
|
if (c_data[position] == 0xff && c_data[position + 1] == 0x64)
|
||||||
|
{
|
||||||
|
U8 high_byte = c_data[position + 2];
|
||||||
|
U8 low_byte = c_data[position + 3];
|
||||||
|
S32 c_length = (high_byte * 256) + low_byte; // This size also counts the markers, 00 01 and itself
|
||||||
|
if (c_length > 200) // sanity check
|
||||||
|
{
|
||||||
|
// While comments can be very long, anything longer then 200 is suspect.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position + 2 + c_length > c_size)
|
||||||
|
{
|
||||||
|
// comment extends past end of data, corruption, or all data not retrived yet.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the comment block does not end at the end of data, check to see if the next
|
||||||
|
// block starts with 0xFF
|
||||||
|
if (position + 2 + c_length < c_size && c_data[position + 2 + c_length] != 0xff)
|
||||||
|
{
|
||||||
|
// invalied comment block
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract the comment minus the markers, 00 01
|
||||||
|
raw_image.mComment.assign((char*)c_data + position + 6, c_length - 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++position;
|
||||||
|
}
|
||||||
|
|
||||||
opj_dparameters_t parameters; /* decompression parameters */
|
opj_dparameters_t parameters; /* decompression parameters */
|
||||||
opj_event_mgr_t event_mgr; /* event manager */
|
opj_event_mgr_t event_mgr = { }; /* event manager */
|
||||||
opj_image_t *image = NULL;
|
opj_image_t *image = nullptr;
|
||||||
|
|
||||||
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
|
opj_dinfo_t* dinfo = nullptr; /* handle to a decompressor */
|
||||||
opj_cio_t *cio = NULL;
|
opj_cio_t *cio = nullptr;
|
||||||
|
|
||||||
|
|
||||||
/* configure the event callbacks (not required) */
|
/* configure the event callbacks (not required) */
|
||||||
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
|
|
||||||
event_mgr.error_handler = error_callback;
|
event_mgr.error_handler = error_callback;
|
||||||
event_mgr.warning_handler = warning_callback;
|
event_mgr.warning_handler = warning_callback;
|
||||||
event_mgr.info_handler = info_callback;
|
event_mgr.info_handler = info_callback;
|
||||||
@@ -168,19 +205,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
opj_setup_decoder(dinfo, ¶meters);
|
opj_setup_decoder(dinfo, ¶meters);
|
||||||
|
|
||||||
/* open a byte stream */
|
/* open a byte stream */
|
||||||
#if 0
|
|
||||||
std::vector<U8> data(base.getData(), base.getData()+base.getDataSize());
|
|
||||||
S32 size = data.size();
|
|
||||||
if (data[size-1] == 0xFF) {
|
|
||||||
data.push_back((U8)0xD9);
|
|
||||||
} else if (data[size-2] != 0xFF || data[size-1] != 0xD9) {
|
|
||||||
data.push_back((U8)0xFF);
|
|
||||||
data.push_back((U8)0xD9);
|
|
||||||
}
|
|
||||||
cio = opj_cio_open((opj_common_ptr)dinfo, &data[0], data.size());
|
|
||||||
#else
|
|
||||||
cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
|
cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
|
||||||
#endif
|
|
||||||
|
|
||||||
/* decode the stream and fill the image structure */
|
/* decode the stream and fill the image structure */
|
||||||
image = opj_decode(dinfo, cio);
|
image = opj_decode(dinfo, cio);
|
||||||
@@ -199,20 +224,11 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
// dereference the array.
|
// dereference the array.
|
||||||
if(!image || !image->numcomps)
|
if(!image || !image->numcomps)
|
||||||
{
|
{
|
||||||
LL_WARNS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
|
LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
|
||||||
if (image)
|
if (image)
|
||||||
{
|
{
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
std::stringstream filename;
|
|
||||||
filename << "err" << (int)base.getRawDiscardLevel() << "_" << rand() << ".jp2";
|
|
||||||
FILE* file = fopen(filename.str().c_str(), "wb");
|
|
||||||
if (file) {
|
|
||||||
fwrite(base.getData(), base.getDataSize(), 1, file);
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
base.decodeFailed();
|
base.decodeFailed();
|
||||||
return TRUE; // done
|
return TRUE; // done
|
||||||
}
|
}
|
||||||
@@ -222,7 +238,6 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
{
|
{
|
||||||
if (image->comps[i].factor != base.getRawDiscardLevel())
|
if (image->comps[i].factor != base.getRawDiscardLevel())
|
||||||
{
|
{
|
||||||
LL_WARNS("Texture") << "Expected discard level not reached!" << LL_ENDL;
|
|
||||||
// if we didn't get the discard level we're expecting, fail
|
// if we didn't get the discard level we're expecting, fail
|
||||||
opj_image_destroy(image);
|
opj_image_destroy(image);
|
||||||
base.decodeFailed();
|
base.decodeFailed();
|
||||||
@@ -262,6 +277,13 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||||||
S32 height = ceildivpow2(image->y1 - image->y0, f);
|
S32 height = ceildivpow2(image->y1 - image->y0, f);
|
||||||
raw_image.resize(width, height, channels);
|
raw_image.resize(width, height, channels);
|
||||||
U8 *rawp = raw_image.getData();
|
U8 *rawp = raw_image.getData();
|
||||||
|
if (!rawp)
|
||||||
|
{
|
||||||
|
opj_image_destroy(image);
|
||||||
|
base.setLastError("Memory error");
|
||||||
|
base.decodeFailed();
|
||||||
|
return true; // done
|
||||||
|
}
|
||||||
|
|
||||||
// first_channel is what channel to start copying from
|
// first_channel is what channel to start copying from
|
||||||
// dest is what channel to copy to. first_channel comes from the
|
// 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
|
|||||||
}
|
}
|
||||||
else // Some rare OpenJPEG versions have this bug.
|
else // Some rare OpenJPEG versions have this bug.
|
||||||
{
|
{
|
||||||
LL_WARNS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
|
LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
|
||||||
opj_image_destroy(image);
|
if (image)
|
||||||
|
{
|
||||||
|
opj_image_destroy(image);
|
||||||
|
}
|
||||||
base.decodeFailed();
|
base.decodeFailed();
|
||||||
return TRUE; // done
|
return TRUE; // done
|
||||||
}
|
}
|
||||||
@@ -302,14 +326,13 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
|
|||||||
{
|
{
|
||||||
const S32 MAX_COMPS = 5;
|
const S32 MAX_COMPS = 5;
|
||||||
opj_cparameters_t parameters; /* compression parameters */
|
opj_cparameters_t parameters; /* compression parameters */
|
||||||
opj_event_mgr_t event_mgr; /* event manager */
|
opj_event_mgr_t event_mgr = { }; /* event manager */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
configure the event callbacks (not required)
|
configure the event callbacks (not required)
|
||||||
setting of each callback is optional
|
setting of each callback is optional
|
||||||
*/
|
*/
|
||||||
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
|
|
||||||
event_mgr.error_handler = error_callback;
|
event_mgr.error_handler = error_callback;
|
||||||
event_mgr.warning_handler = warning_callback;
|
event_mgr.warning_handler = warning_callback;
|
||||||
event_mgr.info_handler = info_callback;
|
event_mgr.info_handler = info_callback;
|
||||||
@@ -354,7 +377,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 = nullptr;
|
||||||
S32 numcomps = llmin((S32)raw_image.getComponents(), 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();
|
||||||
@@ -398,7 +421,7 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
|
|||||||
/* ---------------------------- */
|
/* ---------------------------- */
|
||||||
|
|
||||||
int codestream_length;
|
int codestream_length;
|
||||||
opj_cio_t *cio = NULL;
|
opj_cio_t *cio = nullptr;
|
||||||
|
|
||||||
/* get a J2K compressor handle */
|
/* get a J2K compressor handle */
|
||||||
opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
|
opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
|
||||||
@@ -411,14 +434,14 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
|
|||||||
|
|
||||||
/* open a byte stream for writing */
|
/* open a byte stream for writing */
|
||||||
/* allocate memory for all tiles */
|
/* allocate memory for all tiles */
|
||||||
cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
|
cio = opj_cio_open((opj_common_ptr)cinfo, nullptr, 0);
|
||||||
|
|
||||||
/* encode the image */
|
/* encode the image */
|
||||||
bool bSuccess = opj_encode(cinfo, cio, image, NULL);
|
bool bSuccess = opj_encode(cinfo, cio, image, nullptr);
|
||||||
if (!bSuccess)
|
if (!bSuccess)
|
||||||
{
|
{
|
||||||
opj_cio_close(cio);
|
opj_cio_close(cio);
|
||||||
LL_WARNS("Texture") << "Failed to encode image." << LL_ENDL;
|
LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
codestream_length = cio_tell(cio);
|
codestream_length = cio_tell(cio);
|
||||||
@@ -520,15 +543,14 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
|
|||||||
// Do it the old and slow way, decode the image with openjpeg
|
// Do it the old and slow way, decode the image with openjpeg
|
||||||
|
|
||||||
opj_dparameters_t parameters; /* decompression parameters */
|
opj_dparameters_t parameters; /* decompression parameters */
|
||||||
opj_event_mgr_t event_mgr; /* event manager */
|
opj_event_mgr_t event_mgr = { }; /* event manager */
|
||||||
opj_image_t *image = NULL;
|
opj_image_t *image = nullptr;
|
||||||
|
|
||||||
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
|
opj_dinfo_t* dinfo = nullptr; /* handle to a decompressor */
|
||||||
opj_cio_t *cio = NULL;
|
opj_cio_t *cio = nullptr;
|
||||||
|
|
||||||
|
|
||||||
/* configure the event callbacks (not required) */
|
/* configure the event callbacks (not required) */
|
||||||
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
|
|
||||||
event_mgr.error_handler = error_callback;
|
event_mgr.error_handler = error_callback;
|
||||||
event_mgr.warning_handler = warning_callback;
|
event_mgr.warning_handler = warning_callback;
|
||||||
event_mgr.info_handler = info_callback;
|
event_mgr.info_handler = info_callback;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "llagent.h"
|
#include "llagent.h"
|
||||||
#include "llavataractions.h"
|
#include "llavataractions.h"
|
||||||
|
#include "llavatarnamecache.h"
|
||||||
#include "llbutton.h"
|
#include "llbutton.h"
|
||||||
#include "llcombobox.h"
|
#include "llcombobox.h"
|
||||||
#include "statemachine/aifilepicker.h"
|
#include "statemachine/aifilepicker.h"
|
||||||
@@ -229,25 +230,17 @@ void LLPreviewTexture::init()
|
|||||||
childSetText("desc", item->getDescription());
|
childSetText("desc", item->getDescription());
|
||||||
getChild<LLLineEditor>("desc")->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe);
|
getChild<LLLineEditor>("desc")->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe);
|
||||||
childSetText("uuid", getItemID().asString());
|
childSetText("uuid", getItemID().asString());
|
||||||
childSetText("uploader", getItemCreatorName());
|
|
||||||
childSetText("uploadtime", getItemCreationDate());
|
|
||||||
childSetText("alphanote", LLTrans::getString("LoadingData"));
|
childSetText("alphanote", LLTrans::getString("LoadingData"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
childSetText("uploader", getItemCreatorName());
|
||||||
|
childSetText("uploadtime", getItemCreationDate());
|
||||||
|
|
||||||
childSetCommitCallback("combo_aspect_ratio", onAspectRatioCommit, this);
|
childSetCommitCallback("combo_aspect_ratio", onAspectRatioCommit, this);
|
||||||
LLComboBox* combo = getChild<LLComboBox>("combo_aspect_ratio");
|
LLComboBox* combo = getChild<LLComboBox>("combo_aspect_ratio");
|
||||||
combo->setCurrentByIndex(0);
|
combo->setCurrentByIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLPreviewTexture::callbackLoadAvatarName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
|
|
||||||
{
|
|
||||||
if (!sInstance) return;
|
|
||||||
std::ostringstream fullname;
|
|
||||||
fullname << first << " " << last;
|
|
||||||
sInstance->childSetText("uploader", fullname.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLPreviewTexture::draw()
|
void LLPreviewTexture::draw()
|
||||||
{
|
{
|
||||||
if (mUpdateDimensions)
|
if (mUpdateDimensions)
|
||||||
@@ -486,17 +479,20 @@ std::string LLPreviewTexture::getItemCreationDate()
|
|||||||
timeToFormattedString(item->getCreationDate(), gSavedSettings.getString("TimestampFormat"), time);
|
timeToFormattedString(item->getCreationDate(), gSavedSettings.getString("TimestampFormat"), time);
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
return getString("Unknown");
|
const LLDate date = mImage->getUploadTime();
|
||||||
|
return date.notNull() ? date.toHTTPDateString(gSavedSettings.getString("TimestampFormat"))
|
||||||
|
: getString("Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LLPreviewTexture::getItemCreatorName()
|
std::string LLPreviewTexture::getItemCreatorName()
|
||||||
{
|
{
|
||||||
const LLViewerInventoryItem* item = getItem();
|
const LLViewerInventoryItem* item = getItem();
|
||||||
if(item)
|
const LLUUID& id = item ? item->getCreatorUUID() : mImage->getUploader();
|
||||||
|
if (id.notNull())
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
gCacheName->getFullName(item->getCreatorUUID(), name);
|
LLAvatarNameCache::getNSName(id, name);
|
||||||
mCreatorKey = item->getCreatorUUID();
|
mCreatorKey = id;
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
return getString("Unknown");
|
return getString("Unknown");
|
||||||
@@ -577,6 +573,14 @@ void LLPreviewTexture::updateDimensions()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update the width/height display every time
|
||||||
|
if (mImage->getUploader().notNull())
|
||||||
|
{
|
||||||
|
// Singu Note: This is what Alchemy does, we may need it, but it might help if it didn't load in init.
|
||||||
|
childSetText("uploader", getItemCreatorName());
|
||||||
|
childSetText("uploadtime", getItemCreationDate());
|
||||||
|
}
|
||||||
|
|
||||||
if (!mUserResized)
|
if (!mUserResized)
|
||||||
{
|
{
|
||||||
// clamp texture size to fit within actual size of floater after attempting resize
|
// clamp texture size to fit within actual size of floater after attempting resize
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ private:
|
|||||||
|
|
||||||
static LLPreviewTexture* sInstance;
|
static LLPreviewTexture* sInstance;
|
||||||
static void onClickProfile(void* userdata);
|
static void onClickProfile(void* userdata);
|
||||||
static void callbackLoadAvatarName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data);
|
|
||||||
|
|
||||||
// This is stored off in a member variable, because the save-as
|
// This is stored off in a member variable, because the save-as
|
||||||
// button and drag and drop functionality need to know.
|
// button and drag and drop functionality need to know.
|
||||||
|
|||||||
@@ -1378,70 +1378,107 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
|
|||||||
// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
|
// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
|
||||||
// << mID.getString() << LL_ENDL;
|
// << mID.getString() << LL_ENDL;
|
||||||
BOOL res = TRUE;
|
BOOL res = TRUE;
|
||||||
if (!gNoRender)
|
|
||||||
|
// store original size only for locally-sourced images
|
||||||
|
if (mUrl.compare(0, 7, "file://") == 0)
|
||||||
{
|
{
|
||||||
// store original size only for locally-sourced images
|
mOrigWidth = mRawImage->getWidth();
|
||||||
if (mUrl.compare(0, 7, "file://") == 0)
|
mOrigHeight = mRawImage->getHeight();
|
||||||
{
|
|
||||||
mOrigWidth = mRawImage->getWidth();
|
|
||||||
mOrigHeight = mRawImage->getHeight();
|
|
||||||
|
|
||||||
|
|
||||||
if (mBoostLevel == BOOST_PREVIEW)
|
if (mBoostLevel == BOOST_PREVIEW)
|
||||||
{
|
{
|
||||||
mRawImage->biasedScaleToPowerOfTwo(1024);
|
mRawImage->biasedScaleToPowerOfTwo(1024);
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // leave black border, do not scale image content
|
|
||||||
mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
mFullWidth = mRawImage->getWidth();
|
|
||||||
mFullHeight = mRawImage->getHeight();
|
|
||||||
setTexelsPerImage();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ // leave black border, do not scale image content
|
||||||
mOrigWidth = mFullWidth;
|
mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
|
||||||
mOrigHeight = mFullHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool size_okay = true;
|
|
||||||
|
|
||||||
U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel;
|
|
||||||
U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel;
|
|
||||||
if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
|
|
||||||
{
|
|
||||||
LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
|
|
||||||
size_okay = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
|
mFullWidth = mRawImage->getWidth();
|
||||||
{
|
mFullHeight = mRawImage->getHeight();
|
||||||
// A non power-of-two image was uploaded (through a non standard client)
|
setTexelsPerImage();
|
||||||
LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
|
|
||||||
size_okay = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !size_okay )
|
|
||||||
{
|
|
||||||
// An inappropriately-sized image was uploaded (through a non standard client)
|
|
||||||
// We treat these images as missing assets which causes them to
|
|
||||||
// be renderd as 'missing image' and to stop requesting data
|
|
||||||
LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
|
|
||||||
setIsMissingAsset();
|
|
||||||
destroyRawImage();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(!(res = insertToAtlas()))
|
|
||||||
//{
|
|
||||||
res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
|
|
||||||
//resetFaceAtlas() ;
|
|
||||||
notifyAboutCreatingTexture();
|
|
||||||
//}
|
|
||||||
setActive() ;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mOrigWidth = mFullWidth;
|
||||||
|
mOrigHeight = mFullHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mRawImage->mComment.empty())
|
||||||
|
{
|
||||||
|
// a is for uploader
|
||||||
|
// z is for time
|
||||||
|
// K is the whole thing (just coz)
|
||||||
|
std::string comment = mRawImage->getComment();
|
||||||
|
mComment['K'] = comment;
|
||||||
|
size_t position = 0;
|
||||||
|
size_t length = comment.length();
|
||||||
|
while (position < length)
|
||||||
|
{
|
||||||
|
std::size_t equals_position = comment.find('=', position);
|
||||||
|
if (equals_position != std::string::npos)
|
||||||
|
{
|
||||||
|
S8 type = comment.at(equals_position - 1);
|
||||||
|
position = comment.find('&', position);
|
||||||
|
if (position != std::string::npos)
|
||||||
|
{
|
||||||
|
mComment[type] = comment.substr(equals_position + 1, position - (equals_position + 1));
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mComment[type] = comment.substr(equals_position + 1, length - (equals_position + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
position = equals_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool size_okay = true;
|
||||||
|
|
||||||
|
S32 discard_level = mRawDiscardLevel;
|
||||||
|
if (mRawDiscardLevel < 0)
|
||||||
|
{
|
||||||
|
LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
|
||||||
|
discard_level = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
U32 raw_width = mRawImage->getWidth() << discard_level;
|
||||||
|
U32 raw_height = mRawImage->getHeight() << discard_level;
|
||||||
|
|
||||||
|
if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
|
||||||
|
{
|
||||||
|
LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
|
||||||
|
size_okay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
|
||||||
|
{
|
||||||
|
// A non power-of-two image was uploaded (through a non standard client)
|
||||||
|
LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
|
||||||
|
size_okay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !size_okay )
|
||||||
|
{
|
||||||
|
// An inappropriately-sized image was uploaded (through a non standard client)
|
||||||
|
// We treat these images as missing assets which causes them to
|
||||||
|
// be renderd as 'missing image' and to stop requesting data
|
||||||
|
LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
|
||||||
|
setIsMissingAsset();
|
||||||
|
destroyRawImage();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
|
||||||
|
|
||||||
|
notifyAboutCreatingTexture();
|
||||||
|
|
||||||
|
setActive();
|
||||||
|
|
||||||
if (!needsToSaveRawImage())
|
if (!needsToSaveRawImage())
|
||||||
{
|
{
|
||||||
@@ -2956,190 +2993,29 @@ F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
|
|||||||
{
|
{
|
||||||
return sCurrentTime - mLastReferencedSavedRawImageTime ;
|
return sCurrentTime - mLastReferencedSavedRawImageTime ;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------
|
|
||||||
//atlasing
|
LLUUID LLViewerFetchedTexture::getUploader()
|
||||||
//----------------------------------------------------------------------------------------------
|
|
||||||
/*void LLViewerFetchedTexture::resetFaceAtlas()
|
|
||||||
{
|
{
|
||||||
//Nothing should be done here.
|
return (mComment.find('a') != mComment.end()) ? LLUUID(mComment['a']) : LLUUID::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//invalidate all atlas slots for this image.
|
LLDate LLViewerFetchedTexture::getUploadTime()
|
||||||
void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom)
|
|
||||||
{
|
{
|
||||||
for(U32 i = 0 ; i < mNumFaces ; i++)
|
if (mComment.find('z') != mComment.end())
|
||||||
{
|
{
|
||||||
LLFace* facep = mFaceList[i] ;
|
struct tm t = {0};
|
||||||
facep->removeAtlas() ;
|
sscanf(mComment['z'].c_str(), "%4d%2d%2d%2d%2d%2d",
|
||||||
if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup())
|
&t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec);
|
||||||
{
|
std::string iso_date = llformat("%d-%d-%dT%d:%d:%dZ", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
|
||||||
facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY);
|
return LLDate(iso_date);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return LLDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL LLViewerFetchedTexture::insertToAtlas()
|
std::string LLViewerFetchedTexture::getComment()
|
||||||
{
|
{
|
||||||
if(!LLViewerTexture::sUseTextureAtlas)
|
return (mComment.find('K') != mComment.end()) ? mComment['K'] : LLStringUtil::null;
|
||||||
{
|
}
|
||||||
return FALSE ;
|
|
||||||
}
|
|
||||||
if(getNumFaces() < 1)
|
|
||||||
{
|
|
||||||
return FALSE ;
|
|
||||||
}
|
|
||||||
if(mGLTexturep->getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= mGLTexturep->getDiscardLevelInAtlas())
|
|
||||||
{
|
|
||||||
return FALSE ;
|
|
||||||
}
|
|
||||||
if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), mGLTexturep->getTexTarget()))
|
|
||||||
{
|
|
||||||
return FALSE ;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image.
|
|
||||||
S32 raw_w = mRawImage->getWidth() ;
|
|
||||||
S32 raw_h = mRawImage->getHeight() ;
|
|
||||||
F32 xscale = 1.0f, yscale = 1.0f ;
|
|
||||||
LLPointer<LLTextureAtlasSlot> slot_infop;
|
|
||||||
LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer.
|
|
||||||
LLSpatialGroup* groupp ;
|
|
||||||
LLFace* facep;
|
|
||||||
|
|
||||||
//if the atlas slot pointers for some faces are null, process them later.
|
|
||||||
ll_face_list_t waiting_list ;
|
|
||||||
for(U32 i = 0 ; i < mNumFaces ; i++)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
facep = mFaceList[i] ;
|
|
||||||
|
|
||||||
//face can not use atlas.
|
|
||||||
if(!facep->canUseAtlas())
|
|
||||||
{
|
|
||||||
if(facep->getAtlasInfo())
|
|
||||||
{
|
|
||||||
facep->removeAtlas() ;
|
|
||||||
}
|
|
||||||
ret = FALSE ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//the atlas slot is updated
|
|
||||||
slot_infop = facep->getAtlasInfo() ;
|
|
||||||
groupp = facep->getDrawable()->getSpatialGroup() ;
|
|
||||||
|
|
||||||
if(slot_infop)
|
|
||||||
{
|
|
||||||
if(slot_infop->getSpatialGroup() != groupp)
|
|
||||||
{
|
|
||||||
if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot
|
|
||||||
{
|
|
||||||
facep->setAtlasInfo(cur_slotp) ;
|
|
||||||
facep->setAtlasInUse(TRUE) ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
else //do not forget to update slot_infop->getSpatialGroup().
|
|
||||||
{
|
|
||||||
LLSpatialGroup* gp = slot_infop->getSpatialGroup() ;
|
|
||||||
gp->setCurUpdatingTime(gFrameCount) ;
|
|
||||||
gp->setCurUpdatingTexture(this) ;
|
|
||||||
gp->setCurUpdatingSlot(slot_infop) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //same group
|
|
||||||
{
|
|
||||||
if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated
|
|
||||||
{
|
|
||||||
facep->setAtlasInUse(TRUE) ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//if the slot is null, wait to process them later.
|
|
||||||
waiting_list.push_back(facep) ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------
|
|
||||||
//insert to atlas
|
|
||||||
if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
|
|
||||||
{
|
|
||||||
|
|
||||||
//the texture does not qualify to add to atlas, do not bother to try for other faces.
|
|
||||||
//invalidateAtlas();
|
|
||||||
return FALSE ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//update texture scale
|
|
||||||
slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
|
|
||||||
slot_infop->setTexCoordScale(xscale, yscale) ;
|
|
||||||
slot_infop->setValid() ;
|
|
||||||
slot_infop->setUpdatedTime(gFrameCount) ;
|
|
||||||
|
|
||||||
//update spatial group atlas info
|
|
||||||
groupp->setCurUpdatingTime(gFrameCount) ;
|
|
||||||
groupp->setCurUpdatingTexture(this) ;
|
|
||||||
groupp->setCurUpdatingSlot(slot_infop) ;
|
|
||||||
|
|
||||||
//make the face to switch to the atlas.
|
|
||||||
facep->setAtlasInUse(TRUE) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//process the waiting_list
|
|
||||||
for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter)
|
|
||||||
{
|
|
||||||
facep = (LLFace*)*iter ;
|
|
||||||
groupp = facep->getDrawable()->getSpatialGroup() ;
|
|
||||||
|
|
||||||
//check if this texture already inserted to atlas for this group
|
|
||||||
if((cur_slotp = groupp->getCurUpdatingSlot(this)))
|
|
||||||
{
|
|
||||||
facep->setAtlasInfo(cur_slotp) ;
|
|
||||||
facep->setAtlasInUse(TRUE) ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//need to reserve a slot from atlas
|
|
||||||
slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ;
|
|
||||||
|
|
||||||
facep->setAtlasInfo(slot_infop) ;
|
|
||||||
|
|
||||||
groupp->setCurUpdatingTime(gFrameCount) ;
|
|
||||||
groupp->setCurUpdatingTexture(this) ;
|
|
||||||
groupp->setCurUpdatingSlot(slot_infop) ;
|
|
||||||
|
|
||||||
//slot allocation failed.
|
|
||||||
if(!slot_infop || !slot_infop->getAtlas())
|
|
||||||
{
|
|
||||||
ret = FALSE ;
|
|
||||||
facep->setAtlasInUse(FALSE) ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//insert to atlas
|
|
||||||
if(!slot_infop->getAtlas()->insertSubTexture(mGLTexturep, mRawDiscardLevel, mRawImage, slot_infop->getSlotCol(), slot_infop->getSlotRow()))
|
|
||||||
{
|
|
||||||
//the texture does not qualify to add to atlas, do not bother to try for other faces.
|
|
||||||
ret = FALSE ;
|
|
||||||
//invalidateAtlas();
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//update texture scale
|
|
||||||
slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ;
|
|
||||||
slot_infop->setTexCoordScale(xscale, yscale) ;
|
|
||||||
slot_infop->setValid() ;
|
|
||||||
slot_infop->setUpdatedTime(gFrameCount) ;
|
|
||||||
|
|
||||||
//make the face to switch to the atlas.
|
|
||||||
facep->setAtlasInUse(TRUE) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret ;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
//end of LLViewerFetchedTexture
|
//end of LLViewerFetchedTexture
|
||||||
|
|||||||
@@ -413,6 +413,10 @@ public:
|
|||||||
void forceRefetch();
|
void forceRefetch();
|
||||||
/*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline.
|
/*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline.
|
||||||
|
|
||||||
|
LLUUID getUploader();
|
||||||
|
LLDate getUploadTime();
|
||||||
|
std::string getComment();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*virtual*/ void switchToCachedImage();
|
/*virtual*/ void switchToCachedImage();
|
||||||
S32 getCurrentDiscardLevelForFetching() ;
|
S32 getCurrentDiscardLevelForFetching() ;
|
||||||
@@ -510,6 +514,8 @@ protected:
|
|||||||
|
|
||||||
BOOL mForSculpt ; //a flag if the texture is used as sculpt data.
|
BOOL mForSculpt ; //a flag if the texture is used as sculpt data.
|
||||||
BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
|
BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
|
||||||
|
|
||||||
|
std::map<S8, std::string> mComment;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep; // Texture to show for an image asset that is not in the database
|
static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep; // Texture to show for an image asset that is not in the database
|
||||||
|
|||||||
Reference in New Issue
Block a user