本文整理汇总了C++中LLImageRaw::getData方法的典型用法代码示例。如果您正苦于以下问题:C++ LLImageRaw::getData方法的具体用法?C++ LLImageRaw::getData怎么用?C++ LLImageRaw::getData使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类LLImageRaw
的用法示例。
在下文中一共展示了LLImageRaw::getData方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getWidth
// Src and dst are same size. Src has 3 components. Dst has 4 components.
void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
{
LLImageRaw* dst = this; // Just for clarity.
llassert( 3 == src->getComponents() );
llassert( 4 == dst->getComponents() );
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
S32 pixels = getWidth() * getHeight();
U8* src_data = src->getData();
U8* dst_data = dst->getData();
for( S32 i=0; i<pixels; i++ )
{
dst_data[0] = src_data[0];
dst_data[1] = src_data[1];
dst_data[2] = src_data[2];
dst_data[3] = 255;
src_data += 3;
dst_data += 4;
}
}
示例2: copyUnscaledAlphaMask
void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
{
LLImageRaw* dst = this; // Just for clarity.
llassert( 1 == src->getComponents() );
llassert( 4 == dst->getComponents() );
llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
S32 pixels = getWidth() * getHeight();
U8* src_data = src->getData();
U8* dst_data = dst->getData();
for ( S32 i = 0; i < pixels; i++ )
{
dst_data[0] = fill.mV[0];
dst_data[1] = fill.mV[1];
dst_data[2] = fill.mV[2];
dst_data[3] = src_data[0];
src_data += 1;
dst_data += 4;
}
}
示例3:
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
{
LL_INFOS() << "compositeScaled4onto3" << LL_ENDL;
LLImageRaw* dst = this; // Just for clarity.
llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
llassert_always(temp_data_size > 0);
std::vector<U8> temp_buffer(temp_data_size);
// Vertical: scale but no composite
for( S32 col = 0; col < src->getWidth(); col++ )
{
copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
}
// Horizontal: scale and composite
for( S32 row = 0; row < dst->getHeight(); row++ )
{
compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
}
}
示例4: callbacks
BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
{
const S32 MAX_COMPS = 5;
opj_cparameters_t parameters; /* compression parameters */
opj_event_mgr_t event_mgr; /* event manager */
/*
configure the event callbacks (not required)
setting of each callback is optional
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set encoding parameters to default values */
opj_set_default_encoder_parameters(¶meters);
parameters.cod_format = 0;
parameters.cp_disto_alloc = 1;
if (reversible)
{
parameters.tcp_numlayers = 1;
parameters.tcp_rates[0] = 0.0f;
}
else
{
parameters.tcp_numlayers = 5;
parameters.tcp_rates[0] = 1920.0f;
parameters.tcp_rates[1] = 480.0f;
parameters.tcp_rates[2] = 120.0f;
parameters.tcp_rates[3] = 30.0f;
parameters.tcp_rates[4] = 10.0f;
parameters.irreversible = 1;
if (raw_image.getComponents() >= 3)
{
parameters.tcp_mct = 1;
}
}
if (!comment_text)
{
parameters.cp_comment = (char *) "";
}
else
{
// Awful hacky cast, too lazy to copy right now.
parameters.cp_comment = (char *) comment_text;
}
//
// Fill in the source image from our raw image
//
OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
opj_image_cmptparm_t cmptparm[MAX_COMPS];
opj_image_t * image = NULL;
S32 numcomps = raw_image.getComponents();
S32 width = raw_image.getWidth();
S32 height = raw_image.getHeight();
memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t));
for(S32 c = 0; c < numcomps; c++) {
cmptparm[c].prec = 8;
cmptparm[c].bpp = 8;
cmptparm[c].sgnd = 0;
cmptparm[c].dx = parameters.subsampling_dx;
cmptparm[c].dy = parameters.subsampling_dy;
cmptparm[c].w = width;
cmptparm[c].h = height;
}
/* create the image */
image = opj_image_create(numcomps, &cmptparm[0], color_space);
image->x1 = width;
image->y1 = height;
S32 i = 0;
const U8 *src_datap = raw_image.getData();
for (S32 y = height - 1; y >= 0; y--)
{
for (S32 x = 0; x < width; x++)
{
const U8 *pixel = src_datap + (y*width + x) * numcomps;
for (S32 c = 0; c < numcomps; c++)
{
image->comps[c].data[i] = *pixel;
pixel++;
}
i++;
}
}
/* encode the destination image */
/* ---------------------------- */
int codestream_length;
//.........这里部分代码省略.........
示例5: sizeof
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;
opj_dparameters_t parameters; /* decompression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_image_t *image = NULL;
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
opj_cio_t *cio = NULL;
/* configure the event callbacks (not required) */
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
opj_set_default_decoder_parameters(¶meters);
parameters.cp_reduce = base.getRawDiscardLevel();
/* decode the code-stream */
/* ---------------------- */
/* JPEG-2000 codestream */
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_J2K);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, ¶meters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
/* decode the stream and fill the image structure */
image = opj_decode(dinfo, cio);
/* close the byte stream */
opj_cio_close(cio);
/* free remaining structures */
if(dinfo)
{
opj_destroy_decompress(dinfo);
}
// The image decode failed if the return was NULL or the component
// count was zero. The latter is just a sanity check before we
// dereference the array.
if(!image || !image->numcomps)
{
LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL;
if (image)
{
opj_image_destroy(image);
}
return TRUE; // done
}
// sometimes we get bad data out of the cache - check to see if the decode succeeded
for (S32 i = 0; i < image->numcomps; i++)
{
if (image->comps[i].factor != base.getRawDiscardLevel())
{
// if we didn't get the discard level we're expecting, fail
opj_image_destroy(image);
base.mDecoding = FALSE;
return TRUE;
}
}
if(image->numcomps <= first_channel)
{
llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl;
if (image)
{
opj_image_destroy(image);
}
return TRUE;
}
// 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;
if( channels > max_channel_count )
channels = max_channel_count;
//.........这里部分代码省略.........
示例6:
// Src and dst can be any size. Src has 4 components. Dst has 3 components.
void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
{
LLMemType mt1((LLMemType::EMemType)mMemType);
llinfos << "compositeScaled4onto3" << llendl;
LLImageRaw* dst = this; // Just for clarity.
llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
// Vertical: scale but no composite
S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
U8* temp_buffer = new U8[ temp_data_size ];
for( S32 col = 0; col < src->getWidth(); col++ )
{
copyLineScaled( src->getData() + (src->getComponents() * col), temp_buffer + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
}
// Horizontal: scale and composite
for( S32 row = 0; row < dst->getHeight(); row++ )
{
compositeRowScaled4onto3( temp_buffer + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
}
// Clean up
delete[] temp_buffer;
}
示例7: mem_in
BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
{
// Declare and set simple arguments
bool transpose = false;
bool vflip = true;
bool hflip = false;
try
{
// Set up input image files
siz_params siz;
// Should set rate someplace here
LLKDUMemIn mem_in(raw_image.getData(),
raw_image.getDataSize(),
raw_image.getWidth(),
raw_image.getHeight(),
raw_image.getComponents(),
&siz);
base.setSize(raw_image.getWidth(), raw_image.getHeight(), raw_image.getComponents());
int num_components = raw_image.getComponents();
siz.set(Scomponents,0,0,num_components);
siz.set(Sdims,0,0,base.getHeight()); // Height of first image component
siz.set(Sdims,0,1,base.getWidth()); // Width of first image component
siz.set(Sprecision,0,0,8); // Image samples have original bit-depth of 8
siz.set(Ssigned,0,0,false); // Image samples are originally unsigned
kdu_params *siz_ref = &siz;
siz_ref->finalize();
siz_params transformed_siz; // Use this one to construct code-stream
transformed_siz.copy_from(&siz,-1,-1,-1,0,transpose,false,false);
// Construct the `kdu_codestream' object and parse all remaining arguments
U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents();
max_output_size = (max_output_size < 1000 ? 1000 : max_output_size);
U8 *output_buffer = new U8[max_output_size];
U32 output_size = 0; // Address updated by LLKDUMemTarget to give the final compressed buffer size
LLKDUMemTarget output(output_buffer, output_size, max_output_size);
kdu_codestream codestream;
codestream.create(&transformed_siz,&output);
if (comment_text)
{
// Set the comments for the codestream
kdu_codestream_comment comment = codestream.add_comment();
comment.put_text(comment_text);
}
if (num_components >= 3)
{
// Note that we always use YCC and not YUV
// *TODO: Verify this doesn't screws up reversible textures (like sculpties) as YCC is not reversible but YUV is...
set_default_colour_weights(codestream.access_siz());
}
// Set codestream options
int nb_layers = 0;
kdu_long layer_bytes[MAX_NB_LAYERS];
U32 max_bytes = (U32)(base.getWidth() * base.getHeight() * base.getComponents());
// Rate is the argument passed into the LLImageJ2C which specifies the target compression rate. The default is 8:1.
// *TODO: mRate is actually always 8:1 in the viewer. Test different values.
llassert (base.mRate > 0.f);
max_bytes = (U32)((F32)(max_bytes) * base.mRate);
// This code is where we specify the target number of bytes for each quality layer.
// We're using a logarithmic spacing rule that fits with our way of fetching texture data.
// Note: For more info on this layers business, read kdu_codestream::flush() doc in kdu_compressed.h
layer_bytes[nb_layers++] = FIRST_PACKET_SIZE;
U32 i = MIN_LAYER_SIZE;
while ((i < max_bytes) && (nb_layers < (MAX_NB_LAYERS-1)))
{
layer_bytes[nb_layers++] = i;
i *= 4;
}
// Note: for small images, we can have (max_bytes < FIRST_PACKET_SIZE), hence the test
if (layer_bytes[nb_layers-1] < max_bytes)
{
// Set the last quality layer so to fit the preset compression ratio
layer_bytes[nb_layers++] = max_bytes;
}
if (reversible)
{
// Use 0 for a last quality layer for reversible images so all remaining code blocks will be flushed
// Hack: KDU encoding for reversible images has a bug for small images that leads to j2c images that
// cannot be open or are very blurry. Avoiding that last layer prevents the problem to happen.
if ((base.getWidth() >= 32) || (base.getHeight() >= 32))
{
layer_bytes[nb_layers++] = 0;
}
codestream.access_siz()->parse_string("Creversible=yes");
// *TODO: we should use yuv in reversible mode
// Don't turn this on now though as it creates problems on decoding for the moment
//codestream.access_siz()->parse_string("Cycc=no");
}
//.........这里部分代码省略.........
示例8: LLKDUDecodeState
// Returns TRUE to mean done, whether successful or not.
BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
ECodeStreamMode mode = MODE_FAST;
LLTimer decode_timer;
if (!mCodeStreamp)
{
if (!initDecode(base, raw_image, decode_time, mode, first_channel, max_channel_count))
{
// Initializing the J2C decode failed, bail out.
cleanupCodeStream();
return TRUE; // done
}
}
// These can probably be grabbed from what's saved in the class.
kdu_dims dims;
mCodeStreamp->get_dims(0,dims);
// Now we are ready to walk through the tiles processing them one-by-one.
kdu_byte *buffer = raw_image.getData();
while (mTPosp->y < mTileIndicesp->size.y)
{
while (mTPosp->x < mTileIndicesp->size.x)
{
try
{
if (!mDecodeState)
{
kdu_tile tile = mCodeStreamp->open_tile(*(mTPosp)+mTileIndicesp->pos);
// Find the region of the buffer occupied by this
// tile. Note that we have no control over
// sub-sampling factors which might have been used
// during compression and so it can happen that tiles
// (at the image component level) actually have
// different dimensions. For this reason, we cannot
// figure out the buffer region occupied by a tile
// directly from the tile indices. Instead, we query
// the highest resolution of the first tile-component
// concerning its location and size on the canvas --
// the `dims' object already holds the location and
// size of the entire image component on the same
// canvas coordinate system. Comparing the two tells
// us where the current tile is in the buffer.
S32 channels = base.getComponents() - first_channel;
if (channels > max_channel_count)
{
channels = max_channel_count;
}
kdu_resolution res = tile.access_component(0).access_resolution();
kdu_dims tile_dims; res.get_dims(tile_dims);
kdu_coords offset = tile_dims.pos - dims.pos;
int row_gap = channels*dims.size.x; // inter-row separation
kdu_byte *buf = buffer + offset.y*row_gap + offset.x*channels;
mDecodeState = new LLKDUDecodeState(tile, buf, row_gap);
}
// Do the actual processing
F32 remaining_time = decode_time - decode_timer.getElapsedTimeF32();
// This is where we do the actual decode. If we run out of time, return false.
if (mDecodeState->processTileDecode(remaining_time, (decode_time > 0.0f)))
{
delete mDecodeState;
mDecodeState = NULL;
}
else
{
// Not finished decoding yet.
// setLastError("Ran out of time while decoding");
return FALSE;
}
}
catch (const char* msg)
{
base.setLastError(ll_safe_string(msg));
base.decodeFailed();
cleanupCodeStream();
return TRUE; // done
}
catch (...)
{
base.setLastError( "Unknown J2C error" );
base.decodeFailed();
cleanupCodeStream();
return TRUE; // done
}
mTPosp->x++;
}
mTPosp->y++;
mTPosp->x = 0;
}
cleanupCodeStream();
return TRUE;
//.........这里部分代码省略.........
示例9:
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
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_event_mgr_t event_mgr = { }; /* event manager */
opj_image_t *image = nullptr;
opj_dinfo_t* dinfo = nullptr; /* handle to a decompressor */
opj_cio_t *cio = nullptr;
/* configure the event callbacks (not required) */
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
opj_set_default_decoder_parameters(¶meters);
parameters.cp_reduce = base.getRawDiscardLevel();
if(parameters.cp_reduce == 0 && *(U16*)(base.getData() + base.getDataSize() - 2) != 0xD9FF)
{
bool failed = true;
for(S32 i = base.getDataSize()-1; i > 42; --i)
{
if(base.getData()[i] != 0x00)
{
failed = *(U16*)(base.getData()+i-1) != 0xD9FF;
break;
}
}
if(failed)
{
opj_image_destroy(image);
base.decodeFailed();
return TRUE;
}
}
/* decode the code-stream */
/* ---------------------- */
/* JPEG-2000 codestream */
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_J2K);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, ¶meters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
/* decode the stream and fill the image structure */
//.........这里部分代码省略.........
示例10: sizeof
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
raw_image.decodedComment = LLImageMetaDataReader::ExtractKDUUploadComment(base.getData(), base.getDataSize());
LLTimer decode_timer;
opj_dparameters_t parameters; /* decompression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_image_t *image = NULL;
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
opj_cio_t *cio = NULL;
/* configure the event callbacks (not required) */
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
opj_set_default_decoder_parameters(¶meters);
parameters.cp_reduce = base.getRawDiscardLevel();
/* decode the code-stream */
/* ---------------------- */
/* JPEG-2000 codestream */
/* get a decoder handle */
dinfo = opj_create_decompress(CODEC_J2K);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, ¶meters);
/* open a byte stream */
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 structur to get the decoding result.
This structure is a bit unusual in that it is not received through
opj, but still has somt 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 */
opj_cio_close(cio);
/* free remaining structures */
if(dinfo)
{
opj_destroy_decompress(dinfo);
}
// The image decode failed if the return was NULL or the component
// count was zero. The latter is just a sanity check before we
// dereference the array.
if(!image)
{
LL_WARNS ("Openjpeg") << "Failed to decode image at discard: " << (S32)base.getRawDiscardLevel() << ". No image." << LL_ENDL;
if (base.getRawDiscardLevel() == 0)
{
base.decodeFailed();
}
return TRUE; // done
}
S32 img_components = image->numcomps;
if( !img_components ) // < 1 ||img_components > 4 )
{
LL_WARNS("Openjpeg") << "Failed to decode image at discard: " << (S32)base.getRawDiscardLevel() << ". Wrong number of components: " << img_components << LL_ENDL;
if (image)
{
opj_destroy_cstr_info(&cinfo);
opj_image_destroy(image);
}
if (base.getRawDiscardLevel() == 0)
{
base.decodeFailed();
}
return TRUE; // done
}
// sometimes we get bad data out of the cache - check to see if the decode succeeded
int decompdifference = 0;
if (cinfo.numdecompos) // sanity
{
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
//.........这里部分代码省略.........
示例11: PerformSculptUpdates
void LocalAssetBrowser::PerformSculptUpdates(LocalBitmap& unit)
{
/* looking for sculptmap using objects only */
std::vector<affected_object> object_list = unit.getUsingObjects(false, false, true);
if (object_list.empty()) { return; }
for( std::vector<affected_object>::iterator iter = object_list.begin();
iter != object_list.end(); iter++ )
{
affected_object aobj = *iter;
if (aobj.object)
{
if (!aobj.local_sculptmap) continue; // should never get here. only in case of misuse.
// update code [begin]
if (unit.volume_dirty)
{
LLImageRaw* rawimage = gTextureList.findImage(unit.getID())->getCachedRawImage();
aobj.object->getVolume()->sculpt(rawimage->getWidth(), rawimage->getHeight(), rawimage->getComponents(), rawimage->getData(), 0);
unit.volume_dirty = false;
}
// tell affected drawable it's got updated
aobj.object->mDrawable->getVOVolume()->setSculptChanged(true);
aobj.object->mDrawable->getVOVolume()->markForUpdate(true);
// update code [end]
}
}
}
示例12: timestr
BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
{
const S32 MAX_COMPS = 5;
opj_cparameters_t parameters; /* compression parameters */
opj_event_mgr_t event_mgr; /* event manager */
/*
configure the event callbacks (not required)
setting of each callback is optional
*/
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set encoding parameters to default values */
opj_set_default_encoder_parameters(¶meters);
parameters.cod_format = 0;
parameters.cp_disto_alloc = 1;
if (reversible)
{
parameters.tcp_numlayers = 1;
parameters.tcp_rates[0] = 0.0f;
}
else
{
parameters.tcp_numlayers = 5;
parameters.tcp_rates[0] = 1920.0f;
parameters.tcp_rates[1] = 480.0f;
parameters.tcp_rates[2] = 120.0f;
parameters.tcp_rates[3] = 30.0f;
parameters.tcp_rates[4] = 10.0f;
parameters.irreversible = 1;
if (raw_image.getComponents() >= 3)
{
parameters.tcp_mct = 1;
}
}
std::string comment_metadata;
if (!comment_text)
{
//Inserting owner id, upload time, and dimensions
//See http://wiki.secondlife.com/wiki/Texture_meta-data for details.
extern LLUUID gAgentID;
time_t now = time(NULL);
tm * ptime = gmtime(&now);
//std::string color_avg(llformat("c=%02x%02x%02x%02x")); //Perhaps do this some day...
std::string timestr(llformat("z=%04i%02i%02i%02i%02i%02i",ptime->tm_year+1900,ptime->tm_mon+1,ptime->tm_mday,ptime->tm_hour,ptime->tm_min,ptime->tm_sec));
comment_metadata=llformat("a=%s&%s&h=%u&w=%u",gAgentID.asString().c_str(),timestr.c_str(),(U32)raw_image.getHeight(),(U32)raw_image.getWidth());
parameters.cp_comment = (char *) comment_metadata.c_str();
}
else
{
// Awful hacky cast, too lazy to copy right now.
parameters.cp_comment = (char *) comment_text;
}
//
// Fill in the source image from our raw image
//
OPJ_COLOR_SPACE color_space = CLRSPC_SRGB;
opj_image_cmptparm_t cmptparm[MAX_COMPS];
opj_image_t * image = NULL;
S32 numcomps = llmin((S32)raw_image.getComponents(),(S32)MAX_COMPS); //Clamp avoid overrunning buffer -Shyotl
S32 width = raw_image.getWidth();
S32 height = raw_image.getHeight();
memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t));
for(S32 c = 0; c < numcomps; c++) {
cmptparm[c].prec = 8;
cmptparm[c].bpp = 8;
cmptparm[c].sgnd = 0;
cmptparm[c].dx = parameters.subsampling_dx;
cmptparm[c].dy = parameters.subsampling_dy;
cmptparm[c].w = width;
cmptparm[c].h = height;
}
/* create the image */
image = opj_image_create(numcomps, &cmptparm[0], color_space);
image->x1 = width;
image->y1 = height;
S32 i = 0;
const U8 *src_datap = raw_image.getData();
for (S32 y = height - 1; y >= 0; y--)
{
for (S32 x = 0; x < width; x++)
{
const U8 *pixel = src_datap + (y*width + x) * numcomps;
for (S32 c = 0; c < numcomps; c++)
{
image->comps[c].data[i] = *pixel;
pixel++;
}
i++;
//.........这里部分代码省略.........