svn merge svn+ssh://svn.lindenlab.com/svn/linden/release@56631 svn+ssh://svn.lindenlab.com/svn/linden/branches/abstract-kdu@56647 --ignore-ancestry

master
Jon Wolk 2007-01-10 21:54:56 +00:00
parent 8c344f4da0
commit 0fe36daf56
16 changed files with 610 additions and 24 deletions

36
doc/LICENSE-source.txt Normal file
View File

@ -0,0 +1,36 @@
Source code
========
The license for the source code in this distribution should be clearly
marked on each source file. Unless otherwise specified, the source
code in this distribution ("Source Code") is provided by Linden Lab to
you under the terms of the GNU General Public License, version 2.0
("GPL"), unless you have obtained a separate licensing agreement
("Other License"), formally executed by you and Linden Lab. Terms of
the GPL can be found in doc/GPL-license.txt in this distribution, or
online at http://secondlife.com/developers/opensource/gplv2
There are special exceptions to the terms and conditions of the GPL as
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://secondlife.com/developers/opensource/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.
Logos and trademarks
==============
"Second Life" and "Linden Lab" are registered trademarks of Linden
Research, Inc. Other trademarks include (but are not limited to): the
names Linden and Linden Research, as well as the Linden Lab Hexagon
Design and the Second Life Hand Design logos.
Use of logos and trademarks are subject to the Linden Lab trademark
policy, available at:
http://secondlife.com/corporate/trademark/

View File

@ -4,38 +4,172 @@
* Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#include "linden_common.h"
#ifndef LL_USE_KDU
#define LL_USE_KDU 1
#endif // LL_USE_KDU
#include <apr-1/apr_pools.h>
#include <apr-1/apr_dso.h>
#include "lldir.h"
#include "llimagej2c.h"
#include "llmemory.h"
#if LL_USE_KDU
#include "llimagej2ckdu.h"
typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)();
typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*);
//some "private static" variables so we only attempt to load
//dynamic libaries once
CreateLLImageJ2CFunction j2cimpl_create_func;
DestroyLLImageJ2CFunction j2cimpl_destroy_func;
apr_pool_t *j2cimpl_dso_memory_pool;
apr_dso_handle_t *j2cimpl_dso_handle;
//Declare the prototype for theses functions here, their functionality
//will be implemented in other files which define a derived LLImageJ2CImpl
//but only ONE static library which has the implementation for this
//function should ever be included
LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl();
void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl);
//static
//Loads the required "create" and "destroy" functions needed
void LLImageJ2C::openDSO()
{
//attempt to load a DSO and get some functions from it
std::string dso_name;
std::string dso_path;
bool all_functions_loaded = false;
apr_status_t rv;
#if LL_WINDOWS
dso_name = "llkdu.dll";
#elif LL_DARWIN
dso_name = "libllkdu.dylib";
#else
dso_name = "libllkdu.so";
#endif
#include "llimagej2coj.h"
dso_path = gDirUtilp->findFile(dso_name,
gDirUtilp->getAppRODataDir(),
gDirUtilp->getExecutableDir());
j2cimpl_dso_handle = NULL;
j2cimpl_dso_memory_pool = NULL;
//attempt to load the shared library
apr_pool_create(&j2cimpl_dso_memory_pool, NULL);
rv = apr_dso_load(&j2cimpl_dso_handle,
dso_path.c_str(),
j2cimpl_dso_memory_pool);
//now, check for success
if ( rv == APR_SUCCESS )
{
//found the dynamic library
//now we want to load the functions we're interested in
CreateLLImageJ2CFunction create_func = NULL;
DestroyLLImageJ2CFunction dest_func = NULL;
rv = apr_dso_sym((apr_dso_handle_sym_t*)&create_func,
j2cimpl_dso_handle,
"createLLImageJ2CKDU");
if ( rv == APR_SUCCESS )
{
//we've loaded the create function ok
//we need to delete via the DSO too
//so lets check for a destruction function
rv = apr_dso_sym((apr_dso_handle_sym_t*)&dest_func,
j2cimpl_dso_handle,
"destroyLLImageJ2CKDU");
if ( rv == APR_SUCCESS )
{
//k, everything is loaded alright
j2cimpl_create_func = create_func;
j2cimpl_destroy_func = dest_func;
all_functions_loaded = true;
}
}
}
if ( !all_functions_loaded )
{
//something went wrong with the DSO or function loading..
//fall back onto our satefy impl creation function
#if 0
// precious verbose debugging, sadly we can't use our
// 'llinfos' stream etc. this early in the initialisation seq.
char errbuf[256];
fprintf(stderr, "failed to load syms from DSO %s (%s)\n",
dso_name.c_str(), dso_path.c_str());
apr_strerror(rv, errbuf, sizeof(errbuf));
fprintf(stderr, "error: %d, %s\n", rv, errbuf);
apr_dso_error(j2cimpl_dso_handle, errbuf, sizeof(errbuf));
fprintf(stderr, "dso-error: %d, %s\n", rv, errbuf);
#endif
if ( j2cimpl_dso_handle )
{
apr_dso_unload(j2cimpl_dso_handle);
j2cimpl_dso_handle = NULL;
}
if ( j2cimpl_dso_memory_pool )
{
apr_pool_destroy(j2cimpl_dso_memory_pool);
j2cimpl_dso_memory_pool = NULL;
}
}
}
//static
void LLImageJ2C::closeDSO()
{
if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle);
if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool);
}
LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C),
mMaxBytes(0),
mRawDiscardLevel(-1),
mRate(0.0f)
{
#if LL_USE_KDU
mImpl = new LLImageJ2CKDU();
#else
mImpl = new LLImageJ2COJ();
#endif
//We assume here that if we wanted to destory via
//a dynamic library that the approriate open calls were made
//before any calls to this constructor.
//Therefore, a NULL creation function pointer here means
//we either did not want to create using functions from the dynamic
//library or there were issues loading it, either way
//use our fall back
if ( !j2cimpl_create_func )
{
j2cimpl_create_func = fallbackCreateLLImageJ2CImpl;
}
mImpl = j2cimpl_create_func();
}
// virtual
LLImageJ2C::~LLImageJ2C()
{
delete mImpl;
//We assume here that if we wanted to destory via
//a dynamic library that the approriate open calls were made
//before any calls to this destructor.
//Therefore, a NULL creation function pointer here means
//we either did not want to destroy using functions from the dynamic
//library or there were issues loading it, either way
//use our fall back
if ( !j2cimpl_destroy_func )
{
j2cimpl_destroy_func = fallbackDestroyLLImageJ2CImpl;
}
if ( mImpl )
{
j2cimpl_destroy_func(mImpl);
}
}
// virtual

View File

@ -13,7 +13,6 @@
#include "llassettype.h"
class LLImageJ2CImpl;
class LLImageJ2C : public LLImageFormatted
{
protected:
@ -47,6 +46,9 @@ public:
static S32 calcHeaderSizeJ2C();
static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f);
static void openDSO();
static void closeDSO();
protected:
friend class LLImageJ2CImpl;
friend class LLImageJ2COJ;
@ -63,8 +65,9 @@ protected:
// Derive from this class to implement JPEG2000 decoding
class LLImageJ2CImpl
{
protected:
public:
virtual ~LLImageJ2CImpl();
protected:
virtual BOOL getMetadata(LLImageJ2C &base) = 0;
virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0;
virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0) = 0;

View File

@ -0,0 +1,356 @@
/**
* @file llimagej2coj.cpp
* @brief This is an implementation of JPEG2000 encode/decode using OpenJPEG.
*
* Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#include "linden_common.h"
#include "llimagej2coj.h"
#include "openjpeg/openjpeg.h"
#include "lltimer.h"
#include "llmemory.h"
LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
{
return new LLImageJ2COJ();
}
void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
{
delete impl;
impl = NULL;
}
/**
sample error callback expecting a FILE* client object
*/
void error_callback(const char *msg, void *client_data) {
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
void warning_callback(const char *msg, void *client_data) {
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting no client object
*/
void info_callback(const char *msg, void *client_data) {
fprintf(stdout, "[INFO] %s", msg);
}
LLImageJ2COJ::LLImageJ2COJ() : LLImageJ2CImpl()
{
}
LLImageJ2COJ::~LLImageJ2COJ()
{
}
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(&parameters);
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, &parameters);
/* 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);
if(!image)
{
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
return 1;
}
/* close the byte stream */
opj_cio_close(cio);
/* free remaining structures */
if(dinfo) {
opj_destroy_decompress(dinfo);
}
// Copy image data into our raw image format (instead of the separate channel format
S32 width = 0;
S32 height = 0;
S32 img_components = image->numcomps;
S32 channels = img_components - first_channel;
if( channels > max_channel_count )
{
channels = max_channel_count;
}
width = image->x1 - image->x0;
height = image->y1 - image->y0;
raw_image.resize(width, height, channels);
U8 *rawp = raw_image.getData();
for (S32 comp = first_channel; comp < first_channel + channels; comp++)
{
S32 offset = comp;
for (S32 y = (height - 1); y >= 0; y--)
{
for (S32 x = 0; x < width; x++)
{
rawp[offset] = image->comps[comp].data[y*width + x];
offset += channels;
}
}
}
/* free image data structure */
opj_image_destroy(image);
base.setDecodingDone();
return TRUE;
}
BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time)
{
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(&parameters);
parameters.tcp_rates[0] = 0;
parameters.tcp_numlayers++;
parameters.cp_disto_alloc = 1;
parameters.cod_format = 0;
if (!comment_text)
{
parameters.cp_comment = "";
}
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;
opj_cio_t *cio = NULL;
/* get a J2K compressor handle */
opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
/* setup the encoder parameters using the current image and using user parameters */
opj_setup_encoder(cinfo, &parameters, image);
/* open a byte stream for writing */
/* allocate memory for all tiles */
cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
/* encode the image */
bool bSuccess = opj_encode(cinfo, cio, image, parameters.index);
if (!bSuccess) {
opj_cio_close(cio);
fprintf(stderr, "failed to encode image\n");
return FALSE;
}
codestream_length = cio_tell(cio);
base.copyData(cio->buffer, codestream_length);
/* close and free the byte stream */
opj_cio_close(cio);
/* free remaining compression structures */
opj_destroy_compress(cinfo);
/* free user parameters structure */
if(parameters.cp_matrice) free(parameters.cp_matrice);
/* free image data */
opj_image_destroy(image);
return TRUE;
}
BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
{
//
// FIXME: We get metadata by decoding the ENTIRE image.
//
// Update the raw discard level
base.updateRawDiscardLevel();
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(&parameters);
//parameters.cp_reduce = mRawDiscardLevel;
/* 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, &parameters);
/* 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);
if(!image)
{
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
return 1;
}
/* close the byte stream */
opj_cio_close(cio);
/* free remaining structures */
if(dinfo) {
opj_destroy_decompress(dinfo);
}
// Copy image data into our raw image format (instead of the separate channel format
S32 width = 0;
S32 height = 0;
S32 img_components = image->numcomps;
width = image->x1 - image->x0;
height = image->y1 - image->y0;
base.setSize(width, height, img_components);
/* free image data structure */
opj_image_destroy(image); return TRUE;
}

View File

@ -0,0 +1,29 @@
/**
* @file llimagej2coj.h
* @brief This is an implementation of JPEG2000 encode/decode using OpenJPEG.
*
* Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#ifndef LL_LLIMAGEJ2COJ_H
#define LL_LLIMAGEJ2COJ_H
#include "llimagej2c.h"
class LLImageJ2COJ : public LLImageJ2CImpl
{
public:
LLImageJ2COJ();
virtual ~LLImageJ2COJ();
protected:
/*virtual*/ BOOL getMetadata(LLImageJ2C &base);
/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0);
// Temporary variables for in-progress decodes...
LLImageRaw *mRawImagep;
};
#endif

View File

@ -33,6 +33,9 @@ extern S32 BTN_HEIGHT;
// All button widths should be rounded up to this size
extern S32 BTN_GRID;
class LLUICtrlFactory;
//
// Classes
//

View File

@ -16,6 +16,7 @@
#include "llimagegl.h"
class LLTextBox;
class LLUICtrlFactory;
//
// Classes

View File

@ -29,6 +29,7 @@
class LLScrollbar;
class LLViewBorder;
class LLUICtrlFactory;
class LLScrollableContainerView : public LLUICtrl

View File

@ -12,6 +12,8 @@
#include "lluictrl.h"
#include "v4color.h"
class LLUICtrlFactory;
class LLSlider : public LLUICtrl
{
public:

View File

@ -31,6 +31,7 @@ class LLFontGL;
class LLButton;
class LLTextBox;
class LLLineEditor;
class LLUICtrlFactory;
class LLSpinCtrl

View File

@ -15,6 +15,8 @@
#include "llfontgl.h"
#include "lluistring.h"
class LLUICtrlFactory;
class LLTextBox
: public LLUICtrl

View File

@ -25,6 +25,7 @@ class LLScrollbar;
class LLViewBorder;
class LLKeywordToken;
class LLTextCmd;
class LLUICtrlFactory;
//
// Constants

View File

@ -18,6 +18,7 @@
#include "llxmlnode.h"
class LLUUID;
class LLUICtrlFactory;
class LLViewBorder : public LLView

View File

@ -121,6 +121,21 @@ BOOL LLFloaterTOS::postBuild()
childSetValue("tos_text", LLSD(mMessage));
};
// this displays the critical message
if ( mType != TOS_TOS )
{
LLTextEditor *Editor = LLUICtrlFactory::getTextEditorByName(this, "tos_text");
if (Editor)
{
Editor->setHandleEditKeysDirectly( TRUE );
Editor->setEnabled( FALSE );
Editor->setReadOnlyFgColor(LLColor4::white);
Editor->setWordWrap(TRUE);
Editor->setFocus(TRUE);
}
childSetValue("tos_text", LLSD(mMessage));
};
#if LL_LIBXUL_ENABLED
// disable Agree to TOS radio button until the page has fully loaded
LLRadioGroup* tos_agreement = LLUICtrlFactory::getRadioGroupByName(this, "tos_agreement");

View File

@ -102,19 +102,19 @@
#include "u64.h"
// Library includes from llimage
#include "kdc_flow_control.h"
#include "kde_flow_control.h"
#include "kdu_image.h"
#include "kdu_image_local.h"
#include "llblockdata.h"
#include "llblockdecoder.h"
#include "llblockencoder.h"
//#include "kdc_flow_control.h"
//#include "kde_flow_control.h"
//#include "kdu_image.h"
//#include "kdu_image_local.h"
//#include "llblockdata.h"
//#include "llblockdecoder.h"
//#include "llblockencoder.h"
#include "llimage.h"
#include "llimagebmp.h"
#include "llimagej2c.h"
#include "llimagejpeg.h"
#include "llimagetga.h"
#include "llkdumem.h"
//#include "llkdumem.h"
#include "llmapimagetype.h"
// Library includes from llmath project

View File

@ -12,6 +12,7 @@
#include "lltexteditor.h"
class LLInventoryItem;
class LLEmbeddedItems;
//