diff options
Diffstat (limited to 'indra/llimagej2coj')
-rw-r--r-- | indra/llimagej2coj/llimagej2coj.cpp | 139 |
1 files changed, 38 insertions, 101 deletions
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 6037517103..d8f17561b3 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -31,6 +31,8 @@ #include "openjpeg.h" #include "event.h" #include "cio.h" +#include "owning_ptr.h" +#include <string> #define MAX_ENCODED_DISCARD_LEVELS 5 @@ -231,33 +233,6 @@ public: parameters.cp_reduce = discardLevel; } - ~JPEG2KDecode() - { - if (decoder) - { - opj_destroy_codec(decoder); - } - decoder = nullptr; - - if (image) - { - opj_image_destroy(image); - } - image = nullptr; - - if (stream) - { - opj_stream_destroy(stream); - } - stream = nullptr; - - if (codestream_info) - { - opj_destroy_cstr_info(&codestream_info); - } - codestream_info = nullptr; - } - bool readHeader( U8* data, U32 dataSize, @@ -275,11 +250,6 @@ public: return false; } - if (stream) - { - opj_stream_destroy(stream); - } - stream = opj_stream_create(dataSize, true); if (!stream) { @@ -301,13 +271,14 @@ public: opj_decoder_set_strict_mode(decoder, OPJ_FALSE); /* Read the main header of the codestream and if necessary the JP2 boxes*/ - if (!opj_read_header((opj_stream_t*)stream, decoder, &image)) + opj_image_t* img; + if (!opj_read_header(stream, decoder, &img)) { return false; } + image = img; codestream_info = opj_get_cstr_info(decoder); - if (!codestream_info) { return false; @@ -344,11 +315,6 @@ public: opj_set_warning_handler(decoder, opj_warn, this); opj_set_error_handler(decoder, opj_error, this); - if (stream) - { - opj_stream_destroy(stream); - } - stream = opj_stream_create(dataSize, true); if (!stream) { @@ -366,11 +332,7 @@ public: size = dataSize; offset = 0; - if (image) - { - opj_image_destroy(image); - image = nullptr; - } + image = nullptr; // needs to happen before opj_read_header and opj_decode... opj_set_decoded_resolution_factor(decoder, discard_level); @@ -378,10 +340,12 @@ public: // enable decoding partially loaded images opj_decoder_set_strict_mode(decoder, OPJ_FALSE); - if (!opj_read_header(stream, decoder, &image)) + opj_image_t* img; + if (!opj_read_header(stream, decoder, &img)) { return false; } + image = img; // needs to happen before decode which may fail if (channels) @@ -393,15 +357,9 @@ public: // count was zero. The latter is just a sanity check before we // dereference the array. - if (!decoded || !image || !image->numcomps) - { - opj_end_decompress(decoder, stream); - return false; - } - + bool result = (decoded && image && image->numcomps); opj_end_decompress(decoder, stream); - - return true; + return result; } opj_image_t* getImage() { return image; } @@ -409,10 +367,18 @@ public: private: opj_dparameters_t parameters; opj_event_mgr_t event_mgr; - opj_image_t* image = nullptr; - opj_codec_t* decoder = nullptr; - opj_stream_t* stream = nullptr; - opj_codestream_info_v2_t* codestream_info = nullptr; + owning_ptr<opj_codestream_info_v2_t> codestream_info{ + nullptr, + // opj_destroy_cstr_info(opj_codestream_info_v2_t**) requires a + // pointer to pointer, which is too bad because otherwise we could + // directly pass that function as the owning_ptr's deleter. + [](opj_codestream_info_v2_t* doomed) + { + opj_destroy_cstr_info(&doomed); + }}; + owning_ptr<opj_stream_t> stream{ nullptr, opj_stream_destroy }; + owning_ptr<opj_image_t> image{ nullptr, opj_image_destroy }; + owning_ptr<opj_codec_t> decoder{ nullptr, opj_destroy_codec }; }; class JPEG2KEncode : public JPEG2KBase @@ -447,43 +413,19 @@ public: parameters.irreversible = 1; } - if (comment_text) - { - free(comment_text); - } - comment_text = comment_text_in ? strdup(comment_text_in) : nullptr; + comment_text.assign(comment_text_in? comment_text_in : "no comment"); - parameters.cp_comment = comment_text ? comment_text : (char*)"no comment"; + // Because comment_text is a member declared before parameters, + // it will outlive parameters, so we can safely store in parameters a + // pointer into comment_text's data. Unfortunately cp_comment is + // declared as (non-const) char*. We just have to trust that this is + // legacy C style coding, rather than any intention to modify the + // comment string. (If there was actual modification, we could use a + // std::vector<char> instead, but let's only go there if we must.) + parameters.cp_comment = const_cast<char*>(comment_text.c_str()); llassert(parameters.cp_comment); } - ~JPEG2KEncode() - { - if (encoder) - { - opj_destroy_codec(encoder); - } - encoder = nullptr; - - if (image) - { - opj_image_destroy(image); - } - image = nullptr; - - if (stream) - { - opj_stream_destroy(stream); - } - stream = nullptr; - - if (comment_text) - { - free(comment_text); - } - comment_text = nullptr; - } - bool encode(const LLImageRaw& rawImageIn, LLImageJ2C &compressedImageOut) { LLImageDataSharedLock lockIn(&rawImageIn); @@ -561,11 +503,6 @@ public: memset(buffer, 0, data_size_guess); - if (stream) - { - opj_stream_destroy(stream); - } - stream = opj_stream_create(data_size_guess, false); if (!stream) { @@ -742,12 +679,12 @@ public: opj_image_t* getImage() { return image; } private: - opj_cparameters_t parameters; - opj_event_mgr_t event_mgr; - opj_image_t* image = nullptr; - opj_codec_t* encoder = nullptr; - opj_stream_t* stream = nullptr; - char* comment_text = nullptr; + std::string comment_text; + opj_cparameters_t parameters; + opj_event_mgr_t event_mgr; + owning_ptr<opj_stream_t> stream{ nullptr, opj_stream_destroy }; + owning_ptr<opj_image_t> image{ nullptr, opj_image_destroy }; + owning_ptr<opj_codec_t> encoder{ nullptr, opj_destroy_codec }; }; |