From a0052fac052c527e67f07a978a9413804427a736 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 25 Apr 2016 22:56:58 -0400 Subject: DRTVWR-418: Fix indra/llkdu wrapper for changes in KDU 7.8 API. KDU 7.8 introduces a number of changes to its API, most notably by moving public symbols into a variety of kdu_something namespaces. While this is laudable in a general sense, it does require quite a bit of diagnostic building and patching to update legacy code. Since llimagej2ckdu_test.cpp lamentably stubs out pretty much the entire KDU API, we must also fix those stubs for signature changes even to functions we don't otherwise reference. NOTE: This commit still leaves four symbols undefined. Below I have taken the liberty of juxtaposing the error line with the output from dumpbin /exports build-vc120/packages/lib/release/kdu.lib. I see no differences. unresolved symbol (?kdu_convert_ycc_to_rgb_rev16@kdu_core@@3P6AXPAF00H@ZA) "void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_rev16)(short *,short *,short *,int)" ?kdu_convert_ycc_to_rgb_rev16@kdu_core@@3P6AXPAF00H@ZA (void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_rev16)(short *,short *,short *,int)) unresolved symbol (?kdu_convert_ycc_to_rgb_irrev16@kdu_core@@3P6AXPAF00H@ZA) "void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_irrev16)(short *,short *,short *,int)" ?kdu_convert_ycc_to_rgb_irrev16@kdu_core@@3P6AXPAF00H@ZA (void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_irrev16)(short *,short *,short *,int)) unresolved symbol (?kdu_convert_ycc_to_rgb_rev32@kdu_core@@3P6AXPAH00H@ZA) "void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_rev32)(int *,int *,int *,int)" ?kdu_convert_ycc_to_rgb_rev32@kdu_core@@3P6AXPAH00H@ZA (void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_rev32)(int *,int *,int *,int)) unresolved symbol (?kdu_convert_ycc_to_rgb_irrev32@kdu_core@@3P6AXPAM00H@ZA) "void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_irrev32)(float *,float *,float *,int)" ?kdu_convert_ycc_to_rgb_irrev32@kdu_core@@3P6AXPAM00H@ZA (void (__cdecl* kdu_core::kdu_convert_ycc_to_rgb_irrev32)(float *,float *,float *,int)) 24>C:\Users\Nat\linden\viewer64\build-vc120\newview\RelWithDebInfo\secondlife-bin.exe : fatal error LNK1120: 4 unresolved externals --- indra/llkdu/include_kdu_xxxx.h | 40 ++++++++++++++++++++++++++++++++ indra/llkdu/llimagej2ckdu.cpp | 22 +++++++++++------- indra/llkdu/llimagej2ckdu.h | 17 ++++---------- indra/llkdu/llkdumem.cpp | 3 +++ indra/llkdu/llkdumem.h | 36 +++++++++++++--------------- indra/llkdu/tests/llimagej2ckdu_test.cpp | 33 +++++++++++++------------- 6 files changed, 95 insertions(+), 56 deletions(-) create mode 100644 indra/llkdu/include_kdu_xxxx.h (limited to 'indra/llkdu') diff --git a/indra/llkdu/include_kdu_xxxx.h b/indra/llkdu/include_kdu_xxxx.h new file mode 100644 index 0000000000..5e86944994 --- /dev/null +++ b/indra/llkdu/include_kdu_xxxx.h @@ -0,0 +1,40 @@ +/** + * @file include_kdu_xxxx.h + * @author Nat Goodspeed + * @date 2016-04-25 + * @brief + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// This file specifically omits #include guards of its own: it's sort of an +// #include macro used to wrap KDU #includes with proper incantations. Usage: + +// #define kdu_xxxx "kdu_compressed.h" // or whichever KDU header +// #include "include_kdu_xxxx.h" +// // kdu_xxxx #undef'ed by include_kdu_xxxx.h + +#if LL_DARWIN +// don't *really* want to rebuild KDU so turn off specific warnings for this header +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wself-assign-field" +#pragma clang diagnostic ignored "-Wunused-private-field" +#include kdu_xxxx +#pragma clang diagnostic pop +#elif LL_WINDOWS +// With warnings-as-errors in effect, strange relationship between +// jp2_output_box and its subclass jp2_target in kdu_compressed.h +// causes build failures. Specifically: +// warning C4263: 'void kdu_supp::jp2_target::open(kdu_supp::jp2_family_tgt *)' : member function does not override any base class virtual member function +// warning C4264: 'void kdu_supp::jp2_output_box::open(kdu_core::kdu_uint32)' : no override available for virtual member function from base 'kdu_supp::jp2_output_box'; function is hidden +#pragma warning(push) +#pragma warning(disable : 4263 4264) +#include kdu_xxxx +#pragma warning(pop) +#else // some other platform +#include kdu_xxxx +#endif + +#undef kdu_xxxx diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 6a8959517d..f48e544813 100755 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -32,12 +32,16 @@ #include "llmath.h" #include "llkdumem.h" -#include "kdu_block_coding.h" +#define kdu_xxxx "kdu_block_coding.h" +#include "include_kdu_xxxx.h" + +// Avoid ubiquitous necessity of kdu_core:: qualification +using namespace kdu_core; class kdc_flow_control { public: - kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream); + kdc_flow_control(kdu_supp::kdu_image_in_base *img_in, kdu_codestream codestream); ~kdc_flow_control(); bool advance_components(); void process_components(); @@ -46,7 +50,7 @@ private: struct kdc_component_flow_control { public: - kdu_image_in_base *reader; + kdu_supp::kdu_image_in_base *reader; int vert_subsampling; int ratio_counter; /* Initialized to 0, decremented by `count_delta'; when < 0, a new line must be processed, after @@ -108,7 +112,8 @@ const char* fallbackEngineInfoLLImageJ2CImpl() class LLKDUDecodeState { public: - LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); + LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap, + kdu_codestream* codestreamp); ~LLKDUDecodeState(); BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); @@ -495,7 +500,7 @@ 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 = new LLKDUDecodeState(tile, buf, row_gap, mCodeStreamp); } // Do the actual processing F32 remaining_time = decode_time - decode_timer.getElapsedTimeF32(); @@ -1143,7 +1148,8 @@ all necessary level shifting, type conversion, rounding and truncation. */ } } -LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap) +LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap, + kdu_codestream* codestreamp) { S32 c; @@ -1189,7 +1195,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap) mEngines[c] = kdu_synthesis(res,&mAllocator,use_shorts); } } - mAllocator.finalize(); // Actually creates buffering resources + mAllocator.finalize(*codestreamp); // Actually creates buffering resources for (c = 0; c < mNumComponents; c++) { mLines[c].create(); // Grabs resources from the allocator. @@ -1247,7 +1253,7 @@ separation between consecutive rows in the real buffer. */ // kdc_flow_control -kdc_flow_control::kdc_flow_control (kdu_image_in_base *img_in, kdu_codestream codestream) +kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_codestream codestream) { int n; diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 02281152bf..8d66add38f 100755 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -37,15 +37,8 @@ #include "kdu_messaging.h" #include "kdu_params.h" -// don't *really* want to rebuild KDU so turn off specific warnings for this header -#if LL_DARWIN -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-private-field" -#include "kdu_compressed.h" -#pragma clang diagnostic pop -#else -#include "kdu_compressed.h" -#endif +#define kdu_xxxx "kdu_compressed.h" +#include "include_kdu_xxxx.h" #include "kdu_sample_processing.h" @@ -80,9 +73,9 @@ private: // Encode variable LLKDUMemSource *mInputp; - kdu_codestream *mCodeStreamp; - kdu_coords *mTPosp; // tile position - kdu_dims *mTileIndicesp; + kdu_core::kdu_codestream *mCodeStreamp; + kdu_core::kdu_coords *mTPosp; // tile position + kdu_core::kdu_dims *mTileIndicesp; int mBlocksSize; int mPrecinctsSize; int mLevels; diff --git a/indra/llkdu/llkdumem.cpp b/indra/llkdu/llkdumem.cpp index 0347475559..96e9da25d8 100755 --- a/indra/llkdu/llkdumem.cpp +++ b/indra/llkdu/llkdumem.cpp @@ -28,6 +28,9 @@ #include "llkdumem.h" #include "llerror.h" +using namespace kdu_core; +using kd_supp_image_local::image_line_buf; + #if defined(LL_WINDOWS) # pragma warning(disable: 4702) // unreachable code #endif diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index fab913d93b..09d81f38de 100755 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -29,26 +29,22 @@ // Support classes for reading and writing from memory buffers in KDU #define KDU_NO_THREADS -// don't *really* want to rebuild KDU so turn off specific warnings for this header -#if LL_DARWIN -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wself-assign-field" -#pragma clang diagnostic ignored "-Wunused-private-field" -#include "kdu_image.h" -#pragma clang diagnostic pop -#else -#include "kdu_image.h" -#endif + +#define kdu_xxxx "kdu_image.h" +#include "include_kdu_xxxx.h" #include "kdu_elementary.h" #include "kdu_messaging.h" #include "kdu_params.h" -#include "kdu_compressed.h" + +#define kdu_xxxx "kdu_compressed.h" +#include "include_kdu_xxxx.h" + #include "kdu_sample_processing.h" #include "image_local.h" #include "stdtypes.h" -class LLKDUMemSource: public kdu_compressed_source +class LLKDUMemSource: public kdu_core::kdu_compressed_source { public: LLKDUMemSource(U8 *input_buffer, U32 size) @@ -62,7 +58,7 @@ public: { } - int read(kdu_byte *buf, int num_bytes) + int read(kdu_core::kdu_byte *buf, int num_bytes) { U32 num_out; num_out = num_bytes; @@ -87,7 +83,7 @@ private: U32 mCurPos; }; -class LLKDUMemTarget: public kdu_compressed_target +class LLKDUMemTarget: public kdu_core::kdu_compressed_target { public: LLKDUMemTarget(U8 *output_buffer, U32 &output_size, const U32 buffer_size) @@ -102,7 +98,7 @@ public: { } - bool write(const kdu_byte *buf, int num_bytes) + bool write(const kdu_core::kdu_byte *buf, int num_bytes) { U32 num_out; num_out = num_bytes; @@ -126,7 +122,7 @@ private: U32 *mOutputSize; }; -class LLKDUMemIn : public kdu_image_in_base +class LLKDUMemIn : public kdu_supp::kdu_image_in_base { public: LLKDUMemIn(const U8 *data, @@ -134,10 +130,10 @@ public: const U16 rows, const U16 cols, U8 in_num_components, - siz_params *siz); + kdu_core::siz_params *siz); ~LLKDUMemIn(); - bool get(int comp_idx, kdu_line_buf &line, int x_tnum); + bool get(int comp_idx, kdu_core::kdu_line_buf &line, int x_tnum); private: const U8 *mData; @@ -146,8 +142,8 @@ private: int rows, cols; int alignment_bytes; // Number of 0's at end of each line. int precision[3]; - image_line_buf *incomplete_lines; // Each "sample" represents a full pixel - image_line_buf *free_lines; + kd_supp_image_local::image_line_buf *incomplete_lines; // Each "sample" represents a full pixel + kd_supp_image_local::image_line_buf *free_lines; int num_unread_rows; U32 mCurPos; diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index 0605fad068..056c55933a 100755 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -29,15 +29,7 @@ // Class to test #include "llimagej2ckdu.h" -#if LL_DARWIN -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-private-field" #include "llkdumem.h" -#pragma clang diagnostic pop -#else -#include "llkdumem.h" -#endif - #include "kdu_block_coding.h" // Tut header #include "lltut.h" @@ -113,17 +105,19 @@ void LLImageJ2C::setLastError(const std::string&, const std::string&) { } BOOL LLImageJ2C::updateData() { return FALSE; } void LLImageJ2C::updateRawDiscardLevel() { } -LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, siz_params*) { } +LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, kdu_core::siz_params*) { } LLKDUMemIn::~LLKDUMemIn() { } -bool LLKDUMemIn::get(int, kdu_line_buf&, int) { return false; } +bool LLKDUMemIn::get(int, kdu_core::kdu_line_buf&, int) { return false; } // Stub Kakadu Library calls +// they're all namespaced now +namespace kdu_core { kdu_tile_comp kdu_tile::access_component(int ) { kdu_tile_comp a; return a; } kdu_block_encoder::kdu_block_encoder() { } kdu_block_decoder::kdu_block_decoder() { } void kdu_block::set_max_passes(int , bool ) { } void kdu_block::set_max_bytes(int , bool ) { } -void kdu_tile::close(kdu_thread_env* ) { } +void kdu_tile::close(kdu_thread_env *, bool) {} int kdu_tile::get_num_components() { return 0; } bool kdu_tile::get_ycc() { return false; } void kdu_tile::set_components_of_interest(int , const int* ) { } @@ -156,14 +150,14 @@ void kdu_codestream::set_fussy() { } void kdu_codestream::get_dims(int, kdu_dims&, bool ) { } int kdu_codestream::get_min_dwt_levels() { return 5; } int kdu_codestream::get_max_tile_layers() { return 1; } -void kdu_codestream::change_appearance(bool, bool, bool) { } +void kdu_codestream::change_appearance(bool, bool, bool, kdu_thread_env *) {} void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { } void kdu_codestream::destroy() { } void kdu_codestream::collect_timing_stats(int ) { } void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { } void kdu_codestream::get_valid_tiles(kdu_dims& ) { } void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { } -void kdu_codestream::apply_input_restrictions( int, int, int, int, kdu_dims*, kdu_component_access_mode ) { } +void kdu_codestream::apply_input_restrictions(int, int, int, int, kdu_dims const *, kdu_component_access_mode, kdu_thread_env *, kdu_quality_limiter const *) {} void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { } void kdu_codestream::flush(kdu_long *, int, kdu_uint16 *, bool, bool, double, kdu_thread_env*, int) { } void kdu_codestream::set_resilient(bool ) { } @@ -178,13 +172,15 @@ siz_params* kdu_codestream::access_siz() { return NULL; } kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; } kdu_codestream_comment kdu_codestream::add_comment() { kdu_codestream_comment a; return a; } void kdu_subband::close_block(kdu_block*, kdu_thread_env*) { } -void kdu_subband::get_valid_blocks(kdu_dims &indices) { } -kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return NULL; } +void kdu_subband::get_valid_blocks(kdu_dims &indices) const { } +kdu_block * kdu_subband::open_block(kdu_coords, int *, kdu_thread_env *, int, bool) { return NULL; } bool kdu_codestream_comment::put_text(const char*) { return false; } void kdu_customize_warnings(kdu_message*) { } void kdu_customize_errors(kdu_message*) { } -kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, kdu_thread_env*, kdu_thread_queue*, int, kdu_roi_image*, int) { kdu_long a = 0; return a; } +kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, kdu_thread_env *,kdu_thread_queue *, int, kdu_roi_image *, int, kdu_sample_allocator *, kdu_push_pull_params const *) { return kdu_long(0); } +void kdu_multi_analysis::destroy(kdu_thread_env *) {} siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { } +siz_params::~siz_params() {} void siz_params::finalize(bool ) { } void siz_params::copy_with_xforms(kdu_params*, int, int, bool, bool, bool) { } int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0; } @@ -193,10 +189,15 @@ bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { retur kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*, int) { } void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long, kdu_thread_env* ) { } +kdu_sample_allocator::~kdu_sample_allocator() {} +void kdu_sample_allocator::do_finalize(kdu_codestream) {} void (*kdu_convert_ycc_to_rgb_rev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); void (*kdu_convert_ycc_to_rgb_irrev16)(kdu_int16*,kdu_int16*,kdu_int16*,int); void (*kdu_convert_ycc_to_rgb_rev32)(kdu_int32*,kdu_int32*,kdu_int32*,int); void (*kdu_convert_ycc_to_rgb_irrev32)(float*,float*,float*,int); +bool kdu_core_sample_alignment_checker(int, int, int, int, bool, bool) { return false; } +void kdu_pull_ifc::destroy() {} +} // namespace kdu_core // ------------------------------------------------------------------------------------------- // TUT -- cgit v1.2.3 From 811a0b5726ed965f9f21ace2d3ec97bb95a91311 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 26 Apr 2016 12:14:29 -0700 Subject: DRTVWR-418: add preprocessor define to fix linker error introduced in v7.8 --- indra/llkdu/llimagej2ckdu.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index f48e544813..4f93d85529 100755 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -25,6 +25,12 @@ */ #include "linden_common.h" + +// based on this KDU support group posting: +// https://groups.yahoo.com/neo/groups/kakadu_jpeg2000/conversations/messages/6691 +// Defining this values seems to fix the linker error that appeared with the 7.8 release +#define CORESYS_IMPORTS + #include "llimagej2ckdu.h" #include "lltimer.h" -- cgit v1.2.3 From ec0e3e9f08cc13025b216f1c4576f5c88622043c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 26 Apr 2016 22:23:18 -0400 Subject: DRTVWR-418: Match KDU_X86_INTRINSICS macro set for KDU package build. --- indra/llkdu/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/llkdu') diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index b8f8b420c3..cb0e204e91 100755 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -40,6 +40,14 @@ set_source_files_properties(${llkdu_HEADER_FILES} list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES}) +# Our KDU package is built with KDU_X86_INTRINSICS in its .vcxproj file. +# Unless that macro is also set for every consumer build, KDU freaks out, +# spamming the viewer log with alignment FUD. +set_source_files_properties(${llkdu_SOURCE_FILES} + PROPERTIES + COMPILE_DEFINITIONS + "KDU_X86_INTRINSICS") + if (USE_KDU) add_library (llkdu ${llkdu_SOURCE_FILES}) -- cgit v1.2.3 From 5b233bba3f885cd7f6202a70677d7ae2970bdfeb Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 13 Jul 2016 14:28:45 -0400 Subject: MAINT-5011: Remove alarming ll_kdu_error() function whose body reads: // *FIX: This exception is bad, bad, bad. It gets thrown from a // destructor which can lead to immediate program termination! throw "ll_kdu_error() throwing an exception"; which would be bad indeed... if ll_kdu_error() were ever actually referenced by anything! --- indra/llkdu/llimagej2ckdu.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 282c859e9e..94c7dbdd23 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -128,13 +128,6 @@ private: S32 mRowGap; }; -void ll_kdu_error( void ) -{ - // *FIX: This exception is bad, bad, bad. It gets thrown from a - // destructor which can lead to immediate program termination! - throw "ll_kdu_error() throwing an exception"; -} - // Stuff for new kdu error handling class LLKDUMessageWarning : public kdu_message { -- cgit v1.2.3 From 21e8352de6c4d662ffdb44d31294ce9caca86517 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 13 Jul 2016 14:42:44 -0400 Subject: MAINT-5011: Introduce KduError instead of throw/catch const char*. KduError is derived from std::runtime_error, so the message string becomes its what() message. --- indra/llkdu/llimagej2ckdu.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 94c7dbdd23..50c2e03cd4 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -34,6 +34,13 @@ #include "kdu_block_coding.h" +#include + +struct KduError: public std::runtime_error +{ + KduError(const std::string& msg): std::runtime_error(msg) {} +}; + class kdc_flow_control { public: @@ -171,7 +178,7 @@ void LLKDUMessageError::flush(bool end_of_message) { if (end_of_message) { - throw "KDU throwing an exception"; + throw KduError("LLKDUMessageError::flush()"); } } @@ -415,9 +422,9 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco mTPosp->x = 0; } } - catch (const char* msg) + catch (const KduError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return FALSE; } catch (...) @@ -505,9 +512,9 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco return FALSE; } } - catch (const char* msg) + catch (const KduError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); base.decodeFailed(); cleanupCodeStream(); return TRUE; // done @@ -698,9 +705,9 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.updateData(); // set width, height delete[] output_buffer; } - catch(const char* msg) + catch(const KduError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return FALSE; } catch( ... ) @@ -722,9 +729,9 @@ BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base) setupCodeStream(base, FALSE, MODE_FAST); return TRUE; } - catch (const char* msg) + catch (const KduError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return FALSE; } catch (...) -- cgit v1.2.3 From d7c904632b9dac112228092952f993569477366c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 14 Jul 2016 10:26:57 -0400 Subject: MAINT-5011: On advice from NickyD, say KDUError not KduError. Also place KDUError into anonymous namespace to emphasize that it's entirely local to this .cpp file. --- indra/llkdu/llimagej2ckdu.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 50c2e03cd4..2a5b24fbc1 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -36,10 +36,12 @@ #include -struct KduError: public std::runtime_error +namespace { +struct KDUError: public std::runtime_error { - KduError(const std::string& msg): std::runtime_error(msg) {} + KDUError(const std::string& msg): std::runtime_error(msg) {} }; +} // anonymous namespace class kdc_flow_control { @@ -178,7 +180,7 @@ void LLKDUMessageError::flush(bool end_of_message) { if (end_of_message) { - throw KduError("LLKDUMessageError::flush()"); + throw KDUError("LLKDUMessageError::flush()"); } } @@ -422,7 +424,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco mTPosp->x = 0; } } - catch (const KduError& msg) + catch (const KDUError& msg) { base.setLastError(msg.what()); return FALSE; @@ -512,7 +514,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco return FALSE; } } - catch (const KduError& msg) + catch (const KDUError& msg) { base.setLastError(msg.what()); base.decodeFailed(); @@ -705,7 +707,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.updateData(); // set width, height delete[] output_buffer; } - catch(const KduError& msg) + catch(const KDUError& msg) { base.setLastError(msg.what()); return FALSE; @@ -729,7 +731,7 @@ BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base) setupCodeStream(base, FALSE, MODE_FAST); return TRUE; } - catch (const KduError& msg) + catch (const KDUError& msg) { base.setLastError(msg.what()); return FALSE; -- cgit v1.2.3 From 9c49a6c91dd9b5bbe811fcd91d8992ed6bac33e7 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 19 Jul 2016 16:25:25 -0400 Subject: MAINT-5011: Introduce LLException base class for viewer exceptions. This also introduces LLContinueError for exceptions which should interrupt some part of viewer processing (e.g. the current coroutine) but should attempt to let the viewer session proceed. Derive all existing viewer exception classes from LLException rather than from std::runtime_error or std::logic_error. Use BOOST_THROW_EXCEPTION() rather than plain 'throw' to enrich the thrown exception with source file, line number and containing function. --- indra/llkdu/llimagej2ckdu.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 2a5b24fbc1..fa58931407 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -34,12 +34,13 @@ #include "kdu_block_coding.h" -#include +#include "llexception.h" +#include namespace { -struct KDUError: public std::runtime_error +struct KDUError: public LLException { - KDUError(const std::string& msg): std::runtime_error(msg) {} + KDUError(const std::string& msg): LLException(msg) {} }; } // anonymous namespace @@ -180,7 +181,7 @@ void LLKDUMessageError::flush(bool end_of_message) { if (end_of_message) { - throw KDUError("LLKDUMessageError::flush()"); + BOOST_THROW_EXCEPTION(KDUError("LLKDUMessageError::flush()")); } } -- cgit v1.2.3 From f09a92f1f32179ae24f150670851bf63aad204c4 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 21 Jul 2016 14:29:29 -0400 Subject: DRTVWR-427: Remove engineInfoLLImageJ2CKDU(), createLLImageJ2CKDU(), destroyLLImageJ2CKDU(). These were apparently intended as simple C-style DLL entry points. But as nobody calls them, and as we decided against building the viewer from DLLs, they only clutter the code. --- indra/llkdu/llimagej2ckdu.cpp | 20 ++------------------ indra/llkdu/llimagej2ckdu.h | 12 ------------ 2 files changed, 2 insertions(+), 30 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 282c859e9e..90b8d10ecc 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -72,23 +72,6 @@ private: // void set_default_colour_weights(kdu_params *siz); -const char* engineInfoLLImageJ2CKDU() -{ - static std::string version = llformat("KDU %s", KDU_CORE_VERSION); - return version.c_str(); -} - -LLImageJ2CKDU* createLLImageJ2CKDU() -{ - return new LLImageJ2CKDU(); -} - -void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu) -{ - delete kdu; - kdu = NULL; -} - LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() { return new LLImageJ2CKDU(); @@ -102,7 +85,8 @@ void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl) const char* fallbackEngineInfoLLImageJ2CImpl() { - return engineInfoLLImageJ2CKDU(); + static std::string version = llformat("KDU %s", KDU_CORE_VERSION); + return version.c_str(); } class LLKDUDecodeState diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 02281152bf..b123a6dd52 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -92,16 +92,4 @@ private: LLKDUDecodeState *mDecodeState; }; -#if LL_WINDOWS -# define LLSYMEXPORT __declspec(dllexport) -#elif LL_LINUX -# define LLSYMEXPORT __attribute__ ((visibility("default"))) -#else -# define LLSYMEXPORT -#endif - -extern "C" LLSYMEXPORT const char* engineInfoLLImageJ2CKDU(); -extern "C" LLSYMEXPORT LLImageJ2CKDU* createLLImageJ2CKDU(); -extern "C" LLSYMEXPORT void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu); - #endif -- cgit v1.2.3 From 71b593e88b1e601db84cd3c399865a0bfd8164cf Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 21 Jul 2016 16:49:02 -0400 Subject: MAINT-6584: Streamline static LLImageJ2C implementation API. Specifically, remove unused function pointer types CreateLLImageJ2CFunction, DestroyLLImageJ2CFunction and EngineInfoLLImageJ2CFunction. Also eliminate static fallbackDestroyLLImageJ2CImpl() and fallbackEngineInfoLLImageJ2CImpl(), leaving only static fallbackCreateLLImageJ2CImpl(). We do need a factory function to instantiate the appropriate LLImageJ2CImpl subclass, so leave the fallbackCreateLLImageJ2CImpl() link seam in place. However, given that every known LLImageJ2CImpl subclass is cheap to instantiate, make getEngineInfo() a pure virtual method on that subclass: the static LLImageJ2C::getEngineInfo() method can temporarily construct an instance to query. While we're at it, make getEngineInfo() return std::string like LLImageJ2C::getEngineInfo(). It's ridiculous that fallbackEngineInfoLLImageJ2CImpl() implementations constructed a static std::string and returned its c_str(), only to have LLImageJ2C::getEngineInfo() construct ANOTHER std::string from the returned const char*. fallbackDestroyLLImageJ2CImpl() never did anything useful: it merely deleted the passed LLImageJ2CImpl subclass pointer as the specific subclass type. But since LLImageJ2CImpl's destructor is virtual, LLImageJ2C's destructor could simply delete the stored LLImageJ2CImpl*. In fact, make mImpl a boost::scoped_ptr so we don't even have to delete it manually. --- indra/llkdu/llimagej2ckdu.cpp | 12 +++--------- indra/llkdu/llimagej2ckdu.h | 11 ++++++----- 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 90b8d10ecc..0906fc894e 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -72,21 +72,15 @@ private: // void set_default_colour_weights(kdu_params *siz); +// Factory function: see declaration in llimagej2c.cpp LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() { return new LLImageJ2CKDU(); } -void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl) +std::string LLImageJ2CKDU::getEngineInfo() const { - delete impl; - impl = NULL; -} - -const char* fallbackEngineInfoLLImageJ2CImpl() -{ - static std::string version = llformat("KDU %s", KDU_CORE_VERSION); - return version.c_str(); + return llformat("KDU %s", KDU_CORE_VERSION); } class LLKDUDecodeState diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index b123a6dd52..85dc408d4d 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -65,12 +65,13 @@ public: virtual ~LLImageJ2CKDU(); 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, + 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, BOOL reversible=FALSE); - /*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); - /*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); + virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); + virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); + virtual std::string getEngineInfo() const; void findDiscardLevelsBoundaries(LLImageJ2C &base); private: -- cgit v1.2.3 From ab07b1a46150aaf04e7fd80c141bc9c95656b065 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 22 Jul 2016 10:32:53 -0400 Subject: MAINT-6584: Rationalize custom KDU error/warning message classes. Derive them both from a common base class that does the message logging, instead of having each handler class log redundantly -- especially since the put_text() override accepting const kdu_uint16* was simply streaming the kdu_uint16 pointer to the log file, which would log the hex value of the pointer. Although we want a static instance of each of these handler classes, pull it out rather than nesting the instance within the class itself. --- indra/llkdu/llimagej2ckdu.cpp | 93 +++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 44 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 0906fc894e..44dc9daabd 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -106,62 +106,67 @@ private: S32 mRowGap; }; -void ll_kdu_error( void ) -{ - // *FIX: This exception is bad, bad, bad. It gets thrown from a - // destructor which can lead to immediate program termination! - throw "ll_kdu_error() throwing an exception"; -} - // Stuff for new kdu error handling -class LLKDUMessageWarning : public kdu_message +class LLKDUMessage: public kdu_message { public: - /*virtual*/ void put_text(const char *s); - /*virtual*/ void put_text(const kdu_uint16 *s); + LLKDUMessage(const std::string& type): + mType(type) + {} - static LLKDUMessageWarning sDefaultMessage; -}; - -class LLKDUMessageError : public kdu_message -{ -public: - /*virtual*/ void put_text(const char *s); - /*virtual*/ void put_text(const kdu_uint16 *s); - /*virtual*/ void flush(bool end_of_message = false); - static LLKDUMessageError sDefaultMessage; -}; + virtual void put_text(const char *s) + { + LL_INFOS() << "KDU " << mType << ": " << s << LL_ENDL; + } -void LLKDUMessageWarning::put_text(const char *s) -{ - LL_INFOS() << "KDU Warning: " << s << LL_ENDL; -} + virtual void put_text(const kdu_uint16 *s) + { + // The previous implementation simply streamed 's' to the log. So + // either this put_text() override was never called -- or it produced + // some baffling log messages -- because I assert that streaming a + // const kdu_uint16* to a std::ostream will display only the hex value + // of the pointer. + LL_INFOS() << "KDU " << mType << ": " + << utf16str_to_utf8str(llutf16string(s)) << LL_ENDL; + } -void LLKDUMessageWarning::put_text(const kdu_uint16 *s) -{ - LL_INFOS() << "KDU Warning: " << s << LL_ENDL; -} +private: + std::string mType; +}; -void LLKDUMessageError::put_text(const char *s) +struct LLKDUMessageWarning : public LLKDUMessage { - LL_INFOS() << "KDU Error: " << s << LL_ENDL; -} + LLKDUMessageWarning(): + LLKDUMessage("Warning") + {} +}; +static LLKDUMessageWarning sWarningHandler; -void LLKDUMessageError::put_text(const kdu_uint16 *s) +struct LLKDUMessageError : public LLKDUMessage { - LL_INFOS() << "KDU Error: " << s << LL_ENDL; -} + LLKDUMessageError(): + LLKDUMessage("Error") + {} -void LLKDUMessageError::flush(bool end_of_message) -{ - if (end_of_message) + virtual void flush(bool end_of_message = false) { - throw "KDU throwing an exception"; + // According to the documentation nat found: + // http://pirlwww.lpl.arizona.edu/resources/guide/software/Kakadu/html_pages/globals__kdu$mize_errors.html + // "If a kdu_error object is destroyed, handler→flush will be called with + // an end_of_message argument equal to true and the process will + // subsequently be terminated through exit. The termination may be + // avoided, however, by throwing an exception from within the message + // terminating handler→flush call." + // So throwing an exception here isn't arbitrary: we MUST throw an + // exception if we want to recover from a KDU error. + if (end_of_message) + { + throw "KDU throwing an exception"; + } } -} +}; +static LLKDUMessageError sErrorHandler; -LLKDUMessageWarning LLKDUMessageWarning::sDefaultMessage; -LLKDUMessageError LLKDUMessageError::sDefaultMessage; static bool kdu_message_initialized = false; LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(), @@ -196,8 +201,8 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod if (!kdu_message_initialized) { kdu_message_initialized = true; - kdu_customize_errors(&LLKDUMessageError::sDefaultMessage); - kdu_customize_warnings(&LLKDUMessageWarning::sDefaultMessage); + kdu_customize_errors(&sErrorHandler); + kdu_customize_warnings(&sWarningHandler); } if (mCodeStreamp) -- cgit v1.2.3 From acdb050ce5e672a6e5c83ef6e95257ce68934d1b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 22 Jul 2016 11:35:23 -0400 Subject: MAINT-6584: Convert LLImage class hierarchy to standard 'bool' instead of legacy BOOL. --- indra/llkdu/llimagej2ckdu.cpp | 62 ++++++++++++++++---------------- indra/llkdu/llimagej2ckdu.h | 16 ++++----- indra/llkdu/tests/llimagej2ckdu_test.cpp | 40 ++++++++++----------- 3 files changed, 59 insertions(+), 59 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 44dc9daabd..0b2ac03b9d 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -88,11 +88,11 @@ class LLKDUDecodeState public: LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); ~LLKDUDecodeState(); - BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); + bool processTileDecode(F32 decode_time, bool limit_time = true); private: S32 mNumComponents; - BOOL mUseYCC; + bool mUseYCC; kdu_dims mDims; kdu_sample_allocator mAllocator; kdu_tile_comp mComps[4]; @@ -190,7 +190,7 @@ LLImageJ2CKDU::~LLImageJ2CKDU() // Stuff for new simple decode void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision); -void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode) +void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode) { S32 data_size = base.getDataSize(); S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); @@ -316,12 +316,12 @@ void LLImageJ2CKDU::cleanupCodeStream() mTileIndicesp = NULL; } -BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) { return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region); } -BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) +bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) { mPrecinctsSize = precincts_size; if (mPrecinctsSize != -1) @@ -345,10 +345,10 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MAX_DECOMPOSITION_LEVELS); base.setLevels(mLevels); } - return TRUE; + return true; } -BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) +bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) { base.resetLastError(); @@ -360,7 +360,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco //findDiscardLevelsBoundaries(base); base.updateRawDiscardLevel(); - setupCodeStream(base, TRUE, mode); + setupCodeStream(base, true, mode); mRawImagep = &raw_image; mCodeStreamp->change_appearance(false, true, false); @@ -408,20 +408,20 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco catch (const char* msg) { base.setLastError(ll_safe_string(msg)); - return FALSE; + return false; } catch (...) { base.setLastError("Unknown J2C error"); - return FALSE; + return false; } - return TRUE; + return true; } -// 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) +// 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; @@ -433,7 +433,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco { // Initializing the J2C decode failed, bail out. cleanupCodeStream(); - return TRUE; // done + return true; // done } } @@ -492,7 +492,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco { // Not finished decoding yet. // setLastError("Ran out of time while decoding"); - return FALSE; + return false; } } catch (const char* msg) @@ -500,14 +500,14 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco base.setLastError(ll_safe_string(msg)); base.decodeFailed(); cleanupCodeStream(); - return TRUE; // done + return true; // done } catch (...) { base.setLastError( "Unknown J2C error" ); base.decodeFailed(); cleanupCodeStream(); - return TRUE; // done + return true; // done } @@ -519,11 +519,11 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco cleanupCodeStream(); - return TRUE; + return true; } -BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible) +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; @@ -691,36 +691,36 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co catch(const char* msg) { base.setLastError(ll_safe_string(msg)); - return FALSE; + return false; } catch( ... ) { base.setLastError( "Unknown J2C error" ); - return FALSE; + return false; } - return TRUE; + return true; } -BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base) +bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) { // *FIX: kdu calls our callback function if there's an error, and // then bombs. To regain control, we throw an exception, and // catch it here. try { - setupCodeStream(base, FALSE, MODE_FAST); - return TRUE; + setupCodeStream(base, false, MODE_FAST); + return true; } catch (const char* msg) { base.setLastError(ll_safe_string(msg)); - return FALSE; + return false; } catch (...) { base.setLastError( "Unknown J2C error" ); - return FALSE; + return false; } } @@ -830,7 +830,7 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) { //std::cout << "Parsing discard level = " << discard_level << std::endl; // Create the input codestream object. - setupCodeStream(base, TRUE, MODE_FAST); + setupCodeStream(base, true, MODE_FAST); mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL); mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true); siz_params *siz_in = mCodeStreamp->access_siz(); @@ -1189,7 +1189,7 @@ LLKDUDecodeState::~LLKDUDecodeState() mTile.close(); } -BOOL LLKDUDecodeState::processTileDecode(F32 decode_time, BOOL limit_time) +bool LLKDUDecodeState::processTileDecode(F32 decode_time, bool limit_time) /* Decompresses a tile, writing the data into the supplied byte buffer. The buffer contains interleaved image components, if there are any. Although you may think of the buffer as belonging entirely to this tile, @@ -1221,11 +1221,11 @@ separation between consecutive rows in the real buffer. */ { if (limit_time && decode_timer.getElapsedTimeF32() > decode_time) { - return FALSE; + return false; } } } - return TRUE; + return true; } // kdc_flow_control diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 85dc408d4d..da84749796 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -65,18 +65,18 @@ public: virtual ~LLImageJ2CKDU(); 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, - BOOL reversible=FALSE); - virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); - virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); + 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, + bool reversible=false); + virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); + virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); virtual std::string getEngineInfo() const; void findDiscardLevelsBoundaries(LLImageJ2C &base); private: - BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL); - void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode); + bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL); + void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode); void cleanupCodeStream(); // Encode variable diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index 0605fad068..e8b550baa6 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -60,7 +60,7 @@ LLImageRaw::~LLImageRaw() { } U8* LLImageRaw::allocateData(S32 ) { return NULL; } void LLImageRaw::deleteData() { } U8* LLImageRaw::reallocateData(S32 ) { return NULL; } -BOOL LLImageRaw::resize(U16, U16, S8) { return TRUE; } // this method always returns TRUE... +bool LLImageRaw::resize(U16, U16, S8) { return true; } // this method always returns true... LLImageBase::LLImageBase() : LLTrace::MemTrackable("LLImageBase"), @@ -89,8 +89,8 @@ LLImageFormatted::~LLImageFormatted() { } U8* LLImageFormatted::allocateData(S32 ) { return NULL; } S32 LLImageFormatted::calcDataSize(S32 ) { return 0; } S32 LLImageFormatted::calcDiscardLevelBytes(S32 ) { return 0; } -BOOL LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return FALSE; } -BOOL LLImageFormatted::copyData(U8 *, S32) { return TRUE; } // this method always returns TRUE... +bool LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return false; } +bool LLImageFormatted::copyData(U8 *, S32) { return true; } // this method always returns true... void LLImageFormatted::deleteData() { } void LLImageFormatted::dump() { } U8* LLImageFormatted::reallocateData(S32 ) { return NULL; } @@ -103,14 +103,14 @@ LLImageJ2C::~LLImageJ2C() { } S32 LLImageJ2C::calcDataSize(S32 ) { return 0; } S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; } S32 LLImageJ2C::calcHeaderSize() { return 0; } -BOOL LLImageJ2C::decode(LLImageRaw*, F32) { return FALSE; } -BOOL LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return FALSE; } +bool LLImageJ2C::decode(LLImageRaw*, F32) { return false; } +bool LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return false; } void LLImageJ2C::decodeFailed() { } -BOOL LLImageJ2C::encode(const LLImageRaw*, F32) { return FALSE; } +bool LLImageJ2C::encode(const LLImageRaw*, F32) { return false; } S8 LLImageJ2C::getRawDiscardLevel() { return 0; } void LLImageJ2C::resetLastError() { } void LLImageJ2C::setLastError(const std::string&, const std::string&) { } -BOOL LLImageJ2C::updateData() { return FALSE; } +bool LLImageJ2C::updateData() { return false; } void LLImageJ2C::updateRawDiscardLevel() { } LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, siz_params*) { } @@ -212,12 +212,12 @@ namespace tut { public: // Provides public access to some protected methods for testing - BOOL callGetMetadata(LLImageJ2C &base) { return getMetadata(base); } - BOOL callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) + bool callGetMetadata(LLImageJ2C &base) { return getMetadata(base); } + bool callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) { return decodeImpl(base, raw_image, decode_time, first_channel, max_channel_count); } - BOOL callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text) + bool callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text) { return encodeImpl(base, raw_image, comment_text); } @@ -254,10 +254,10 @@ namespace tut void llimagej2ckdu_object_t::test<1>() { LLImageJ2C* image = new LLImageJ2C(); - BOOL res = mImage->callGetMetadata(*image); - // Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return TRUE - // Note that is linking with KDU, that call will throw an exception and fail, returning FALSE - ensure("getMetadata() test failed", res == TRUE); + bool res = mImage->callGetMetadata(*image); + // Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return true + // Note that is linking with KDU, that call will throw an exception and fail, returning false + ensure("getMetadata() test failed", res); } // Test 2 : test decodeImpl() @@ -266,9 +266,9 @@ namespace tut { LLImageJ2C* image = new LLImageJ2C(); LLImageRaw* raw = new LLImageRaw(); - BOOL res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0); - // Decoding returns TRUE whenever there's nothing else to do, including if decoding failed, so we'll get TRUE here - ensure("decodeImpl() test failed", res == TRUE); + bool res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0); + // Decoding returns true whenever there's nothing else to do, including if decoding failed, so we'll get true here + ensure("decodeImpl() test failed", res); } // Test 3 : test encodeImpl() @@ -277,8 +277,8 @@ namespace tut { LLImageJ2C* image = new LLImageJ2C(); LLImageRaw* raw = new LLImageRaw(); - BOOL res = mImage->callEncodeImpl(*image, *raw, NULL); - // Encoding returns TRUE unless an exception was raised, so we'll get TRUE here though nothing really was done - ensure("encodeImpl() test failed", res == TRUE); + bool res = mImage->callEncodeImpl(*image, *raw, NULL); + // Encoding returns true unless an exception was raised, so we'll get true here though nothing really was done + ensure("encodeImpl() test failed", res); } } -- cgit v1.2.3 From 03bff896bd18b71c9a2d8e0b163647b1cd64b871 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 3 Aug 2016 20:40:03 -0400 Subject: MAINT-6584: Use RAII classes to manage helper object lifespans. Use boost::scoped_ptr instead of raw pointers to LLKDUMemSource, LLKDUDecodeState, kdu_coords and kdu_dims so cleanup is simpler, and automated on destruction of LLImageJ2CKDU. Replace pointer to kdu_codestream with a custom RAII class. kdu_codestream is itself an opaque handle, so we don't need to add another layer of indirection. Just wrap it to ensure its destroy() method is reliably called when needed. Make static instances of LLKDUMessageWarning and LLKDUMessageError self-register, eliminating the companion static bool and explicit checks in code. --- indra/llkdu/llimagej2ckdu.cpp | 98 +++++++++++++++++-------------------------- indra/llkdu/llimagej2ckdu.h | 45 +++++++++++++++++--- 2 files changed, 78 insertions(+), 65 deletions(-) (limited to 'indra/llkdu') 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 +#include 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 mInputp; + CodeStreamHolder mCodeStreamp; + boost::scoped_ptr mTPosp; // tile position + boost::scoped_ptr 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 mDecodeState; }; #endif -- cgit v1.2.3 From 2339e759fc2d6f36a4b9425022a22a747ec55dad Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Wed, 27 Jul 2016 05:49:07 +0300 Subject: MAINT-4327/MAINT-6584 Supress the crash on memory allocation error when decoding J2C images --- indra/llkdu/llimagej2ckdu.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 0d37b123ec..0863240686 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -422,6 +422,13 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco // Now we are ready to walk through the tiles processing them one-by-one. kdu_byte *buffer = raw_image.getData(); + if (!buffer) + { + base.setLastError("Memory error"); + base.decodeFailed(); + cleanupCodeStream(); + return true; // done + } while (mTPosp->y < mTileIndicesp->size.y) { -- cgit v1.2.3 From 2ce38c3c9890f6cf65238e125a78cdc57841f3bd Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 4 Aug 2016 16:20:39 -0400 Subject: MAINT-6584: Comment out completely unused LLImageJ2CKDU code. The only call to the findDiscardLevelsBoundaries() method was commented out inside initDecode(), with a comment: // Merov : Test!! DO NOT COMMIT!! This was the only caller of copy_tile(), which was the only caller of copy_block(). Commented out all three of these (biggish!) functions, since I have no idea what any of them were supposed to do or when it might be useful to call them. In other words, I can't yet rule out the possibility that I might have to uncomment them. --- indra/llkdu/llimagej2ckdu.cpp | 9 +++++++++ indra/llkdu/llimagej2ckdu.h | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 0863240686..9347e51b85 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -713,6 +713,8 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) /* STATIC copy_block */ /*****************************************************************************/ +/*==========================================================================*| +// Only called by copy_tile(), which is itself commented out static void copy_block(kdu_block *in, kdu_block *out) { if (in->K_max_prime != out->K_max_prime) @@ -741,11 +743,14 @@ static void copy_block(kdu_block *in, kdu_block *out) out->set_max_bytes(num_bytes,false); memcpy(out->byte_buffer,in->byte_buffer,(size_t) num_bytes); } +|*==========================================================================*/ /*****************************************************************************/ /* STATIC copy_tile */ /*****************************************************************************/ +/*==========================================================================*| +// Only called by findDiscardLevelsBoundaries(), which is itself commented out static void copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out, kdu_params *siz_in, kdu_params *siz_out, int skip_components, @@ -802,10 +807,13 @@ copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out, } } } +|*==========================================================================*/ // Find the block boundary for each discard level in the input image. // We parse the input blocks and copy them in a temporary output stream. // For the moment, we do nothing more that parsing the raw list of blocks and outputing result. +/*==========================================================================*| +// See comments in header file for why this is commented out. void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) { // We need the number of levels in that image before starting. @@ -909,6 +917,7 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) } return; } +|*==========================================================================*/ void set_default_colour_weights(kdu_params *siz) { diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 5fb093826e..7d234435a4 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -74,13 +74,18 @@ protected: virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); virtual std::string getEngineInfo() const; - void findDiscardLevelsBoundaries(LLImageJ2C &base); private: bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL); void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode); void cleanupCodeStream(); + // This method was public, but the only call to it is commented out in our + // own initDecode() method. I (nat 2016-08-04) don't know what it does or + // why. Even if it should be uncommented, it should probably still be + // private. +// void findDiscardLevelsBoundaries(LLImageJ2C &base); + // 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 -- cgit v1.2.3 From 65d608cdac701ab10f84bd8dc4a6c0be7eef26f1 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 5 Aug 2016 14:02:12 -0400 Subject: MAINT-6584: Clarify LLKDUMessageError::flush() throwing exception. --- indra/llkdu/llimagej2ckdu.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 9347e51b85..2adb90320c 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -165,6 +165,12 @@ struct LLKDUMessageError : public LLKDUMessage // terminating handler→flush call." // So throwing an exception here isn't arbitrary: we MUST throw an // exception if we want to recover from a KDU error. + // Because this confused me: the above quote specifically refers to + // the kdu_error class, which is constructed internally within KDU at + // the point where a fatal error is discovered and reported. It is NOT + // talking about the kdu_message subclass passed to + // kdu_customize_errors(). Destroying this static object at program + // shutdown will NOT engage the behavior described above. if (end_of_message) { throw "KDU throwing an exception"; -- cgit v1.2.3 From a5ce63eb3c4a3f3ea57ca2a353954a2afd43fc72 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 5 Aug 2016 17:44:13 -0400 Subject: MAINT-6584: Add explanatory comments to LLImageJ2CKDU implementation. These comments are inherently fragile, in that they enumerate all present callers of certain methods. Adding, removing or relocating calls would invalidate these comments. However, the LLImageJ2CKDU implementation is probably pretty stable by now. --- indra/llkdu/llimagej2ckdu.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 2adb90320c..1201170f6d 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -202,6 +202,10 @@ LLImageJ2CKDU::~LLImageJ2CKDU() // Stuff for new simple decode void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision); +// This is called by the real (private) initDecode() (keep_codestream true) +// and getMetadata() methods (keep_codestream false). As far as nat can tell, +// mode is always MODE_FAST. It was called by findDiscardLevelsBoundaries() +// as well, when that still existed, with keep_codestream true and MODE_FAST. void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode) { S32 data_size = base.getDataSize(); @@ -212,6 +216,12 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // mCodeStreamp.reset(); + // It's not clear to nat under what circumstances we would reuse a + // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of + // two U32s and a pointer, so it's not as if it would be a huge overhead + // to allocate a new one every time. + // Also -- why is base.getData() tested specifically here? If that returns + // NULL, shouldn't we bail out of the whole method? if (!mInputp && base.getData()) { // The compressed data has been loaded @@ -301,6 +311,9 @@ void LLImageJ2CKDU::cleanupCodeStream() mTileIndicesp.reset(); } +// This is the protected virtual method called by LLImageJ2C::initDecode(). +// However, as far as nat can tell, LLImageJ2C::initDecode() is called only by +// llimage_libtest.cpp's load_image() function. No detectable production use. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) { return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region); @@ -333,6 +346,9 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc return true; } +// This is the real (private) initDecode() called both by the protected +// initDecode() method and by decodeImpl(). As far as nat can tell, only the +// decodeImpl() usage matters for production. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) { base.resetLastError(); -- cgit v1.2.3 From 80adc9b6aa9814c74fd0c67c5de9d1765a089925 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 5 Aug 2016 17:57:24 -0400 Subject: MAINT-6584: Introduce KDUError exception from other viewer project. Specifically, manually apply changesets b4db8a8 and b98371d from nat_linden/viewer-mac-mainloop. We need to throw from a new place, but if we threw const char* (current convention), the new throw wouldn't be patched when we merge to new exception convention. --- indra/llkdu/llimagej2ckdu.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 1201170f6d..ba1560ec56 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -34,6 +34,15 @@ #include "kdu_block_coding.h" +#include + +namespace { +struct KDUError: public std::runtime_error +{ + KDUError(const std::string& msg): std::runtime_error(msg) {} +}; +} // anonymous namespace + class kdc_flow_control { public: @@ -173,7 +182,7 @@ struct LLKDUMessageError : public LLKDUMessage // shutdown will NOT engage the behavior described above. if (end_of_message) { - throw "KDU throwing an exception"; + throw KDUError("LLKDUMessageError::flush()"); } } }; @@ -406,9 +415,9 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco mTPosp->x = 0; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch (...) @@ -502,9 +511,9 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco return false; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); base.decodeFailed(); cleanupCodeStream(); return true; // done @@ -695,9 +704,9 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.updateData(); // set width, height delete[] output_buffer; } - catch(const char* msg) + catch(const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch( ... ) @@ -719,9 +728,9 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) setupCodeStream(base, false, MODE_FAST); return true; } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch (...) -- cgit v1.2.3 From 1773f44b6d9fffa7f5d0b2449184b2998e99be5a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 6 Aug 2016 11:39:11 -0400 Subject: MAINT-6584: Don't crash on inconsistent dims in a JPEG-2000 image. Previous code would crump with LL_ERRS. But a bad image file should fail only the image load -- not crash the viewer. While at it, validate all components present, not just 0, 1, 2. While at it, make the failure message report which component and what the mismatched dimensions are, not just "Components don't have matching dimensions!" --- indra/llkdu/llimagej2ckdu.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index ba1560ec56..025c77b85e 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -31,18 +31,31 @@ #include "llpointer.h" #include "llmath.h" #include "llkdumem.h" +#include "stringize.h" #include "kdu_block_coding.h" #include +#include namespace { +// exception used to keep KDU from terminating entire program -- see comments +// in LLKDUMessageError::flush() struct KDUError: public std::runtime_error { - KDUError(const std::string& msg): std::runtime_error(msg) {} + KDUError(const std::string& msg): std::runtime_error(msg) {} }; } // anonymous namespace +// stream kdu_dims to std::ostream +// Turns out this must NOT be in the anonymous namespace! +inline +std::ostream& operator<<(std::ostream& out, const kdu_dims& dims) +{ + return out << "(" << dims.pos.x << "," << dims.pos.y << ")," + "[" << dims.size.x << "x" << dims.size.y << "]"; +} + class kdc_flow_control { public: @@ -287,13 +300,19 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod S32 components = mCodeStreamp->get_num_components(); - if (components >= 3) - { // Check that components have consistent dimensions (for PPM file) - kdu_dims dims1; mCodeStreamp->get_dims(1,dims1); - kdu_dims dims2; mCodeStreamp->get_dims(2,dims2); - if ((dims1 != dims) || (dims2 != dims)) + // Check that components have consistent dimensions (for PPM file) + for (int idx = 1; idx < components; ++idx) + { + kdu_dims other_dims; + mCodeStreamp->get_dims(idx, other_dims); + if (other_dims != dims) { - LL_ERRS() << "Components don't have matching dimensions!" << LL_ENDL; + // This method is only called from methods that catch KDUError. + // We want to fail the image load, not crash the viewer. + throw KDUError(STRINGIZE("Component " << idx << " dimensions " + << other_dims + << " do not match component 0 dimensions " + << dims << "!")); } } -- cgit v1.2.3 From 5e9d2f57c82a57307a48afea09aa539b9fa80abf Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 17 Aug 2016 11:36:24 -0400 Subject: MAINT-5011: Use LLTHROW() instead of plain BOOST_THROW_EXCEPTION(). A level of preprocessor indirection lets us later change the implementation if desired. --- indra/llkdu/llimagej2ckdu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index fa58931407..8dd0b6d458 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -35,7 +35,6 @@ #include "kdu_block_coding.h" #include "llexception.h" -#include namespace { struct KDUError: public LLException @@ -181,7 +180,7 @@ void LLKDUMessageError::flush(bool end_of_message) { if (end_of_message) { - BOOST_THROW_EXCEPTION(KDUError("LLKDUMessageError::flush()")); + LLTHROW(KDUError("LLKDUMessageError::flush()")); } } -- cgit v1.2.3 From db4f13e7bcfc7ef61f750152494f1e52ad5a9080 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 17 Aug 2016 11:48:33 -0400 Subject: MAINT-5011: Clean up indentation from merge of viewer-release. --- indra/llkdu/llimagej2ckdu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index fe79079db3..e6ed6b2202 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -176,7 +176,7 @@ struct LLKDUMessageError : public LLKDUMessage // exception if we want to recover from a KDU error. if (end_of_message) { - LLTHROW(KDUError("LLKDUMessageError::flush()")); + LLTHROW(KDUError("LLKDUMessageError::flush()")); } } }; -- cgit v1.2.3 From 993f54f6e91d78a9c2e1389ad878d6bd46e9be5b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 17 Aug 2016 15:40:03 -0400 Subject: MAINT-5011: Try to enrich catch (...) logging throughout viewer. Turns out we have a surprising number of catch (...) clauses in the viewer code base. If all we currently do is LL_ERRS() << "unknown exception" << LL_ENDL; then call CRASH_ON_UNHANDLED_EXCEPTION() instead. If what we do is LL_WARNS() << "unknown exception" << LL_ENDL; then call LOG_UNHANDLED_EXCEPTION() instead. Since many places need LOG_UNHANDLED_EXCEPTION() and nobody catches LLContinueError yet, eliminate LLContinueError& parameter from LOG_UNHANDLED_EXCEPTION(). This permits us to use the same log message as CRASH_ON_UNHANDLED_EXCEPTION(), just with a different severity level. Where a catch (...) clause actually provides contextual information, or makes an error string, add boost::current_exception_diagnostic_information() to try to figure out actual exception class and message. --- indra/llkdu/llimagej2ckdu.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index e6ed6b2202..341c47a268 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -35,6 +35,7 @@ #include "kdu_block_coding.h" #include "llexception.h" +#include namespace { struct KDUError: public LLException @@ -400,7 +401,8 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco } catch (...) { - base.setLastError("Unknown J2C error"); + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); return false; } @@ -498,7 +500,8 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco } catch (...) { - base.setLastError( "Unknown J2C error" ); + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); base.decodeFailed(); cleanupCodeStream(); return true; // done @@ -689,7 +692,8 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co } catch( ... ) { - base.setLastError( "Unknown J2C error" ); + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); return false; } @@ -713,7 +717,8 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) } catch (...) { - base.setLastError( "Unknown J2C error" ); + base.setLastError("Unknown J2C error: " + + boost::current_exception_diagnostic_information()); return false; } } -- cgit v1.2.3 From 83eb9600631fcb98275b8d3db736f692fd5e6e1c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 17 Aug 2016 15:47:08 -0400 Subject: MAINT-5011: Derive image-load exceptions from LLContinueError. Failure to load an image shouldn't crash the whole viewer. --- indra/llkdu/llimagej2ckdu.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 341c47a268..4c2eac9eea 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -38,9 +38,10 @@ #include namespace { -struct KDUError: public LLException +// Failure to load an image shouldn't crash the whole viewer. +struct KDUError: public LLContinueError { - KDUError(const std::string& msg): LLException(msg) {} + KDUError(const std::string& msg): LLContinueError(msg) {} }; } // anonymous namespace -- cgit v1.2.3 From 0eac1f41f68bd2cd3b7e73db9eb96c690507b448 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 17 Aug 2016 16:42:10 -0400 Subject: MAINT-5011: Catch kdu_exception (aka int) in case it leaks out. KDU internally throws kdu_exception, which is a typedef for int. It's possible that such an exception might leak out. Our usual strategy for unknown exceptions is to catch (...) and let boost::current_exception_diagnostic_information() handle them. However, for int (or a class not derived from std::exception), that function will only shrug and report no information available. Besides, we want to format kdu_exception specially anyway. First, the KDU #defines are in hex, so we should report the value in hex. But on inspection, certain of those hex values are actually multibyte ASCII literals in disguise -- so also report the byte string value. --- indra/llkdu/llimagej2ckdu.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 4c2eac9eea..9e1dfc7213 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1,4 +1,4 @@ - /** +/** * @file llimagej2ckdu.cpp * @brief This is an implementation of JPEG2000 encode/decode using Kakadu * @@ -36,6 +36,8 @@ #include "llexception.h" #include +#include +#include namespace { // Failure to load an image shouldn't crash the whole viewer. @@ -43,6 +45,40 @@ struct KDUError: public LLContinueError { KDUError(const std::string& msg): LLContinueError(msg) {} }; + +// KDU defines int error codes as hex values, so we should log them in hex +// so we can grep KDU headers for the hex. However those hex values +// generally "happen" to encode big-endian multibyte character sequences, +// e.g. KDU_ERROR_EXCEPTION is 0x6b647545: 'kduE' +// But beware because KDU_NULL_EXCEPTION is simply 0 -- which doesn't +// preclude somebody from throwing it. +std::string report_kdu_exception(kdu_exception mb) +{ + std::ostringstream out; + // always report mb in hex + out << "kdu_exception " << std::hex << mb; + + // Also display as many chars as are encoded in the kdu_exception + // value. Make a char array; reserve 1 extra byte for nul terminator. + char bytes[sizeof(kdu_exception) + 1]; + // Back up through 'bytes' + char *bptr = bytes + sizeof(bytes); + *(--bptr) = '\0'; + while (mb) + { + // store low-order byte of mb in next-left char + *(--bptr) = char(mb & 0xFF); + // then shift mb right by one byte + mb >>= 8; + } + // did that produce any characters? + if (*bptr) + { + out << " (" << bptr << ')'; + } + + return out.str(); +} } // anonymous namespace class kdc_flow_control { @@ -400,6 +436,15 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco base.setLastError(msg.what()); return false; } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + return false; + } catch (...) { base.setLastError("Unknown J2C error: " + @@ -499,6 +544,17 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco cleanupCodeStream(); return true; // done } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + base.decodeFailed(); + cleanupCodeStream(); + return true; // done + } catch (...) { base.setLastError("Unknown J2C error: " + @@ -691,6 +747,15 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.setLastError(msg.what()); return false; } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + return false; + } catch( ... ) { base.setLastError("Unknown J2C error: " + @@ -716,6 +781,15 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) base.setLastError(msg.what()); return false; } + catch (kdu_exception kdu_value) + { + // KDU internally throws kdu_exception. It's possible that such an + // exception might leak out into our code. Catch kdu_exception + // specially because boost::current_exception_diagnostic_information() + // could do nothing with it. + base.setLastError(report_kdu_exception(kdu_value)); + return false; + } catch (...) { base.setLastError("Unknown J2C error: " + -- cgit v1.2.3 From c7cb6636c4fae7187f321473f93cbeb6ab8522e0 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 7 Sep 2016 10:57:07 -0400 Subject: MAINT-6584, MAINT-5011: Change new 'throw' to LLTHROW() to be consistent with new exception conventions. --- indra/llkdu/llimagej2ckdu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 0ed6ffefa9..aa405362e8 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -344,10 +344,10 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod { // This method is only called from methods that catch KDUError. // We want to fail the image load, not crash the viewer. - throw KDUError(STRINGIZE("Component " << idx << " dimensions " + LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " << other_dims << " do not match component 0 dimensions " - << dims << "!")); + << dims << "!"))); } } -- cgit v1.2.3 From 0413e40d82cc53c1e8180023db36108557b6f21c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 3 Nov 2016 20:48:41 -0400 Subject: DRTVWR-418: Update KDU and llimagej2ckdu* with certain clang fixes. --- indra/llkdu/llimagej2ckdu.cpp | 31 +++++++++++++++++-------------- indra/llkdu/llimagej2ckdu.h | 6 ++++-- indra/llkdu/tests/llimagej2ckdu_test.cpp | 6 ++++++ 3 files changed, 27 insertions(+), 16 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index b85e39b452..0540e55e07 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -37,7 +37,6 @@ #include "llpointer.h" #include "llmath.h" #include "llkdumem.h" -#include "stringize.h" #define kdu_xxxx "kdu_block_coding.h" #include "include_kdu_xxxx.h" @@ -50,6 +49,18 @@ using namespace kdu_core; #include #include +// stream kdu_dims to std::ostream +// Turns out this must NOT be in the anonymous namespace! +// It must also precede #include "stringize.h". +inline +std::ostream& operator<<(std::ostream& out, const kdu_dims& dims) +{ + return out << "(" << dims.pos.x << "," << dims.pos.y << ")," + "[" << dims.size.x << "x" << dims.size.y << "]"; +} + +#include "stringize.h" + namespace { // Failure to load an image shouldn't crash the whole viewer. struct KDUError: public LLContinueError @@ -92,15 +103,6 @@ std::string report_kdu_exception(kdu_exception mb) } } // anonymous namespace -// stream kdu_dims to std::ostream -// Turns out this must NOT be in the anonymous namespace! -inline -std::ostream& operator<<(std::ostream& out, const kdu_dims& dims) -{ - return out << "(" << dims.pos.x << "," << dims.pos.y << ")," - "[" << dims.size.x << "x" << dims.size.y << "]"; -} - class kdc_flow_control { public: @@ -356,9 +358,9 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // This method is only called from methods that catch KDUError. // We want to fail the image load, not crash the viewer. LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " - << other_dims - << " do not match component 0 dimensions " - << dims << "!"))); + << stringize(other_dims) + << " do not match component 0 dimensions " + << stringize(dims) << "!"))); } } @@ -570,7 +572,8 @@ 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.reset(new LLKDUDecodeState(tile, buf, row_gap)); + mDecodeState.reset(new LLKDUDecodeState(tile, buf, row_gap, + mCodeStreamp.get())); } // Do the actual processing F32 remaining_time = decode_time - decode_timer.getElapsedTimeF32(); diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index fd9a396722..b57e4cc40e 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -104,10 +104,12 @@ private: } } - kdu_codestream* operator->() { return &mCodeStream; } + // for those few times when you need a raw kdu_codestream* + kdu_core::kdu_codestream* get() { return &mCodeStream; } + kdu_core::kdu_codestream* operator->() { return &mCodeStream; } private: - kdu_codestream mCodeStream; + kdu_core::kdu_codestream mCodeStream; }; // Encode variable diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index 1407da3aa2..ae6138d4c6 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -29,7 +29,13 @@ // Class to test #include "llimagej2ckdu.h" +#if LL_DARWIN +// For this source, it's true that private fields in llkdumem.h are unused. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-private-field" #include "llkdumem.h" +#pragma clang diagnostic pop +#endif #include "kdu_block_coding.h" // Tut header #include "lltut.h" -- cgit v1.2.3 From b1185eca82a1c0fff1a885fd5dfea09e5b9c0b3a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 Nov 2016 08:59:01 -0500 Subject: DRTVWR-418: Fix Windows line endings in include_kdu_xxxx.h --- indra/llkdu/include_kdu_xxxx.h | 80 +++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/include_kdu_xxxx.h b/indra/llkdu/include_kdu_xxxx.h index 5e86944994..a1dbced60b 100644 --- a/indra/llkdu/include_kdu_xxxx.h +++ b/indra/llkdu/include_kdu_xxxx.h @@ -1,40 +1,40 @@ -/** - * @file include_kdu_xxxx.h - * @author Nat Goodspeed - * @date 2016-04-25 - * @brief - * - * $LicenseInfo:firstyear=2016&license=viewerlgpl$ - * Copyright (c) 2016, Linden Research, Inc. - * $/LicenseInfo$ - */ - -// This file specifically omits #include guards of its own: it's sort of an -// #include macro used to wrap KDU #includes with proper incantations. Usage: - -// #define kdu_xxxx "kdu_compressed.h" // or whichever KDU header -// #include "include_kdu_xxxx.h" -// // kdu_xxxx #undef'ed by include_kdu_xxxx.h - -#if LL_DARWIN -// don't *really* want to rebuild KDU so turn off specific warnings for this header -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wself-assign-field" -#pragma clang diagnostic ignored "-Wunused-private-field" -#include kdu_xxxx -#pragma clang diagnostic pop -#elif LL_WINDOWS -// With warnings-as-errors in effect, strange relationship between -// jp2_output_box and its subclass jp2_target in kdu_compressed.h -// causes build failures. Specifically: -// warning C4263: 'void kdu_supp::jp2_target::open(kdu_supp::jp2_family_tgt *)' : member function does not override any base class virtual member function -// warning C4264: 'void kdu_supp::jp2_output_box::open(kdu_core::kdu_uint32)' : no override available for virtual member function from base 'kdu_supp::jp2_output_box'; function is hidden -#pragma warning(push) -#pragma warning(disable : 4263 4264) -#include kdu_xxxx -#pragma warning(pop) -#else // some other platform -#include kdu_xxxx -#endif - -#undef kdu_xxxx +/** + * @file include_kdu_xxxx.h + * @author Nat Goodspeed + * @date 2016-04-25 + * @brief + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// This file specifically omits #include guards of its own: it's sort of an +// #include macro used to wrap KDU #includes with proper incantations. Usage: + +// #define kdu_xxxx "kdu_compressed.h" // or whichever KDU header +// #include "include_kdu_xxxx.h" +// // kdu_xxxx #undef'ed by include_kdu_xxxx.h + +#if LL_DARWIN +// don't *really* want to rebuild KDU so turn off specific warnings for this header +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wself-assign-field" +#pragma clang diagnostic ignored "-Wunused-private-field" +#include kdu_xxxx +#pragma clang diagnostic pop +#elif LL_WINDOWS +// With warnings-as-errors in effect, strange relationship between +// jp2_output_box and its subclass jp2_target in kdu_compressed.h +// causes build failures. Specifically: +// warning C4263: 'void kdu_supp::jp2_target::open(kdu_supp::jp2_family_tgt *)' : member function does not override any base class virtual member function +// warning C4264: 'void kdu_supp::jp2_output_box::open(kdu_core::kdu_uint32)' : no override available for virtual member function from base 'kdu_supp::jp2_output_box'; function is hidden +#pragma warning(push) +#pragma warning(disable : 4263 4264) +#include kdu_xxxx +#pragma warning(pop) +#else // some other platform +#include kdu_xxxx +#endif + +#undef kdu_xxxx -- cgit v1.2.3 From b9cc216b9cbded6f4adbc67f58d0fbc464ee0c9f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 23 Nov 2016 12:07:31 -0500 Subject: DRTVWR-418: Have to #include "llkdumem.h" even when not LL_DARWIN. --- indra/llkdu/tests/llimagej2ckdu_test.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llkdu') diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index ae6138d4c6..e386a9f71b 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -35,6 +35,8 @@ #pragma clang diagnostic ignored "-Wunused-private-field" #include "llkdumem.h" #pragma clang diagnostic pop +#else +#include "llkdumem.h" #endif #include "kdu_block_coding.h" // Tut header -- cgit v1.2.3 From 7b2cf53f782ac9ffa2766d006c870f10c320c9a0 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 30 Nov 2016 12:21:05 -0800 Subject: Pull in new version of KDU third party package that is build (correctly) as a static library vs. a stub library/DLL --- indra/llkdu/llimagej2ckdu.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'indra/llkdu') diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 0540e55e07..cb29da8f5f 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -26,11 +26,6 @@ #include "linden_common.h" -// based on this KDU support group posting: -// https://groups.yahoo.com/neo/groups/kakadu_jpeg2000/conversations/messages/6691 -// Defining this values seems to fix the linker error that appeared with the 7.8 release -#define CORESYS_IMPORTS - #include "llimagej2ckdu.h" #include "lltimer.h" -- cgit v1.2.3