diff options
| author | Merov Linden <merov@lindenlab.com> | 2010-12-21 15:40:42 -0800 | 
|---|---|---|
| committer | Merov Linden <merov@lindenlab.com> | 2010-12-21 15:40:42 -0800 | 
| commit | ab100825bd0064dc64b9ef8bea1c70bc04090716 (patch) | |
| tree | f7e15f125d584b150abbc753829f03567dcd52b5 /indra | |
| parent | 704873e0da333a4f911f41cf81582f837d8e0ce4 (diff) | |
| parent | a8edb1af21a8c145e68935c30c1707ec8feb34b8 (diff) | |
STORM-151 : pull in viewer-development
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | indra/cmake/Copy3rdPartyLibs.cmake | 103 | ||||
| -rw-r--r-- | indra/cmake/LLKDU.cmake | 17 | ||||
| -rw-r--r-- | indra/integration_tests/llui_libtest/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | indra/llimage/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | indra/llimage/llimage.cpp | 2 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.cpp | 162 | ||||
| -rw-r--r-- | indra/llimage/llimagej2c.h | 2 | ||||
| -rw-r--r-- | indra/llkdu/CMakeLists.txt | 45 | ||||
| -rw-r--r-- | indra/llkdu/llimagej2ckdu.cpp | 1084 | ||||
| -rw-r--r-- | indra/llkdu/llimagej2ckdu.h | 91 | ||||
| -rw-r--r-- | indra/llkdu/llkdumem.cpp | 196 | ||||
| -rw-r--r-- | indra/llkdu/llkdumem.h | 145 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 19 | ||||
| -rw-r--r-- | indra/newview/viewer_manifest.py | 51 | 
15 files changed, 1640 insertions, 289 deletions
| diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index d01e1869b6..6d17a6f402 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -43,6 +43,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)  add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)  add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)  add_subdirectory(${LIBS_OPEN_PREFIX}llimage) +add_subdirectory(${LIBS_OPEN_PREFIX}llkdu)  add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)  add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)  add_subdirectory(${LIBS_OPEN_PREFIX}llmath) @@ -53,10 +54,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llvfs)  add_subdirectory(${LIBS_OPEN_PREFIX}llwindow)  add_subdirectory(${LIBS_OPEN_PREFIX}llxml) -if (EXISTS ${LIBS_CLOSED_DIR}llkdu) -  add_subdirectory(${LIBS_CLOSED_PREFIX}llkdu) -endif (EXISTS ${LIBS_CLOSED_DIR}llkdu) -  add_subdirectory(${LIBS_OPEN_PREFIX}lscript)  if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index e852cf463c..176ae9787e 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -60,22 +60,6 @@ if(WINDOWS)        set(release_files ${release_files} fmod.dll)      endif (FMOD) -    #******************************* -    # LLKDU -    set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu") -    if(NOT EXISTS ${internal_llkdu_path}) -        if (EXISTS "${debug_src_dir}/llkdu.dll") -            set(debug_llkdu_src "${debug_src_dir}/llkdu.dll") -            set(debug_llkdu_dst "${SHARED_LIB_STAGING_DIR_DEBUG}/llkdu.dll") -        endif (EXISTS "${debug_src_dir}/llkdu.dll") - -        if (EXISTS "${release_src_dir}/llkdu.dll") -            set(release_llkdu_src "${release_src_dir}/llkdu.dll") -            set(release_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELEASE}/llkdu.dll") -            set(relwithdebinfo_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}/llkdu.dll") -        endif (EXISTS "${release_src_dir}/llkdu.dll") -    endif (NOT EXISTS ${internal_llkdu_path}) -  #*******************************  # Copy MS C runtime dlls, required for packaging.  # *TODO - Adapt this to support VC9 @@ -174,21 +158,6 @@ elseif(DARWIN)      # fmod is statically linked on darwin      set(fmod_files "") -    #******************************* -    # LLKDU -    set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu") -    if(NOT EXISTS ${internal_llkdu_path}) -        if (EXISTS "${debug_src_dir}/libllkdu.dylib") -            set(debug_llkdu_src "${debug_src_dir}/libllkdu.dylib") -            set(debug_llkdu_dst "${SHARED_LIB_STAGING_DIR_DEBUG}/libllkdu.dylib") -        endif (EXISTS "${debug_src_dir}/libllkdu.dylib") - -        if (EXISTS "${release_src_dir}/libllkdu.dylib") -            set(release_llkdu_src "${release_src_dir}/libllkdu.dylib") -            set(release_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELEASE}/libllkdu.dylib") -            set(relwithdebinfo_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}/libllkdu.dylib") -        endif (EXISTS "${release_src_dir}/libllkdu.dylib") -    endif (NOT EXISTS ${internal_llkdu_path})  elseif(LINUX)      # linux is weird, multiple side by side configurations aren't supported      # and we don't seem to have any debug shared libs built yet anyways... @@ -242,21 +211,6 @@ elseif(LINUX)        set(release_files ${release_files} "libfmod-3.75.so")      endif (FMOD) -    #******************************* -    # LLKDU -    set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu") -    if(NOT EXISTS ${internal_llkdu_path}) -        if (EXISTS "${debug_src_dir}/libllkdu.so") -            set(debug_llkdu_src "${debug_src_dir}/libllkdu.so") -            set(debug_llkdu_dst "${SHARED_LIB_STAGING_DIR_DEBUG}/libllkdu.so") -        endif (EXISTS "${debug_src_dir}/libllkdu.so") - -        if (EXISTS "${release_src_dir}/libllkdu.so") -            set(release_llkdu_src "${release_src_dir}/libllkdu.so") -            set(release_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELEASE}/libllkdu.so") -            set(relwithdebinfo_llkdu_dst "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}/libllkdu.so") -        endif (EXISTS "${release_src_dir}/libllkdu.so") -    endif(NOT EXISTS ${internal_llkdu_path})  else(WINDOWS)      message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")      set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-linux") @@ -334,40 +288,29 @@ copy_if_different(      )  set(third_party_targets ${third_party_targets} ${out_targets}) -#******************************* -# LLKDU -set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu") -if(NOT EXISTS ${internal_llkdu_path}) -    if (EXISTS "${debug_llkdu_src}") -        ADD_CUSTOM_COMMAND( -            OUTPUT  ${debug_llkdu_dst} -            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${debug_llkdu_src} ${debug_llkdu_dst} -            DEPENDS ${debug_llkdu_src} -            COMMENT "Copying llkdu.dll ${SHARED_LIB_STAGING_DIR_DEBUG}" -            ) -        set(third_party_targets ${third_party_targets} $} ${debug_llkdu_dst}) -    endif (EXISTS "${debug_llkdu_src}") - -    if (EXISTS "${release_llkdu_src}") -        ADD_CUSTOM_COMMAND( -            OUTPUT  ${release_llkdu_dst} -            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${release_llkdu_src} ${release_llkdu_dst} -            DEPENDS ${release_llkdu_src} -            COMMENT "Copying llkdu.dll ${SHARED_LIB_STAGING_DIR_RELEASE}" -            ) -        set(third_party_targets ${third_party_targets} ${release_llkdu_dst}) - -        ADD_CUSTOM_COMMAND( -            OUTPUT  ${relwithdebinfo_llkdu_dst} -            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${release_llkdu_src} ${relwithdebinfo_llkdu_dst} -            DEPENDS ${release_llkdu_src} -            COMMENT "Copying llkdu.dll ${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}" -            ) -        set(third_party_targets ${third_party_targets} ${relwithdebinfo_llkdu_dst}) -    endif (EXISTS "${release_llkdu_src}") - -endif (NOT EXISTS ${internal_llkdu_path}) - +if (FMOD_SDK_DIR) +    copy_if_different( +        ${FMOD_SDK_DIR}  +        "${CMAKE_CURRENT_BINARY_DIR}/Debug" +        out_targets  +        ${fmod_files} +        ) +    set(all_targets ${all_targets} ${out_targets}) +    copy_if_different( +        ${FMOD_SDK_DIR}  +        "${CMAKE_CURRENT_BINARY_DIR}/Release" +        out_targets  +        ${fmod_files} +        ) +    set(all_targets ${all_targets} ${out_targets}) +    copy_if_different( +        ${FMOD_SDK_DIR}  +        "${CMAKE_CURRENT_BINARY_DIR}/RelWithDbgInfo" +        out_targets  +        ${fmod_files} +        ) +    set(all_targets ${all_targets} ${out_targets}) +endif (FMOD_SDK_DIR)  if(NOT STANDALONE)    add_custom_target( diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake index 27c8ada686..f5cbad03a6 100644 --- a/indra/cmake/LLKDU.cmake +++ b/indra/cmake/LLKDU.cmake @@ -1,7 +1,20 @@  # -*- cmake -*-  include(Prebuilt) +# USE_KDU can be set when launching cmake or develop.py as an option using the argument -DUSE_KDU:BOOL=ON +# When building using proprietary binaries though (i.e. having access to LL private servers), we always build with KDU  if (INSTALL_PROPRIETARY AND NOT STANDALONE) -  use_prebuilt_binary(kdu) -  set(LLKDU_LIBRARY llkdu) +  set(USE_KDU ON)  endif (INSTALL_PROPRIETARY AND NOT STANDALONE) + +if (USE_KDU) +  use_prebuilt_binary(kdu) +  if (WINDOWS) +    set(KDU_LIBRARY kdu.lib) +  else (WINDOWS) +    set(KDU_LIBRARY libkdu.a) +  endif (WINDOWS) +  set(KDU_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/kdu) +  set(LLKDU_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llkdu) +  set(LLKDU_LIBRARIES llkdu) +endif (USE_KDU) diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt index 452d37d3be..e0772e55ca 100644 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt @@ -10,6 +10,7 @@ include(00-Common)  include(LLCommon)  include(LLImage)  include(LLImageJ2COJ)   # ugh, needed for images +include(LLKDU)  include(LLMath)  include(LLMessage)  include(LLRender) @@ -71,6 +72,11 @@ endif (DARWIN)  target_link_libraries(llui_libtest      llui      llmessage +    ${LLRENDER_LIBRARIES} +    ${LLIMAGE_LIBRARIES} +    ${LLKDU_LIBRARIES} +    ${KDU_LIBRARY} +    ${LLIMAGEJ2COJ_LIBRARIES}      ${OS_LIBRARIES}      ${GOOGLE_PERFTOOLS_LIBRARIES}      ) diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index a69621a57b..6834267d4b 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -57,7 +57,6 @@ add_library (llimage ${llimage_SOURCE_FILES})  # Sort by high-level to low-level  target_link_libraries(llimage      llcommon -    llimagej2coj        # *HACK: In theory a noop for KDU builds?      ${JPEG_LIBRARIES}      ${PNG_LIBRARIES}      ${ZLIB_LIBRARIES} diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 5c33b675ca..b46a99e030 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -52,13 +52,11 @@ LLMutex* LLImage::sMutex = NULL;  void LLImage::initClass()  {  	sMutex = new LLMutex(NULL); -	LLImageJ2C::openDSO();  }  //static  void LLImage::cleanupClass()  { -	LLImageJ2C::closeDSO();  	delete sMutex;  	sMutex = NULL;  } diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index d005aaf29f..cb2a85fa91 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -24,9 +24,6 @@   */  #include "linden_common.h" -#include "apr_pools.h" -#include "apr_dso.h" -  #include "lldir.h"  #include "llimagej2c.h"  #include "llmemtype.h" @@ -37,18 +34,10 @@ typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)();  typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*);  typedef const char* (*EngineInfoLLImageJ2CFunction)(); -//some "private static" variables so we only attempt to load -//dynamic libaries once -CreateLLImageJ2CFunction j2cimpl_create_func; -DestroyLLImageJ2CFunction j2cimpl_destroy_func; -EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func; -apr_pool_t *j2cimpl_dso_memory_pool; -apr_dso_handle_t *j2cimpl_dso_handle; - -//Declare the prototype for theses functions here, their functionality -//will be implemented in other files which define a derived LLImageJ2CImpl -//but only ONE static library which has the implementation for this -//function should ever be included +// Declare the prototype for theses functions here. Their functionality +// will be implemented in other files which define a derived LLImageJ2CImpl +// but only ONE static library which has the implementation for these +// functions should ever be included.  LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl();  void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl);  const char* fallbackEngineInfoLLImageJ2CImpl(); @@ -58,120 +47,9 @@ LLImageCompressionTester* LLImageJ2C::sTesterp = NULL ;  const std::string sTesterName("ImageCompressionTester");  //static -//Loads the required "create", "destroy" and "engineinfo" functions needed -void LLImageJ2C::openDSO() -{ -	//attempt to load a DSO and get some functions from it -	std::string dso_name; -	std::string dso_path; - -	bool all_functions_loaded = false; -	apr_status_t rv; - -#if LL_WINDOWS -	dso_name = "llkdu.dll"; -#elif LL_DARWIN -	dso_name = "libllkdu.dylib"; -#else -	dso_name = "libllkdu.so"; -#endif - -	dso_path = gDirUtilp->findFile(dso_name, -								   gDirUtilp->getAppRODataDir(), -								   gDirUtilp->getExecutableDir()); - -	j2cimpl_dso_handle      = NULL; -	j2cimpl_dso_memory_pool = NULL; - -	//attempt to load the shared library -	apr_pool_create(&j2cimpl_dso_memory_pool, NULL); -	rv = apr_dso_load(&j2cimpl_dso_handle, -					  dso_path.c_str(), -					  j2cimpl_dso_memory_pool); - -	//now, check for success -	if ( rv == APR_SUCCESS ) -	{ -		//found the dynamic library -		//now we want to load the functions we're interested in -		CreateLLImageJ2CFunction  create_func = NULL; -		DestroyLLImageJ2CFunction dest_func = NULL; -		EngineInfoLLImageJ2CFunction engineinfo_func = NULL; - -		rv = apr_dso_sym((apr_dso_handle_sym_t*)&create_func, -						 j2cimpl_dso_handle, -						 "createLLImageJ2CKDU"); -		if ( rv == APR_SUCCESS ) -		{ -			//we've loaded the create function ok -			//we need to delete via the DSO too -			//so lets check for a destruction function -			rv = apr_dso_sym((apr_dso_handle_sym_t*)&dest_func, -							 j2cimpl_dso_handle, -							 "destroyLLImageJ2CKDU"); -			if ( rv == APR_SUCCESS ) -			{ -				//we've loaded the destroy function ok -				rv = apr_dso_sym((apr_dso_handle_sym_t*)&engineinfo_func, -						 j2cimpl_dso_handle, -						 "engineInfoLLImageJ2CKDU"); -				if ( rv == APR_SUCCESS ) -				{ -					//ok, everything is loaded alright -					j2cimpl_create_func  = create_func; -					j2cimpl_destroy_func = dest_func; -					j2cimpl_engineinfo_func = engineinfo_func; -					all_functions_loaded = true; -				} -			} -		} -	} - -	if ( !all_functions_loaded ) -	{ -		//something went wrong with the DSO or function loading.. -		//fall back onto our satefy impl creation function - -#if 0 -		// precious verbose debugging, sadly we can't use our -		// 'llinfos' stream etc. this early in the initialisation seq. -		char errbuf[256]; -		fprintf(stderr, "failed to load syms from DSO %s (%s)\n", -			dso_name.c_str(), dso_path.c_str()); -		apr_strerror(rv, errbuf, sizeof(errbuf)); -		fprintf(stderr, "error: %d, %s\n", rv, errbuf); -		apr_dso_error(j2cimpl_dso_handle, errbuf, sizeof(errbuf)); -		fprintf(stderr, "dso-error: %d, %s\n", rv, errbuf); -#endif - -		if ( j2cimpl_dso_handle ) -		{ -			apr_dso_unload(j2cimpl_dso_handle); -			j2cimpl_dso_handle = NULL; -		} - -		if ( j2cimpl_dso_memory_pool ) -		{ -			apr_pool_destroy(j2cimpl_dso_memory_pool); -			j2cimpl_dso_memory_pool = NULL; -		} -	} -} - -//static -void LLImageJ2C::closeDSO() -{ -	if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle); -	if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool); -} - -//static  std::string LLImageJ2C::getEngineInfo()  { -	if (!j2cimpl_engineinfo_func) -		j2cimpl_engineinfo_func = fallbackEngineInfoLLImageJ2CImpl; - -	return j2cimpl_engineinfo_func(); +    return fallbackEngineInfoLLImageJ2CImpl();  }  LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C), @@ -181,20 +59,7 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  							mReversible(FALSE),  							mAreaUsedForDataSizeCalcs(0)  { -	//We assume here that if we wanted to create via -	//a dynamic library that the approriate open calls were made -	//before any calls to this constructor. - -	//Therefore, a NULL creation function pointer here means -	//we either did not want to create using functions from the dynamic -	//library or there were issues loading it, either way -	//use our fall back -	if ( !j2cimpl_create_func ) -	{ -		j2cimpl_create_func = fallbackCreateLLImageJ2CImpl; -	} - -	mImpl = j2cimpl_create_func(); +	mImpl = fallbackCreateLLImageJ2CImpl();  	// Clear data size table  	for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++) @@ -217,22 +82,9 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),  // virtual  LLImageJ2C::~LLImageJ2C()  { -	//We assume here that if we wanted to destroy via -	//a dynamic library that the approriate open calls were made -	//before any calls to this destructor. - -	//Therefore, a NULL creation function pointer here means -	//we either did not want to destroy using functions from the dynamic -	//library or there were issues loading it, either way -	//use our fall back -	if ( !j2cimpl_destroy_func ) -	{ -		j2cimpl_destroy_func = fallbackDestroyLLImageJ2CImpl; -	} -  	if ( mImpl )  	{ -		j2cimpl_destroy_func(mImpl); +        fallbackDestroyLLImageJ2CImpl(mImpl);  	}  } diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index cc3dabd7d8..dd5bec8b2e 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -72,8 +72,6 @@ public:  	static S32 calcHeaderSizeJ2C();  	static S32 calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate = 0.f); -	static void openDSO(); -	static void closeDSO();  	static std::string getEngineInfo();  protected: diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt new file mode 100644 index 0000000000..b8b44b44fc --- /dev/null +++ b/indra/llkdu/CMakeLists.txt @@ -0,0 +1,45 @@ +# -*- cmake -*- + +project(llkdu) + +# Visual Studio 2005 has a dumb bug that causes it to fail compilation +# of KDU if building with both optimisation and /WS (treat warnings as +# errors), even when the specific warnings that make it croak are +# disabled. + +#set(VS_DISABLE_FATAL_WARNINGS ON) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLKDU) +include(LLMath) + +include_directories( +    ${LLCOMMON_INCLUDE_DIRS} +    ${LLIMAGE_INCLUDE_DIRS} +    ${KDU_INCLUDE_DIR} +    ${LLMATH_INCLUDE_DIRS} +    ) + +set(llkdu_SOURCE_FILES +    llimagej2ckdu.cpp +    llkdumem.cpp +    ) + +set(llkdu_HEADER_FILES +    CMakeLists.txt +	 +    llimagej2ckdu.h +    llkdumem.h +    ) + +set_source_files_properties(${llkdu_HEADER_FILES} +                            PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES}) + +if (USE_KDU) +  add_library (${LLKDU_LIBRARIES} ${llkdu_SOURCE_FILES}) +   +endif (USE_KDU) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp new file mode 100644 index 0000000000..1a286d1406 --- /dev/null +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -0,0 +1,1084 @@ + /**  + * @file llimagej2ckdu.cpp + * @brief This is an implementation of JPEG2000 encode/decode using Kakadu + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llimagej2ckdu.h" + +#include "lltimer.h" +#include "llpointer.h" +#include "llkdumem.h" + + +class kdc_flow_control { +	 +public: // Member functions +    kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream); +    ~kdc_flow_control(); +    bool advance_components(); +    void process_components(); +	 +private: // Data +     +    struct kdc_component_flow_control { +    public: // Data +        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 +                                which it is incremented by `vert_subsampling'.  */ +        int initial_lines; +        int remaining_lines; +        kdu_line_buf *line; +    }; +     +    kdu_codestream codestream; +    kdu_dims valid_tile_indices; +    kdu_coords tile_idx; +    kdu_tile tile; +    int num_components; +    kdc_component_flow_control *components; +    int count_delta; // Holds the minimum of the `vert_subsampling' fields +    kdu_multi_analysis engine; +    kdu_long max_buffer_memory; +}; + +// +// Kakadu specific implementation +// +void set_default_colour_weights(kdu_params *siz); + +const char* engineInfoLLImageJ2CKDU() +{ +	return "KDU v6.4.1"; +} + +LLImageJ2CKDU* createLLImageJ2CKDU() +{ +	return new LLImageJ2CKDU(); +} + +void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu) +{ +	delete kdu; +	kdu = NULL; +} + +LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() +{ +	return new LLImageJ2CKDU(); +} + +void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl) +{ +	delete impl; +	impl = NULL; +} + +const char* fallbackEngineInfoLLImageJ2CImpl() +{ +	return engineInfoLLImageJ2CKDU(); +} + +class LLKDUDecodeState +{ +public: + +	S32 mNumComponents; +	BOOL mUseYCC; +	kdu_dims mDims; +	kdu_sample_allocator mAllocator; +	kdu_tile_comp mComps[4]; +	kdu_line_buf mLines[4]; +	kdu_pull_ifc mEngines[4]; +	bool mReversible[4]; // Some components may be reversible and others not. +	int mBitDepths[4]; // Original bit-depth may be quite different from 8. + +	kdu_tile mTile; +	kdu_byte *mBuf; +	S32 mRowGap; + +	LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); +	~LLKDUDecodeState(); +	BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); + +public: +	int *AssignLayerBytes(siz_params *siz, int &num_specs); + +	void setupCodeStream(BOOL keep_codestream, LLImageJ2CKDU::ECodeStreamMode mode); +	BOOL initDecode(LLImageRaw &raw_image, F32 decode_time, LLImageJ2CKDU::ECodeStreamMode mode, S32 first_channel, S32 max_channel_count ); +}; + +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 +{ +public: +	/*virtual*/ void put_text(const char *s); +	/*virtual*/ void put_text(const kdu_uint16 *s); + +	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; +}; + +void LLKDUMessageWarning::put_text(const char *s) +{ +	llinfos << "KDU Warning: " << s << llendl; +} + +void LLKDUMessageWarning::put_text(const kdu_uint16 *s) +{ +	llinfos << "KDU Warning: " << s << llendl; +} + +void LLKDUMessageError::put_text(const char *s) +{ +	llinfos << "KDU Error: " << s << llendl; +} + +void LLKDUMessageError::put_text(const kdu_uint16 *s) +{ +	llinfos << "KDU Error: " << s << llendl; +} + +void LLKDUMessageError::flush(bool end_of_message) +{ +	if( end_of_message )  +	{ +		throw "KDU throwing an exception"; +	} +} + +LLKDUMessageWarning LLKDUMessageWarning::sDefaultMessage; +LLKDUMessageError	LLKDUMessageError::sDefaultMessage; +static bool kdu_message_initialized = false; + +LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(), +mInputp(NULL), +mCodeStreamp(NULL), +mTPosp(NULL), +mTileIndicesp(NULL), +mRawImagep(NULL), +mDecodeState(NULL) +{ +} + +LLImageJ2CKDU::~LLImageJ2CKDU() +{ +	cleanupCodeStream(); // in case destroyed before decode completed +} + +// 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) +{ +	S32 data_size = base.getDataSize(); +	S32 max_bytes = base.getMaxBytes() ? base.getMaxBytes() : data_size; + +	// +	//  Initialization +	// +	if (!kdu_message_initialized) +	{ +		kdu_message_initialized = true; +		kdu_customize_errors(&LLKDUMessageError::sDefaultMessage); +		kdu_customize_warnings(&LLKDUMessageWarning::sDefaultMessage); +	} + +	if (mCodeStreamp) +	{ +		mCodeStreamp->destroy(); +		delete mCodeStreamp; +		mCodeStreamp = NULL; +	} + +	if (!mInputp) +	{ +		llassert(base.getData()); +		// The compressed data has been loaded +		// Setup the source for the codestrea +		mInputp = new LLKDUMemSource(base.getData(), data_size); +	} + +	llassert(mInputp); +	mInputp->reset(); +	mCodeStreamp = new kdu_codestream; + +	mCodeStreamp->create(mInputp); + +	// Set the maximum number of bytes to use from the codestream +	mCodeStreamp->set_max_bytes(max_bytes); + +	//    If you want to flip or rotate the image for some reason, change +	// the resolution, or identify a restricted region of interest, this is +	// the place to do it.  You may use "kdu_codestream::change_appearance" +	// and "kdu_codestream::apply_input_restrictions" for this purpose. +	//    If you wish to truncate the code-stream prior to decompression, you +	// may use "kdu_codestream::set_max_bytes". +	//    If you wish to retain all compressed data so that the material +	// can be decompressed multiple times, possibly with different appearance +	// parameters, you should call "kdu_codestream::set_persistent" here. +	//    There are a variety of other features which must be enabled at +	// this point if you want to take advantage of them.  See the +	// descriptions appearing with the "kdu_codestream" interface functions +	// in "kdu_compressed.h" for an itemized account of these capabilities. + +	switch( mode ) +	{ +	case MODE_FAST: +		mCodeStreamp->set_fast(); +		break; +	case MODE_RESILIENT: +		mCodeStreamp->set_resilient(); +		break; +	case MODE_FUSSY: +		mCodeStreamp->set_fussy(); +		break; +	default: +		llassert(0); +		mCodeStreamp->set_fast(); +	} + +	kdu_dims dims; +	mCodeStreamp->get_dims(0,dims); + +	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)) +		{ +			llerrs << "Components don't have matching dimensions!" << llendl; +		} +	} + +	base.setSize(dims.size.x, dims.size.y, components); + +	if (!keep_codestream) +	{ +		mCodeStreamp->destroy(); +		delete mCodeStreamp; +		mCodeStreamp = NULL; +		delete mInputp; +		mInputp = NULL; +	} +} + +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; +} + +BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count ) +{ +	base.resetLastError(); + +	// *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 +	{ +		base.updateRawDiscardLevel(); +		setupCodeStream(base, TRUE, mode); + +		mRawImagep = &raw_image; +		mCodeStreamp->change_appearance(false, true, false); +		mCodeStreamp->apply_input_restrictions(first_channel,max_channel_count,base.getRawDiscardLevel(),0,NULL); + +		kdu_dims dims; mCodeStreamp->get_dims(0,dims); +		S32 channels = base.getComponents() - first_channel; +		if( channels > max_channel_count ) +		{ +			channels = max_channel_count; +		} +		raw_image.resize(dims.size.x, dims.size.y, channels); + +		//	llinfos << "Resizing to " << dims.size.x << ":" << dims.size.y << llendl; +		if (!mTileIndicesp) +		{ +			mTileIndicesp = new kdu_dims; +		} +		mCodeStreamp->get_valid_tiles(*mTileIndicesp); +		if (!mTPosp) +		{ +			mTPosp = new kdu_coords; +			mTPosp->y = 0; +			mTPosp->x = 0; +		} +	} +	catch (const char* msg) +	{ +		base.setLastError(ll_safe_string(msg)); +		return FALSE; +	} +	catch (...) +	{ +		base.setLastError("Unknown J2C error"); +		return FALSE; +	} + +	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) +{ +	ECodeStreamMode mode = MODE_FAST; + +	LLTimer decode_timer; + +	if (!mCodeStreamp) +	{ +		if (!initDecode(base, raw_image, decode_time, mode, first_channel, max_channel_count)) +		{ +			// Initializing the J2C decode failed, bail out. +			cleanupCodeStream(); +			return TRUE; // done +		} +	} + +	// These can probably be grabbed from what's saved in the class. +	kdu_dims dims; +	mCodeStreamp->get_dims(0,dims); + +	// Now we are ready to walk through the tiles processing them one-by-one. +	kdu_byte *buffer = raw_image.getData(); + +	while (mTPosp->y < mTileIndicesp->size.y) +	{ +		while (mTPosp->x < mTileIndicesp->size.x) +		{ +			try +			{ +				if (!mDecodeState) +				{ +					kdu_tile tile = mCodeStreamp->open_tile(*(mTPosp)+mTileIndicesp->pos); + +					// Find the region of the buffer occupied by this +					// tile.  Note that we have no control over +					// sub-sampling factors which might have been used +					// during compression and so it can happen that tiles +					// (at the image component level) actually have +					// different dimensions.  For this reason, we cannot +					// figure out the buffer region occupied by a tile +					// directly from the tile indices.  Instead, we query +					// the highest resolution of the first tile-component +					// concerning its location and size on the canvas -- +					// the `dims' object already holds the location and +					// size of the entire image component on the same +					// canvas coordinate system.  Comparing the two tells +					// us where the current tile is in the buffer. +					S32 channels = base.getComponents() - first_channel; +					if( channels > max_channel_count ) +					{ +						channels = max_channel_count; +					} +					kdu_resolution res = tile.access_component(0).access_resolution(); +					kdu_dims tile_dims; res.get_dims(tile_dims); +					kdu_coords offset = tile_dims.pos - dims.pos; +					int row_gap = channels*dims.size.x; // inter-row separation +					kdu_byte *buf = buffer + offset.y*row_gap + offset.x*channels; +					mDecodeState = new LLKDUDecodeState(tile, buf, row_gap); +				} +				// Do the actual processing +				F32 remaining_time = decode_time - decode_timer.getElapsedTimeF32(); +				// This is where we do the actual decode.  If we run out of time, return false. +				if (mDecodeState->processTileDecode(remaining_time, (decode_time > 0.0f))) +				{ +					delete mDecodeState; +					mDecodeState = NULL; +				} +				else +				{ +					// Not finished decoding yet. +					//					setLastError("Ran out of time while decoding"); +					return FALSE; +				} +			} +			catch( const char* msg ) +			{ +				base.setLastError(ll_safe_string(msg)); +				base.decodeFailed(); +				cleanupCodeStream(); +				return TRUE; // done +			} +			catch( ... ) +			{ +				base.setLastError( "Unknown J2C error" ); +				base.decodeFailed(); +				cleanupCodeStream(); +				return TRUE; // done +			} + + +			mTPosp->x++; +		} +		mTPosp->y++; +		mTPosp->x = 0; +	} + +	cleanupCodeStream(); + +	return TRUE; +} + + +BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible) +{ +	// Collect simple arguments. +	bool transpose, vflip, hflip; +	bool allow_rate_prediction, mem, quiet, no_weights; +	int cpu_iterations; +	std::ostream *record_stream; + +	transpose = false; +	record_stream = NULL; +	allow_rate_prediction = true; +	no_weights = false; +	cpu_iterations = -1; +	mem = false; +	quiet = false; +	vflip = true; +	hflip = false; + +	try +	{ +		// Set up input image files. +		siz_params siz; +		 +		// Should set rate someplace here. +		LLKDUMemIn mem_in(raw_image.getData(), +			raw_image.getDataSize(), +			raw_image.getWidth(), +			raw_image.getHeight(), +			raw_image.getComponents(), +			&siz); + +		base.setSize(raw_image.getWidth(), raw_image.getHeight(), raw_image.getComponents()); + +		int num_components = raw_image.getComponents(); + +		siz.set(Scomponents,0,0,num_components); +		siz.set(Sdims,0,0,base.getHeight());  // Height of first image component +		siz.set(Sdims,0,1,base.getWidth());   // Width of first image component +		siz.set(Sprecision,0,0,8);  // Image samples have original bit-depth of 8 +		siz.set(Ssigned,0,0,false); // Image samples are originally unsigned + +		kdu_params *siz_ref = &siz; siz_ref->finalize(); +		siz_params transformed_siz; // Use this one to construct code-strea +		transformed_siz.copy_from(&siz,-1,-1,-1,0,transpose,false,false); + +		// Construct the `kdu_codestream' object and parse all remaining arguments. + +		U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents(); +		if (max_output_size < 1000) +		{ +			max_output_size = 1000; +		} +		U8 *output_buffer = new U8[max_output_size]; + +		U32 output_size = max_output_size; // gets modified +		LLKDUMemTarget output(output_buffer, output_size, base.getWidth()*base.getHeight()*base.getComponents()); +		if (output_size > max_output_size) +		{ +			llerrs << llformat("LLImageJ2C::encode output_size(%d) > max_output_size(%d)", +				output_size,max_output_size) << llendl; +		} + +		kdu_codestream codestream; +		codestream.create(&transformed_siz,&output); + +		if (comment_text) +		{ +			// Set the comments for the codestream +			kdu_codestream_comment comment = codestream.add_comment(); +			comment.put_text(comment_text); +		} + +		// Set codestream options +		int num_layer_specs = 0; + +		kdu_long layer_bytes[64]; +		U32 max_bytes = 0; + +		if ((num_components >= 3) && !no_weights) +		{ +			set_default_colour_weights(codestream.access_siz()); +		} + +		if (reversible) +		{ +			// If we're doing reversible, assume we're not using quality layers. +			// Yes, I know this is incorrect! +			codestream.access_siz()->parse_string("Creversible=yes"); +			codestream.access_siz()->parse_string("Clayers=1"); +			num_layer_specs = 1; +			layer_bytes[0] = 0; +		} +		else +		{ +			// Rate is the argument passed into the LLImageJ2C which +			// specifies the target compression rate.  The default is 8:1. +			// Possibly if max_bytes < 500, we should just use the default setting? +			if (base.mRate != 0.f) +			{ +				max_bytes = (U32)(base.mRate*base.getWidth()*base.getHeight()*base.getComponents()); +			} +			else +			{ +				max_bytes = (U32)(base.getWidth()*base.getHeight()*base.getComponents()*0.125); +			} + +			const U32 min_bytes = FIRST_PACKET_SIZE; +			if (max_bytes > min_bytes) +			{ +				U32 i; +				// This code is where we specify the target number of bytes for +				// each layer.  Not sure if we should do this for small images +				// or not.  The goal is to have this roughly align with +				// different quality levels that we decode at. +				for (i = min_bytes; i < max_bytes; i*=4) +				{ +					if (i == min_bytes * 4) +					{ +						i = 2000; +					} +					layer_bytes[num_layer_specs] = i; +					num_layer_specs++; +				} +				layer_bytes[num_layer_specs] = max_bytes; +				num_layer_specs++; + +				std::string layer_string = llformat("Clayers=%d",num_layer_specs); +				codestream.access_siz()->parse_string(layer_string.c_str()); +			} +			else +			{ +				layer_bytes[0] = min_bytes; +				num_layer_specs = 1; +				std::string layer_string = llformat("Clayers=%d",num_layer_specs); +				codestream.access_siz()->parse_string(layer_string.c_str()); +			} +		} +		codestream.access_siz()->finalize_all(); +		if (cpu_iterations >= 0) +		{ +			codestream.collect_timing_stats(cpu_iterations); +		} +		codestream.change_appearance(transpose,vflip,hflip); + +		// Now we are ready for sample data processing. +        kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream); +        bool done = false; +        while (!done) +        {  +            // Process line by line +            done = true; +            if (tile->advance_components()) +            { +                done = false; +                tile->process_components(); +            } +        } + +		// Produce the compressed output +        codestream.flush(layer_bytes,num_layer_specs); + +		// Cleanup +        delete tile; + +		codestream.destroy(); +		if (record_stream != NULL) +		{ +			delete record_stream; +		} + +		// Now that we're done encoding, create the new data buffer for the compressed +		// image and stick it there. + +		base.copyData(output_buffer, output_size); +		base.updateData(); // set width, height +		delete[] output_buffer; +	} +	catch(const char* msg) +	{ +		base.setLastError(ll_safe_string(msg)); +		return FALSE; +	} +	catch( ... ) +	{ +		base.setLastError( "Unknown J2C error" ); +		return FALSE; +	} + +	return TRUE; +} + +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; +	} +	catch( const char* msg ) +	{ +		base.setLastError(ll_safe_string(msg)); +		return FALSE; +	} +	catch( ... ) +	{ +		base.setLastError( "Unknown J2C error" ); +		return FALSE; +	} +} + +void set_default_colour_weights(kdu_params *siz) +{ +	kdu_params *cod = siz->access_cluster(COD_params); +	assert(cod != NULL); + +	bool can_use_ycc = true; +	bool rev0=false; +	int depth0=0, sub_x0=1, sub_y0=1; +	for (int c=0; c < 3; c++) +	{ +		int depth=0; siz->get(Sprecision,c,0,depth); +		int sub_y=1; siz->get(Ssampling,c,0,sub_y); +		int sub_x=1; siz->get(Ssampling,c,1,sub_x); +		kdu_params *coc = cod->access_relation(-1,c); +		bool rev=false; coc->get(Creversible,0,0,rev); +		if (c == 0) +		{ rev0=rev; depth0=depth; sub_x0=sub_x; sub_y0=sub_y; } +		else if ((rev != rev0) || (depth != depth0) || +			(sub_x != sub_x0) || (sub_y != sub_y0)) +			can_use_ycc = false; +	} +	if (!can_use_ycc) +		return; + +	bool use_ycc; +	if (!cod->get(Cycc,0,0,use_ycc)) +		cod->set(Cycc,0,0,use_ycc=true); +	if (!use_ycc) +		return; +	float weight; +	if (cod->get(Clev_weights,0,0,weight) || +		cod->get(Cband_weights,0,0,weight)) +		return; // Weights already specified explicitly. + +	/* These example weights are adapted from numbers generated by Marcus Nadenau +	at EPFL, for a viewing distance of 15 cm and a display resolution of +	300 DPI. */ + +	cod->parse_string("Cband_weights:C0=" +		"{0.0901},{0.2758},{0.2758}," +		"{0.7018},{0.8378},{0.8378},{1}"); +	cod->parse_string("Cband_weights:C1=" +		"{0.0263},{0.0863},{0.0863}," +		"{0.1362},{0.2564},{0.2564}," +		"{0.3346},{0.4691},{0.4691}," +		"{0.5444},{0.6523},{0.6523}," +		"{0.7078},{0.7797},{0.7797},{1}"); +	cod->parse_string("Cband_weights:C2=" +		"{0.0773},{0.1835},{0.1835}," +		"{0.2598},{0.4130},{0.4130}," +		"{0.5040},{0.6464},{0.6464}," +		"{0.7220},{0.8254},{0.8254}," +		"{0.8769},{0.9424},{0.9424},{1}"); +} + +/******************************************************************************/ +/*                              transfer_bytes                                */ +/******************************************************************************/ + +void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision) +/* Transfers source samples from the supplied line buffer into the output +byte buffer, spacing successive output samples apart by `gap' bytes +(to allow for interleaving of colour components).  The function performs +all necessary level shifting, type conversion, rounding and truncation. */ +{ +	int width = src.get_width(); +	if (src.get_buf32() != NULL) +	{ // Decompressed samples have a 32-bit representation (integer or float) +		assert(precision >= 8); // Else would have used 16 bit representation +		kdu_sample32 *sp = src.get_buf32(); +		if (!src.is_absolute()) +		{ // Transferring normalized floating point data. +			float scale16 = (float)(1<<16); +			kdu_int32 val; + +			for (; width > 0; width--, sp++, dest+=gap) +			{ +				val = (kdu_int32)(sp->fval*scale16); +				val = (val+128)>>8; // May be faster than true rounding +				val += 128; +				if (val & ((-1)<<8)) +				{ +					val = (val<0)?0:255; +				} +				*dest = (kdu_byte) val; +			} +		} +		else +		{ // Transferring 32-bit absolute integers. +			kdu_int32 val; +			kdu_int32 downshift = precision-8; +			kdu_int32 offset = (1<<downshift)>>1; + +			for (; width > 0; width--, sp++, dest+=gap) +			{ +				val = sp->ival; +				val = (val+offset)>>downshift; +				val += 128; +				if (val & ((-1)<<8)) +				{ +					val = (val<0)?0:255; +				} +				*dest = (kdu_byte) val; +			} +		} +	} +	else +	{ // Source data is 16 bits. +		kdu_sample16 *sp = src.get_buf16(); +		if (!src.is_absolute()) +		{ // Transferring 16-bit fixed point quantities +			kdu_int16 val; + +			if (precision >= 8) +			{ // Can essentially ignore the bit-depth. +				for (; width > 0; width--, sp++, dest+=gap) +				{ +					val = sp->ival; +					val += (1<<(KDU_FIX_POINT-8))>>1; +					val >>= (KDU_FIX_POINT-8); +					val += 128; +					if (val & ((-1)<<8)) +					{ +						val = (val<0)?0:255; +					} +					*dest = (kdu_byte) val; +				} +			} +			else +			{ // Need to force zeros into one or more least significant bits. +				kdu_int16 downshift = KDU_FIX_POINT-precision; +				kdu_int16 upshift = 8-precision; +				kdu_int16 offset = 1<<(downshift-1); + +				for (; width > 0; width--, sp++, dest+=gap) +				{ +					val = sp->ival; +					val = (val+offset)>>downshift; +					val <<= upshift; +					val += 128; +					if (val & ((-1)<<8)) +					{ +						val = (val<0)?0:(256-(1<<upshift)); +					} +					*dest = (kdu_byte) val; +				} +			} +		} +		else +		{ // Transferring 16-bit absolute integers. +			kdu_int16 val; + +			if (precision >= 8) +			{ +				kdu_int16 downshift = precision-8; +				kdu_int16 offset = (1<<downshift)>>1; + +				for (; width > 0; width--, sp++, dest+=gap) +				{ +					val = sp->ival; +					val = (val+offset)>>downshift; +					val += 128; +					if (val & ((-1)<<8)) +					{ +						val = (val<0)?0:255; +					} +					*dest = (kdu_byte) val; +				} +			} +			else +			{ +				kdu_int16 upshift = 8-precision; + +				for (; width > 0; width--, sp++, dest+=gap) +				{ +					val = sp->ival; +					val <<= upshift; +					val += 128; +					if (val & ((-1)<<8)) +					{ +						val = (val<0)?0:(256-(1<<upshift)); +					} +					*dest = (kdu_byte) val; +				} +			} +		} +	} +} + +LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap) +{ +	S32 c; + +	mTile = tile; +	mBuf = buf; +	mRowGap = row_gap; + +	mNumComponents = tile.get_num_components(); + +	llassert(mNumComponents<=4); +	mUseYCC = tile.get_ycc(); + +	for (c=0; c<4; ++c) +	{ +		mReversible[c] = false; +		mBitDepths[c] = 0; +	} + +	// Open tile-components and create processing engines and resources +	for (c=0; c < mNumComponents; c++) +	{ +		mComps[c] = mTile.access_component(c); +		mReversible[c] = mComps[c].get_reversible(); +		mBitDepths[c] = mComps[c].get_bit_depth(); +		kdu_resolution res = mComps[c].access_resolution(); // Get top resolution +		kdu_dims comp_dims; res.get_dims(comp_dims); +		if (c == 0) +		{ +			mDims = comp_dims; +		} +		else +		{ +			llassert(mDims == comp_dims); // Safety check; the caller has ensured this +		} +		bool use_shorts = (mComps[c].get_bit_depth(true) <= 16); +		mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts); +		if (res.which() == 0) // No DWT levels used +		{ +			mEngines[c] = kdu_decoder(res.access_subband(LL_BAND),&mAllocator,use_shorts); +		} +		else +		{ +			mEngines[c] = kdu_synthesis(res,&mAllocator,use_shorts); +		} +	} +	mAllocator.finalize(); // Actually creates buffering resources +	for (c=0; c < mNumComponents; c++) +	{ +		mLines[c].create(); // Grabs resources from the allocator. +	} +} + +LLKDUDecodeState::~LLKDUDecodeState() +{ +	S32 c; +	// Cleanup +	for (c=0; c < mNumComponents; c++) +	{ +		mEngines[c].destroy(); // engines are interfaces; no default destructors +	} + +	mTile.close(); +} + +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, +the `buf' pointer may actually point into a larger buffer representing +multiple tiles.  For this reason, `row_gap' is needed to identify the +separation between consecutive rows in the real buffer. */ +{ +	S32 c; +	// Now walk through the lines of the buffer, recovering them from the +	// relevant tile-component processing engines. + +	LLTimer decode_timer; +	while (mDims.size.y--) +	{ +		for (c=0; c < mNumComponents; c++) +		{ +			mEngines[c].pull(mLines[c],true); +		} +		if ((mNumComponents >= 3) && mUseYCC) +		{ +			kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]); +		} +		for (c=0; c < mNumComponents; c++) +		{ +			transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]); +		} +		mBuf += mRowGap; +		if (mDims.size.y % 10) +		{ +			if (limit_time && decode_timer.getElapsedTimeF32() > decode_time) +			{ +				return FALSE; +			} +		} +	} +	return TRUE; +} + +// kdc_flow_control  + +kdc_flow_control::kdc_flow_control (kdu_image_in_base *img_in, kdu_codestream codestream) +{ +    int n; +     +    this->codestream = codestream; +    codestream.get_valid_tiles(valid_tile_indices); +    tile_idx = valid_tile_indices.pos; +    tile = codestream.open_tile(tile_idx,NULL); +     +    // Set up the individual components +    num_components = codestream.get_num_components(true); +    components = new kdc_component_flow_control[num_components]; +    count_delta = 0; +    kdc_component_flow_control *comp = components; +    for (n = 0; n < num_components; n++, comp++) +    { +        comp->line = NULL; +        comp->reader = img_in; +        kdu_coords subsampling;   +        codestream.get_subsampling(n,subsampling,true); +        kdu_dims dims;   +        codestream.get_tile_dims(tile_idx,n,dims,true); +        comp->vert_subsampling = subsampling.y; +        if ((n == 0) || (comp->vert_subsampling < count_delta)) +        { +            count_delta = comp->vert_subsampling; +        } +        comp->ratio_counter = 0; +        comp->remaining_lines = comp->initial_lines = dims.size.y; +    } +    assert(num_components > 0); +     +    tile.set_components_of_interest(num_components); +    max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false); +} + +kdc_flow_control::~kdc_flow_control() +{ +    if (components != NULL) +        delete[] components; +    if (engine.exists()) +        engine.destroy(); +} + +bool kdc_flow_control::advance_components() +{ +    bool found_line = false; +    while (!found_line) +    { +        bool all_done = true; +        kdc_component_flow_control *comp = components; +        for (int n = 0; n < num_components; n++, comp++) +        { +            assert(comp->ratio_counter >= 0); +            if (comp->remaining_lines > 0) +            { +                all_done = false; +                comp->ratio_counter -= count_delta; +                if (comp->ratio_counter < 0) +                { +                    found_line = true; +                    comp->line = engine.exchange_line(n,NULL,NULL); +                    assert(comp->line != NULL); +					if (comp->line->get_width()) +					{ +						comp->reader->get(n,*(comp->line),0); +					} +                } +            } +        } +        if (all_done) +        { +            return false; +        } +    } +    return true; +} + +void kdc_flow_control::process_components() +{ +    kdc_component_flow_control *comp = components; +    for (int n = 0; n < num_components; n++, comp++) +    { +        if (comp->ratio_counter < 0) +        { +            comp->ratio_counter += comp->vert_subsampling; +            assert(comp->ratio_counter >= 0); +            assert(comp->remaining_lines > 0); +            comp->remaining_lines--; +            assert(comp->line != NULL); +            engine.exchange_line(n,comp->line,NULL); +            comp->line = NULL; +        } +    } +} diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h new file mode 100644 index 0000000000..03f289f8b1 --- /dev/null +++ b/indra/llkdu/llimagej2ckdu.h @@ -0,0 +1,91 @@ +/**  + * @file llimagej2ckdu.h + * @brief This is an implementation of JPEG2000 encode/decode using Kakadu + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLIMAGEJ2CKDU_H +#define LL_LLIMAGEJ2CKDU_H + +#include "llimagej2c.h" + +// +// KDU core header files +// +#include "kdu_elementary.h" +#include "kdu_messaging.h" +#include "kdu_params.h" +#include "kdu_compressed.h" +#include "kdu_sample_processing.h" + +class LLKDUDecodeState; +class LLKDUMemSource; + +class LLImageJ2CKDU : public LLImageJ2CImpl +{	 +public: +	enum ECodeStreamMode  +	{ +		MODE_FAST = 0, +		MODE_RESILIENT = 1, +		MODE_FUSSY = 2 +	}; +	 +public: +	LLImageJ2CKDU(); +	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); + +	void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode); +	void cleanupCodeStream(); +	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count ); + +	// Encode variable +	LLKDUMemSource *mInputp; +	kdu_codestream *mCodeStreamp; +	kdu_coords *mTPosp; // tile position +	kdu_dims *mTileIndicesp; + +	// Temporary variables for in-progress decodes... +	LLImageRaw *mRawImagep; +	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 diff --git a/indra/llkdu/llkdumem.cpp b/indra/llkdu/llkdumem.cpp new file mode 100644 index 0000000000..1f549cbbe0 --- /dev/null +++ b/indra/llkdu/llkdumem.cpp @@ -0,0 +1,196 @@ + /**  + * @file llkdumem.cpp + * @brief Helper class for kdu memory management + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llkdumem.h" +#include "llerror.h" + +#if defined(LL_WINDOWS) +# pragma warning(disable: 4702) // unreachable code +#endif + +LLKDUMemIn::LLKDUMemIn(const U8 *data, +					   const U32 size, +					   const U16 width, +					   const U16 height, +					   const U8 in_num_components, +					   siz_params *siz) +{ +	U8 n; + +	first_comp_idx = 0; +	rows = height; +	cols = width; +	num_components = in_num_components; +	alignment_bytes = 0; + +	for (n=0; n<3; ++n) +	{ +		precision[n] = 0; +	} + +	for (n=0; n < num_components; ++n) +	{ +		siz->set(Sdims,n,0,rows); +		siz->set(Sdims,n,1,cols); +		siz->set(Ssigned,n,0,false); +		siz->set(Sprecision,n,0,8); +	} +	incomplete_lines = NULL; +	free_lines = NULL; +	num_unread_rows = rows; + +	mData = data; +	mDataSize = size; +	mCurPos = 0; +} + +LLKDUMemIn::~LLKDUMemIn() +{ +	if ((num_unread_rows > 0) || (incomplete_lines != NULL)) +	{ +		kdu_warning w; +		w << "Not all rows of image components " +			<< first_comp_idx << " through " +			<< first_comp_idx+num_components-1 +			<< " were consumed!"; +	} +	image_line_buf *tmp; +	while ((tmp=incomplete_lines) != NULL) +    { +		incomplete_lines = tmp->next; +		delete tmp;  +	} +	while ((tmp=free_lines) != NULL) +    { +		free_lines = tmp->next; +		delete tmp; +	} +} + + +bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum) +{ +	int idx = comp_idx - this->first_comp_idx; +	assert((idx >= 0) && (idx < num_components)); +	x_tnum = x_tnum*num_components+idx; +	image_line_buf *scan, *prev=NULL; +	for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next) +    { +		assert(scan->next_x_tnum >= x_tnum); +		if (scan->next_x_tnum == x_tnum) +		{ +			break; +		} +    } +	if (scan == NULL) +    { // Need to read a new image line. +		assert(x_tnum == 0); // Must consume in very specific order. +		if (num_unread_rows == 0) +		{ +	        return false; +		} +		if ((scan = free_lines) == NULL) +		{ +			scan = new image_line_buf(cols+3,num_components); +		} +		free_lines = scan->next; +		if (prev == NULL) +		{ +	        incomplete_lines = scan; +		} +		else +		{ +			prev->next = scan; +		} + +		// Copy from image buffer into scan. +		memcpy(scan->buf, mData+mCurPos, cols*num_components); +		mCurPos += cols*num_components; + +		num_unread_rows--; +		scan->accessed_samples = 0; +		scan->next_x_tnum = 0; +    } + +	assert((cols-scan->accessed_samples) >= line.get_width()); + +	int comp_offset = idx; +	kdu_byte *sp = scan->buf+num_components*scan->accessed_samples + comp_offset; +	int n=line.get_width(); + +	if (line.get_buf32() != NULL) +	{ +		kdu_sample32 *dp = line.get_buf32(); +		if (line.is_absolute()) +		{ // 32-bit absolute integers +			for (; n > 0; n--, sp+=num_components, dp++) +			{ +				dp->ival = ((kdu_int32)(*sp)) - 128; +			} +		} +		else +		{ // true 32-bit floats +			for (; n > 0; n--, sp+=num_components, dp++) +			{ +				dp->fval = (((float)(*sp)) / 256.0F) - 0.5F; +			} +		} +	} +	else +    { +		kdu_sample16 *dp = line.get_buf16(); +		if (line.is_absolute()) +		{ // 16-bit absolute integers +			for (; n > 0; n--, sp+=num_components, dp++) +			{ +				dp->ival = ((kdu_int16)(*sp)) - 128; +			} +		} +		else +		{ // 16-bit normalized representation. +			for (; n > 0; n--, sp+=num_components, dp++) +			{ +				dp->ival = (((kdu_int16)(*sp)) - 128) << (KDU_FIX_POINT-8); +			} +		} +    } + +	scan->next_x_tnum++; +	if (idx == (num_components-1)) +	{ +		scan->accessed_samples += line.get_width(); +	} +	if (scan->accessed_samples == cols) +	{ // Send empty line to free list. +		assert(scan == incomplete_lines); +		incomplete_lines = scan->next; +		scan->next = free_lines; +		free_lines = scan; +	} + +  return true; +} diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h new file mode 100644 index 0000000000..7064de4408 --- /dev/null +++ b/indra/llkdu/llkdumem.h @@ -0,0 +1,145 @@ +/**  + * @file llkdumem.h + * @brief Helper class for kdu memory management + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLKDUMEM_H +#define LL_LLKDUMEM_H + +// Support classes for reading and writing from memory buffers in KDU +#include "kdu_image.h" +#include "kdu_elementary.h" +#include "kdu_messaging.h" +#include "kdu_params.h" +#include "kdu_compressed.h" +#include "kdu_sample_processing.h" +#include "image_local.h" +#include "stdtypes.h" + +class LLKDUMemSource: public kdu_compressed_source +{ +public: // Member functions +	LLKDUMemSource(U8 *input_buffer, U32 size) +	{ +		mData = input_buffer; +		mSize = size; +		mCurPos = 0; +	} + +    ~LLKDUMemSource() +	{ +	} + +    int read(kdu_byte *buf, int num_bytes) +	{ +		U32 num_out; +		num_out = num_bytes; + +		if ((mSize - mCurPos) < (U32)num_bytes) +		{ +			num_out = mSize -mCurPos; +		} +		memcpy(buf, mData + mCurPos, num_out); +		mCurPos += num_out; +		return num_out; +	} + +	void reset() +	{ +		mCurPos = 0; +	} + +private: // Data +	U8 *mData; +	U32 mSize; +	U32 mCurPos; +}; + +class LLKDUMemTarget: public kdu_compressed_target +{ +public: // Member functions +	LLKDUMemTarget(U8 *output_buffer, U32 &output_size, const U32 buffer_size) +	{ +		mData = output_buffer; +		mSize = buffer_size; +		mCurPos = 0; +		mOutputSize = &output_size; +	} + +    ~LLKDUMemTarget() +    { +	} + +    bool write(const kdu_byte *buf, int num_bytes) +	{ +		U32 num_out; +		num_out = num_bytes; + +		if ((mSize - mCurPos) < (U32)num_bytes) +		{ +			num_out = mSize - mCurPos; +			memcpy(mData + mCurPos, buf, num_out); +			return false; +		} +		memcpy(mData + mCurPos, buf, num_out); +		mCurPos += num_out; +		*mOutputSize = mCurPos; +		return true; +	} +	 +private: // Data +	U8 *mData; +	U32 mSize; +	U32 mCurPos; +	U32 *mOutputSize; +}; + +class LLKDUMemIn : public kdu_image_in_base +{ +public: // Member functions +    LLKDUMemIn(const U8 *data, +				const U32 size, +				const U16 rows, +				const U16 cols, +				U8 in_num_components, +				siz_params *siz); +    ~LLKDUMemIn(); + +    bool get(int comp_idx, kdu_line_buf &line, int x_tnum); + +private: // Data +	const U8 *mData; +    int first_comp_idx; +    int num_components; +    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; +    int num_unread_rows; + +	U32 mCurPos; +	U32 mDataSize; +}; +#endif diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1176edc130..4869aa72a0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -50,6 +50,7 @@ include_directories(      ${LLCHARACTER_INCLUDE_DIRS}      ${LLCOMMON_INCLUDE_DIRS}      ${LLIMAGE_INCLUDE_DIRS} +    ${LLKDU_INCLUDE_DIRS}      ${LLINVENTORY_INCLUDE_DIRS}      ${LLMATH_INCLUDE_DIRS}      ${LLMESSAGE_INCLUDE_DIRS} @@ -1455,11 +1456,6 @@ if (WINDOWS)      # In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py      # and have the build deps get tracked *please* tell me about it. -    if(LLKDU_LIBRARY) -      # Configure a var for llkdu which may not exist for all builds. -      set(LLKDU_DLL_SOURCE ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/llkdu.dll) -    endif(LLKDU_LIBRARY) -      if(USE_GOOGLE_PERFTOOLS)        # Configure a var for tcmalloc location, if used.        # Note the need to specify multiple names explicitly. @@ -1476,7 +1472,6 @@ if (WINDOWS)        #${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libtcmalloc_minimal.dll => None ... Skipping libtcmalloc_minimal.dll        ${CMAKE_SOURCE_DIR}/../etc/message.xml        ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg -      ${LLKDU_DLL_SOURCE}        ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/llcommon.dll        ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libapr-1.dll        ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libaprutil-1.dll @@ -1662,7 +1657,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}      ${LLAUDIO_LIBRARIES}      ${LLCHARACTER_LIBRARIES}      ${LLIMAGE_LIBRARIES} -    ${LLIMAGEJ2COJ_LIBRARIES}      ${LLINVENTORY_LIBRARIES}      ${LLMESSAGE_LIBRARIES}      ${LLPLUGIN_LIBRARIES} @@ -1698,6 +1692,17 @@ target_link_libraries(${VIEWER_BINARY_NAME}      ${GOOGLE_PERFTOOLS_LIBRARIES}      ) +if (USE_KDU) +    target_link_libraries(${VIEWER_BINARY_NAME} +        ${LLKDU_LIBRARIES} +        ${KDU_LIBRARY} +        ) +else (USE_KDU) +    target_link_libraries(${VIEWER_BINARY_NAME} +        ${LLIMAGEJ2COJ_LIBRARIES} +        ) +endif (USE_KDU) +      build_version(viewer)  set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 6c77f8ec38..338c62b9fb 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -255,12 +255,6 @@ class WindowsManifest(ViewerManifest):              self.enable_crt_manifest_check() -            # Get kdu dll, continue if missing. -            try: -                self.path('llkdu.dll', dst='llkdu.dll') -            except RuntimeError: -                print "Skipping llkdu.dll" -              # Get llcommon and deps. If missing assume static linkage and continue.              try:                  self.path('llcommon.dll') @@ -625,21 +619,21 @@ class DarwinManifest(ViewerManifest):                  libdir = "../../libraries/universal-darwin/lib_release"                  dylibs = {} -                # need to get the kdu dll from any of the build directories as well -                for lib in "llkdu", "llcommon": -                    libfile = "lib%s.dylib" % lib -                    try: -                        self.path(self.find_existing_file(os.path.join(os.pardir, -                                                                       lib, -                                                                       self.args['configuration'], -                                                                       libfile), -                                                          os.path.join(libdir, libfile)), -                                  dst=libfile) -                    except RuntimeError: -                        print "Skipping %s" % libfile -                        dylibs[lib] = False -                    else: -                        dylibs[lib] = True +                # Need to get the llcommon dll from any of the build directories as well +                lib = "llcommon" +                libfile = "lib%s.dylib" % lib +                try: +                    self.path(self.find_existing_file(os.path.join(os.pardir, +                                                                    lib, +                                                                    self.args['configuration'], +                                                                    libfile), +                                                      os.path.join(libdir, libfile)), +                                                      dst=libfile) +                except RuntimeError: +                    print "Skipping %s" % libfile +                    dylibs[lib] = False +                else: +                    dylibs[lib] = True                  if dylibs["llcommon"]:                      for libfile in ("libapr-1.0.3.7.dylib", @@ -931,15 +925,6 @@ class Linux_i686Manifest(LinuxManifest):      def construct(self):          super(Linux_i686Manifest, self).construct() -        # install either the libllkdu we just built, or a prebuilt one, in -        # decreasing order of preference.  for linux package, this goes to bin/ -        try: -            self.path(self.find_existing_file('../llkdu/libllkdu.so', -                '../../libraries/i686-linux/lib_release_client/libllkdu.so'), -                  dst='bin/libllkdu.so') -        except: -            print "Skipping libllkdu.so - not found" -          if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"):              self.path("libapr-1.so.0")              self.path("libaprutil-1.so.0") @@ -956,12 +941,6 @@ class Linux_i686Manifest(LinuxManifest):              self.path("libopenal.so", "libopenal.so.1")              self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname              try: -                    self.path("libkdu.so") -                    pass -            except: -                    print "Skipping libkdu.so - not found" -                    pass -            try:                      self.path("libfmod-3.75.so")                      pass              except: | 
