summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llkdu/llimagej2ckdu.cpp98
-rw-r--r--indra/llkdu/llimagej2ckdu.h45
2 files changed, 78 insertions, 65 deletions
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 0b2ac03b9d..0d37b123ec 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -138,15 +138,21 @@ struct LLKDUMessageWarning : public LLKDUMessage
{
LLKDUMessageWarning():
LLKDUMessage("Warning")
- {}
+ {
+ kdu_customize_warnings(this);
+ }
};
+// Instantiating LLKDUMessageWarning calls kdu_customize_warnings() with the
+// new instance. Make it static so this only happens once.
static LLKDUMessageWarning sWarningHandler;
struct LLKDUMessageError : public LLKDUMessage
{
LLKDUMessageError():
LLKDUMessage("Error")
- {}
+ {
+ kdu_customize_errors(this);
+ }
virtual void flush(bool end_of_message = false)
{
@@ -165,20 +171,20 @@ struct LLKDUMessageError : public LLKDUMessage
}
}
};
+// Instantiating LLKDUMessageError calls kdu_customize_errors() with the new
+// instance. Make it static so this only happens once.
static LLKDUMessageError sErrorHandler;
-static bool kdu_message_initialized = false;
-
LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(),
-mInputp(NULL),
-mCodeStreamp(NULL),
-mTPosp(NULL),
-mTileIndicesp(NULL),
-mRawImagep(NULL),
-mDecodeState(NULL),
-mBlocksSize(-1),
-mPrecinctsSize(-1),
-mLevels(0)
+ mInputp(),
+ mCodeStreamp(),
+ mTPosp(),
+ mTileIndicesp(),
+ mRawImagep(NULL),
+ mDecodeState(),
+ mBlocksSize(-1),
+ mPrecinctsSize(-1),
+ mLevels(0)
{
}
@@ -198,38 +204,27 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
//
// Initialization
//
- if (!kdu_message_initialized)
- {
- kdu_message_initialized = true;
- kdu_customize_errors(&sErrorHandler);
- kdu_customize_warnings(&sWarningHandler);
- }
-
- if (mCodeStreamp)
- {
- mCodeStreamp->destroy();
- delete mCodeStreamp;
- mCodeStreamp = NULL;
- }
+ mCodeStreamp.reset();
if (!mInputp && base.getData())
{
// The compressed data has been loaded
// Setup the source for the codestream
- mInputp = new LLKDUMemSource(base.getData(), data_size);
+ mInputp.reset(new LLKDUMemSource(base.getData(), data_size));
}
if (mInputp)
{
+ // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset().
mInputp->reset();
}
- mCodeStreamp = new kdu_codestream;
- mCodeStreamp->create(mInputp);
+ mCodeStreamp->create(mInputp.get());
// Set the maximum number of bytes to use from the codestream
- // *TODO: This seems to be wrong. The base class should have no idea of how j2c compression works so no
- // good way of computing what's the byte range to be used.
+ // *TODO: This seems to be wrong. The base class should have no idea of
+ // how j2c compression works so no good way of computing what's the byte
+ // range to be used.
mCodeStreamp->set_max_bytes(max_bytes,true);
// If you want to flip or rotate the image for some reason, change
@@ -286,34 +281,18 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
if (!keep_codestream)
{
- mCodeStreamp->destroy();
- delete mCodeStreamp;
- mCodeStreamp = NULL;
- delete mInputp;
- mInputp = NULL;
+ mCodeStreamp.reset();
+ mInputp.reset();
}
}
void LLImageJ2CKDU::cleanupCodeStream()
{
- delete mInputp;
- mInputp = NULL;
-
- delete mDecodeState;
- mDecodeState = NULL;
-
- if (mCodeStreamp)
- {
- mCodeStreamp->destroy();
- delete mCodeStreamp;
- mCodeStreamp = NULL;
- }
-
- delete mTPosp;
- mTPosp = NULL;
-
- delete mTileIndicesp;
- mTileIndicesp = NULL;
+ mInputp.reset();
+ mDecodeState.reset();
+ mCodeStreamp.reset();
+ mTPosp.reset();
+ mTileIndicesp.reset();
}
bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
@@ -395,12 +374,12 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
if (!mTileIndicesp)
{
- mTileIndicesp = new kdu_dims;
+ mTileIndicesp.reset(new kdu_dims);
}
mCodeStreamp->get_valid_tiles(*mTileIndicesp);
if (!mTPosp)
{
- mTPosp = new kdu_coords;
+ mTPosp.reset(new kdu_coords);
mTPosp->y = 0;
mTPosp->x = 0;
}
@@ -427,7 +406,7 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
LLTimer decode_timer;
- if (!mCodeStreamp)
+ if (!mCodeStreamp->exists())
{
if (!initDecode(base, raw_image, decode_time, mode, first_channel, max_channel_count))
{
@@ -478,15 +457,14 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
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);
+ mDecodeState.reset(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;
+ mDecodeState.reset();
}
else
{
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index da84749796..5fb093826e 100644
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -48,6 +48,8 @@
#endif
#include "kdu_sample_processing.h"
+#include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
class LLKDUDecodeState;
class LLKDUMemSource;
@@ -79,18 +81,51 @@ private:
void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode);
void cleanupCodeStream();
+ // Helper class to hold a kdu_codestream, which is a handle to the
+ // underlying implementation object. When CodeStreamHolder is reset() or
+ // destroyed, it calls kdu_codestream::destroy() -- which kdu_codestream
+ // itself does not.
+ //
+ // Call through it like a smart pointer using operator->().
+ //
+ // Every RAII class must be noncopyable. For this we don't need move
+ // support.
+ class CodeStreamHolder: public boost::noncopyable
+ {
+ public:
+ ~CodeStreamHolder()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ if (mCodeStream.exists())
+ {
+ mCodeStream.destroy();
+ }
+ }
+
+ kdu_codestream* operator->() { return &mCodeStream; }
+
+ private:
+ kdu_codestream mCodeStream;
+ };
+
// Encode variable
- LLKDUMemSource *mInputp;
- kdu_codestream *mCodeStreamp;
- kdu_coords *mTPosp; // tile position
- kdu_dims *mTileIndicesp;
+ boost::scoped_ptr<LLKDUMemSource> mInputp;
+ CodeStreamHolder mCodeStreamp;
+ boost::scoped_ptr<kdu_coords> mTPosp; // tile position
+ boost::scoped_ptr<kdu_dims> mTileIndicesp;
int mBlocksSize;
int mPrecinctsSize;
int mLevels;
// Temporary variables for in-progress decodes...
+ // We don't own this LLImageRaw. We're simply pointing to an instance
+ // passed into initDecode().
LLImageRaw *mRawImagep;
- LLKDUDecodeState *mDecodeState;
+ boost::scoped_ptr<LLKDUDecodeState> mDecodeState;
};
#endif