Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Latif Khalifa
2012-12-25 11:47:32 +01:00
423 changed files with 17177 additions and 9997 deletions

27
README
View File

@@ -9,15 +9,30 @@
Sin-gu-la-ri-ty (noun) - a distinctive feature, a uniqueness; a point at which
continuity breaks up; a point in history at which machine becomes smarter than
humanity and/or fuses with it indivisively; or simply a cool sounding word with
my initials in it :)
the initials S.G. in it :)
Singularity Viewer is a Second Life protocol compatible client application. It
can be used to access Second LIfe service as well as a number of other such as
those based upon OpenSim plattform. It is directly based upon source code of
Ascent Viewer by Balseraph Software Group, which is in turn based upon source
code released by Linden Lab, with contributions from various sources.
Singularity Viewer is a SecondLife(tm) protocol compatible client application.
It can be used to access SecondLife services as well as a number of others such
as those based upon the OpenSim platform.
Singulariy is maintained by a small group of volunteers who can be contacted
both, in-world (SingularityViewer group) as well on IRC (#SingularityViewer
@ FreeNode). Bug requests and features requests can be submitted through our
Issue Tracker (http://code.google.com/p/singularity-viewer/issues/list or from
the viewer menu: Help --> Bug Reporting --> Singularity Issue Tracker...)
As this Readme grows out of date, please refer to
http://www.singularityviewer.org/about
00000000011111111112222222222333333333344444444445555555555666666666677777777778
12345678901234567890123456789012345678901234567890123456789012345678901234567890
History
The Singularity viewer was started by Siana Gearz in November 2010 by forking it
from the Ascent Viewer, by Balseraph Software Group, which in turn was based upon
source code modified from the snowglobe source code released by Linden Lab.

View File

@@ -248,6 +248,7 @@ Celierra Darling
VWR-6975
Cron Stardust
VWR-10579
STORM-1919
Cypren Christenson
SNOW-129
SNOW-140

View File

@@ -3,16 +3,18 @@
# - Find JSONCpp
# Find the JSONCpp includes and library
# This module defines
# JSONCPP_INCLUDE_DIR, where to find json.h, etc.
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
# JSONCPP_FOUND, If false, do not try to use jsoncpp.
# also defined, but not for general use are
# JSONCPP_LIBRARY, where to find the jsoncpp library.
# JSONCPP_FOUND, System has libjsoncpp.
# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories.
# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp.
# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp.
FIND_PATH(JSONCPP_INCLUDE_DIR json/json.h
/usr/local/include
/usr/include
)
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_JSONCPP jsoncpp)
SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER})
FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h
HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS}
PATH_SUFFIXES jsoncpp)
# Get the GCC compiler version
EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
@@ -22,39 +24,16 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
)
# Try to find a library that was compiled with the same compiler version as we currently use.
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so)
IF (STANDALONE)
# On standalone, assume that the system installed library was compiled with the used compiler.
SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so)
ENDIF (STANDALONE)
FIND_LIBRARY(JSONCPP_LIBRARY
NAMES ${JSONCPP_NAMES}
PATHS /usr/lib /usr/local/lib
)
NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so
HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS}
PATHS /usr/lib /usr/local/lib)
IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
SET(JSONCPP_FOUND "YES")
ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
SET(JSONCPP_FOUND "NO")
ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG
JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
IF (JSONCPP_FOUND)
IF (NOT JSONCPP_FIND_QUIETLY)
MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
ENDIF (NOT JSONCPP_FIND_QUIETLY)
ELSE (JSONCPP_FOUND)
IF (JSONCPP_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find JSONCpp library")
ENDIF (JSONCPP_FIND_REQUIRED)
ENDIF (JSONCPP_FOUND)
# Deprecated declarations.
SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} )
GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH)
MARK_AS_ADVANCED(
JSONCPP_LIBRARY
JSONCPP_INCLUDE_DIR
)
MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)

View File

@@ -11,10 +11,10 @@ else (STANDALONE)
if (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
use_prebuilt_binary(gperftools)
endif (LINUX OR WINDOWS AND NOT WORD_SIZE EQUAL 64)
if (WINDOWS)
if (WINDOWS AND NOT DISABLE_TCMALLOC)
set(TCMALLOC_LIBRARIES libtcmalloc_minimal.lib)
set(TCMALLOC_LINKER_FLAGS "/INCLUDE:\"__tcmalloc\"")
endif (WINDOWS)
endif (WINDOWS AND NOT DISABLE_TCMALLOC)
if (LINUX)
if(USE_GOOGLE_PERFTOOLS)
set(TCMALLOC_LIBRARIES tcmalloc)

View File

@@ -2,7 +2,7 @@
include(Prebuilt)
set(JSONCPP_FIND_QUIETLY ON)
set(JSONCPP_FIND_QUIETLY OFF)
set(JSONCPP_FIND_REQUIRED ON)
if (STANDALONE)

View File

@@ -30,6 +30,7 @@ set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)")
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)")
set(VISTA_ICON OFF CACHE BOOL "Allow vista icon with pre 2008 Visual Studio IDEs. (Assumes replacement old rcdll.dll with new rcdll.dll from win sdk 7.0 or later)")

View File

@@ -782,13 +782,14 @@ Commands:
Command-options for "configure":
We use cmake variables to change the build configuration.
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
-DVIEWER:BOOL=OFF Don't configure the viewer
-DPACKAGE:BOOL=ON Create "package" target to make installers
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
-VISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!)
-DSERVER:BOOL=OFF Don't configure simulator/dataserver/etc
-DVIEWER:BOOL=OFF Don't configure the viewer
-DPACKAGE:BOOL=ON Create "package" target to make installers
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
-DDISABLE_TCMALLOC:BOOL=ON Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)
-DVISTA_ICON:BOOL=ON Allow pre-2008 VS to use vista-optimized resource file. (Requires updated rcdll.dll!)
Examples:
Set up a viewer-only project for your system:

View File

@@ -7,14 +7,15 @@ include(00-Common)
# OPENJPEG version number, useful for packaging and doxygen doc:
set(OPENJPEG_VERSION_MAJOR 1)
set(OPENJPEG_VERSION_MINOR 4)
set(OPENJPEG_VERSION_BUILD 0)
set(OPENJPEG_VERSION_MINOR 5)
set(OPENJPEG_VERSION_BUILD 2)
set(OPENJPEG_VERSION
"${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}")
set(openjpeg_SOURCE_FILES
bio.c
cio.c
cidx_manager.c
dwt.c
event.c
image.c
@@ -26,20 +27,26 @@ set(openjpeg_SOURCE_FILES
mqc.c
openjpeg.c
pi.c
phix_manager.c
ppix_manager.c
raw.c
t1.c
t2.c
tcd.c
tgt.c
thix_manager.c
tpix_manager.c
)
set(openjpeg_HEADER_FILES
bio.h
cio.h
cidx_manager.h
dwt.h
event.h
event.h
fix.h
image.h
indexbox_manager.h
int.h
j2k.h
j2k_lib.h
@@ -48,6 +55,7 @@ set(openjpeg_HEADER_FILES
mct.h
mqc.h
openjpeg.h
opj_config.h
opj_includes.h
opj_malloc.h
pi.h

View File

@@ -0,0 +1,211 @@
/*
* $Id: cidx_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opj_includes.h"
/*
* Write CPTR Codestream finder box
*
* @param[in] coff offset of j2k codestream
* @param[in] clen length of j2k codestream
* @param[in] cio file output handle
*/
void write_cptr(int coff, int clen, opj_cio_t *cio);
/*
* Write main header index table (box)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] cio file output handle
* @return length of mainmhix box
*/
int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
/*
* Check if EPH option is used
*
* @param[in] coff offset of j2k codestream
* @param[in] markers marker information
* @param[in] marknum number of markers
* @param[in] cio file output handle
* @return true if EPH is used
*/
opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio);
int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen)
{
int len, i, lenp;
opj_jp2_box_t *box;
int num_box = 0;
opj_bool EPHused;
(void)image; /* unused ? */
lenp = -1;
box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
for (i=0;i<2;i++){
if(i)
cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_CIDX, 4); /* CIDX */
write_cptr( offset, cstr_info.codestream_size, cio);
write_manf( i, num_box, box, cio);
num_box = 0;
box[num_box].length = write_mainmhix( offset, cstr_info, cio);
box[num_box].type = JPIP_MHIX;
num_box++;
box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio);
box[num_box].type = JPIP_TPIX;
num_box++;
box[num_box].length = write_thix( offset, cstr_info, cio);
box[num_box].type = JPIP_THIX;
num_box++;
EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio);
box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio);
box[num_box].type = JPIP_PPIX;
num_box++;
box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio);
box[num_box].type = JPIP_PHIX;
num_box++;
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free( box);
return len;
}
void write_cptr(int coff, int clen, opj_cio_t *cio)
{
int len, lenp;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_CPTR, 4); /* T */
cio_write( cio, 0, 2); /* DR A PRECISER !! */
cio_write( cio, 0, 2); /* CONT */
cio_write( cio, coff, 8); /* COFF A PRECISER !! */
cio_write( cio, clen, 8); /* CLEN */
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio)
{
int len, lenp, i;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_MANF,4); /* T */
if (second){ /* Write only during the second pass */
for( i=0; i<v; i++){
cio_write( cio, box[i].length, 4); /* Box length */
cio_write( cio, box[i].type, 4); /* Box type */
}
}
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
{
int i;
int len, lenp;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_MHIX, 4); /* MHIX */
cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8); /* TLEN */
for(i = 1; i < cstr_info.marknum; i++){ /* Marker restricted to 1 apparition, skip SOC marker */
cio_write( cio, cstr_info.marker[i].type, 2);
cio_write( cio, 0, 2);
cio_write( cio, cstr_info.marker[i].pos-coff, 8);
cio_write( cio, cstr_info.marker[i].len, 2);
}
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}
opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio)
{
opj_bool EPHused = OPJ_FALSE;
int i=0;
int org_pos;
unsigned int Scod;
for(i = 0; i < marknum; i++){
if( markers[i].type == J2K_MS_COD){
org_pos = cio_tell( cio);
cio_seek( cio, coff+markers[i].pos+2);
Scod = cio_read( cio, 1);
if( ((Scod >> 2) & 1))
EPHused = OPJ_TRUE;
cio_seek( cio, org_pos);
break;
}
}
return EPHused;
}

View File

@@ -0,0 +1,56 @@
/*
* $Id: cidx_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.h from 2KAN indexer
*/
#ifndef CIDX_MANAGER_H_
# define CIDX_MANAGER_H_
#include "openjpeg.h"
/*
* Write Codestream index box (superbox)
*
* @param[in] offset offset of j2k codestream
* @param[in] cio file output handle
* @param[in] image image data
* @param[in] cstr_info codestream information
* @param[in] j2klen length of j2k codestream
* @return length of cidx box
*/
int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen);
#endif /* !CIDX_MANAGER_H_ */

View File

@@ -126,13 +126,13 @@ unsigned char *cio_getbp(opj_cio_t *cio) {
/*
* Write a byte.
*/
bool cio_byteout(opj_cio_t *cio, unsigned char v) {
opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) {
if (cio->bp >= cio->end) {
opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n");
return false;
return OPJ_FALSE;
}
*cio->bp++ = v;
return true;
return OPJ_TRUE;
}
/*
@@ -152,7 +152,7 @@ unsigned char cio_bytein(opj_cio_t *cio) {
* v : value to write
* n : number of bytes to write
*/
unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) {
unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n) {
int i;
for (i = n - 1; i >= 0; i--) {
if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) )

View File

@@ -31,6 +31,13 @@
#ifndef __CIO_H
#define __CIO_H
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define int64 __int64
#else
#define int64 long long
#endif
/**
@file cio.h
@brief Implementation of a byte input-output process (CIO)
@@ -63,7 +70,7 @@ Write some bytes
@param n Number of bytes to write
@return Returns the number of bytes written or 0 if an error occured
*/
unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n);
unsigned int cio_write(opj_cio_t *cio, unsigned int64 v, int n);
/**
Read some bytes
@param cio CIO handle

View File

@@ -64,12 +64,12 @@ typedef struct v4dwt_local {
int cas ;
} v4dwt_t ;
static const float dwt_alpha = 1.586134342f; // 12994
static const float dwt_beta = 0.052980118f; // 434
static const float dwt_gamma = -0.882911075f; // -7233
static const float dwt_delta = -0.443506852f; // -3633
static const float dwt_alpha = 1.586134342f; /* 12994 */
static const float dwt_beta = 0.052980118f; /* 434 */
static const float dwt_gamma = -0.882911075f; /* -7233 */
static const float dwt_delta = -0.443506852f; /* -3633 */
static const float K = 1.230174105f; // 10078
static const float K = 1.230174105f; /* 10078 */
/* FIXME: What is this constant? */
static const float c13318 = 1.625732422f;
@@ -527,7 +527,7 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1
int w = tilec->x1 - tilec->x0;
h.mem = (int *)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int));
h.mem = (int*)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int));
v.mem = h.mem;
while( --numres) {
@@ -570,7 +570,7 @@ static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, in
int count = w->sn;
int i, k;
for(k = 0; k < 2; ++k){
if (count + 3 * x < size && ((long) a & 0x0f) == 0 && ((long) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
/* Fast code path */
for(i = 0; i < count; ++i){
int j = i;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Hervé Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,6 +26,42 @@
#include "opj_includes.h"
/* ==========================================================
Utility functions
==========================================================*/
#ifdef OPJ_CODE_NOT_USED
#ifndef _WIN32
static char*
i2a(unsigned i, char *a, unsigned r) {
if (i/r > 0) a = i2a(i/r,a,r);
*a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
return a+1;
}
/**
Transforms integer i into an ascii string and stores the result in a;
string is encoded in the base indicated by r.
@param i Number to be converted
@param a String result
@param r Base of value; must be in the range 2 - 36
@return Returns a
*/
static char *
_itoa(int i, char *a, int r) {
r = ((r < 2) || (r > 36)) ? 10 : r;
if(i < 0) {
*a = '-';
*i2a(-i, a+1, r) = 0;
}
else *i2a(i, a, r) = 0;
return a;
}
#endif /* !_WIN32 */
#endif
/* ----------------------------------------------------------------------- */
opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) {
if(cinfo) {
opj_event_mgr_t *previous = cinfo->event_mgr;
@@ -37,7 +73,7 @@ opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_
return NULL;
}
bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
opj_msg_callback msg_handler = NULL;
@@ -57,30 +93,29 @@ bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) {
break;
}
if(msg_handler == NULL) {
return false;
return OPJ_FALSE;
}
} else {
return false;
return OPJ_FALSE;
}
if ((fmt != NULL) && (event_mgr != NULL)) {
va_list arg;
int str_length/*, i, j*/; /* UniPG */
char message[MSG_SIZE];
memset(message, 0, MSG_SIZE);
/* initialize the optional parameter list */
va_start(arg, fmt);
/* check the length of the format string */
str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt);
/* parse the format string and put the result in 'message' */
vsprintf(message, fmt, arg); /* UniPG */
str_length = vsnprintf(message, MSG_SIZE, fmt, arg); /* UniPG */
/* deinitialize the optional parameter list */
va_end(arg);
/* output the message to the user program */
msg_handler(message, cinfo->client_data);
if( str_length > -1 && str_length < MSG_SIZE )
msg_handler(message, cinfo->client_data);
else return OPJ_FALSE;
}
return true;
return OPJ_TRUE;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@ Write formatted data to a string and send the string to a user callback.
@param fmt Format-control string (plus optionnal arguments)
@return Returns true if successful, returns false otherwise
*/
bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,6 @@
opj_image_t* opj_image_create0(void) {
opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t));
image->comps=NULL;
return image;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@@ -0,0 +1,118 @@
/*
* $Id: indexbox_manager.h 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#ifndef INDEXBOX_MANAGER_H_
# define INDEXBOX_MANAGER_H_
#include "openjpeg.h"
#include "j2k.h" /* needed to use jp2.h */
#include "jp2.h"
#define JPIP_CIDX 0x63696478 /* Codestream index */
#define JPIP_CPTR 0x63707472 /* Codestream Finder Box */
#define JPIP_MANF 0x6d616e66 /* Manifest Box */
#define JPIP_FAIX 0x66616978 /* Fragment array Index box */
#define JPIP_MHIX 0x6d686978 /* Main Header Index Table */
#define JPIP_TPIX 0x74706978 /* Tile-part Index Table box */
#define JPIP_THIX 0x74686978 /* Tile header Index Table box */
#define JPIP_PPIX 0x70706978 /* Precinct Packet Index Table box */
#define JPIP_PHIX 0x70686978 /* Packet Header index Table */
#define JPIP_FIDX 0x66696478 /* File Index */
#define JPIP_FPTR 0x66707472 /* File Finder */
#define JPIP_PRXY 0x70727879 /* Proxy boxes */
#define JPIP_IPTR 0x69707472 /* Index finder box */
#define JPIP_PHLD 0x70686c64 /* Place holder */
/*
* Write tile-part Index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of tpix box
*/
int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio);
/*
* Write tile header index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information pointer
* @param[in] cio file output handle
* @return length of thix box
*/
int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
/*
* Write precinct packet index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] EPHused true if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of ppix box
*/
int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
/*
* Write packet header index table box (superbox)
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] EPHused true if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of ppix box
*/
int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
/*
* Wriet manifest box (box)
*
* @param[in] second number to be visited
* @param[in] v number of boxes
* @param[in] box box to be manifested
* @param[in] cio file output handle
*/
void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio);
#endif /* !INDEXBOX_MANAGER_H_ */

View File

@@ -6,6 +6,7 @@
* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2006-2007, Parvatha Elangovan
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -228,6 +229,23 @@ Read an unknown marker
@param j2k J2K handle
*/
static void j2k_read_unk(opj_j2k_t *j2k);
/**
Add main header marker information
@param cstr_info Codestream information structure
@param type marker type
@param pos byte offset of marker segment
@param len length of marker segment
*/
static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
/**
Add tile header marker information
@param tileno tile index number
@param cstr_info Codestream information structure
@param type marker type
@param pos byte offset of marker segment
@param len length of marker segment
*/
static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len);
/*@}*/
@@ -258,80 +276,6 @@ char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){
return po->str_prog;
}
void j2k_dump_image(FILE *fd, opj_image_t * img) {
int compno;
fprintf(fd, "image {\n");
fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1);
fprintf(fd, " numcomps=%d\n", img->numcomps);
for (compno = 0; compno < img->numcomps; compno++) {
opj_image_comp_t *comp = &img->comps[compno];
fprintf(fd, " comp %d {\n", compno);
fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy);
fprintf(fd, " prec=%d\n", comp->prec);
//fprintf(fd, " bpp=%d\n", comp->bpp);
fprintf(fd, " sgnd=%d\n", comp->sgnd);
fprintf(fd, " }\n");
}
fprintf(fd, "}\n");
}
void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) {
int tileno, compno, layno, bandno, resno, numbands;
fprintf(fd, "coding parameters {\n");
fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0);
fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy);
fprintf(fd, " tw=%d, th=%d\n", cp->tw, cp->th);
for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
opj_tcp_t *tcp = &cp->tcps[tileno];
fprintf(fd, " tile %d {\n", tileno);
fprintf(fd, " csty=%x\n", tcp->csty);
fprintf(fd, " prg=%d\n", tcp->prg);
fprintf(fd, " numlayers=%d\n", tcp->numlayers);
fprintf(fd, " mct=%d\n", tcp->mct);
fprintf(fd, " rates=");
for (layno = 0; layno < tcp->numlayers; layno++) {
fprintf(fd, "%.1f ", tcp->rates[layno]);
}
fprintf(fd, "\n");
for (compno = 0; compno < img->numcomps; compno++) {
opj_tccp_t *tccp = &tcp->tccps[compno];
fprintf(fd, " comp %d {\n", compno);
fprintf(fd, " csty=%x\n", tccp->csty);
fprintf(fd, " numresolutions=%d\n", tccp->numresolutions);
fprintf(fd, " cblkw=%d\n", tccp->cblkw);
fprintf(fd, " cblkh=%d\n", tccp->cblkh);
fprintf(fd, " cblksty=%x\n", tccp->cblksty);
fprintf(fd, " qmfbid=%d\n", tccp->qmfbid);
fprintf(fd, " qntsty=%d\n", tccp->qntsty);
fprintf(fd, " numgbits=%d\n", tccp->numgbits);
fprintf(fd, " roishift=%d\n", tccp->roishift);
fprintf(fd, " stepsizes=");
numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2;
for (bandno = 0; bandno < numbands; bandno++) {
fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant,
tccp->stepsizes[bandno].expn);
}
fprintf(fd, "\n");
if (tccp->csty & J2K_CCP_CSTY_PRT) {
fprintf(fd, " prcw=");
for (resno = 0; resno < tccp->numresolutions; resno++) {
fprintf(fd, "%d ", tccp->prcw[resno]);
}
fprintf(fd, "\n");
fprintf(fd, " prch=");
for (resno = 0; resno < tccp->numresolutions; resno++) {
fprintf(fd, "%d ", tccp->prch[resno]);
}
fprintf(fd, "\n");
}
fprintf(fd, " }\n");
}
fprintf(fd, " }\n");
}
fprintf(fd, "}\n");
}
/* ----------------------------------------------------------------------- */
static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
char *prog;
@@ -371,6 +315,9 @@ static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){
/** mem allocation for TLM marker*/
int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){
int pino,tileno,totnum_tp=0;
OPJ_ARG_NOT_USED(img_numcomp);
j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int));
for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
int cur_totnum_tp = 0;
@@ -399,12 +346,14 @@ static void j2k_write_soc(opj_j2k_t *j2k) {
opj_cio_t *cio = j2k->cio;
cio_write(cio, J2K_MS_SOC, 2);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio), 0);
/* UniPG>> */
#ifdef USE_JPWL
/* update markers struct */
j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2);
#endif /* USE_JPWL */
/* <<UniPG */
}
@@ -425,7 +374,7 @@ static void j2k_write_siz(opj_j2k_t *j2k) {
opj_cio_t *cio = j2k->cio;
opj_image_t *image = j2k->image;
opj_cp_t *cp = j2k->cp;
cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */
lenp = cio_tell(cio);
cio_skip(cio, 2);
@@ -448,6 +397,9 @@ static void j2k_write_siz(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2); /* Lsiz */
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_SIZ, lenp, len);
}
static void j2k_read_siz(opj_j2k_t *j2k) {
@@ -516,6 +468,12 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
}
#endif /* USE_JPWL */
/* prevent division by zero */
if (!(cp->tdx * cp->tdy)) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid tile size (tdx: %d, tdy: %d)\n", cp->tdx, cp->tdy);
return;
}
image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t));
for (i = 0; i < image->numcomps; i++) {
int tmp, w, h;
@@ -554,6 +512,12 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
}
#endif /* USE_JPWL */
/* prevent division by zero */
if (!(image->comps[i].dx * image->comps[i].dy)) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: invalid component size (dx: %d, dy: %d)\n", image->comps[i].dx, image->comps[i].dy);
return;
}
/* TODO: unused ? */
w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx);
h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy);
@@ -606,7 +570,17 @@ static void j2k_read_siz(opj_j2k_t *j2k) {
#endif /* USE_JPWL */
cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
if (cp->tcps == NULL)
{
opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
return;
}
cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int));
if (cp->tileno == NULL)
{
opj_event_msg(j2k->cinfo, EVT_ERROR, "Out of memory\n");
return;
}
cp->tileno_size = 0;
#ifdef USE_JPWL
@@ -678,6 +652,11 @@ static void j2k_write_com(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2);
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COM, lenp, len);
}
}
@@ -721,12 +700,18 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */
// If user wants to remove more resolutions than the codestream contains, return error
/* If user wants to remove more resolutions than the codestream contains, return error*/
if (cp->reduce >= tccp->numresolutions) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
"of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
j2k->state |= J2K_STATE_ERR;
}
if( tccp->numresolutions > J2K_MAXRLVLS ) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n",
compno, tccp->numresolutions, J2K_MAXRLVLS);
j2k->state |= J2K_STATE_ERR;
tccp->numresolutions = J2K_MAXRLVLS;
}
tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */
tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */
@@ -781,6 +766,10 @@ static void j2k_write_cod(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2); /* Lcod */
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_COD, lenp, len);
}
static void j2k_read_cod(opj_j2k_t *j2k) {
@@ -846,6 +835,12 @@ static void j2k_read_coc(opj_j2k_t *j2k) {
len = cio_read(cio, 2); /* Lcoc */
compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */
if (compno >= image->numcomps) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
"bad component number in COC (%d out of a maximum of %d)\n",
compno, image->numcomps);
return;
}
tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */
j2k_read_cox(j2k, compno);
}
@@ -909,6 +904,15 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
};
};
#else
/* We check whether there are too many subbands */
if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) {
opj_event_msg(j2k->cinfo, EVT_WARNING ,
"bad number of subbands in Sqcx (%d) regarding to J2K_MAXBANDS (%d) \n"
"- limiting number of bands to J2K_MAXBANDS and try to move to the next markers\n", numbands, J2K_MAXBANDS);
}
#endif /* USE_JPWL */
for (bandno = 0; bandno < numbands; bandno++) {
@@ -921,8 +925,10 @@ static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) {
expn = tmp >> 11;
mant = tmp & 0x7ff;
}
tccp->stepsizes[bandno].expn = expn;
tccp->stepsizes[bandno].mant = mant;
if (bandno < J2K_MAXBANDS){
tccp->stepsizes[bandno].expn = expn;
tccp->stepsizes[bandno].mant = mant;
}
}
/* Add Antonin : if scalar_derived -> compute other stepsizes */
@@ -950,6 +956,9 @@ static void j2k_write_qcd(opj_j2k_t *j2k) {
cio_seek(cio, lenp);
cio_write(cio, len, 2); /* Lqcd */
cio_seek(cio, lenp + len);
if(j2k->cstr_info)
j2k_add_mhmarker(j2k->cstr_info, J2K_MS_QCD, lenp, len);
}
static void j2k_read_qcd(opj_j2k_t *j2k) {
@@ -986,7 +995,7 @@ static void j2k_read_qcc(opj_j2k_t *j2k) {
int len, compno;
int numcomp = j2k->image->numcomps;
opj_cio_t *cio = j2k->cio;
len = cio_read(cio, 2); /* Lqcc */
compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */
@@ -1013,9 +1022,16 @@ static void j2k_read_qcc(opj_j2k_t *j2k) {
/* keep your private count of tiles */
backup_compno++;
};
}
#endif /* USE_JPWL */
if ((compno < 0) || (compno >= numcomp)) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
"bad component number in QCC (%d out of a maximum of %d)\n",
compno, j2k->image->numcomps);
return;
}
j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
}
@@ -1271,6 +1287,10 @@ static void j2k_write_sot(opj_j2k_t *j2k) {
j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2);
#endif /* USE_JPWL */
/* <<UniPG */
if( j2k->cstr_info && j2k->cur_tp_num==0){
j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOT, lenp, len);
}
}
static void j2k_read_sot(opj_j2k_t *j2k) {
@@ -1354,6 +1374,11 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
partno = cio_read(cio, 1);
numparts = cio_read(cio, 1);
if (partno >= numparts) {
opj_event_msg(j2k->cinfo, EVT_WARNING, "SOT marker inconsistency in tile %d: tile-part index greater (%d) than number of tile-parts (%d)\n", tileno, partno, numparts);
numparts = partno+1;
}
j2k->curtileno = tileno;
j2k->cur_tp_num = partno;
@@ -1369,15 +1394,14 @@ static void j2k_read_sot(opj_j2k_t *j2k) {
j2k->cstr_info->tile[tileno].tileno = tileno;
j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12;
j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1;
j2k->cstr_info->tile[tileno].num_tps = numparts;
if (numparts)
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t));
else
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10)
}
else {
} else {
j2k->cstr_info->tile[tileno].end_pos += totlen;
}
}
j2k->cstr_info->tile[tileno].num_tps = numparts;
if (numparts)
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, numparts * sizeof(opj_tp_info_t));
else
j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_realloc(j2k->cstr_info->tile[tileno].tp, 10 * sizeof(opj_tp_info_t)); /* Fixme (10)*/
j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12;
j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos =
j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1;
@@ -1413,6 +1437,11 @@ static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) {
tcd->cur_tp_num = j2k->cur_tp_num;
cio_write(cio, J2K_MS_SOD, 2);
if( j2k->cstr_info && j2k->cur_tp_num==0){
j2k_add_tlmarker( j2k->curtileno, j2k->cstr_info, J2K_MS_SOD, cio_tell(cio), 0);
}
if (j2k->curtileno == 0) {
j2k->sod_start = cio_tell(cio) + j2k->pos_correction;
}
@@ -1489,6 +1518,24 @@ static void j2k_read_sod(opj_j2k_t *j2k) {
truncate = 1; /* Case of a truncate codestream */
}
{/* chop padding bytes: */
unsigned char *s, *e;
s = cio_getbp(cio);
e = s + len;
if(len > 8) s = e - 8;
if(e[-2] == 0x00 && e[-1] == 0x00) /* padding bytes */
{
while(e > s)
{
if(e[-2] == 0xff && e[-1] == 0xd9) break;
--len; --e; truncate = 1;
}
}
}
data = j2k->tile_data[curtileno];
data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
@@ -1548,6 +1595,13 @@ static void j2k_read_rgn(opj_j2k_t *j2k) {
};
#endif /* USE_JPWL */
if (compno >= numcomps) {
opj_event_msg(j2k->cinfo, EVT_ERROR,
"bad component number in RGN (%d out of a maximum of %d)\n",
compno, j2k->image->numcomps);
return;
}
tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */
}
@@ -1566,7 +1620,7 @@ static void j2k_write_eoc(opj_j2k_t *j2k) {
static void j2k_read_eoc(opj_j2k_t *j2k) {
int i, tileno;
bool success;
opj_bool success = OPJ_FALSE;
/* if packets should be decoded */
if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) {
@@ -1574,12 +1628,17 @@ static void j2k_read_eoc(opj_j2k_t *j2k) {
tcd_malloc_decode(tcd, j2k->image, j2k->cp);
for (i = 0; i < j2k->cp->tileno_size; i++) {
tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info);
tileno = j2k->cp->tileno[i];
success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
opj_free(j2k->tile_data[tileno]);
j2k->tile_data[tileno] = NULL;
tcd_free_decode_tile(tcd, i);
if (success == false) {
if (j2k->cp->tileno[i] != -1)
{
tileno = j2k->cp->tileno[i];
success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info);
opj_free(j2k->tile_data[tileno]);
j2k->tile_data[tileno] = NULL;
tcd_free_decode_tile(tcd, i);
}
else
success = OPJ_FALSE;
if (success == OPJ_FALSE) {
j2k->state |= J2K_STATE_ERR;
break;
}
@@ -1749,6 +1808,14 @@ void j2k_destroy_decompress(opj_j2k_t *j2k) {
opj_free(j2k->tile_len);
}
if(j2k->tile_data != NULL) {
if(j2k->cp != NULL) {
for (i = 0; i < j2k->cp->tileno_size; i++) {
int tileno = j2k->cp->tileno[i];
opj_free(j2k->tile_data[tileno]);
j2k->tile_data[tileno] = NULL;
}
}
opj_free(j2k->tile_data);
}
if(j2k->default_tcp != NULL) {
@@ -1834,7 +1901,7 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
if (j2k->cp->correct) {
int orig_pos = cio_tell(cio);
bool status;
opj_bool status;
/* call the corrector */
status = jpwl_correct(j2k);
@@ -1868,18 +1935,24 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
#endif /* USE_JPWL */
if (id >> 8 != 0xff) {
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
return 0;
if(cio_numbytesleft(cio) != 0) /* not end of file reached and no EOC */
{
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
opj_image_destroy(image);
return 0;
}
opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
j2k->state = J2K_STATE_NEOC;
break;
}
e = j2k_dec_mstab_lookup(id);
// Check if the marker is known
/* Check if the marker is known*/
if (!(j2k->state & e->states)) {
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id);
return 0;
}
// Check if the decoding is limited to the main header
/* Check if the decoding is limited to the main header*/
if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) {
opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n");
return image;
@@ -1889,7 +1962,10 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
(*e->handler)(j2k);
}
if (j2k->state & J2K_STATE_ERR)
{
opj_image_destroy(image);
return NULL;
}
if (j2k->state == J2K_STATE_MT) {
break;
@@ -1905,7 +1981,6 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
if (j2k->state != J2K_STATE_MT) {
opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
}
return image;
}
@@ -1917,9 +1992,10 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre
opj_image_t *image = NULL;
opj_jpt_msg_header_t header;
int position;
opj_common_ptr cinfo = j2k->cinfo;
OPJ_ARG_NOT_USED(cstr_info);
j2k->cio = cio;
/* create an empty image */
@@ -1961,9 +2037,15 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre
id = cio_read(cio, 2);
if (id >> 8 != 0xff) {
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
return 0;
if(cio_numbytesleft(cio) != 0) /* no end of file reached and no EOC */
{
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
opj_image_destroy(image);
return 0;
}
opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
j2k->state = J2K_STATE_NEOC;
break;
}
e = j2k_dec_mstab_lookup(id);
if (!(j2k->state & e->states)) {
@@ -2110,12 +2192,12 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
int i;
/* set JPWL on */
cp->epc_on = true;
cp->info_on = false; /* no informative technique */
cp->epc_on = OPJ_TRUE;
cp->info_on = OPJ_FALSE; /* no informative technique */
/* set EPB on */
if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) {
cp->epb_on = true;
cp->epb_on = OPJ_TRUE;
cp->hprot_MH = parameters->jpwl_hprot_MH;
for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) {
@@ -2136,7 +2218,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
/* set ESD writing */
if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) {
cp->esd_on = true;
cp->esd_on = OPJ_TRUE;
cp->sens_size = parameters->jpwl_sens_size;
cp->sens_addr = parameters->jpwl_sens_addr;
@@ -2150,10 +2232,10 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
}
/* always set RED writing to false: we are at the encoder */
cp->red_on = false;
cp->red_on = OPJ_FALSE;
} else {
cp->epc_on = false;
cp->epc_on = OPJ_FALSE;
}
#endif /* USE_JPWL */
@@ -2226,10 +2308,10 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
if(parameters->cp_cinema)
{
//Precinct size for lowest frequency subband=128
/*Precinct size for lowest frequency subband=128*/
tccp->prcw[0] = 7;
tccp->prch[0] = 7;
//Precinct size at all other resolutions = 256
/*Precinct size at all other resolutions = 256*/
for (j = 1; j < tccp->numresolutions; j++) {
tccp->prcw[j] = 8;
tccp->prch[j] = 8;
@@ -2271,7 +2353,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
}
p++;
/*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
} //end for
} /*end for*/
} else {
for (j = 0; j < tccp->numresolutions; j++) {
tccp->prcw[j] = 15;
@@ -2285,7 +2367,7 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
}
}
bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
int tileno, compno;
opj_cp_t *cp = NULL;
@@ -2296,8 +2378,6 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
cp = j2k->cp;
/* j2k_dump_cp(stdout, image, cp); */
/* INDEX >> */
j2k->cstr_info = cstr_info;
if (cstr_info) {
@@ -2394,6 +2474,9 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
/* INDEX >> */
if(cstr_info) {
cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction;
cstr_info->tile[j2k->curtileno].maxmarknum = 10;
cstr_info->tile[j2k->curtileno].marker = (opj_marker_info_t *) opj_malloc(cstr_info->tile[j2k->curtileno].maxmarknum * sizeof(opj_marker_info_t));
cstr_info->tile[j2k->curtileno].marknum = 0;
}
/* << INDEX */
@@ -2500,11 +2583,46 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre
}
#endif /* USE_JPWL */
return true;
return OPJ_TRUE;
}
static void j2k_add_mhmarker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
if (!cstr_info)
return;
/* expand the list? */
if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F);
cstr_info->marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum);
}
/* add the marker */
cstr_info->marker[cstr_info->marknum].type = type;
cstr_info->marker[cstr_info->marknum].pos = pos;
cstr_info->marker[cstr_info->marknum].len = len;
cstr_info->marknum++;
}
static void j2k_add_tlmarker( int tileno, opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
opj_marker_info_t *marker;
if (!cstr_info)
return;
/* expand the list? */
if ((cstr_info->tile[tileno].marknum + 1) > cstr_info->tile[tileno].maxmarknum) {
cstr_info->tile[tileno].maxmarknum = 100 + (int) ((float) cstr_info->tile[tileno].maxmarknum * 1.0F);
cstr_info->tile[tileno].marker = (opj_marker_info_t*)opj_realloc(cstr_info->tile[tileno].marker, cstr_info->maxmarknum);
}
marker = &(cstr_info->tile[tileno].marker[cstr_info->tile[tileno].marknum]);
/* add the marker */
marker->type = type;
marker->pos = pos;
marker->len = len;
cstr_info->tile[tileno].marknum++;
}

View File

@@ -265,15 +265,15 @@ typedef struct opj_cp {
/* UniPG>> */
#ifdef USE_JPWL
/** enables writing of EPC in MH, thus activating JPWL */
bool epc_on;
opj_bool epc_on;
/** enables writing of EPB, in case of activated JPWL */
bool epb_on;
opj_bool epb_on;
/** enables writing of ESD, in case of activated JPWL */
bool esd_on;
opj_bool esd_on;
/** enables writing of informative techniques of ESD, in case of activated JPWL */
bool info_on;
opj_bool info_on;
/** enables writing of RED, in case of activated JPWL */
bool red_on;
opj_bool red_on;
/** error protection method for MH (0,1,16,32,37-128) */
int hprot_MH;
/** tile number of header protection specification (>=0) */
@@ -299,7 +299,7 @@ typedef struct opj_cp {
/** sensitivity methods for TPHs (-1,0-7) */
int sens_TPH[JPWL_MAX_NO_TILESPECS];
/** enables JPWL correction at the decoder */
bool correct;
opj_bool correct;
/** expected number of components at the decoder */
int exp_comps;
/** maximum number of tiles at the decoder */
@@ -436,10 +436,8 @@ Encode an image into a JPEG-2000 codestream
@param cstr_info Codestream information structure if required, NULL otherwise
@return Returns true if successful, returns false otherwise
*/
bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
void j2k_dump_image(FILE *fd, opj_image_t * img);
void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,18 +24,18 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include "opj_includes.h"
double opj_clock(void) {
#ifdef WIN32
/* WIN32: use QueryPerformance (very accurate) */
#ifdef _WIN32
/* _WIN32: use QueryPerformance (very accurate) */
LARGE_INTEGER freq , t ;
/* freq is the clock speed of the CPU */
QueryPerformanceFrequency(&freq) ;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

File diff suppressed because it is too large Load Diff

View File

@@ -46,11 +46,64 @@
#define JP2_COLR 0x636f6c72 /**< Colour specification box */
#define JP2_JP2C 0x6a703263 /**< Contiguous codestream box */
#define JP2_URL 0x75726c20 /**< URL box */
#define JP2_DBTL 0x6474626c /**< ??? */
#define JP2_DTBL 0x6474626c /**< Data Reference box */
#define JP2_BPCC 0x62706363 /**< Bits per component box */
#define JP2_JP2 0x6a703220 /**< File type fields */
#define JP2_PCLR 0x70636c72 /**< Palette box */
#define JP2_CMAP 0x636d6170 /**< Component Mapping box */
#define JP2_CDEF 0x63646566 /**< Channel Definition box */
/* ----------------------------------------------------------------------- */
/**
Channel description: channel index, type, assocation
*/
typedef struct opj_jp2_cdef_info
{
unsigned short cn, typ, asoc;
} opj_jp2_cdef_info_t;
/**
Channel descriptions and number of descriptions
*/
typedef struct opj_jp2_cdef
{
opj_jp2_cdef_info_t *info;
unsigned short n;
} opj_jp2_cdef_t;
/**
Component mappings: channel index, mapping type, palette index
*/
typedef struct opj_jp2_cmap_comp
{
unsigned short cmp;
unsigned char mtyp, pcol;
} opj_jp2_cmap_comp_t;
/**
Palette data: table entries, palette columns
*/
typedef struct opj_jp2_pclr
{
unsigned int *entries;
unsigned char *channel_sign;
unsigned char *channel_size;
opj_jp2_cmap_comp_t *cmap;
unsigned short nr_entries, nr_channels;
} opj_jp2_pclr_t;
/**
Collector for ICC profile, palette, component mapping, channel description
*/
typedef struct opj_jp2_color
{
unsigned char *icc_profile_buf;
int icc_profile_len;
opj_jp2_cdef_t *jp2_cdef;
opj_jp2_pclr_t *jp2_pclr;
unsigned char jp2_has_colr;
} opj_jp2_color_t;
/**
JP2 component
@@ -87,6 +140,8 @@ typedef struct opj_jp2 {
opj_jp2_comps_t *comps;
unsigned int j2k_codestream_offset;
unsigned int j2k_codestream_length;
opj_bool jpip_on;
opj_bool ignore_pclr_cmap_cdef;
} opj_jp2_t;
/**
@@ -111,9 +166,10 @@ void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
Read the JP2H box - JP2 Header box (used in MJ2)
@param jp2 JP2 handle
@param cio Input buffer stream
@param ext Collector for profile, cdef and pclr data
@return Returns true if successful, returns false otherwise
*/
bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio);
opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color);
/**
Creates a JP2 decompression structure
@param cinfo Codec context info
@@ -139,7 +195,7 @@ Decode an image from a JPEG-2000 file stream
@param cstr_info Codestream information structure if required, NULL otherwise
@return Returns a decoded image if successful, returns NULL otherwise
*/
opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info);
/**
Creates a JP2 compression structure
@param cinfo Codec context info
@@ -167,7 +223,8 @@ Encode an image into a JPEG-2000 file stream
@param cstr_info Codestream information structure if required, NULL otherwise
@return Returns true if successful, returns false otherwise
*/
bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -521,22 +521,21 @@ void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
unsigned int c;
unsigned int *ip;
unsigned char *end = mqc->end - 1;
mqc->buffer = opj_realloc(mqc->buffer, (2 * len + 1) * sizeof(unsigned int));
mqc->buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(unsigned int));
ip = (unsigned int *) mqc->buffer;
while (bp != end) {
while (bp < end) {
c = *(bp + 1);
if (*bp == 0xff) {
if (c > 0x8f) {
*ip = 0x0000ff18;
break;
} else {
bp++;
*ip = 0x00000017 | (c << 9);
}
} else {
bp++;
*ip = 0x00000018 | (c << 8);
}
bp++;
ip++;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,17 +24,22 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#endif /* WIN32 */
#endif /* _WIN32 */
#include "opj_config.h"
#include "opj_includes.h"
/* ---------------------------------------------------------------------- */
#ifdef WIN32
#ifdef _WIN32
#ifndef OPJ_STATIC
BOOL APIENTRY
DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
OPJ_ARG_NOT_USED(lpReserved);
OPJ_ARG_NOT_USED(hModule);
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH :
break;
@@ -48,19 +53,19 @@ DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
return TRUE;
}
#endif /* OPJ_STATIC */
#endif /* WIN32 */
#endif /* _WIN32 */
/* ---------------------------------------------------------------------- */
const char* OPJ_CALLCONV opj_version(void) {
return OPENJPEG_VERSION;
return PACKAGE_VERSION;
}
opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) {
opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_calloc(1, sizeof(opj_dinfo_t));
if(!dinfo) return NULL;
dinfo->is_decompressor = true;
dinfo->is_decompressor = OPJ_TRUE;
switch(format) {
case CODEC_J2K:
case CODEC_JPT:
@@ -120,9 +125,10 @@ void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *paramete
parameters->decod_format = -1;
parameters->cod_format = -1;
parameters->flags = 0;
/* UniPG>> */
#ifdef USE_JPWL
parameters->jpwl_correct = false;
parameters->jpwl_correct = OPJ_FALSE;
parameters->jpwl_exp_comps = JPWL_EXPECTED_COMPONENTS;
parameters->jpwl_max_tiles = JPWL_MAXIMUM_TILES;
#endif /* USE_JPWL */
@@ -159,7 +165,7 @@ opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *ci
case CODEC_JPT:
return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info);
case CODEC_JP2:
return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info);
return opj_jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info);
case CODEC_UNKNOWN:
default:
break;
@@ -171,7 +177,7 @@ opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *ci
opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) {
opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_calloc(1, sizeof(opj_cinfo_t));
if(!cinfo) return NULL;
cinfo->is_decompressor = false;
cinfo->is_decompressor = OPJ_FALSE;
switch(format) {
case CODEC_J2K:
/* get a J2K coder handle */
@@ -243,10 +249,10 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete
parameters->cp_disto_alloc = 0;
parameters->cp_fixed_alloc = 0;
parameters->cp_fixed_quality = 0;
parameters->jpip_on = OPJ_FALSE;
/* UniPG>> */
#ifdef USE_JPWL
parameters->jpwl_epc_on = false;
parameters->jpwl_epc_on = OPJ_FALSE;
parameters->jpwl_hprot_MH = -1; /* -1 means unassigned */
{
int i;
@@ -296,7 +302,7 @@ void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *param
}
}
bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) {
opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) {
if (index != NULL)
opj_event_msg((opj_common_ptr)cinfo, EVT_WARNING, "Set index to NULL when calling the opj_encode function.\n"
"To extract the index, use the opj_encode_with_info() function.\n"
@@ -304,20 +310,20 @@ bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *im
return opj_encode_with_info(cinfo, cio, image, NULL);
}
bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
if(cinfo && cio && image) {
switch(cinfo->codec_format) {
case CODEC_J2K:
return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, cio, image, cstr_info);
case CODEC_JP2:
return jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info);
return opj_jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info);
case CODEC_JPT:
case CODEC_UNKNOWN:
default:
break;
}
}
return false;
return OPJ_FALSE;
}
void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) {
@@ -328,6 +334,7 @@ void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) {
opj_free(tile_info->thresh);
opj_free(tile_info->packet);
opj_free(tile_info->tp);
opj_free(tile_info->marker);
}
opj_free(cstr_info->tile);
opj_free(cstr_info->marker);

View File

@@ -6,6 +6,7 @@
* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2006-2007, Parvatha Elangovan
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +33,6 @@
#ifndef OPENJPEG_H
#define OPENJPEG_H
#define OPENJPEG_VERSION "1.4.0.635"
/*
==========================================================
@@ -40,7 +40,7 @@
==========================================================
*/
#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__))
#if defined(OPJ_STATIC) || !defined(_WIN32)
#define OPJ_API
#define OPJ_CALLCONV
#else
@@ -53,38 +53,19 @@ that uses this DLL. This way any other project whose source files include this f
OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
defined with this macro as being exported.
*/
#ifdef OPJ_EXPORTS
#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
#define OPJ_API __declspec(dllexport)
#else
#define OPJ_API __declspec(dllimport)
#endif /* OPJ_EXPORTS */
#endif /* !OPJ_STATIC || !WIN32 */
#endif /* !OPJ_STATIC || !_WIN32 */
#ifndef __cplusplus
#if defined(HAVE_STDBOOL_H)
/*
The C language implementation does correctly provide the standard header
file "stdbool.h".
*/
#include <stdbool.h>
#else
/*
The C language implementation does not provide the standard header file
"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this
braindamage below.
*/
#if !defined(bool)
#define bool int
#endif
#if !defined(true)
#define true 1
#endif
#if !defined(false)
#define false 0
#endif
#endif
#endif /* __cplusplus */
typedef int opj_bool;
#define OPJ_TRUE 1
#define OPJ_FALSE 0
/* Avoid compile-time warning because parameter is not used */
#define OPJ_ARG_NOT_USED(x) (void)(x)
/*
==========================================================
Useful constant definitions
@@ -154,14 +135,18 @@ typedef enum COLOR_SPACE {
CLRSPC_SYCC = 3 /**< YUV */
} OPJ_COLOR_SPACE;
#define ENUMCS_SRGB 16
#define ENUMCS_GRAY 17
#define ENUMCS_SYCC 18
/**
Supported codec
*/
typedef enum CODEC_FORMAT {
CODEC_UNKNOWN = -1, /**< place-holder */
CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */
CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */
CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */
CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */
CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */
CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */
} OPJ_CODEC_FORMAT;
/**
@@ -244,7 +229,7 @@ Compression parameters
*/
typedef struct opj_cparameters {
/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */
bool tile_size_on;
opj_bool tile_size_on;
/** XTOsiz */
int cp_tx0;
/** YTOsiz */
@@ -326,7 +311,7 @@ typedef struct opj_cparameters {
/**@name JPWL encoding parameters */
/*@{*/
/** enables writing of EPC in MH, thus activating JPWL */
bool jpwl_epc_on;
opj_bool jpwl_epc_on;
/** error protection method for MH (0,1,16,32,37-128) */
int jpwl_hprot_MH;
/** tile number of header protection specification (>=0) */
@@ -366,8 +351,12 @@ typedef struct opj_cparameters {
char tp_flag;
/** MCT (multiple component transform) */
char tcp_mct;
/** Enable JPIP indexing*/
opj_bool jpip_on;
} opj_cparameters_t;
#define OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG 0x0001
/**
Decompression parameters
*/
@@ -404,7 +393,7 @@ typedef struct opj_dparameters {
/**@name JPWL decoding parameters */
/*@{*/
/** activates the JPWL correction capabilities */
bool jpwl_correct;
opj_bool jpwl_correct;
/** expected number of components */
int jpwl_exp_comps;
/** maximum number of tiles */
@@ -420,6 +409,7 @@ typedef struct opj_dparameters {
*/
OPJ_LIMIT_DECODING cp_limit_decoding;
unsigned int flags;
} opj_dparameters_t;
/** Common fields between JPEG-2000 compression and decompression master structs. */
@@ -427,7 +417,7 @@ typedef struct opj_dparameters {
#define opj_common_fields \
opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\
void * client_data; /**< Available for use by application */\
bool is_decompressor; /**< So common code can tell which is which */\
opj_bool is_decompressor; /**< So common code can tell which is which */\
OPJ_CODEC_FORMAT codec_format; /**< selected codec */\
void *j2k_handle; /**< pointer to the J2K codec */\
void *jp2_handle; /**< pointer to the JP2 codec */\
@@ -555,6 +545,10 @@ typedef struct opj_image {
OPJ_COLOR_SPACE color_space;
/** image components */
opj_image_comp_t *comps;
/** 'restricted' ICC profile */
unsigned char *icc_profile_buf;
/** size of ICC profile */
int icc_profile_len;
} opj_image_t;
/**
@@ -601,6 +595,21 @@ typedef struct opj_packet_info {
double disto;
} opj_packet_info_t;
/* UniPG>> */
/**
Marker structure
*/
typedef struct opj_marker_info_t {
/** marker type */
unsigned short int type;
/** position in codestream */
int pos;
/** length, marker val included */
int len;
} opj_marker_info_t;
/* <<UniPG */
/**
Index structure : Information concerning tile-parts
*/
@@ -645,26 +654,18 @@ typedef struct opj_tile_info {
int numpix;
/** add fixed_quality */
double distotile;
/** number of markers */
int marknum;
/** list of markers */
opj_marker_info_t *marker;
/** actual size of markers array */
int maxmarknum;
/** number of tile parts */
int num_tps;
/** information concerning tile parts */
opj_tp_info_t *tp;
} opj_tile_info_t;
/* UniPG>> */
/**
Marker structure
*/
typedef struct opj_marker_info_t {
/** marker type */
unsigned short int type;
/** position in codestream */
int pos;
/** length, marker val included */
int len;
} opj_marker_info_t;
/* <<UniPG */
/**
Index structure of the codestream
*/
@@ -883,13 +884,13 @@ Setup the encoder parameters using the current image and using user parameters.
OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image);
/**
Encode an image into a JPEG-2000 codestream
@param cinfo compressor handle
3@param cinfo compressor handle
@param cio Output buffer stream
@param image Image to encode
@param index Depreacted -> Set to NULL. To extract index, used opj_encode_wci()
@return Returns true if successful, returns false otherwise
*/
OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index);
OPJ_API opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index);
/**
Encode an image into a JPEG-2000 codestream and extract the codestream information
@param cinfo compressor handle
@@ -898,13 +899,14 @@ Encode an image into a JPEG-2000 codestream and extract the codestream informati
@param cstr_info Codestream information structure if needed afterwards, NULL otherwise
@return Returns true if successful, returns false otherwise
*/
OPJ_API bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
OPJ_API opj_bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
/**
Destroy Codestream information after compression or decompression
@param cstr_info Codestream information structure
*/
OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,36 @@
/* create config.h for CMake */
#define PACKAGE_VERSION "1.5.2"
#define HAVE_INTTYPES_H
#define HAVE_MEMORY_H
#define HAVE_STDINT_H
#define HAVE_STDLIB_H
#define HAVE_STRINGS_H
#define HAVE_STRING_H
#define HAVE_SYS_STAT_H
#define HAVE_SYS_TYPES_H
#define HAVE_UNISTD_H
/* #define HAVE_LIBPNG */
/* #define HAVE_PNG_H */
/* #define HAVE_LIBTIFF */
/* #define HAVE_TIFF_H */
/* #undef HAVE_LIBLCMS1 */
/* #undef HAVE_LIBLCMS2 */
/* #undef HAVE_LCMS1_H */
/* #undef HAVE_LCMS2_H */
/* Byte order. */
/* All compilers that support Mac OS X define either __BIG_ENDIAN__ or
* __LITTLE_ENDIAN__ to match the endianness of the architecture being
* compiled for. This is not necessarily the same as the architecture of the
* machine doing the building. In order to support Universal Binaries on
* Mac OS X, we prefer those defines to decide the endianness.
* On other platforms we use the result of the TRY_RUN. */
#if !defined(__APPLE__)
/* #undef OPJ_BIG_ENDIAN */
#elif defined(__BIG_ENDIAN__)
# define OPJ_BIG_ENDIAN
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -89,20 +89,25 @@ Most compilers implement their own version of this keyword ...
/* MSVC and Borland C do not have lrintf */
#if defined(_MSC_VER) || defined(__BORLANDC__)
static INLINE long lrintf(float f){
int i;
_asm{
fld f
fistp i
};
return i;
#ifdef _M_X64
return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f));
#else
int i;
_asm{
fld f
fistp i
};
return i;
#endif
}
#endif
#include "j2k_lib.h"
#include "opj_malloc.h"
#include "event.h"
#include "bio.h"
#include "cio.h"
#include "image.h"
@@ -123,9 +128,12 @@ static INLINE long lrintf(float f){
#include "int.h"
#include "fix.h"
#include "cidx_manager.h"
#include "indexbox_manager.h"
/* JPWL>> */
#ifdef USE_JPWL
#include "../jpwl/jpwl.h"
#include "./jpwl/jpwl.h"
#endif /* USE_JPWL */
/* <<JPWL */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Herv<EFBFBD> Drolon, FreeImage Team
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
* All rights reserved.
*
@@ -69,7 +69,7 @@ Allocate memory aligned to a 16 byte boundry
@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available
*/
/* FIXME: These should be set with cmake tests, but we're currently not requiring use of cmake */
#ifdef WIN32
#ifdef _WIN32
/* Someone should tell the mingw people that their malloc.h ought to provide _mm_malloc() */
#ifdef __GNUC__
#include <mm_malloc.h>
@@ -80,11 +80,13 @@ Allocate memory aligned to a 16 byte boundry
#define HAVE_MM_MALLOC
#endif
#endif
#else /* Not WIN32 */
#else /* Not _WIN32 */
#if defined(__sun)
#define HAVE_MEMALIGN
#elif defined(__FreeBSD__)
#define HAVE_POSIX_MEMALIGN
/* Linux x86_64 and OSX always align allocations to 16 bytes */
#elif !defined(__amd64__) && !defined(__APPLE__)
#elif !defined(__amd64__) && !defined(__APPLE__) && !defined(_AIX)
#define HAVE_MEMALIGN
#include <malloc.h>
#endif
@@ -130,22 +132,22 @@ Allocate memory aligned to a 16 byte boundry
/**
Reallocate memory blocks.
@param memblock Pointer to previously allocated memory block
@param size New size in bytes
@param m Pointer to previously allocated memory block
@param s New size in bytes
@return Returns a void pointer to the reallocated (and possibly moved) memory block
*/
#ifdef ALLOC_PERF_OPT
void * OPJ_CALLCONV opj_realloc(void * _Memory, size_t NewSize);
void * OPJ_CALLCONV opj_realloc(void * m, size_t s);
#else
#define opj_realloc(m, s) realloc(m, s)
#endif
/**
Deallocates or frees a memory block.
@param memblock Previously allocated memory block to be freed
@param m Previously allocated memory block to be freed
*/
#ifdef ALLOC_PERF_OPT
void OPJ_CALLCONV opj_free(void * _Memory);
void OPJ_CALLCONV opj_free(void * m);
#else
#define opj_free(m) free(m)
#endif

View File

@@ -0,0 +1,170 @@
/*
* $Id: phix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <stdlib.h>
#include <math.h>
#include "opj_includes.h"
/*
* Write faix box of phix
*
* @param[in] coff offset of j2k codestream
* @param[in] compno component number
* @param[in] cstr_info codestream information
* @param[in] EPHused true if if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of faix box
*/
int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
int write_phix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp=0, compno, i;
opj_jp2_box_t *box;
box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t));
for( i=0;i<2;i++){
if (i) cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_PHIX, 4); /* PHIX */
write_manf( i, cstr_info.numcomps, box, cio);
for( compno=0; compno<cstr_info.numcomps; compno++){
box[compno].length = write_phixfaix( coff, compno, cstr_info, EPHused, j2klen, cio);
box[compno].type = JPIP_FAIX;
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free(box);
return len;
}
int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp, tileno, version, i, nmax, size_of_coding; /* 4 or 8 */
opj_tile_info_t *tile_Idx;
opj_packet_info_t packet;
int resno, precno, layno, num_packet;
int numOfres, numOfprec, numOflayers;
packet.end_ph_pos = packet.start_pos = -1;
(void)EPHused; /* unused ? */
if( j2klen > pow( 2.0, 32)){
size_of_coding = 8;
version = 1;
}
else{
size_of_coding = 4;
version = 0;
}
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version,1); /* Version 0 = 4 bytes */
nmax = 0;
for( i=0; i<=cstr_info.numdecompos[compno]; i++)
nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
cio_write( cio, nmax, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
tile_Idx = &cstr_info.tile[ tileno];
num_packet = 0;
numOfres = cstr_info.numdecompos[compno] + 1;
for( resno=0; resno<numOfres ; resno++){
numOfprec = tile_Idx->pw[resno]*tile_Idx->ph[resno];
for( precno=0; precno<numOfprec; precno++){
numOflayers = cstr_info.numlayers;
for( layno=0; layno<numOflayers; layno++){
switch ( cstr_info.prog){
case LRCP:
packet = tile_Idx->packet[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RLCP:
packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RPCL:
packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno];
break;
case PCRL:
packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno];
break;
case CPRL:
packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno];
break;
default:
fprintf( stderr, "failed to ppix indexing\n");
}
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_ph_pos-packet.start_pos+1, size_of_coding); /* length */
num_packet++;
}
}
}
/* PADDING */
while( num_packet < nmax){
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
num_packet++;
}
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}

View File

@@ -43,31 +43,31 @@ Get next packet in layer-resolution-component-precinct order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_lrcp(opj_pi_iterator_t * pi);
static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi);
/**
Get next packet in resolution-layer-component-precinct order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_rlcp(opj_pi_iterator_t * pi);
static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi);
/**
Get next packet in resolution-precinct-component-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_rpcl(opj_pi_iterator_t * pi);
static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi);
/**
Get next packet in precinct-component-resolution-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_pcrl(opj_pi_iterator_t * pi);
static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi);
/**
Get next packet in component-precinct-resolution-layer order.
@param pi packet iterator to modify
@return returns false if pi pointed to the last packet or else returns true
*/
static bool pi_next_cprl(opj_pi_iterator_t * pi);
static opj_bool pi_next_cprl(opj_pi_iterator_t * pi);
/*@}*/
@@ -79,7 +79,7 @@ static bool pi_next_cprl(opj_pi_iterator_t * pi);
==========================================================
*/
static bool pi_next_lrcp(opj_pi_iterator_t * pi) {
static opj_bool pi_next_lrcp(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -108,7 +108,7 @@ static bool pi_next_lrcp(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -116,10 +116,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_rlcp(opj_pi_iterator_t * pi) {
static opj_bool pi_next_rlcp(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -147,7 +147,7 @@ static bool pi_next_rlcp(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -155,10 +155,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_rpcl(opj_pi_iterator_t * pi) {
static opj_bool pi_next_rpcl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -229,7 +229,7 @@ if (!pi->tp_on){
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -238,10 +238,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_pcrl(opj_pi_iterator_t * pi) {
static opj_bool pi_next_pcrl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -310,7 +310,7 @@ static bool pi_next_pcrl(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -319,10 +319,10 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
static bool pi_next_cprl(opj_pi_iterator_t * pi) {
static opj_bool pi_next_cprl(opj_pi_iterator_t * pi) {
opj_pi_comp_t *comp = NULL;
opj_pi_resolution_t *res = NULL;
long index = 0;
@@ -389,7 +389,7 @@ static bool pi_next_cprl(opj_pi_iterator_t * pi) {
index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
if (!pi->include[index]) {
pi->include[index] = 1;
return true;
return OPJ_TRUE;
}
LABEL_SKIP:;
}
@@ -398,7 +398,7 @@ LABEL_SKIP:;
}
}
return false;
return OPJ_FALSE;
}
/*
@@ -707,7 +707,7 @@ void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
}
}
bool pi_next(opj_pi_iterator_t * pi) {
opj_bool pi_next(opj_pi_iterator_t * pi) {
switch (pi->poc.prg) {
case LRCP:
return pi_next_lrcp(pi);
@@ -720,13 +720,13 @@ bool pi_next(opj_pi_iterator_t * pi) {
case CPRL:
return pi_next_cprl(pi);
case PROG_UNKNOWN:
return false;
return OPJ_FALSE;
}
return false;
return OPJ_FALSE;
}
bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){
opj_bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp){
char prog[4];
int i;
int incr_top=1,resetX=0;
@@ -748,7 +748,7 @@ bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,
case RPCL: strncpy(prog, "RPCL",4);
break;
case PROG_UNKNOWN:
return true;
return OPJ_TRUE;
}
if(!(cp->tp_on && ((!cp->cinema && (t2_mode == FINAL_PASS)) || cp->cinema))){
@@ -958,6 +958,6 @@ bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,
}
}
}
return false;
return OPJ_FALSE;
}

View File

@@ -115,12 +115,14 @@ Modify the packet iterator for enabling tile part generation
@param pi Handle to the packet iterator generated in pi_initialise_encode
@param cp Coding parameters
@param tileno Number that identifies the tile for which to list the packets
@param pino Iterator index for pi
@param tpnum Tile part number of the current tile
@param tppos The position of the tile part flag in the progression order
@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
@param cur_totnum_tp The total number of tile parts in the current tile
@return Returns true if an error is detected
*/
bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp);
opj_bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp);
/**
Create a packet iterator for Decoder
@param image Raw image for which the packets will be listed
@@ -145,7 +147,7 @@ Modify the packet iterator to point to the next packet
@param pi Packet iterator to modify
@return Returns false if pi pointed to the last packet or else returns true
*/
bool pi_next(opj_pi_iterator_t * pi);
opj_bool pi_next(opj_pi_iterator_t * pi);
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@@ -0,0 +1,173 @@
/*
* $Id: ppix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "opj_includes.h"
/*
* Write faix box of ppix
*
* @param[in] coff offset of j2k codestream
* @param[in] compno component number
* @param[in] cstr_info codestream information
* @param[in] EPHused true if if EPH option used
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of faix box
*/
int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio);
int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp, compno, i;
opj_jp2_box_t *box;
/* printf("cstr_info.packno %d\n", cstr_info.packno); //NMAX? */
lenp = -1;
box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t));
for (i=0;i<2;i++){
if (i) cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_PPIX, 4); /* PPIX */
write_manf( i, cstr_info.numcomps, box, cio);
for (compno=0; compno<cstr_info.numcomps; compno++){
box[compno].length = write_ppixfaix( coff, compno, cstr_info, EPHused, j2klen, cio);
box[compno].type = JPIP_FAIX;
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free(box);
return len;
}
int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp, tileno, version, i, nmax, size_of_coding; /* 4 or 8*/
opj_tile_info_t *tile_Idx;
opj_packet_info_t packet;
int resno, precno, layno, num_packet;
int numOfres, numOfprec, numOflayers;
packet.end_pos = packet.end_ph_pos = packet.start_pos = -1;
(void)EPHused; /* unused ? */
if( j2klen > pow( 2.0, 32)){
size_of_coding = 8;
version = 1;
}
else{
size_of_coding = 4;
version = 0;
}
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version, 1); /* Version 0 = 4 bytes */
nmax = 0;
for( i=0; i<=cstr_info.numdecompos[compno]; i++)
nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
cio_write( cio, nmax, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
tile_Idx = &cstr_info.tile[ tileno];
num_packet=0;
numOfres = cstr_info.numdecompos[compno] + 1;
for( resno=0; resno<numOfres ; resno++){
numOfprec = tile_Idx->pw[resno]*tile_Idx->ph[resno];
for( precno=0; precno<numOfprec; precno++){
numOflayers = cstr_info.numlayers;
for( layno=0; layno<numOflayers; layno++){
switch ( cstr_info.prog){
case LRCP:
packet = tile_Idx->packet[ ((layno*numOfres+resno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RLCP:
packet = tile_Idx->packet[ ((resno*numOflayers+layno)*cstr_info.numcomps+compno)*numOfprec+precno];
break;
case RPCL:
packet = tile_Idx->packet[ ((resno*numOfprec+precno)*cstr_info.numcomps+compno)*numOflayers+layno];
break;
case PCRL:
packet = tile_Idx->packet[ ((precno*cstr_info.numcomps+compno)*numOfres+resno)*numOflayers + layno];
break;
case CPRL:
packet = tile_Idx->packet[ ((compno*numOfprec+precno)*numOfres+resno)*numOflayers + layno];
break;
default:
fprintf( stderr, "failed to ppix indexing\n");
}
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_pos-packet.start_pos+1, size_of_coding); /* length */
num_packet++;
}
}
}
while( num_packet < nmax){ /* PADDING */
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
num_packet++;
}
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}

View File

@@ -123,20 +123,20 @@ static void t1_enc_refpass_step(
/**
Decode refinement pass
*/
static void INLINE t1_dec_refpass_step_raw(
static INLINE void t1_dec_refpass_step_raw(
opj_t1_t *t1,
flag_t *flagsp,
int *datap,
int poshalf,
int neghalf,
int vsc);
static void INLINE t1_dec_refpass_step_mqc(
static INLINE void t1_dec_refpass_step_mqc(
opj_t1_t *t1,
flag_t *flagsp,
int *datap,
int poshalf,
int neghalf);
static void INLINE t1_dec_refpass_step_mqc_vsc(
static INLINE void t1_dec_refpass_step_mqc_vsc(
opj_t1_t *t1,
flag_t *flagsp,
int *datap,
@@ -240,6 +240,7 @@ Encode 1 code-block
@param stepsize
@param cblksty Code-block style
@param numcomps
@param mct
@param tile
*/
static void t1_encode_cblk(
@@ -381,9 +382,10 @@ static INLINE void t1_dec_sigpass_step_raw(
int vsc)
{
int v, flag;
opj_raw_t *raw = t1->raw; /* RAW component */
OPJ_ARG_NOT_USED(orient);
flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp);
if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) {
if (raw_decode(raw)) {
@@ -822,9 +824,10 @@ static void t1_dec_clnpass_step_partial(
int oneplushalf)
{
int v, flag;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
OPJ_ARG_NOT_USED(orient);
flag = *flagsp;
mqc_setcurctx(mqc, t1_getctxno_sc(flag));
v = mqc_decode(mqc) ^ t1_getspb(flag);
@@ -1088,34 +1091,21 @@ static double t1_getwmsedec(
int numcomps,
int mct)
{
double w1 = 1, w2, wmsedec;
// Prevent running an MCT on more than 3 components. NB openjpeg v2.0 will support this via
// custom MCT tables that can be passed as encode parameters, 1.3 cannot support this as it
// uses a static table of 3 entries and there for can only cope with 3 components with out an
// array overflow
if(numcomps==3) {
if (qmfbid == 1) {
w1 = (numcomps > 1) ? mct_getnorm(compno) : 1.0;
} else {
w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1.0;
}
}
double w1, w2, wmsedec;
if (qmfbid == 1) {
w1 = (mct && numcomps==3) ? mct_getnorm(compno) : 1.0;
w2 = dwt_getnorm(level, orient);
} else { /* if (qmfbid == 0) */
w1 = (mct && numcomps==3) ? mct_getnorm_real(compno) : 1.0;
w2 = dwt_getnorm_real(level, orient);
}
wmsedec = w1 * w2 * stepsize * (1 << bpno);
wmsedec *= wmsedec * nmsedec / 8192.0;
return wmsedec;
}
static bool allocate_buffers(
static opj_bool allocate_buffers(
opj_t1_t *t1,
int w,
int h)
@@ -1127,7 +1117,7 @@ static bool allocate_buffers(
opj_aligned_free(t1->data);
t1->data = (int*) opj_aligned_malloc(datasize * sizeof(int));
if(!t1->data){
return false;
return OPJ_FALSE;
}
t1->datasize=datasize;
}
@@ -1140,7 +1130,7 @@ static bool allocate_buffers(
opj_aligned_free(t1->flags);
t1->flags = (flag_t*) opj_aligned_malloc(flagssize * sizeof(flag_t));
if(!t1->flags){
return false;
return OPJ_FALSE;
}
t1->flagssize=flagssize;
}
@@ -1149,7 +1139,7 @@ static bool allocate_buffers(
t1->w=w;
t1->h=h;
return true;
return OPJ_TRUE;
}
/** mod fixed_quality */
@@ -1425,6 +1415,7 @@ void t1_encode_cblks(
for (bandno = 0; bandno < res->numbands; ++bandno) {
opj_tcd_band_t* restrict band = &res->bands[bandno];
int bandconst = 8192 * 8192 / ((int) floor(band->stepsize * 8192));
for (precno = 0; precno < res->pw * res->ph; ++precno) {
opj_tcd_precinct_t *prc = &band->precincts[precno];
@@ -1475,7 +1466,7 @@ void t1_encode_cblks(
datap[(j * cblk_w) + i] =
fix_mul(
tmp,
8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (11 - T1_NMSEDEC_FRACBITS);
bandconst) >> (11 - T1_NMSEDEC_FRACBITS);
}
}
}
@@ -1586,6 +1577,7 @@ void t1_decode_cblks(
opj_free(cblk->segs);
} /* cblkno */
opj_free(precinct->cblks.dec);
precinct->cblks.dec = NULL;
} /* precno */
} /* bandno */
} /* resno */

View File

@@ -135,8 +135,8 @@ void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
/**
Decode the code-blocks of a tile
@param t1 T1 handle
@param tile The tile to decode
@param tcp Tile coding parameters
@param tilec The tile to decode
@param tccp Tile coding parameters
*/
void t1_decode_cblks(opj_t1_t* t1, opj_tcd_tilecomp_t* tilec, opj_tccp_t* tccp);
/* ----------------------------------------------------------------------- */

View File

@@ -59,11 +59,12 @@ Encode a packet of a tile to a destination buffer
*/
static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_codestream_info_t *cstr_info, int tileno);
/**
@param seg
@param cblk
@param index
@param cblksty
@param first
*/
static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first);
/**
Decode a packet of a tile from a source buffer
@param t2 T2 handle
@@ -72,6 +73,7 @@ Decode a packet of a tile from a source buffer
@param tile Tile for which to write the packets
@param tcp Tile coding parameters
@param pi Packet identity
@param pack_info Packet information
@return
*/
static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile,
@@ -147,8 +149,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
c[1] = 145;
c[2] = 0;
c[3] = 4;
c[4] = (tile->packno % 65536) / 256;
c[5] = (tile->packno % 65536) % 256;
c[4] = (unsigned char)((tile->packno % 65536) / 256);
c[5] = (unsigned char)((tile->packno % 65536) % 256);
c += 6;
}
/* </SOP> */
@@ -253,8 +255,8 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
/* </EPH> */
/* << INDEX */
// End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value
/* End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value */
if(cstr_info && cstr_info->index_write) {
opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
info_PK->end_ph_pos = (int)(c - dest);
@@ -294,9 +296,17 @@ static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_itera
return (c - dest);
}
static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
static opj_bool t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int first) {
opj_tcd_seg_t* seg;
cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
opj_tcd_seg_t* segs;
segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, (index + 1) * sizeof(opj_tcd_seg_t));
if (segs == NULL)
{
return OPJ_FALSE;
}
cblk->segs = segs;
seg = &cblk->segs[index];
seg->data = NULL;
seg->dataindex = 0;
@@ -314,6 +324,8 @@ static void t2_init_seg(opj_tcd_cblk_dec_t* cblk, int index, int cblksty, int fi
} else {
seg->maxpasses = 109;
}
return OPJ_TRUE;
}
static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile,
@@ -401,8 +413,8 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
}
/* << INDEX */
// End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value
/* End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value*/
if(pack_info) {
pack_info->end_ph_pos = (int)(c - src);
}
@@ -460,12 +472,22 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
cblk->numlenbits += increment;
segno = 0;
if (!cblk->numsegs) {
t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1);
if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 1))
{
opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
bio_destroy(bio);
return -999;
}
} else {
segno = cblk->numsegs - 1;
if (cblk->segs[segno].numpasses == cblk->segs[segno].maxpasses) {
++segno;
t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
{
opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
bio_destroy(bio);
return -999;
}
}
}
n = cblk->numnewpasses;
@@ -476,7 +498,12 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
n -= cblk->segs[segno].numnewpasses;
if (n > 0) {
++segno;
t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0);
if (!t2_init_seg(cblk, segno, tcp->tccps[compno].cblksty, 0))
{
opj_event_msg(t2->cinfo, EVT_ERROR, "Out of memory\n");
bio_destroy(bio);
return -999;
}
}
} while (n > 0);
}
@@ -494,14 +521,15 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
if (tcp->csty & J2K_CP_CSTY_EPH) {
if ((*hd) != 0xff || (*(hd + 1) != 0x92)) {
opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n");
return -999;
} else {
hd += 2;
}
}
/* << INDEX */
// End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value
/* End of packet header position. Currently only represents the distance to start of packet
// Will be updated later by incrementing with packet start value*/
if(pack_info) {
pack_info->end_ph_pos = (int)(hd - src);
}
@@ -565,7 +593,7 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t
#endif /* USE_JPWL */
cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char*));
cblk->data = (unsigned char*) opj_realloc(cblk->data, (cblk->len + seg->newlen) * sizeof(unsigned char));
memcpy(cblk->data + cblk->len, c, seg->newlen);
if (seg->numpasses == 0) {
seg->data = &cblk->data;
@@ -659,8 +687,8 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye
info_PK->start_pos = ((cp->tp_on | tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
}
info_PK->end_pos = info_PK->start_pos + e - 1;
info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet
info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet*/
}
cstr_info->packno++;
@@ -711,7 +739,11 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
} else {
e = 0;
}
if(e == -999)
{
pi_destroy(pi, cp, tileno);
return -999;
}
/* progression in resolution */
image->comps[pi[pino].compno].resno_decoded =
(e > 0) ?
@@ -725,8 +757,9 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
if (!cstr_info->packno) {
info_PK->start_pos = info_TL->end_header + 1;
} else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ // New tile part
info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in previous tile-part
} else if (info_TL->packet[cstr_info->packno-1].end_pos >= (int)cstr_info->tile[tileno].tp[curtp].tp_end_pos){ /* New tile part*/
info_TL->tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in previous tile-part*/
info_TL->tp[curtp].tp_start_pack = tp_start_packno;
tp_start_packno = cstr_info->packno;
curtp++;
info_PK->start_pos = cstr_info->tile[tileno].tp[curtp].tp_end_header+1;
@@ -734,8 +767,8 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
info_PK->start_pos = (cp->tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
}
info_PK->end_pos = info_PK->start_pos + e - 1;
info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet
info_PK->end_ph_pos += info_PK->start_pos - 1; /* End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet*/
cstr_info->packno++;
}
/* << INDEX */
@@ -749,7 +782,8 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
}
/* INDEX >> */
if(cstr_info) {
cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; // Number of packets in last tile-part
cstr_info->tile[tileno].tp[curtp].tp_numpacks = cstr_info->packno - tp_start_packno; /* Number of packets in last tile-part*/
cstr_info->tile[tileno].tp[curtp].tp_start_pack = tp_start_packno;
}
/* << INDEX */

View File

@@ -67,6 +67,7 @@ Encode the packets of a tile to a destination buffer
@param cstr_info Codestream information structure
@param tpnum Tile part number of the current tile
@param tppos The position of the tile part flag in the progression order
@param pino
@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
@param cur_totnum_tp The total number of tile parts in the current tile
*/
@@ -78,6 +79,7 @@ Decode the packets of a tile from a source buffer
@param len length of the source buffer
@param tileno number that identifies the tile for which to decode the packets
@param tile tile for which to decode the packets
@param cstr_info Codestream information structure
*/
int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info);

View File

@@ -30,10 +30,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#define _ISOC99_SOURCE /* lrintf is C99 */
#include "opj_includes.h"
void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
int tileno, compno, resno, bandno, precno;//, cblkno;
int tileno, compno, resno, bandno, precno;/*, cblkno;*/
fprintf(fd, "image {\n");
fprintf(fd, " tw=%d, th=%d x0=%d x1=%d y0=%d y1=%d\n",
@@ -290,6 +291,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
for (i = 0; i < res->pw * res->ph * 3; i++) {
band->precincts[i].imsbtree = NULL;
band->precincts[i].incltree = NULL;
band->precincts[i].cblks.enc = NULL;
}
for (precno = 0; precno < res->pw * res->ph; precno++) {
@@ -332,8 +334,10 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
cblk->y0 = int_max(cblkystart, prc->y0);
cblk->x1 = int_min(cblkxend, prc->x1);
cblk->y1 = int_min(cblkyend, prc->y1);
cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char));
cblk->data = (unsigned char*) opj_calloc(9728+2, sizeof(unsigned char));
/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
cblk->data[0] = 0;
cblk->data[1] = 0;
cblk->data += 2;
cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
@@ -593,6 +597,8 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
cblk->y1 = int_min(cblkyend, prc->y1);
cblk->data = (unsigned char*) opj_calloc(8192+2, sizeof(unsigned char));
/* FIXME: mqc_init_enc and mqc_byteout underrun the buffer if we don't do this. Why? */
cblk->data[0] = 0;
cblk->data[1] = 0;
cblk->data += 2;
cblk->layers = (opj_tcd_layer_t*) opj_calloc(100, sizeof(opj_tcd_layer_t));
cblk->passes = (opj_tcd_pass_t*) opj_calloc(100, sizeof(opj_tcd_pass_t));
@@ -613,7 +619,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) {
tcd->image = image;
tcd->tcd_image->tw = cp->tw;
tcd->tcd_image->th = cp->th;
tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcd_tile_t));
tcd->tcd_image->tiles = (opj_tcd_tile_t *) opj_calloc(cp->tw * cp->th, sizeof(opj_tcd_tile_t));
/*
Allocate place to store the decoded data = final image
@@ -656,7 +662,7 @@ void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp) {
tilec->y1 = int_ceildiv(tile->y1, image->comps[i].dy);
x0 = j == 0 ? tilec->x0 : int_min(x0, (unsigned int) tilec->x0);
y0 = j == 0 ? tilec->y0 : int_min(y0, (unsigned int) tilec->x0);
y0 = j == 0 ? tilec->y0 : int_min(y0, (unsigned int) tilec->y0);
x1 = j == 0 ? tilec->x1 : int_max(x1, (unsigned int) tilec->x1);
y1 = j == 0 ? tilec->y1 : int_max(y1, (unsigned int) tilec->y1);
}
@@ -676,6 +682,8 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
opj_tcp_t *tcp;
opj_tcd_tile_t *tile;
OPJ_ARG_NOT_USED(cstr_info);
tcd->cp = cp;
tcp = &(cp->tcps[cp->tileno[tileno]]);
@@ -687,6 +695,12 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
opj_tccp_t *tccp = &tcp->tccps[compno];
opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
if (tccp->numresolutions <= 0)
{
cp->tileno[tileno] = -1;
return;
}
/* border of each tile component (global) */
tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
tilec->y0 = int_ceildiv(tile->y0, image->comps[compno].dy);
@@ -997,7 +1011,7 @@ void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {
}
}
bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
int compno, resno, bandno, precno, cblkno, passno, layno;
double min, max;
double cumdisto[100]; /* fixed_quality */
@@ -1149,7 +1163,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre
}
if (!success) {
return false;
return OPJ_FALSE;
}
if(cstr_info) { /* Threshold for Marcela Index */
@@ -1161,7 +1175,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestre
cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
}
return true;
return OPJ_TRUE;
}
int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
@@ -1313,7 +1327,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op
return l;
}
bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) {
opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info) {
int l;
int compno;
int eof = 0;
@@ -1349,7 +1363,7 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
}
else {
cstr_info->tile[tileno].pdx[resno] = 15;
cstr_info->tile[tileno].pdx[resno] = 15;
cstr_info->tile[tileno].pdy[resno] = 15;
}
}
}
@@ -1373,14 +1387,24 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
t1_time = opj_clock(); /* time needed to decode a tile */
t1 = t1_create(tcd->cinfo);
if (t1 == NULL)
{
opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
t1_destroy(t1);
return OPJ_FALSE;
}
for (compno = 0; compno < tile->numcomps; ++compno) {
opj_tcd_tilecomp_t* tilec = &tile->comps[compno];
/* The +3 is headroom required by the vectorized DWT */
tilec->data = (int*) opj_aligned_malloc((((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0))+3) * sizeof(int));
if(tilec->data)
t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]);
else
opj_event_msg(tcd->cinfo, EVT_ERROR, "tcd_decode: tile size invalid\n");
if (tilec->data == NULL)
{
opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
return OPJ_FALSE;
}
t1_decode_cblks(t1, tilec, &tcd->tcp->tccps[compno]);
}
t1_destroy(t1);
t1_time = opj_clock() - t1_time;
@@ -1394,18 +1418,15 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
int numres2decode;
if (tcd->cp->reduce != 0) {
tcd->image->comps[compno].resno_decoded =
tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
if (tcd->image->comps[compno].resno_decoded < 0) {
if ( tile->comps[compno].numresolutions < ( tcd->cp->reduce - 1 ) ) {
opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number "
" of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions);
return false;
return OPJ_FALSE;
}
}
if(!tilec->data) {
opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. null data\n");
return false;
else {
tcd->image->comps[compno].resno_decoded =
tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
}
}
numres2decode = tcd->image->comps[compno].resno_decoded + 1;
@@ -1424,18 +1445,23 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
if (tcd->tcp->mct) {
int n = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0);
if (tcd->tcp->tccps[0].qmfbid == 1) {
mct_decode(
tile->comps[0].data,
tile->comps[1].data,
tile->comps[2].data,
n);
} else {
mct_decode_real(
(float*)tile->comps[0].data,
(float*)tile->comps[1].data,
(float*)tile->comps[2].data,
n);
if (tile->numcomps >= 3 ){
if (tcd->tcp->tccps[0].qmfbid == 1) {
mct_decode(
tile->comps[0].data,
tile->comps[1].data,
tile->comps[2].data,
n);
} else {
mct_decode_real(
(float*)tile->comps[0].data,
(float*)tile->comps[1].data,
(float*)tile->comps[2].data,
n);
}
} else{
opj_event_msg(tcd->cinfo, EVT_WARNING,"Number of components (%d) is inconsistent with a MCT. Skip the MCT step.\n",tile->numcomps);
}
}
@@ -1459,6 +1485,11 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
if(!imagec->data){
imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int));
}
if (!imagec->data)
{
opj_event_msg(tcd->cinfo, EVT_ERROR, "Out of memory\n");
return OPJ_FALSE;
}
if(tcd->tcp->tccps[compno].qmfbid == 1) {
for(j = res->y0; j < res->y1; ++j) {
for(i = res->x0; i < res->x1; ++i) {
@@ -1484,40 +1515,59 @@ bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, op
opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time);
if (eof) {
return false;
return OPJ_FALSE;
}
return true;
return OPJ_TRUE;
}
void tcd_free_decode(opj_tcd_t *tcd) {
opj_tcd_image_t *tcd_image = tcd->tcd_image;
int i = 0;
for (i = 0; i < tcd_image->tw * tcd_image->th; i++)
{
tcd_free_decode_tile(tcd, i);
}
opj_free(tcd_image->tiles);
}
void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno) {
int compno,resno,bandno,precno;
int compno,resno,bandno,precno,cblkno;
opj_tcd_image_t *tcd_image = tcd->tcd_image;
opj_tcd_tile_t *tile = &tcd_image->tiles[tileno];
for (compno = 0; compno < tile->numcomps; compno++) {
opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_t *band = &res->bands[bandno];
for (precno = 0; precno < res->ph * res->pw; precno++) {
opj_tcd_precinct_t *prec = &band->precincts[precno];
if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
if (prec->incltree != NULL) tgt_destroy(prec->incltree);
if (tile->comps != NULL) {
for (compno = 0; compno < tile->numcomps; compno++) {
opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_t *band = &res->bands[bandno];
for (precno = 0; precno < res->ph * res->pw; precno++) {
opj_tcd_precinct_t *prec = &band->precincts[precno];
if (prec->cblks.dec != NULL) {
for (cblkno = 0; cblkno < prec->cw * prec->ch; ++cblkno) {
opj_tcd_cblk_dec_t* cblk = &prec->cblks.dec[cblkno];
opj_free(cblk->data);
opj_free(cblk->segs);
}
opj_free(prec->cblks.dec);
}
if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);
if (prec->incltree != NULL) tgt_destroy(prec->incltree);
}
opj_free(band->precincts);
}
opj_free(band->precincts);
}
opj_free(tilec->resolutions);
}
opj_free(tilec->resolutions);
opj_free(tile->comps);
tile->comps = NULL;
}
opj_free(tile->comps);
}

View File

@@ -251,7 +251,7 @@ void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp,
void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final);
void tcd_rateallocate_fixed(opj_tcd_t *tcd);
void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final);
bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info);
opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info);
/**
Encode a tile from the raw image into a buffer
@param tcd TCD handle
@@ -268,8 +268,9 @@ Decode a tile from a buffer into a raw image
@param src Source buffer
@param len Length of source buffer
@param tileno Number that identifies one of the tiles to be decoded
@param cstr_info Codestream information structure
*/
bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info);
opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno, opj_codestream_info_t *cstr_info);
/**
Free the memory allocated for decoding
@param tcd TCD handle

View File

@@ -0,0 +1,120 @@
/*
* $Id: thix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "opj_includes.h"
/*
* Write tile-part headers mhix box
*
* @param[in] coff offset of j2k codestream
* @param[in] cstr_info codestream information
* @param[in] tileno tile number
* @param[in] cio file output handle
* @return length of mhix box
*/
int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio);
int write_thix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
{
int len, lenp, i;
int tileno;
opj_jp2_box_t *box;
lenp = 0;
box = (opj_jp2_box_t *)opj_calloc( cstr_info.tw*cstr_info.th, sizeof(opj_jp2_box_t));
for ( i = 0; i < 2 ; i++ ){
if (i)
cio_seek( cio, lenp);
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_THIX, 4); /* THIX */
write_manf( i, cstr_info.tw*cstr_info.th, box, cio);
for (tileno = 0; tileno < cstr_info.tw*cstr_info.th; tileno++){
box[tileno].length = write_tilemhix( coff, cstr_info, tileno, cio);
box[tileno].type = JPIP_MHIX;
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
}
opj_free(box);
return len;
}
int write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, opj_cio_t *cio)
{
int i;
opj_tile_info_t tile;
opj_tp_info_t tp;
int len, lenp;
opj_marker_info_t *marker;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_MHIX, 4); /* MHIX */
tile = cstr_info.tile[tileno];
tp = tile.tp[0];
cio_write( cio, tp.tp_end_header-tp.tp_start_pos+1, 8); /* TLEN */
marker = cstr_info.tile[tileno].marker;
for( i=0; i<cstr_info.tile[tileno].marknum; i++){ /* Marker restricted to 1 apparition */
cio_write( cio, marker[i].type, 2);
cio_write( cio, 0, 2);
cio_write( cio, marker[i].pos-coff, 8);
cio_write( cio, marker[i].len, 2);
}
/* free( marker);*/
len = cio_tell( cio) - lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}

View File

@@ -0,0 +1,153 @@
/*
* $Id: tpix_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
*
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq
* Copyright (c) 2003-2004, Yannick Verschueren
* Copyright (c) 2010-2011, Kaori Hagihara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*! \file
* \brief Modification of jpip.c from 2KAN indexer
*/
#include <math.h>
#include "opj_includes.h"
#define MAX(a,b) ((a)>(b)?(a):(b))
/*
* Write faix box of tpix
*
* @param[in] coff offset of j2k codestream
* @param[in] compno component number
* @param[in] cstr_info codestream information
* @param[in] j2klen length of j2k codestream
* @param[in] cio file output handle
* @return length of faix box
*/
int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio);
int write_tpix( int coff, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio)
{
int len, lenp;
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_TPIX, 4); /* TPIX */
write_tpixfaix( coff, 0, cstr_info, j2klen, cio);
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}
/*
* Get number of maximum tile parts per tile
*
* @param[in] cstr_info codestream information
* @return number of maximum tile parts per tile
*/
int get_num_max_tile_parts( opj_codestream_info_t cstr_info);
int write_tpixfaix( int coff, int compno, opj_codestream_info_t cstr_info, int j2klen, opj_cio_t *cio)
{
int len, lenp;
int i, j;
int Aux;
int num_max_tile_parts;
int size_of_coding; /* 4 or 8 */
opj_tp_info_t tp;
int version;
num_max_tile_parts = get_num_max_tile_parts( cstr_info);
if( j2klen > pow( 2.0, 32)){
size_of_coding = 8;
version = num_max_tile_parts == 1 ? 1:3;
}
else{
size_of_coding = 4;
version = num_max_tile_parts == 1 ? 0:2;
}
lenp = cio_tell( cio);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version, 1); /* Version 0 = 4 bytes */
cio_write( cio, num_max_tile_parts, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for (i = 0; i < cstr_info.tw*cstr_info.th; i++){
for (j = 0; j < cstr_info.tile[i].num_tps; j++){
tp = cstr_info.tile[i].tp[j];
cio_write( cio, tp.tp_start_pos-coff, size_of_coding); /* start position */
cio_write( cio, tp.tp_end_pos-tp.tp_start_pos+1, size_of_coding); /* length */
if (version & 0x02){
if( cstr_info.tile[i].num_tps == 1 && cstr_info.numdecompos[compno] > 1)
Aux = cstr_info.numdecompos[compno] + 1;
else
Aux = j + 1;
cio_write( cio, Aux,4);
/*cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4);*/ /* Aux_i,j : Auxiliary value */
/* fprintf(stderr,"AUX value %d\n",Aux);*/
}
/*cio_write(0,4);*/
}
/* PADDING */
while (j < num_max_tile_parts){
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
if (version & 0x02)
cio_write( cio, 0,4); /* Aux_i,j : Auxiliary value */
j++;
}
}
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
cio_write( cio, len, 4); /* L */
cio_seek( cio, lenp+len);
return len;
}
int get_num_max_tile_parts( opj_codestream_info_t cstr_info)
{
int num_max_tp = 0, i;
for( i=0; i<cstr_info.tw*cstr_info.th; i++)
num_max_tp = MAX( cstr_info.tile[i].num_tps, num_max_tp);
return num_max_tp;
}

View File

@@ -50,8 +50,7 @@ LLMultiGesture::LLMultiGesture()
mSteps(),
mPlaying(FALSE),
mCurrentStep(0),
mDoneCallback(NULL),
mCallbackData(NULL)
mDoneCallback(NULL)
{
reset();
}

View File

@@ -100,8 +100,7 @@ public:
// Timer for waiting
LLFrameTimer mWaitTimer;
void (*mDoneCallback)(LLMultiGesture* gesture, void* data);
void* mCallbackData;
boost::function<void (LLMultiGesture*)> mDoneCallback;
// Animations that we requested to start
std::set<LLUUID> mRequestedAnimIDs;

View File

@@ -27,7 +27,7 @@
#include "linden_common.h"
#include "llallocator.h"
#if LL_USE_TCMALLOC
#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER)
#include "google/heap-profiler.h"
#include "google/commandlineflags_public.h"

View File

@@ -56,6 +56,7 @@ public:
};
LLDynamicArray(S32 size=0) : std::vector<Type>(size) { if (size < BlockSize) std::vector<Type>::reserve(BlockSize); }
LLDynamicArray(const std::vector<Type>& copy) : std::vector<Type>(copy) {}
void reset() { std::vector<Type>::clear(); }

View File

@@ -444,13 +444,13 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL
{
// The new node isn't last. Place it between the previous node and
// the successor.
newNode = (myprev + mydmi->second)/2.0;
newNode = (myprev + mydmi->second)/2.f;
}
else
{
// The new node is last. Bump myprev up to the next integer, add
// 1.0 and use that.
newNode = std::ceil(myprev) + 1.0;
newNode = std::ceil(myprev) + 1.f;
}
// Now that newNode has a value that places it appropriately in mSignal,
// connect it.

View File

@@ -67,6 +67,17 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker;
#endif
void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
{
#ifdef SHOW_ASSERT
// Redundant, place to set breakpoints.
if (ptr%alignment!=0)
{
llwarns << "alignment check failed" << llendl;
}
llassert(ptr%alignment==0);
#endif
}
//static
void LLMemory::initClass()
{
@@ -246,21 +257,6 @@ U32 LLMemory::getAllocatedMemKB()
return sAllocatedMemInKB ;
}
void* ll_allocate (size_t size)
{
if (size == 0)
{
llwarns << "Null allocation" << llendl;
}
void *p = malloc(size);
if (p == NULL)
{
LLMemory::freeReserve();
llerrs << "Out of memory Error" << llendl;
}
return p;
}
//----------------------------------------------------------------------------
#if defined(LL_WINDOWS)
@@ -1358,7 +1354,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)
//if the asked size larger than MAX_BLOCK_SIZE, fetch from heap directly, the pool does not manage it
if(size >= CHUNK_SIZE)
{
return (char*)malloc(size) ;
return (char*)ll_aligned_malloc_16(size) ;
}
char* p = NULL ;
@@ -1415,7 +1411,7 @@ char* LLPrivateMemoryPool::allocate(U32 size)
to_log = false ;
}
return (char*)malloc(size) ;
return (char*)ll_aligned_malloc_16(size) ;
}
return p ;
@@ -1434,7 +1430,7 @@ void LLPrivateMemoryPool::freeMem(void* addr)
if(!chunk)
{
free(addr) ; //release from heap
ll_aligned_free_16(addr) ; //release from heap
}
else
{
@@ -1558,7 +1554,7 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde
mReservedPoolSize += preferred_size + overhead ;
char* buffer = (char*)malloc(preferred_size + overhead) ;
char* buffer = (char*)ll_aligned_malloc_16(preferred_size + overhead) ;
if(!buffer)
{
return NULL ;
@@ -1626,7 +1622,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk)
mReservedPoolSize -= chunk->getBufferSize() ;
//release memory
free(chunk->getBuffer()) ;
ll_aligned_free_16(chunk->getBuffer()) ;
}
U16 LLPrivateMemoryPool::findHashKey(const char* addr)
@@ -1970,7 +1966,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size,
if(!poolp)
{
p = (char*)malloc(size) ;
p = (char*)ll_aligned_malloc_16(size) ;
}
else
{
@@ -1999,7 +1995,7 @@ char* LLPrivateMemoryPoolManager::allocate(LLPrivateMemoryPool* poolp, U32 size)
}
else
{
return (char*)malloc(size) ;
return (char*)ll_aligned_malloc_16(size) ;
}
}
#endif
@@ -2024,7 +2020,7 @@ void LLPrivateMemoryPoolManager::freeMem(LLPrivateMemoryPool* poolp, void* addr
{
if(!sPrivatePoolEnabled)
{
free(addr) ; //private pool is disabled.
ll_aligned_free_16(addr) ; //private pool is disabled.
}
else if(!sInstance) //the private memory manager is destroyed, try the dangling list
{

View File

@@ -39,9 +39,14 @@
#include <stdint.h> // uintptr_t
#endif
#include "llerror.h"
#include "llmemtype.h"
#if LL_DEBUG
#if LL_WINDOWS && LL_DEBUG
#define LL_CHECK_MEMORY llassert(_CrtCheckMemory());
#else
#define LL_CHECK_MEMORY
#endif
inline void* ll_aligned_malloc( size_t size, int align )
{
void* mem = malloc( size + (align - 1) + sizeof(void*) );
@@ -57,10 +62,11 @@ inline void ll_aligned_free( void* ptr )
free( ((void**)ptr)[-1] );
}
#if !LL_USE_TCMALLOC
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
{
#if defined(LL_WINDOWS)
return _mm_malloc(size, 16);
return _aligned_malloc(size, 16);
#elif defined(LL_DARWIN)
return malloc(size); // default osx malloc is 16 byte aligned.
#else
@@ -75,7 +81,7 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi
inline void ll_aligned_free_16(void *p)
{
#if defined(LL_WINDOWS)
_mm_free(p);
_aligned_free(p);
#elif defined(LL_DARWIN)
return free(p);
#else
@@ -83,10 +89,39 @@ inline void ll_aligned_free_16(void *p)
#endif
}
inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // returned hunk MUST be freed with ll_aligned_free_16().
{
#if defined(LL_WINDOWS)
return _aligned_realloc(ptr, size, 16);
#elif defined(LL_DARWIN)
return realloc(ptr,size); // default osx malloc is 16 byte aligned.
#else
//FIXME: memcpy is SLOW
void* ret = ll_aligned_malloc_16(size);
if (ptr)
{
if (ret)
{
// Only copy the size of the smallest memory block to avoid memory corruption.
memcpy(ret, ptr, llmin(old_size, size));
}
ll_aligned_free_16(ptr);
}
return ret;
#endif
}
#else // USE_TCMALLOC
// ll_aligned_foo_16 are not needed with tcmalloc
#define ll_aligned_malloc_16 malloc
#define ll_aligned_realloc_16(a,b,c) realloc(a,b)
#define ll_aligned_free_16 free
#endif // USE_TCMALLOC
inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
{
#if defined(LL_WINDOWS)
return _mm_malloc(size, 32);
return _aligned_malloc(size, 32);
#elif defined(LL_DARWIN)
return ll_aligned_malloc( size, 32 );
#else
@@ -101,22 +136,13 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
inline void ll_aligned_free_32(void *p)
{
#if defined(LL_WINDOWS)
_mm_free(p);
_aligned_free(p);
#elif defined(LL_DARWIN)
ll_aligned_free( p );
#else
free(p); // posix_memalign() is compatible with heap deallocator
#endif
}
#else // LL_DEBUG
// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals)
#define ll_aligned_malloc( size, align ) malloc(size)
#define ll_aligned_free( ptr ) free(ptr)
#define ll_aligned_malloc_16 malloc
#define ll_aligned_free_16 free
#define ll_aligned_malloc_32 malloc
#define ll_aligned_free_32 free
#endif // LL_DEBUG
#ifndef __DEBUG_PRIVATE_MEM__
#define __DEBUG_PRIVATE_MEM__ 0
@@ -521,6 +547,14 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr)
#endif
#endif
LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
#ifdef SHOW_ASSERT
#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
#else
#define ll_assert_aligned(ptr,alignment)
#endif
//EVENTUALLY REMOVE THESE:
#include "llpointer.h"
#include "llsingleton.h"

View File

@@ -1690,6 +1690,12 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*
dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
}
void LLImageBase::setDataAndSize(U8 *data, S32 size)
{
ll_assert_aligned(data, 16);
mData = data; mDataSize = size;
}
//static
void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels)
{

View File

@@ -134,7 +134,7 @@ public:
protected:
// special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }
void setDataAndSize(U8 *data, S32 size);
public:
static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);

View File

@@ -1,4 +1,4 @@
/**
/**
* @file llimagej2coj.cpp
* @brief This is an implementation of JPEG2000 encode/decode using OpenJPEG.
*
@@ -35,9 +35,7 @@
const char* fallbackEngineInfoLLImageJ2CImpl()
{
static std::string version_string =
std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
+ opj_version();
static std::string version_string = std::string("OpenJPEG: ") + opj_version();
return version_string.c_str();
}
@@ -186,7 +184,15 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
{
opj_image_destroy(image);
}
#if 0
std::stringstream filename;
filename << "err" << (int)base.getRawDiscardLevel() << "_" << rand() << ".jp2";
FILE* file = fopen(filename.str().c_str(), "wb");
if (file) {
fwrite(base.getData(), base.getDataSize(), 1, file);
fclose(file);
}
#endif
base.decodeFailed();
return TRUE; // done
}

View File

@@ -66,7 +66,7 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
// roll(), pitch(), yaw()
// etc...
LL_ALIGN_PREFIX(16)
class LLCamera
: public LLCoordFrame
{
@@ -114,7 +114,7 @@ public:
};
private:
LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
U8 mPlaneMask[8]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
@@ -122,13 +122,13 @@ private:
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
F32 mNearPlane;
F32 mFarPlane;
LLPlane mLocalPlanes[4];
LL_ALIGN_16(LLPlane mLocalPlanes[4]);
F32 mFixedDistance; // Always return this distance, unless < 0
LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test
F32 mFrustRadiusSquared;
LLPlane mWorldPlanes[PLANE_NUM];
LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]);
LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]);
U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
@@ -214,7 +214,7 @@ protected:
void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
void calculateWorldFrustumPlanes();
};
} LL_ALIGN_POSTFIX(16);
#endif

View File

@@ -111,7 +111,7 @@ public:
protected:
LLVector4a mColumns[3];
LL_ALIGN_16(LLVector4a mColumns[3]);
};

View File

@@ -34,7 +34,7 @@
class LLMatrix4a
{
public:
LLVector4a mMatrix[4];
LL_ALIGN_16(LLVector4a mMatrix[4]);
inline void clear()
{

View File

@@ -37,6 +37,7 @@
#include "v3math.h"
#include "llvector4a.h"
#include <vector>
#include <boost/pool/pool.hpp>
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
#define OCT_ERRS LL_ERRS("OctreeErrors")
@@ -46,6 +47,7 @@
#endif
extern U32 gOctreeMaxCapacity;
extern U32 gOctreeReserveCapacity;
#if LL_DEBUG
#define LL_OCTREE_PARANOIA_CHECK 0
#else
@@ -56,6 +58,106 @@ extern U32 gOctreeMaxCapacity;
template <class T> class LLOctreeNode;
#include "lltimer.h"
//#define LL_OCTREE_STATS
#define LL_OCTREE_POOLS
#ifdef LL_OCTREE_STATS
class OctreeStats : public LLSingleton<OctreeStats>
{
public:
OctreeStats() :
mPeriodNodesCreated(0),
mPeriodNodesDestroyed(0),
mPeriodAllocs(0),
mPeriodFrees(0),
mPeriodLargestSize(0),
mTotalNodes(0),
mTotalAllocs(0),
mTotalFrees(0),
mLargestSize(0),
mTotalSize(0)
{
mTotalTimer.reset();
mPeriodTimer.reset();
}
void addNode()
{
++mTotalNodes;
++mPeriodNodesCreated;
}
void removeNode()
{
--mTotalNodes;
++mPeriodNodesDestroyed;
}
void realloc(U32 old_count, U32 new_count)
{
if(new_count >= old_count)
mTotalSize+=new_count-old_count;
else
mTotalSize-=old_count-new_count;
if(mLargestSize < new_count)
mLargestSize = new_count;
if(mPeriodLargestSize < new_count)
mPeriodLargestSize = new_count;
++mTotalAllocs;
++mPeriodAllocs;
}
void free(U32 count)
{
mTotalSize-=count;
++mTotalFrees;
++mPeriodFrees;
}
void dump()
{
llinfos << llformat("Lifetime: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes: %u AccumSize: %llubytes Avg: %lf LargestSize: %u",
mTotalAllocs,
mTotalFrees,
F64(mTotalAllocs)/mTotalTimer.getElapsedTimeF64(),
F64(mTotalFrees)/mTotalTimer.getElapsedTimeF64(),
mTotalNodes,
mTotalSize*sizeof(LLPointer<LLRefCount>),
F64(mTotalSize)/F64(mTotalNodes),
mLargestSize
) << llendl;
llinfos << llformat("Timeslice: Allocs:(+%u|-%u) Allocs/s: (+%lf|-%lf) Nodes:(+%u|-%u) LargestSize: %u",
mPeriodAllocs,
mPeriodFrees,
F64(mPeriodAllocs)/mPeriodTimer.getElapsedTimeF64(),
F64(mPeriodFrees)/mPeriodTimer.getElapsedTimeF64(),
mPeriodNodesCreated,
mPeriodNodesDestroyed,
mPeriodLargestSize
) << llendl;
mPeriodNodesCreated=0;
mPeriodNodesDestroyed=0;
mPeriodAllocs=0;
mPeriodFrees=0;
mPeriodLargestSize=0;
mPeriodTimer.reset();
}
private:
//Accumulate per timer update
U32 mPeriodNodesCreated;
U32 mPeriodNodesDestroyed;
U32 mPeriodAllocs;
U32 mPeriodFrees;
U32 mPeriodLargestSize;
LLTimer mPeriodTimer;
//Accumulate through entire app lifetime:
U32 mTotalNodes;
U32 mTotalAllocs;
U32 mTotalFrees;
U32 mLargestSize;
U64 mTotalSize;
LLTimer mTotalTimer;
};
#endif //LL_OCTREE_STATS
template <class T>
class LLOctreeListener: public LLTreeListener<T>
{
@@ -129,25 +231,52 @@ public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
typedef LLPointer<T>* element_list;
typedef LLPointer<T>* element_iter;
typedef const LLPointer<T>* const_element_iter;
typedef std::vector<LLPointer<T> > element_list;
typedef typename element_list::iterator element_iter;
typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
typedef LLOctreeNode<T>** child_list;
typedef LLOctreeNode<T>** child_iter;
typedef LLTreeNode<T> BaseType;
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> oct_listener;
/*void* operator new(size_t size)
#ifdef LL_OCTREE_POOLS
struct octree_pool_alloc
{
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static char * malloc(const std::size_t bytes)
{ return (char *)ll_aligned_malloc_16(bytes); }
static void free(char * const block)
{ ll_aligned_free_16(block); }
};
static boost::pool<octree_pool_alloc>& getPool(const std::size_t& size)
{
static boost::pool<octree_pool_alloc> sPool((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size),1200);
llassert_always((std::size_t)LL_NEXT_ALIGNED_ADDRESS((char*)size) == sPool.get_requested_size());
return sPool;
}
void* operator new(size_t size)
{
return getPool(size).malloc();
}
void operator delete(void* ptr)
{
getPool(sizeof(LLOctreeNode<T>)).free(ptr);
}
#else
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}*/
}
#endif
LLOctreeNode( const LLVector4a& center,
const LLVector4a& size,
@@ -156,8 +285,16 @@ public:
: mParent((oct_node*)parent),
mOctant(octant)
{
mData = NULL;
mDataEnd = NULL;
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->addNode();
#endif
if(gOctreeReserveCapacity)
mData.reserve(gOctreeReserveCapacity);
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->realloc(0,mData.capacity());
#endif
//mData = NULL;
//mDataEnd = NULL;
mCenter = center;
mSize = size;
@@ -168,24 +305,31 @@ public:
mOctant = ((oct_node*) mParent)->getOctant(mCenter);
}
mElementCount = 0;
//mElementCount = 0;
clearChildren();
}
virtual ~LLOctreeNode()
{
{
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->removeNode();
#endif
BaseType::destroyListeners();
for (U32 i = 0; i < mElementCount; ++i)
//for (U32 i = 0; i < mElementCount; ++i)
for (U32 i = 0; i < mData.size(); ++i)
{
mData[i]->setBinIndex(-1);
mData[i] = NULL;
}
free(mData);
mData = NULL;
mDataEnd = NULL;
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->free(mData.capacity());
#endif
//free(mData);
//mData = NULL;
//mDataEnd = NULL;
for (U32 i = 0; i < getChildCount(); i++)
{
@@ -285,14 +429,14 @@ public:
void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChildCount == 0; }
U32 getElementCount() const { return mElementCount; }
bool isEmpty() const { return mElementCount == 0; }
U32 getElementCount() const { return mData.size(); }
bool isEmpty() const { return mData.size() == 0; }
//element_list& getData() { return mData; }
//const element_list& getData() const { return mData; }
element_iter getDataBegin() { return mData; }
element_iter getDataEnd() { return mDataEnd; }
const_element_iter getDataBegin() const { return mData; }
const_element_iter getDataEnd() const { return mDataEnd; }
element_iter getDataBegin() { return mData.begin(); }
element_iter getDataEnd() { return mData.end(); }
const_element_iter getDataBegin() const { return mData.begin(); }
const_element_iter getDataEnd() const { return mData.end(); }
U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
@@ -372,7 +516,10 @@ public:
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
mElementCount++;
/*mElementCount++;
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount);
#endif
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
//avoid unref on uninitialized memory
@@ -380,7 +527,18 @@ public:
mData[mElementCount-1] = data;
mDataEnd = mData + mElementCount;
data->setBinIndex(mElementCount-1);
data->setBinIndex(mElementCount-1);*/
#ifdef LL_OCTREE_STATS
U32 old_cap = mData.capacity();
#endif
data->setBinIndex(mData.size());
mData.push_back(data);
#ifdef LL_OCTREE_STATS
if(old_cap != mData.capacity())
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif
BaseType::insert(data);
return true;
}
@@ -415,7 +573,10 @@ public:
if( lt == 0x7 )
{
mElementCount++;
/*mElementCount++;
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->realloc(mElementCount-1,mElementCount);
#endif
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
//avoid unref on uninitialized memory
@@ -423,7 +584,17 @@ public:
mData[mElementCount-1] = data;
mDataEnd = mData + mElementCount;
data->setBinIndex(mElementCount-1);
data->setBinIndex(mElementCount-1);*/
#ifdef LL_OCTREE_STATS
U32 old_cap = mData.capacity();
#endif
data->setBinIndex(mData.size());
mData.push_back(data);
#ifdef LL_OCTREE_STATS
if(old_cap != mData.capacity())
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif
BaseType::insert(data);
return true;
}
@@ -476,10 +647,10 @@ public:
void _remove(T* data, S32 i)
{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
OctreeGuard::checkGuarded(this);
mElementCount--;
//mElementCount--;
data->setBinIndex(-1);
if (mElementCount > 0)
/* if (mElementCount > 0)
{
if (mElementCount != i)
{
@@ -488,15 +659,51 @@ public:
}
mData[mElementCount] = NULL; //needed for unref
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->realloc(mElementCount+1,mElementCount);
#endif
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
mDataEnd = mData+mElementCount;
}
else
{
mData[0] = NULL; //needed for unref
#ifdef LL_OCTREE_STATS
OctreeStats::getInstance()->free(1);
#endif
free(mData);
mData = NULL;
mDataEnd = NULL;
}*/
if(mData.size())
{
if((mData.size()-1)!=i)
{
mData[i] = mData[mData.size()-1];
mData[i]->setBinIndex(i);
}
#ifdef LL_OCTREE_STATS
U32 old_cap = mData.capacity();
#endif
mData.pop_back();
if( mData.size() == gOctreeReserveCapacity ||
(mData.size() > gOctreeReserveCapacity && mData.capacity() > gOctreeReserveCapacity + mData.size() - 1 - (mData.size() - gOctreeReserveCapacity - 1) % 4))
{
//Shrink to lowest possible (reserve)+4*i size.. Say reserve is 5, here are [size,capacity] pairs. [10,13],[9,9],[8,9],[7,9],[6,9],[5,5],[4,5],[3,5],[2,5],[1,5],[0,5]
//For Windows: We always assume vs2010 or later, which support this c++11 feature with no configuration needed.
//For GCC: __cplusplus >= 201103L indicates C++11 support. __GXX_EXPERIMENTAL_CXX0X being set indicates experimental c++0x support. C++11 support replaces C++0x support.
// std::vector::shrink_to_fit was added to GCCs C++0x implementation in version 4.5.0.
#if defined(LL_WINDOWS) || __cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X) && __GNUC_MINOR__ >= 5)
mData.shrink_to_fit();
#else
std::vector<LLPointer<T> >(mData.begin(), mData.end()).swap(mData); //Need to confirm this works on OSX..
#endif
}
#ifdef LL_OCTREE_STATS
if(old_cap != mData.capacity())
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif
}
this->notifyRemoval(data);
@@ -508,7 +715,8 @@ public:
OctreeGuard::checkGuarded(this);
S32 i = data->getBinIndex();
if (i >= 0 && i < (S32)mElementCount)
//if (i >= 0 && i < mElementCount)
if (i >= 0 && i < (S32)mData.size())
{
if (mData[i] == data)
{ //found it
@@ -552,7 +760,8 @@ public:
void removeByAddress(T* data)
{
OctreeGuard::checkGuarded(this);
for (U32 i = 0; i < mElementCount; ++i)
//for (U32 i = 0; i < mElementCount; ++i)
for (U32 i = 0; i < mData.size(); ++i)
{
if (mData[i] == data)
{ //we have data
@@ -660,8 +869,6 @@ public:
listener->handleChildRemoval(this, getChild(index));
}
if (destroy)
{
mChild[index]->destroy();
@@ -733,8 +940,8 @@ protected:
U32 mChildCount;
element_list mData;
element_iter mDataEnd;
U32 mElementCount;
//element_iter mDataEnd;
//U32 mElementCount;
};

View File

@@ -42,6 +42,8 @@
// The plane normal = [A, B, C]
// The closest approach = D / sqrt(A*A + B*B + C*C)
LL_ALIGN_PREFIX(16)
class LLPlane
{
public:
@@ -100,7 +102,7 @@ public:
private:
LLVector4a mV;
};
} LL_ALIGN_POSTFIX(16);

View File

@@ -124,8 +124,8 @@ public:
if (end_y < mBottom) clip_y = end_y - mBottom;
// clip_? and delta_? should have same sign, since starting point is in rect
// so ratios will be positive
F32 ratio_x = ((F32)clip_x / (F32)delta_x);
F32 ratio_y = ((F32)clip_y / (F32)delta_y);
F32 ratio_x = delta_x ? ((F32)clip_x / (F32)delta_x) : 0.f;
F32 ratio_y = delta_y ? ((F32)clip_y / (F32)delta_y) : 0.f;
if (ratio_x > ratio_y)
{
// clip along x direction

View File

@@ -67,11 +67,10 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
#include <xmmintrin.h>
#include <emmintrin.h>
#include "llmemory.h"
#include "llsimdtypes.h"
#include "llsimdtypes.inl"

View File

@@ -62,6 +62,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b)
inline LLSimdScalar operator-(const LLSimdScalar& a)
{
static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 };
ll_assert_aligned(signMask,16);
return _mm_xor_ps(*reinterpret_cast<const LLQuad*>(signMask), a);
}
@@ -146,6 +147,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs)
inline LLSimdScalar LLSimdScalar::getAbs() const
{
static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
ll_assert_aligned(F_ABS_MASK_4A,16);
return _mm_and_ps( mQ, *reinterpret_cast<const LLQuad*>(F_ABS_MASK_4A));
}

View File

@@ -24,6 +24,7 @@
* $/LicenseInfo$
*/
#include "llmemory.h"
#include "llmath.h"
#include "llquantize.h"
@@ -44,7 +45,10 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F
assert(dst != NULL);
assert(bytes > 0);
assert((bytes % sizeof(F32))== 0);
ll_assert_aligned(src,16);
ll_assert_aligned(dst,16);
assert(bytes%16==0);
F32* end = dst + (bytes / sizeof(F32) );
if (bytes > 64)
@@ -189,6 +193,8 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high )
LLVector4a oneOverDelta;
{
static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f };
ll_assert_aligned(F_TWO_4A,16);
LLVector4a two; two.load4a( F_TWO_4A );
// Here we use _mm_rcp_ps plus one round of newton-raphson

View File

@@ -32,6 +32,7 @@ class LLRotation;
#include <assert.h>
#include "llpreprocessor.h"
#include "llmemory.h"
///////////////////////////////////
// FIRST TIME USERS PLEASE READ
@@ -46,6 +47,7 @@ class LLRotation;
// LLVector3/LLVector4.
/////////////////////////////////
LL_ALIGN_PREFIX(16)
class LLVector4a
{
public:
@@ -90,6 +92,7 @@ public:
LLVector4a()
{ //DO NOT INITIALIZE -- The overhead is completely unnecessary
ll_assert_aligned(this,16);
}
LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f)
@@ -313,7 +316,7 @@ public:
private:
LLQuad mQ;
};
} LL_ALIGN_POSTFIX(16);
inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p)
{

View File

@@ -27,6 +27,7 @@
#ifndef LL_VECTOR4LOGICAL_H
#define LL_VECTOR4LOGICAL_H
#include "llmemory.h"
////////////////////////////
// LLVector4Logical
@@ -77,6 +78,7 @@ public:
inline LLVector4Logical& invert()
{
static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
ll_assert_aligned(allOnes,16);
mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) );
return *this;
}

View File

@@ -29,6 +29,10 @@
#include "llmath.h"
#include <set>
#if !LL_WINDOWS
#include <stdint.h>
#endif
#include <cmath>
#include "llerror.h"
#include "llmemtype.h"
@@ -91,17 +95,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;
extern BOOL gDebugGL;
void assert_aligned(void* ptr, uintptr_t alignment)
{
#if 0
uintptr_t t = (uintptr_t) ptr;
if (t%alignment != 0)
{
llerrs << "Alignment check failed." << llendl;
}
#endif
}
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
{
LLVector3 test = (pt2-pt1)%(pt3-pt2);
@@ -6963,14 +6956,14 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
if (num_verts)
{
mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
assert_aligned(mPositions, 16);
ll_assert_aligned(mPositions, 16);
mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
assert_aligned(mNormals, 16);
ll_assert_aligned(mNormals, 16);
//pad texture coordinate block end to allow for QWORD reads
S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF;
mTexCoords = (LLVector2*) ll_aligned_malloc_16(size);
assert_aligned(mTexCoords, 16);
ll_assert_aligned(mTexCoords, 16);
}
else
{
@@ -6991,17 +6984,21 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
{
S32 new_verts = mNumVertices+1;
S32 new_size = new_verts*16;
// S32 old_size = mNumVertices*16;
S32 old_size = mNumVertices*16;
//positions
mPositions = (LLVector4a*) realloc(mPositions, new_size);
mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size, old_size);
ll_assert_aligned(mPositions,16);
//normals
mNormals = (LLVector4a*) realloc(mNormals, new_size);
mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size, old_size);
ll_assert_aligned(mNormals,16);
//tex coords
new_size = ((new_verts*8)+0xF) & ~0xF;
mTexCoords = (LLVector2*) realloc(mTexCoords, new_size);
old_size = ((mNumVertices*8)+0xF) & ~0xF;
mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size, old_size);
ll_assert_aligned(mTexCoords,16);
//just clear binormals
@@ -7054,7 +7051,8 @@ void LLVolumeFace::pushIndex(const U16& idx)
S32 old_size = ((mNumIndices*2)+0xF) & ~0xF;
if (new_size != old_size)
{
mIndices = (U16*) realloc(mIndices, new_size);
mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size, old_size);
ll_assert_aligned(mIndices,16);
}
mIndices[mNumIndices++] = idx;
@@ -7095,12 +7093,12 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
}
//allocate new buffer space
mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a));
assert_aligned(mPositions, 16);
mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a));
assert_aligned(mNormals, 16);
mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF);
assert_aligned(mTexCoords, 16);
mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a));
ll_assert_aligned(mPositions, 16);
mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a));
ll_assert_aligned(mNormals, 16);
mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF, (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF);
ll_assert_aligned(mTexCoords, 16);
mNumVertices = new_count;
@@ -7146,7 +7144,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
new_count = mNumIndices + face.mNumIndices;
//allocate new index buffer
mIndices = (U16*) realloc(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF);
mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF, (mNumIndices*sizeof(U16)+0xF) & ~0xF);
//get destination address into new index buffer
U16* dst_idx = mIndices+mNumIndices;

View File

@@ -37,6 +37,15 @@
class LLVolumeTriangle : public LLRefCount
{
public:
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLVolumeTriangle()
{
mBinIndex = -1;
@@ -58,7 +67,7 @@ public:
}
LLVector4a mPositionGroup;
LL_ALIGN_16(LLVector4a mPositionGroup);
const LLVector4a* mV[3];
U16 mIndex[3];
@@ -78,6 +87,16 @@ class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
{
public:
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
~LLVolumeOctreeListener();
@@ -104,8 +123,8 @@ public:
public:
LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
LLVector4a mExtents[2]; // extents (min, max) of this node and all its children
LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
};
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle>

View File

@@ -492,12 +492,10 @@ void Stats::print(void)
// Even more strict, BufferedCurlEasyRequest may not be created directly either, only as
// base class of ThreadSafeBufferedCurlEasyRequest.
llassert(BufferedCurlEasyRequest_count == ThreadSafeBufferedCurlEasyRequest_count);
// Each AICurlEasyRequestStateMachine is responsible for exactly one easy handle.
llassert(easy_handles >= AICurlEasyRequest_count);
// Each AICurlEasyRequestStateMachine has one AICurlEasyRequest member.
llassert(AICurlEasyRequest_count >= AICurlEasyRequestStateMachine_count);
// AIFIXME: is this really always the case? And why?
llassert(easy_handles <= ResponderBase_count);
llassert(easy_handles <= S32(ResponderBase_count));
}
} // namespace AICurlInterface
@@ -1349,11 +1347,22 @@ void BufferedCurlEasyRequest::prepRequest(AICurlEasyRequest_wat& curl_easy_reque
curl_easy_request_w->setReadCallback(&curlReadCallback, lockobj);
curl_easy_request_w->setHeaderCallback(&curlHeaderCallback, lockobj);
bool allow_cookies = headers.hasHeader("Cookie");
// Allow up to ten redirects.
if (responder->followRedir())
{
curl_easy_request_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
curl_easy_request_w->setopt(CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
// This is needed (at least) for authentication after temporary redirection
// to id.secondlife.com for marketplace.secondlife.com.
allow_cookies = true;
}
if (allow_cookies)
{
// Given an empty or non-existing file or by passing the empty string (""),
// this option will enable cookies for this curl handle, making it understand
// and parse received cookies and then use matching cookies in future requests.
curl_easy_request_w->setopt(CURLOPT_COOKIEFILE, "");
}
// Keep responder alive.

View File

@@ -92,13 +92,13 @@ void PerHostRequestQueue::release(PerHostRequestQueuePtr& instance)
bool PerHostRequestQueue::throttled() const
{
llassert(mAdded <= curl_concurrent_connections_per_host);
return mAdded == curl_concurrent_connections_per_host;
llassert(mAdded <= int(curl_concurrent_connections_per_host));
return mAdded == int(curl_concurrent_connections_per_host);
}
void PerHostRequestQueue::added_to_multi_handle(void)
{
llassert(mAdded < curl_concurrent_connections_per_host);
llassert(mAdded < int(curl_concurrent_connections_per_host));
++mAdded;
}

View File

@@ -1613,7 +1613,9 @@ CURLMcode MultiHandle::remove_easy_request(addedEasyRequests_type::iterator cons
ThreadSafeBufferedCurlEasyRequest* lockobj = iter->get_ptr().get();
#endif
mAddedEasyRequests.erase(iter);
#if CWDEBUG
Dout(dc::curl, "MultiHandle::remove_easy_request: Removed AICurlEasyRequest " << (void*)lockobj << "; now processing " << mAddedEasyRequests.size() << " easy handles.");
#endif
// Attempt to add a queued request, if any.
PerHostRequestQueue_wat(*per_host)->add_queued_to(this);
@@ -2170,6 +2172,12 @@ void BufferedCurlEasyRequest::setStatusAndReason(U32 status, std::string const&
mStatus = status;
mReason = reason;
AICurlInterface::Stats::status_count[AICurlInterface::Stats::status2index(mStatus)]++;
// Sanity check. If the server replies with a redirect status then we better have that option turned on!
if ((status >= 300 && status < 400) && mResponder && !mResponder->followRedir())
{
llerrs << "Received " << status << " (" << reason << ") for responder \"" << mTimeoutPolicy->name() << "\" which has no followRedir()!" << llendl;
}
}
void BufferedCurlEasyRequest::processOutput(void)
@@ -2361,10 +2369,10 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr)
{
BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr;
#ifdef CWDEBUG
using namespace ::libcwd;
BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr;
std::ostringstream marker;
marker << (void*)request->get_lockobj();
libcw_do.push_marker();

View File

@@ -646,6 +646,12 @@ AIHTTPTimeoutPolicyBase transfer_18s(AIHTTPTimeoutPolicyBase::getDebugSettingsCu
transactionOp18s
);
// This used to be '30 seconds'.
Transaction transactionOp30s(30);
AIHTTPTimeoutPolicyBase transfer_30s(AIHTTPTimeoutPolicyBase::getDebugSettingsCurlTimeout(),
transactionOp30s
);
// This used to be '300 seconds'. We derive this from the hardcoded result so users can't mess with it.
Transaction transactionOp300s(300);
AIHTTPTimeoutPolicyBase transfer_300s(HTTPTimeoutPolicy_default,
@@ -820,6 +826,7 @@ P(accountingCostResponder);
P(agentStateResponder);
P(assetUploadResponder);
P(asyncConsoleResponder);
P(avatarPickerResponder);
P(authHandler);
P(avatarNameResponder);
P2(baseCapabilitiesComplete, transfer_18s);
@@ -838,6 +845,7 @@ P(estateChangeInfoResponder);
P(eventPollResponder);
P(fetchInventoryResponder);
P(fnPtrResponder);
P2(groupMemberDataResponder, transfer_300s);
P2(groupProposalBallotResponder, transfer_300s);
P(homeLocationResponder);
P(HTTPGetResponder);
@@ -850,6 +858,7 @@ P(lcl_responder);
P(MPImportGetResponder);
P(MPImportPostResponder);
P(mapLayerResponder);
P(maturityPreferences, transfer_30s);
P(mediaTypeResponder);
P(meshDecompositionResponder);
P(meshHeaderResponder);
@@ -889,6 +898,7 @@ P(viewerStatsResponder);
P(viewerVoiceAccountProvisionResponder);
P(voiceCallCapResponder);
P(voiceClientCapResponder);
P(webProfileResponders);
P(wholeModelFeeResponder);
P(wholeModelUploadResponder);
P2(XMLRPCResponder, connect_40s);

View File

@@ -624,7 +624,7 @@ void debug_curl_easy_reset(CURL* handle)
CURLcode debug_curl_easy_setopt(CURL* handle, CURLoption option, ...)
{
CURLcode ret;
CURLcode ret = CURLE_UNKNOWN_OPTION; // Suppress compiler warning.
va_list ap;
union param_type {
long along;
@@ -841,7 +841,7 @@ CURLMcode debug_curl_multi_remove_handle(CURLM* multi_handle, CURL* easy_handle)
CURLMcode debug_curl_multi_setopt(CURLM* multi_handle, CURLMoption option, ...)
{
CURLMcode ret;
CURLMcode ret = CURLM_UNKNOWN_OPTION; // Suppress compiler warning.
va_list ap;
union param_type {
long along;

View File

@@ -24,12 +24,12 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llavatarnamecache.h"
#include "llcachename.h" // we wrap this system
#include "llcontrol.h" // For LLCachedControl
#include "llframetimer.h"
#include "llhttpclient.h"
#include "llsd.h"
@@ -93,6 +93,9 @@ namespace LLAvatarNameCache
/// Time when unrefreshed cached names were checked last
static F64 sLastExpireCheck;
/// Time-to-live for a temp cache entry.
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
//-----------------------------------------------------------------------
// Internal methods
//-----------------------------------------------------------------------
@@ -291,13 +294,14 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
// Clear this agent from the pending list
LLAvatarNameCache::sPendingQueue.erase(agent_id);
const LLAvatarName& av_name = existing->second;
LLAvatarName& av_name = existing->second;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
<< agent_id
<< "user '" << av_name.mUsername << "' "
<< "display '" << av_name.mDisplayName << "' "
<< "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
<< LL_ENDL;
av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
}
}
@@ -342,19 +346,23 @@ void LLAvatarNameCache::requestNamesViaCapability()
// http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0
//
// Apache can handle URLs of 4096 chars, but let's be conservative
const U32 NAME_URL_MAX = 4096;
const U32 NAME_URL_SEND_THRESHOLD = 3000;
static const U32 NAME_URL_MAX = 4096;
static const U32 NAME_URL_SEND_THRESHOLD = 3500;
std::string url;
url.reserve(NAME_URL_MAX);
std::vector<LLUUID> agent_ids;
agent_ids.reserve(128);
U32 id_total = sAskQueue.size();
U32 ids = 0;
ask_queue_t::const_iterator it = sAskQueue.begin();
for ( ; it != sAskQueue.end(); ++it)
ask_queue_t::const_iterator it;
while(!sAskQueue.empty())
{
it = sAskQueue.begin();
const LLUUID& agent_id = *it;
sAskQueue.erase(it);
if (url.empty())
{
@@ -377,27 +385,17 @@ void LLAvatarNameCache::requestNamesViaCapability()
if (url.size() > NAME_URL_SEND_THRESHOLD)
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability first "
<< ids << " ids"
<< LL_ENDL;
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
url.clear();
agent_ids.clear();
break;
}
}
if (!url.empty())
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability all "
<< ids << " ids"
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested "
<< ids << "/" << id_total << "ids "
<< LL_ENDL;
LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
url.clear();
agent_ids.clear();
}
// We've moved all asks to the pending request queue
sAskQueue.clear();
}
void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
@@ -414,20 +412,25 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
<< LL_ENDL;
buildLegacyName(full_name, &av_name);
// Don't add to cache, the data already exists in the legacy name system
// cache and we don't want or need duplicate storage, because keeping the
// two copies in sync is complex.
processName(agent_id, av_name, false);
// Add to cache, because if we don't we'll keep rerequesting the
// same record forever. buildLegacyName should always guarantee
// that these records expire reasonably soon
// (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
// to something temporary we will eventually request and get the right data.
processName(agent_id, av_name, true);
}
void LLAvatarNameCache::requestNamesViaLegacy()
{
static const S32 MAX_REQUESTS = 100;
F64 now = LLFrameTimer::getTotalSeconds();
std::string full_name;
ask_queue_t::const_iterator it = sAskQueue.begin();
for (; it != sAskQueue.end(); ++it)
ask_queue_t::const_iterator it;
for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
{
it = sAskQueue.begin();
const LLUUID& agent_id = *it;
sAskQueue.erase(it);
// Mark as pending first, just in case the callback is immediately
// invoked below. This should never happen in practice.
@@ -439,10 +442,6 @@ void LLAvatarNameCache::requestNamesViaLegacy()
boost::bind(&LLAvatarNameCache::legacyNameCallback,
_1, _2, _3));
}
// We've either answered immediately or moved all asks to the
// pending queue
sAskQueue.clear();
}
void LLAvatarNameCache::initClass(bool running)
@@ -519,11 +518,11 @@ void LLAvatarNameCache::idle()
// *TODO: Possibly re-enabled this based on People API load measurements
// 100 ms is the threshold for "user speed" operations, so we can
// stall for about that long to batch up requests.
//const F32 SECS_BETWEEN_REQUESTS = 0.1f;
//if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS))
//{
// return;
//}
const F32 SECS_BETWEEN_REQUESTS = 0.1f;
if (!sRequestTimer.hasExpired())
{
return;
}
if (!sAskQueue.empty())
{
@@ -538,6 +537,12 @@ void LLAvatarNameCache::idle()
}
}
if (sAskQueue.empty())
{
// cleared the list, reset the request timer.
sRequestTimer.reset(SECS_BETWEEN_REQUESTS);
}
// erase anything that has not been refreshed for more than MAX_UNREFRESHED_TIME
eraseUnrefreshed();
}
@@ -595,7 +600,7 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
av_name->mDisplayName = full_name;
av_name->mIsDisplayNameDefault = true;
av_name->mIsTemporaryName = true;
av_name->mExpires = F64_MAX; // not used because these are not cached
av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
<< full_name
<< LL_ENDL;
@@ -619,7 +624,6 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
// ...only do immediate lookups when cache is running
if (useDisplayNames())
{
// ...use display names cache
std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
if (it != sCache.end())
@@ -664,6 +668,29 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
return false;
}
// Return true when name has been set to Phoenix Name System Name, if not return false.
bool LLAvatarNameCache::getPNSName(const LLUUID& agent_id, std::string& name)
{
LLAvatarName avatar_name;
if (get(agent_id, &avatar_name))
getPNSName(avatar_name, name);
else return false;
return true;
}
// get() with callback compatible version of getPNSName
void LLAvatarNameCache::getPNSName(const LLAvatarName& avatar_name, std::string& name)
{
static LLCachedControl<S32> phoenix_name_system("PhoenixNameSystem", 0);
switch (phoenix_name_system)
{
case 0 : name = avatar_name.getLegacyName(); break;
case 1 : name = avatar_name.getCompleteName(); break;
case 2 : name = avatar_name.mDisplayName; break;
default : name = avatar_name.getLegacyName(); break;
}
}
void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
const callback_slot_t& slot,
const LLAvatarName& av_name)
@@ -673,8 +700,10 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
signal(agent_id, av_name);
}
void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
callback_connection_t connection;
if (sRunning)
{
// ...only do immediate lookups when cache is running
@@ -690,7 +719,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
// ...name already exists in cache, fire callback now
fireSignal(agent_id, slot, av_name);
return;
return connection;
}
}
}
@@ -703,7 +732,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
LLAvatarName av_name;
buildLegacyName(full_name, &av_name);
fireSignal(agent_id, slot, av_name);
return;
return connection;
}
}
}
@@ -720,15 +749,17 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
// ...new callback for this id
callback_signal_t* signal = new callback_signal_t();
signal->connect(slot);
connection = signal->connect(slot);
sSignalMap[agent_id] = signal;
}
else
{
// ...existing callback, bind additional slot
callback_signal_t* signal = sig_it->second;
signal->connect(slot);
connection = signal->connect(slot);
}
return connection;
}
// [RLVa:KB] - Checked: 2010-12-08 (RLVa-1.4.0a) | Added: RLVa-1.2.2c
@@ -774,12 +805,6 @@ void LLAvatarNameCache::erase(const LLUUID& agent_id)
sCache.erase(agent_id);
}
void LLAvatarNameCache::fetch(const LLUUID& agent_id)
{
// re-request, even if request is already pending
sAskQueue.insert(agent_id);
}
void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
{
// *TODO: update timestamp if zero?
@@ -788,26 +813,35 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
F64 LLAvatarNameCache::nameExpirationFromHeaders(AIHTTPReceivedHeaders const& headers)
{
F64 expires;
expirationFromCacheControl(headers, &expires);
return expires;
F64 expires = 0.0;
if (expirationFromCacheControl(headers, &expires))
{
return expires;
}
else
{
// With no expiration info, default to an hour
const F64 DEFAULT_EXPIRES = 60.0 * 60.0;
F64 now = LLFrameTimer::getTotalSeconds();
return now + DEFAULT_EXPIRES;
}
}
bool LLAvatarNameCache::expirationFromCacheControl(AIHTTPReceivedHeaders const& headers, F64* expires)
{
bool fromCacheControl = false;
S32 max_age = 3600; // With no expiration info, default to an hour.
F64 now = LLFrameTimer::getTotalSeconds();
// Allow the header to override the default
std::string cache_control;
if (headers.getFirstValue("cache-control", cache_control))
{
S32 max_age = 0;
if (max_age_from_cache_control(cache_control, &max_age))
{
*expires = now + (F64)max_age;
fromCacheControl = true;
}
}
*expires = now + (F64)max_age;
LL_DEBUGS("AvNameCache")
<< ( fromCacheControl ? "expires based on cache control " : "default expiration " )
<< "in " << *expires - now << " seconds"

View File

@@ -65,16 +65,23 @@ namespace LLAvatarNameCache
// If name is in cache, returns true and fills in provided LLAvatarName
// otherwise returns false
bool get(const LLUUID& agent_id, LLAvatarName *av_name);
// If get() succeeds, returns true and fills in name string
// via void function below, otherwise returns false
bool getPNSName(const LLUUID& agent_id, std::string& name);
// Perform a filling of name string according to Phoenix Name System,
// when we have an LLAvatarName already.
void getPNSName(const LLAvatarName& avatar_name, std::string& name);
// Callback types for get() below
typedef boost::signals2::signal<
void (const LLUUID& agent_id, const LLAvatarName& av_name)>
callback_signal_t;
typedef callback_signal_t::slot_type callback_slot_t;
typedef boost::signals2::connection callback_connection_t;
// Fetches name information and calls callback.
// If name information is in cache, callback will be called immediately.
void get(const LLUUID& agent_id, callback_slot_t slot);
callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
// Allow display names to be explicitly disabled for testing.
void setUseDisplayNames(bool use);
@@ -90,10 +97,6 @@ namespace LLAvatarNameCache
/// Provide some fallback for agents that return errors
void handleAgentError(const LLUUID& agent_id);
// Force a re-fetch of the most recent data, but keep the current
// data in cache
void fetch(const LLUUID& agent_id);
void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
// Compute name expiration time from HTTP Cache-Control header,

View File

@@ -161,7 +161,7 @@ public:
// A derived class should return true if curl should follow redirections.
// The default is not to follow redirections.
virtual bool followRedir(void) { return false; }
virtual bool followRedir(void) const { return false; }
// Timeout policy to use.
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const = 0;
@@ -188,6 +188,7 @@ public:
class ResponderHeadersOnly : public ResponderBase {
private:
/*virtual*/ bool needsHeaders(void) const { return true; }
/*virtual*/ bool followRedir(void) const { return true; }
protected:
// ResponderBase event

View File

@@ -85,11 +85,6 @@ LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string cons
void LLURLRequest::initialize_impl(void)
{
if (mHeaders.hasHeader("Cookie"))
{
allowCookies();
}
// If the header is "Pragma" with no value, the caller intends to
// force libcurl to drop the Pragma header it so gratuitously inserts.
// Before inserting the header, force libcurl to not use the proxy.
@@ -105,7 +100,7 @@ void LLURLRequest::initialize_impl(void)
// but if they did not specify a Content-Type, then ask the injector.
mHeaders.addHeader("Content-Type", mBody->contentType(), AIHTTPHeaders::keep_existing_header);
}
else
else if (mAction != HTTP_HEAD)
{
// Check to see if we have already set Accept or not. If no one
// set it, set it to application/llsd+xml since that's what we
@@ -199,12 +194,6 @@ void LLURLRequest::useProxy(const std::string &proxy)
}
#endif
void LLURLRequest::allowCookies()
{
AICurlEasyRequest_wat curlEasyRequest_w(*mCurlEasyRequest);
curlEasyRequest_w->setoptString(CURLOPT_COOKIEFILE, "");
}
bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w)
{
bool rv = false;
@@ -213,13 +202,11 @@ bool LLURLRequest::configure(AICurlEasyRequest_wat const& curlEasyRequest_w)
{
case HTTP_HEAD:
curlEasyRequest_w->setopt(CURLOPT_NOBODY, 1);
curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
rv = true;
break;
case HTTP_GET:
curlEasyRequest_w->setopt(CURLOPT_HTTPGET, 1);
curlEasyRequest_w->setopt(CURLOPT_FOLLOWLOCATION, 1);
// Set Accept-Encoding to allow response compression
curlEasyRequest_w->setoptString(CURLOPT_ENCODING, mNoCompression ? "identity" : "");

View File

@@ -84,11 +84,6 @@ class LLURLRequest : public AICurlEasyRequestStateMachine {
/*virtual*/ ~LLURLRequest() { }
public:
/**
* @brief Turn on cookie handling for this request with CURLOPT_COOKIEFILE.
*/
void allowCookies(void);
/**
* @ brief Turn off (or on) the CURLOPT_PROXY header.
*/

View File

@@ -1027,7 +1027,8 @@ void LLModel::setVolumeFaceData(
if (tc.get())
{
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32));
U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF;
LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size);
}
else
{

View File

@@ -71,7 +71,7 @@ void LLStyle::drawControl(ControlElement element, const QStyleOption *option, QP
QPlastiqueStyle::drawControl(element, &localOption, painter, widget);
return;
}
default:
break;
}

View File

@@ -935,7 +935,7 @@ void LLGLManager::initExtensions()
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
mHasTransformFeedback = mGLVersion >= 4.f || ExtensionExists("GL_EXT_transform_feedback", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif

View File

@@ -1329,6 +1329,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
llassert(mCurrentDiscardLevel >= 0);
discard_level = mCurrentDiscardLevel;
}
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
{
@@ -1586,7 +1587,18 @@ void LLImageGL::destroyGLTexture()
}
}
//force to invalidate the gl texture, most likely a sculpty texture
void LLImageGL::forceToInvalidateGLTexture()
{
if (mTexName != 0)
{
destroyGLTexture();
}
else
{
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
}
}
//----------------------------------------------------------------------------

View File

@@ -119,6 +119,7 @@ public:
// Read back a raw image for this discard level, if it exists
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok);
void destroyGLTexture();
void forceToInvalidateGLTexture();
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
void setComponents(S8 ncomponents) { mComponents = ncomponents; }

View File

@@ -49,12 +49,63 @@ extern LLGLSLShader gPostNightVisionProgram;
extern LLGLSLShader gPostGaussianBlurProgram;
extern LLGLSLShader gPostPosterizeProgram;
extern LLGLSLShader gPostMotionBlurProgram;
extern LLGLSLShader gPostVignetteProgram;
static const unsigned int NOISE_SIZE = 512;
static const char * const XML_FILENAME = "postprocesseffects.xml";
template<> LLSD LLPostProcessShader::LLShaderSetting<LLVector4>::getDefaultValue()
class LLPostProcessShader : public IPostProcessShader, public LLRefCount
{
public:
LLPostProcessShader(const std::string& enable_name, LLGLSLShader& shader, bool enabled = false) :
mShader(shader), mEnabled(enable_name,enabled)
{
addSetting(mEnabled);
}
/*virtual*/ bool isEnabled() const {return mShader.mProgramObject && mEnabled;}
/*virtual*/ void bindShader() {mShader.bind();}
/*virtual*/ void unbindShader() {mShader.unbind();}
/*virtual*/ LLGLSLShader& getShader() {return mShader;}
/*virtual*/ LLSD getDefaults(); //See IPostProcessShader::getDefaults
/*virtual*/ void loadSettings(const LLSD& settings); //See IPostProcessShader::loadSettings
/*virtual*/ void addSetting(IShaderSettingBase& setting) { mSettings.push_back(&setting); }
protected:
template<typename T>
struct LLShaderSetting : public IShaderSettingBase
{
LLShaderSetting(const std::string& name, T def) :
mValue(def), mDefault(def), mSettingName(name) {}
operator T() const { return mValue; }
T get() const { return mValue; }
/*virtual*/ const std::string& getName() const { return mSettingName; } //See LLShaderSettingBase::getName
/*virtual*/ LLSD getDefaultValue() const { return mDefault; } //See LLShaderSettingBase::getDefaultValue
/*virtual*/ void setValue(const LLSD& value) { mValue = value; } //See LLShaderSettingBase::setValue
private:
const std::string mSettingName; //LLSD key names as found in postprocesseffects.xml. eg 'contrast_base'
T mValue; //The member variable mentioned above.
T mDefault; //Set via ctor. Value is inserted into the defaults LLSD list if absent from postprocesseffects.xml
};
private:
std::vector<IShaderSettingBase*> mSettings; //Contains a list of all the 'settings' this shader uses. Manually add via push_back in ctor.
LLGLSLShader& mShader;
LLShaderSetting<bool> mEnabled;
};
//helpers
class LLPostProcessSinglePassColorShader : public LLPostProcessShader
{
public:
LLPostProcessSinglePassColorShader(const std::string& enable_name, LLGLSLShader& shader, bool enabled = false) :
LLPostProcessShader(enable_name, shader, enabled) {}
/*virtual*/ S32 getColorChannel() const {return 0;}
/*virtual*/ S32 getDepthChannel() const {return -1;}
/*virtual*/ bool draw(U32 pass) {return pass == 1;}
/*virtual*/ void postDraw() {}
};
template<> LLSD LLPostProcessShader::LLShaderSetting<LLVector4>::getDefaultValue() const
{
return mDefault.getValue();
}
@@ -66,223 +117,181 @@ template<> void LLPostProcessShader::LLShaderSetting<LLVector4>::setValue(const
LLSD LLPostProcessShader::getDefaults()
{
LLSD defaults;
for(std::vector<LLShaderSettingBase*>::iterator it=mSettings.begin();it!=mSettings.end();++it)
for(std::vector<IShaderSettingBase*>::iterator it=mSettings.begin();it!=mSettings.end();++it)
{
defaults[(*it)->mSettingName]=(*it)->getDefaultValue();
defaults[(*it)->getName()]=(*it)->getDefaultValue();
}
return defaults;
}
void LLPostProcessShader::loadSettings(const LLSD& settings)
{
for(std::vector<LLShaderSettingBase*>::iterator it=mSettings.begin();it!=mSettings.end();++it)
for(std::vector<IShaderSettingBase*>::iterator it=mSettings.begin();it!=mSettings.end();++it)
{
LLSD value = settings[(*it)->mSettingName];
LLSD value = settings[(*it)->getName()];
(*it)->setValue(value);
}
}
class LLColorFilterShader : public LLPostProcessShader
class LLColorFilterShader : public LLPostProcessSinglePassColorShader
{
private:
LLShaderSetting<bool> mEnabled;
LLShaderSetting<F32> mGamma, mBrightness, mContrast, mSaturation;
LLShaderSetting<LLVector4> mContrastBase;
public:
LLColorFilterShader() :
mEnabled("enable_color_filter",false),
LLColorFilterShader() :
LLPostProcessSinglePassColorShader("enable_color_filter",gPostColorFilterProgram),
mGamma("gamma",1.f),
mBrightness("brightness",1.f),
mContrast("contrast",1.f),
mSaturation("saturation",1.f),
mContrastBase("contrast_base",LLVector4(1.f,1.f,1.f,0.5f))
{
mSettings.push_back(&mEnabled);
mSettings.push_back(&mGamma);
mSettings.push_back(&mBrightness);
mSettings.push_back(&mContrast);
mSettings.push_back(&mSaturation);
mSettings.push_back(&mContrastBase);
addSetting(mGamma);
addSetting(mBrightness);
addSetting(mContrast);
addSetting(mSaturation);
addSetting(mContrastBase);
}
bool isEnabled() { return mEnabled && gPostColorFilterProgram.mProgramObject; }
S32 getColorChannel() { return 0; }
S32 getDepthChannel() { return -1; }
QuadType bind()
/*virtual*/ QuadType preDraw()
{
if(!isEnabled())
return QUAD_NONE;
/// CALCULATING LUMINANCE (Using NTSC lum weights)
/// http://en.wikipedia.org/wiki/Luma_%28video%29
static const float LUMINANCE_R = 0.299f;
static const float LUMINANCE_G = 0.587f;
static const float LUMINANCE_B = 0.114f;
gPostColorFilterProgram.bind();
getShader().uniform1f("gamma", mGamma);
getShader().uniform1f("brightness", mBrightness);
getShader().uniform1f("contrast", mContrast);
float baseI = (mContrastBase.get()[VX] + mContrastBase.get()[VY] + mContrastBase.get()[VZ]) / 3.0f;
baseI = mContrastBase.get()[VW] / llmax(baseI,0.001f);
float baseR = mContrastBase.get()[VX] * baseI;
float baseG = mContrastBase.get()[VY] * baseI;
float baseB = mContrastBase.get()[VZ] * baseI;
getShader().uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV);
getShader().uniform1f("saturation", mSaturation);
gPostColorFilterProgram.uniform1f("gamma", mGamma);
gPostColorFilterProgram.uniform1f("brightness", mBrightness);
gPostColorFilterProgram.uniform1f("contrast", mContrast);
float baseI = (mContrastBase.mValue[VX] + mContrastBase.mValue[VY] + mContrastBase.mValue[VZ]) / 3.0f;
baseI = mContrastBase.mValue[VW] / ((baseI < 0.001f) ? 0.001f : baseI);
float baseR = mContrastBase.mValue[VX] * baseI;
float baseG = mContrastBase.mValue[VY] * baseI;
float baseB = mContrastBase.mValue[VZ] * baseI;
gPostColorFilterProgram.uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV);
gPostColorFilterProgram.uniform1f("saturation", mSaturation);
gPostColorFilterProgram.uniform3fv("lumWeights", 1, LLVector3(LUMINANCE_R, LUMINANCE_G, LUMINANCE_B).mV);
return QUAD_NORMAL;
}
bool draw(U32 pass) {return pass == 1;}
void unbind()
{
gPostColorFilterProgram.unbind();
}
};
class LLNightVisionShader : public LLPostProcessShader
class LLNightVisionShader : public LLPostProcessSinglePassColorShader
{
private:
LLShaderSetting<bool> mEnabled;
LLShaderSetting<F32> mBrightnessMult, mNoiseStrength;
public:
LLNightVisionShader() :
mEnabled("enable_night_vision",false),
LLPostProcessSinglePassColorShader("enable_night_vision",gPostNightVisionProgram),
mBrightnessMult("brightness_multiplier",3.f),
mNoiseStrength("noise_strength",.4f)
{
mSettings.push_back(&mEnabled);
mSettings.push_back(&mBrightnessMult);
mSettings.push_back(&mNoiseStrength);
addSetting(mBrightnessMult);
addSetting(mNoiseStrength);
}
bool isEnabled() { return mEnabled && gPostNightVisionProgram.mProgramObject; }
S32 getColorChannel() { return 0; }
S32 getDepthChannel() { return -1; }
QuadType bind()
/*virtual*/ QuadType preDraw()
{
if(!isEnabled())
return QUAD_NONE;
gPostNightVisionProgram.bind();
LLPostProcess::getInstance()->bindNoise(1);
gPostNightVisionProgram.uniform1f("brightMult", mBrightnessMult);
gPostNightVisionProgram.uniform1f("noiseStrength", mNoiseStrength);
getShader().uniform1f("brightMult", mBrightnessMult);
getShader().uniform1f("noiseStrength", mNoiseStrength);
return QUAD_NOISE;
}
bool draw(U32 pass) {return pass == 1;}
void unbind()
};
class LLPosterizeShader : public LLPostProcessSinglePassColorShader
{
private:
LLShaderSetting<S32> mNumLayers;
public:
LLPosterizeShader() : LLPostProcessSinglePassColorShader("enable_posterize",gPostPosterizeProgram),
mNumLayers("posterize_layers",2)
{
gPostNightVisionProgram.unbind();
addSetting(mNumLayers);
}
/*virtual*/ QuadType preDraw()
{
getShader().uniform1i("layerCount", mNumLayers);
return QUAD_NORMAL;
}
};
class LLVignetteShader : public LLPostProcessSinglePassColorShader
{
private:
LLShaderSetting<F32> mStrength, mRadius, mDarkness, mDesaturation, mChromaticAberration;
public:
LLVignetteShader() : LLPostProcessSinglePassColorShader("enable_vignette",gPostVignetteProgram),
mStrength("vignette_strength",.85f),
mRadius("vignette_radius",.7f),
mDarkness("vignette_darkness",1.f),
mDesaturation("vignette_desaturation",1.5f),
mChromaticAberration("vignette_chromatic_aberration",.05f)
{
addSetting(mStrength);
addSetting(mRadius);
addSetting(mDarkness);
addSetting(mDesaturation);
addSetting(mChromaticAberration);
}
/*virtual*/ QuadType preDraw()
{
LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions();
getShader().uniform1f("vignette_strength", mStrength);
getShader().uniform1f("vignette_radius", mRadius);
getShader().uniform1f("vignette_darkness", mDarkness);
getShader().uniform1f("vignette_desaturation", mDesaturation);
getShader().uniform1f("vignette_chromatic_aberration", mChromaticAberration);
getShader().uniform2fv("screen_res", 1, screen_rect.mV);
return QUAD_NORMAL;
}
};
class LLGaussBlurShader : public LLPostProcessShader
{
private:
LLShaderSetting<bool> mEnabled;
LLShaderSetting<S32> mNumPasses;
GLint mPassLoc;
public:
LLGaussBlurShader() :
mEnabled("enable_gauss_blur",false),
LLGaussBlurShader() : LLPostProcessShader("enable_gauss_blur",gPostGaussianBlurProgram),
mNumPasses("gauss_blur_passes",2),
mPassLoc(0)
{
mSettings.push_back(&mEnabled);
mSettings.push_back(&mNumPasses);
addSetting(mNumPasses);
}
bool isEnabled() { return mEnabled && mNumPasses && gPostGaussianBlurProgram.mProgramObject; }
S32 getColorChannel() { return 0; }
S32 getDepthChannel() { return -1; }
QuadType bind()
/*virtual*/ bool isEnabled() const { return LLPostProcessShader::isEnabled() && mNumPasses.get(); }
/*virtual*/ S32 getColorChannel() const { return 0; }
/*virtual*/ S32 getDepthChannel() const { return -1; }
/*virtual*/ QuadType preDraw()
{
if(!isEnabled())
return QUAD_NONE;
gPostGaussianBlurProgram.bind();
mPassLoc = gPostGaussianBlurProgram.getUniformLocation("horizontalPass");
mPassLoc = getShader().getUniformLocation("horizontalPass");
return QUAD_NORMAL;
}
bool draw(U32 pass)
/*virtual*/ bool draw(U32 pass)
{
if((S32)pass > mNumPasses*2)
return false;
glUniform1iARB(mPassLoc, (pass-1) % 2);
return true;
}
void unbind()
{
gPostGaussianBlurProgram.unbind();
}
};
class LLPosterizeShader : public LLPostProcessShader
{
private:
LLShaderSetting<bool> mEnabled;
LLShaderSetting<S32> mNumLayers;
public:
LLPosterizeShader() :
mEnabled("enable_posterize",false),
mNumLayers("posterize_layers",2)
{
mSettings.push_back(&mEnabled);
mSettings.push_back(&mNumLayers);
}
bool isEnabled() { return mEnabled && gPostPosterizeProgram.mProgramObject; }
S32 getColorChannel() { return 0; }
S32 getDepthChannel() { return -1; }
QuadType bind()
{
if(!isEnabled())
return QUAD_NONE;
gPostPosterizeProgram.bind();
gPostPosterizeProgram.uniform1i("layerCount", mNumLayers);
return QUAD_NORMAL;
}
bool draw(U32 pass)
{
return pass == 1;
}
void unbind()
{
gPostPosterizeProgram.unbind();
}
/*virtual*/ void postDraw() {}
};
class LLMotionShader : public LLPostProcessShader
{
private:
LLShaderSetting<bool> mEnabled;
LLShaderSetting<S32> mStrength;
public:
LLMotionShader() :
mEnabled("enable_motionblur",false),
mStrength("blur_strength",false)
LLMotionShader() : LLPostProcessShader("enable_motionblur",gPostMotionBlurProgram),
mStrength("blur_strength",1)
{
mSettings.push_back(&mEnabled);
mSettings.push_back(&mStrength);
addSetting(mStrength);
}
bool isEnabled() { return mEnabled && gPostMotionBlurProgram.mProgramObject; }
S32 getColorChannel() { return 0; }
S32 getDepthChannel() { return 1; }
QuadType bind()
/*virtual*/ S32 getColorChannel() const { return 0; }
/*virtual*/ S32 getDepthChannel() const { return 1; }
/*virtual*/ QuadType preDraw()
{
if(!isEnabled())
{
return QUAD_NONE;
}
glh::matrix4f inv_proj(gGLModelView);
inv_proj.mult_left(gGLProjection);
inv_proj = inv_proj.inverse();
@@ -291,22 +300,18 @@ public:
LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions();
gPostMotionBlurProgram.bind();
gPostMotionBlurProgram.uniformMatrix4fv("prev_proj", 1, GL_FALSE, prev_proj.m);
gPostMotionBlurProgram.uniformMatrix4fv("inv_proj", 1, GL_FALSE, inv_proj.m);
gPostMotionBlurProgram.uniform2fv("screen_res", 1, screen_rect.mV);
gPostMotionBlurProgram.uniform1i("blur_strength", mStrength);
getShader().uniformMatrix4fv("prev_proj", 1, GL_FALSE, prev_proj.m);
getShader().uniformMatrix4fv("inv_proj", 1, GL_FALSE, inv_proj.m);
getShader().uniform2fv("screen_res", 1, screen_rect.mV);
getShader().uniform1i("blur_strength", mStrength);
return QUAD_NORMAL;
}
bool draw(U32 pass)
/*virtual*/ bool draw(U32 pass)
{
return pass == 1;
}
void unbind()
{
gPostMotionBlurProgram.unbind();
}
/*virtual*/ void postDraw() {}
};
LLPostProcess::LLPostProcess(void) :
@@ -320,12 +325,12 @@ LLPostProcess::LLPostProcess(void) :
mAllEffectInfo(LLSD::emptyMap())
{
mShaders.push_back(new LLMotionShader());
mShaders.push_back(new LLVignetteShader());
mShaders.push_back(new LLColorFilterShader());
mShaders.push_back(new LLNightVisionShader());
mShaders.push_back(new LLGaussBlurShader());
mShaders.push_back(new LLPosterizeShader());
/* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.*/
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL;
@@ -547,20 +552,19 @@ void LLPostProcess::doEffects(void)
void LLPostProcess::applyShaders(void)
{
QuadType quad;
bool primary_rendertarget = 1;
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
{
if((quad = (*it)->bind()) != QUAD_NONE)
if((*it)->isEnabled())
{
S32 color_channel = (*it)->getColorChannel();
S32 depth_channel = (*it)->getDepthChannel();
if(depth_channel >= 0)
gGL.getTexUnit(depth_channel)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mDepthTexture);
U32 pass = 1;
(*it)->bindShader();
QuadType quad = (*it)->preDraw();
while((*it)->draw(pass++))
{
mRenderTarget[!primary_rendertarget].bindTarget();
@@ -573,7 +577,8 @@ void LLPostProcess::applyShaders(void)
if(mRenderTarget[0].getFBO())
primary_rendertarget = !primary_rendertarget;
}
(*it)->unbind();
(*it)->postDraw();
(*it)->unbindShader();
}
}
//Only need to copy to framebuffer if FBOs are supported, else we've already been drawing to the framebuffer to begin with.

View File

@@ -38,57 +38,48 @@
#include "llrendertarget.h"
class LLSD;
class LLGLSLShader;
typedef enum _QuadType {
QUAD_NONE,
QUAD_NORMAL,
QUAD_NOISE
} QuadType;
//LLPostProcessShader is an attempt to encapsulate the shaders a little better.
class LLPostProcessShader : public LLRefCount //Abstract. PostProcess shaders derive off of this common base.
class IPostProcessShader //Abstract. PostProcess shaders derive off of this common base.
{
protected:
//LLShaderSetting is used to associate key names to member variables to avoid LLSD lookups when drawing.
//It also facilitates automating the assigning of defaults to, as well as parsing from, the effects LLSD list.
//This replaces the entire old PostProcessTweaks structure. More will be done in the future to move into a more
//xml-driven configuration.
struct LLShaderSettingBase
struct IShaderSettingBase
{
LLShaderSettingBase(const char* name) : mSettingName(name) {}
const char* mSettingName; //LLSD key names as found in postprocesseffects.xml. eg 'contrast_base'
virtual LLSD getDefaultValue() = 0; //Converts the member variable as an LLSD. Used to set defaults absent in postprocesseffects.xml
virtual ~IShaderSettingBase() {} //virtual dtor.
virtual const std::string& getName() const = 0; //Returns the name of this setting
virtual LLSD getDefaultValue() const = 0; //Converts the member variable as an LLSD. Used to set defaults absent in postprocesseffects.xml
virtual void setValue(const LLSD& value) = 0; //Connects the LLSD element to the member variable. Used when loading effects (such as default)
};
template<typename T>
struct LLShaderSetting : public LLShaderSettingBase
{
LLShaderSetting(const char* setting_name, T def) : LLShaderSettingBase(setting_name), mValue(def), mDefault(def) {}
T mValue; //The member variable mentioned above.
T mDefault; //Set via ctor. Value is inserted into the defaults LLSD list if absent from postprocesseffects.xml
LLSD getDefaultValue() { return mDefault; } //See LLShaderSettingBase::getDefaultValue
void setValue(const LLSD& value) { mValue = value; } //See LLShaderSettingBase::setValue
operator T() { return mValue; } //Typecast operator overload so this object can be handled as if it was whatever T represents.
};
std::vector<LLShaderSettingBase*> mSettings; //Contains a list of all the 'settings' this shader uses. Manually add via push_back in ctor.
public:
virtual ~LLPostProcessShader() {};
virtual bool isEnabled() = 0; //Returning false avoids bind/draw/unbind calls. If no shaders are enabled, framebuffer copying is skipped.
virtual S32 getColorChannel() = 0; //If color buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer.
virtual S32 getDepthChannel() = 0; //If depth buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer.
virtual QuadType bind() = 0; //Bind shader and textures, set up attribs. Returns the 'type' of quad to be drawn.
virtual ~IPostProcessShader() {} //virtual dtor.
virtual bool isEnabled() const = 0; //Returning false avoids bind/draw/unbind calls. If no shaders are enabled, framebuffer copying is skipped.
virtual S32 getColorChannel() const = 0; //If color buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer.
virtual S32 getDepthChannel() const = 0; //If depth buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer.
virtual void bindShader() = 0;
virtual void unbindShader() = 0;
virtual LLGLSLShader& getShader() = 0;
virtual QuadType preDraw() = 0; //Bind shader and textures, set up attribs. Returns the 'type' of quad to be drawn.
virtual bool draw(U32 pass) = 0; //returning false means finished. Used to update per-pass attributes and such. LLPostProcess will call
//drawOrthoQuad when this returns true, increment pass, then call this again, and keep repeating this until false is returned.
virtual void unbind() = 0; //Unbind shader and textures.
virtual void postDraw() = 0; //Done drawing..
LLSD getDefaults(); //Returns a full LLSD kvp list filled with default values.
void loadSettings(const LLSD& settings); //Parses the effects LLSD list and sets the member variables linked to them (via LLShaderSetting::setValue())
virtual LLSD getDefaults() = 0; //Returns a full LLSD kvp list filled with default values.
virtual void loadSettings(const LLSD& settings) = 0; //Parses the effects LLSD list and sets the member variables linked to them (via LLShaderSetting::setValue())
virtual void addSetting(IShaderSettingBase& setting) = 0;
};
//LLVector4 does not implicitly convert to and from LLSD, so template specilizations are necessary.
template<> LLSD LLPostProcessShader::LLShaderSetting<LLVector4>::getDefaultValue();
template<> void LLPostProcessShader::LLShaderSetting<LLVector4>::setValue(const LLSD& value);
class LLPostProcessShader;
class LLPostProcess : public LLSingleton<LLPostProcess>
{
private:

View File

@@ -229,8 +229,6 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
stop_glerror();
if (mIndex < 0) return false;
gGL.flush();
LLImageGL* gl_tex = NULL ;
if (texture == NULL || !(gl_tex = texture->getGLTexture()))
{
@@ -258,6 +256,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
}
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
gGL.flush();
activate();
enable(gl_tex->getTarget());
mCurrTexture = gl_tex->getTexName();
@@ -1120,6 +1119,9 @@ void LLRender::refreshState(void)
setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal);
//Singu note: Also reset glBlendFunc
blendFunc(mCurrBlendColorSFactor,mCurrBlendColorDFactor,mCurrBlendAlphaSFactor,mCurrBlendAlphaDFactor);
mDirty = false;
}
@@ -1510,20 +1512,26 @@ void LLRender::pushUIMatrix()
{
if (mUIOffset.empty())
{
mUIOffset.push_back(new LLVector4a(0.f));
mUIOffset.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
mUIOffset.back()->splat(0.f);
}
else
{
mUIOffset.push_back(new LLVector4a(*mUIOffset.back()));
const LLVector4a* last_entry = mUIOffset.back();
mUIOffset.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
*mUIOffset.back() = *last_entry;
}
if (mUIScale.empty())
{
mUIScale.push_back(new LLVector4a(1.f));
mUIScale.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
mUIScale.back()->splat(1.f);
}
else
{
mUIScale.push_back(new LLVector4a(*mUIScale.back()));
const LLVector4a* last_entry = mUIScale.back();
mUIScale.push_back(static_cast<LLVector4a*>(ll_aligned_malloc_16(sizeof(LLVector4a))));
*mUIScale.back() = *last_entry;
}
}
@@ -1533,9 +1541,9 @@ void LLRender::popUIMatrix()
{
llerrs << "UI offset stack blown." << llendl;
}
delete mUIOffset.back();
ll_aligned_free_16(mUIOffset.back());
mUIOffset.pop_back();
delete mUIScale.back();
ll_aligned_free_16(mUIScale.back());
mUIScale.pop_back();
}
@@ -1580,7 +1588,7 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB
if (mCurrColorMask[0] != writeColorR ||
mCurrColorMask[1] != writeColorG ||
mCurrColorMask[2] != writeColorB ||
mCurrColorMask[3] != writeAlpha)
mCurrColorMask[3] != writeAlpha || mDirty)
{
mCurrColorMask[0] = writeColorR;
mCurrColorMask[1] = writeColorG;
@@ -1635,7 +1643,7 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
}
if (mCurrAlphaFunc != func ||
mCurrAlphaFuncVal != value)
mCurrAlphaFuncVal != value || mDirty)
{
mCurrAlphaFunc = func;
mCurrAlphaFuncVal = value;
@@ -1679,7 +1687,7 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
llassert(sfactor < BF_UNDEF);
llassert(dfactor < BF_UNDEF);
if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor ||
mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)
mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor || mDirty)
{
mCurrBlendColorSFactor = sfactor;
mCurrBlendAlphaSFactor = sfactor;
@@ -1704,7 +1712,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
return;
}
if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor || mDirty)
{
mCurrBlendColorSFactor = color_sfactor;
mCurrBlendAlphaSFactor = alpha_sfactor;

View File

@@ -813,7 +813,6 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
}
check_framebuffer_status();
}
stop_glerror();

View File

@@ -25,6 +25,7 @@
*/
#include "linden_common.h"
#include <boost/filesystem.hpp> //First, because glh_linear #defines equivalent.. which boost uses internally
#include "llshadermgr.h"
@@ -53,6 +54,17 @@ LLShaderMgr * LLShaderMgr::sInstance = NULL;
LLShaderMgr::LLShaderMgr()
{
{
const std::string dumpdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"shader_dump")+gDirUtilp->getDirDelimiter();
try
{
boost::filesystem::remove_all(dumpdir);
}
catch(const boost::filesystem::filesystem_error& e)
{
llinfos << "boost::filesystem::remove_all(\""+dumpdir+"\") failed: '" + e.code().message() + "'" << llendl;
}
}
}
@@ -660,6 +672,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
}
static const LLCachedControl<bool> SHPackDeferredNormals("SHPackDeferredNormals",false);
if(SHPackDeferredNormals)
text[count++] = strdup("#define PACK_NORMALS\n");
//copy preprocessor definitions into buffer
for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
{
@@ -1116,7 +1132,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("ssao_max_radius");
mReservedUniforms.push_back("ssao_factor");
mReservedUniforms.push_back("ssao_factor_inv");
mReservedUniforms.push_back("ssao_effect_mat");
mReservedUniforms.push_back("ssao_effect");
mReservedUniforms.push_back("screen_res");
mReservedUniforms.push_back("near_clip");
mReservedUniforms.push_back("shadow_offset");

View File

@@ -120,7 +120,7 @@ public:
DEFERRED_SSAO_MAX_RADIUS,
DEFERRED_SSAO_FACTOR,
DEFERRED_SSAO_FACTOR_INV,
DEFERRED_SSAO_EFFECT_MAT,
DEFERRED_SSAO_EFFECT,
DEFERRED_SCREEN_RES,
DEFERRED_NEAR_CLIP,
DEFERRED_SHADOW_OFFSET,

View File

@@ -2083,6 +2083,16 @@ void LLVertexBuffer::flush()
}
}
// bind for transform feedback (quick 'n dirty)
void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
{
#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
U32 offset = mOffsets[type] + sTypeSize[type]*index;
U32 size= (sTypeSize[type]*count);
glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
#endif
}
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{

View File

@@ -202,16 +202,18 @@ protected:
void destroyGLIndices();
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
bool useVBOs() const;
void unmapBuffer();
public:
LLVertexBuffer(U32 typemask, S32 usage);
// map for data access
volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
void bindForFeedback(U32 channel, U32 type, U32 index, U32 count);
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
void flush(); //flush pending data to GL memory
@@ -240,6 +242,7 @@ public:
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool useVBOs() const;
bool isEmpty() const { return mEmpty; }
bool isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; }

View File

@@ -615,7 +615,7 @@ void LLComboBox::showList()
S32 min_width = getRect().getWidth();
S32 max_width = llmax(min_width, MAX_COMBO_WIDTH);
// make sure we have up to date content width metrics
mList->calcColumnWidths();
mList->updateColumnWidths();
S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width);
if (mListPosition == BELOW)
@@ -707,7 +707,7 @@ void LLComboBox::hideList()
mButton->setToggleState(FALSE);
mList->setVisible(FALSE);
mList->highlightNthItem(-1);
mList->mouseOverHighlightNthItem(-1);
setUseBoundingRect(FALSE);
if( gFocusMgr.getTopCtrl() == this )
@@ -731,7 +731,7 @@ void LLComboBox::onButtonDown(void *userdata)
if (last_selected_item)
{
// highlight the original selection before potentially selecting a new item
self->mList->highlightNthItem(self->mList->getItemIndex(last_selected_item));
self->mList->mouseOverHighlightNthItem(self->mList->getItemIndex(last_selected_item));
}
if( self->mPrearrangeCallback )
@@ -839,7 +839,7 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
if (last_selected_item)
{
// highlight the original selection before potentially selecting a new item
mList->highlightNthItem(mList->getItemIndex(last_selected_item));
mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
}
result = mList->handleKeyHere(key, mask);
@@ -873,7 +873,7 @@ BOOL LLComboBox::handleUnicodeCharHere(llwchar uni_char)
if (last_selected_item)
{
// highlight the original selection before potentially selecting a new item
mList->highlightNthItem(mList->getItemIndex(last_selected_item));
mList->mouseOverHighlightNthItem(mList->getItemIndex(last_selected_item));
}
result = mList->handleUnicodeCharHere(uni_char);
if (mList->getLastSelectedItem() != last_selected_item)

View File

@@ -148,7 +148,6 @@ LLFloater::LLFloater() :
mResizeHandle[i] = NULL;
}
mDragHandle = NULL;
mHandle.bind(this);
mNotificationContext = new LLFloaterNotificationContext(getHandle());
}
@@ -222,7 +221,6 @@ void LLFloater::initFloater(const std::string& title,
BOOL resizable, S32 min_width, S32 min_height,
BOOL drag_on_left, BOOL minimizable, BOOL close_btn)
{
mHandle.bind(this);
mNotificationContext = new LLFloaterNotificationContext(getHandle());
// Init function can be called more than once, so clear out old data.
@@ -422,7 +420,7 @@ void LLFloater::initFloater(const std::string& title,
setVisible(FALSE);
// add self to handle->floater map
sFloaterMap[mHandle] = this;
sFloaterMap[getHandle()] = this;
if (!getParent())
{
@@ -483,7 +481,7 @@ LLFloater::~LLFloater()
// correct, non-minimized positions.
setMinimized( FALSE );
sFloaterMap.erase(mHandle);
sFloaterMap.erase(getHandle());
delete mDragHandle;
for (S32 i = 0; i < 4; i++)

View File

@@ -227,7 +227,7 @@ public:
void clearSnapTarget() { mSnappedTo.markDead(); }
LLHandle<LLFloater> getSnapTarget() const { return mSnappedTo; }
LLHandle<LLFloater> getHandle() const { return mHandle; }
LLHandle<LLFloater> getHandle() const { return getDerivedHandle<LLFloater>(); }
// Return a closeable floater, if any, given the current focus.
static LLFloater* getClosableFloaterFromFocus();
@@ -331,7 +331,6 @@ private:
S32 mPreviousMinimizedLeft;
LLFloaterNotificationContext* mNotificationContext;
LLRootHandle<LLFloater> mHandle;
};
/////////////////////////////////////////////////////////////

View File

@@ -28,38 +28,67 @@
#define LLHANDLE_H
#include "llpointer.h"
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
template <typename T>
/**
* Helper object for LLHandle. Don't instantiate these directly, used
* exclusively by LLHandle.
*/
class LLTombStone : public LLRefCount
{
public:
LLTombStone(T* target = NULL) : mTarget(target) {}
LLTombStone(void* target = NULL) : mTarget(target) {}
void setTarget(T* target) { mTarget = target; }
T* getTarget() const { return mTarget; }
void setTarget(void* target) { mTarget = target; }
void* getTarget() const { return mTarget; }
private:
T* mTarget;
mutable void* mTarget;
};
// LLHandles are used to refer to objects whose lifetime you do not control or influence.
// Calling get() on a handle will return a pointer to the referenced object or NULL,
// if the object no longer exists. Note that during the lifetime of the returned pointer,
// you are assuming that the object will not be deleted by any action you perform,
// or any other thread, as normal when using pointers, so avoid using that pointer outside of
// the local code block.
//
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
/**
* LLHandles are used to refer to objects whose lifetime you do not control or influence.
* Calling get() on a handle will return a pointer to the referenced object or NULL,
* if the object no longer exists. Note that during the lifetime of the returned pointer,
* you are assuming that the object will not be deleted by any action you perform,
* or any other thread, as normal when using pointers, so avoid using that pointer outside of
* the local code block.
*
* https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
*
* The implementation is like some "weak pointer" implementations. When we
* can't control the lifespan of the referenced object of interest, we can
* still instantiate a proxy object whose lifespan we DO control, and store in
* the proxy object a dumb pointer to the actual target. Then we just have to
* ensure that on destruction of the target object, the proxy's dumb pointer
* is set NULL.
*
* LLTombStone is our proxy object. LLHandle contains an LLPointer to the
* LLTombStone, so every copy of an LLHandle increments the LLTombStone's ref
* count as usual.
*
* One copy of the LLHandle, specifically the LLRootHandle, must be stored in
* the referenced object. Destroying the LLRootHandle is what NULLs the
* proxy's target pointer.
*
* Minor optimization: we want LLHandle's mTombStone to always be a valid
* LLPointer, saving some conditionals in dereferencing. That's the
* getDefaultTombStone() mechanism. The default LLTombStone object's target
* pointer is always NULL, so it's semantically identical to allowing
* mTombStone to be invalid.
*/
template <typename T>
class LLHandle
{
template <typename U> friend class LLHandle;
template <typename U> friend class LLHandleProvider;
public:
LLHandle() : mTombStone(getDefaultTombStone()) {}
const LLHandle<T>& operator =(const LLHandle<T>& other)
{
mTombStone = other.mTombStone;
return *this;
}
template<typename U>
LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
: mTombStone(other.mTombStone)
{}
bool isDead() const
{
@@ -73,7 +102,7 @@ public:
T* get() const
{
return mTombStone->getTarget();
return reinterpret_cast<T*>(mTombStone->getTarget());
}
friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
@@ -94,37 +123,49 @@ public:
}
protected:
LLPointer<LLTombStone<T> > mTombStone;
LLPointer<LLTombStone> mTombStone;
private:
static LLPointer<LLTombStone<T> >& getDefaultTombStone()
typedef T* pointer_t;
static LLPointer<LLTombStone>& getDefaultTombStone()
{
static LLPointer<LLTombStone<T> > sDefaultTombStone = new LLTombStone<T>;
static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
return sDefaultTombStone;
}
};
/**
* LLRootHandle isa LLHandle which must be stored in the referenced object.
* You can either store it directly and explicitly bind(this), or derive from
* LLHandleProvider (q.v.) which automates that for you. The essential point
* is that destroying the LLRootHandle (as a consequence of destroying the
* referenced object) calls unbind(), setting the LLTombStone's target pointer
* NULL.
*/
template <typename T>
class LLRootHandle : public LLHandle<T>
{
public:
typedef LLRootHandle<T> self_t;
typedef LLHandle<T> base_t;
LLRootHandle(T* object) { bind(object); }
LLRootHandle() {};
~LLRootHandle() { unbind(); }
// this is redundant, since a LLRootHandle *is* an LLHandle
LLHandle<T> getHandle() { return LLHandle<T>(*this); }
// this is redundant, since an LLRootHandle *is* an LLHandle
//LLHandle<T> getHandle() { return LLHandle<T>(*this); }
void bind(T* object)
{
// unbind existing tombstone
if (LLHandle<T>::mTombStone.notNull())
{
if (LLHandle<T>::mTombStone->getTarget() == object) return;
if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
LLHandle<T>::mTombStone->setTarget(NULL);
}
// tombstone reference counted, so no paired delete
LLHandle<T>::mTombStone = new LLTombStone<T>(object);
LLHandle<T>::mTombStone = new LLTombStone((void*)object);
}
void unbind()
@@ -137,11 +178,22 @@ private:
LLRootHandle(const LLRootHandle& other) {};
};
// Use this as a mixin for simple classes that need handles and when you don't
// want handles at multiple points of the inheritance hierarchy
/**
* Use this as a mixin for simple classes that need handles and when you don't
* want handles at multiple points of the inheritance hierarchy
*/
template <typename T>
class LLHandleProvider
{
public:
LLHandle<T> getHandle() const
{
// perform lazy binding to avoid small tombstone allocations for handle
// providers whose handles are never referenced
mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this)));
return mHandle;
}
protected:
typedef LLHandle<T> handle_type_t;
LLHandleProvider()
@@ -149,16 +201,17 @@ protected:
// provided here to enforce T deriving from LLHandleProvider<T>
}
LLHandle<T> getHandle()
{
// perform lazy binding to avoid small tombstone allocations for handle
// providers whose handles are never referenced
mHandle.bind(static_cast<T*>(this));
return mHandle;
template <typename U>
LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
{
LLHandle<U> downcast_handle;
downcast_handle.mTombStone = getHandle().mTombStone;
return downcast_handle;
}
private:
LLRootHandle<T> mHandle;
mutable LLRootHandle<T> mHandle;
};
#endif

View File

@@ -80,7 +80,6 @@ void LLPanel::init()
mDefaultBtn = NULL;
setIsChrome(FALSE); //is this a decorator to a live window or a form?
mPanelHandle.bind(this);
setTabStop(FALSE);
mVisibleSignal = NULL;
}
@@ -766,19 +765,6 @@ void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*
}
}
void LLPanel::childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void *userdata )
{
LLUICtrl* child = getChild<LLUICtrl>(id, true);
if (child)
{
child->setDoubleClickCallback(cb);
if (userdata)
{
child->setCallbackUserData(userdata);
}
}
}
void LLPanel::childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*))
{
LLUICtrl* child = getChild<LLUICtrl>(id, true);
@@ -963,7 +949,7 @@ void LLPanel::childSetWrappedText(const std::string& id, const std::string& text
}
}
void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void* value)
void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
{
LLButton* button = getChild<LLButton>(id);
if (button)
@@ -972,6 +958,15 @@ void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void
}
}
void LLPanel::childSetAction(const std::string& id, const commit_signal_t::slot_type& function)
{
LLButton* button = getChild<LLButton>(id);
if (button)
{
button->setClickedCallback(function);
}
}
void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value)
{
LLTextBox* textbox = getChild<LLTextBox>(id);

View File

@@ -57,7 +57,7 @@ const BOOL BORDER_NO = FALSE;
* With or without border,
* Can contain LLUICtrls.
*/
class LLPanel : public LLUICtrl, public boost::signals2::trackable
class LLPanel : public LLUICtrl
{
public:
@@ -136,7 +136,7 @@ public:
void setCtrlsEnabled(BOOL b);
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
LLHandle<LLPanel> getHandle() const { return getDerivedHandle<LLPanel>(); }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
@@ -170,7 +170,6 @@ public:
BOOL childHasFocus(const std::string& id);
void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL );
void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL );
void childSetValidate(const std::string& id, BOOL (*cb)(LLUICtrl*, void*) );
void childSetUserData(const std::string& id, void* userdata);
@@ -211,7 +210,8 @@ public:
void childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) );
// LLButton
void childSetAction(const std::string& id, void(*function)(void*), void* value);
void childSetAction(const std::string& id, boost::function<void(void*)> function, void* value);
void childSetAction(const std::string& id, const commit_signal_t::slot_type& function);
void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL);
void childSetControlName(const std::string& id, const std::string& control_name);
@@ -246,7 +246,6 @@ private:
LLViewBorder* mBorder;
LLButton* mDefaultBtn;
std::string mLabel;
LLRootHandle<LLPanel> mPanelHandle;
typedef std::map<std::string, std::string> ui_string_map_t;
ui_string_map_t mUIStrings;

View File

@@ -54,6 +54,7 @@ LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const
mAllowDoubleClickSnapping(TRUE),
mResizingView(resizing_view)
{
setFollowsNone();
// set up some generically good follow code.
switch( side )
{
@@ -87,6 +88,8 @@ LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const
BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (!canResize()) return FALSE;
// Route future Mouse messages here preemptively. (Release on mouse up.)
// No handler needed for focus lost since this clas has no state that depends on it.
gFocusMgr.setMouseCapture( this );
@@ -240,7 +243,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
handled = TRUE;
}
if( handled )
if( handled && canResize() )
{
switch( mSide )
{

View File

@@ -52,6 +52,7 @@ public:
void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; }
void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
bool canResize() { return getEnabled() && mMaxSize > mMinSize; }
private:
S32 mDragLastScreenX;

File diff suppressed because it is too large Load Diff

View File

@@ -51,6 +51,7 @@
#include "lldate.h"
// <edit>
#include "lllineeditor.h"
#include <boost/function.hpp>
// </edit>
/*
@@ -69,13 +70,13 @@ public:
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible
virtual S32 getWidth() const {return mWidth;}
virtual S32 getContentWidth() const { return 0; }
virtual S32 getHeight() const = 0;
virtual S32 getHeight() const { return 0; }
virtual const LLSD getValue() const { return LLStringUtil::null; }
virtual void setValue(const LLSD& value) { }
virtual BOOL getVisible() const { return TRUE; }
virtual void setWidth(S32 width) { mWidth = width; }
virtual void highlightText(S32 offset, S32 num_chars) {}
virtual BOOL isText() const = 0;
virtual BOOL isText() const { return FALSE; }
virtual void setColor(const LLColor4&) {}
virtual void onCommit() {};
@@ -86,19 +87,6 @@ private:
S32 mWidth;
};
/*
* Draws a horizontal line.
*/
class LLScrollListSeparator : public LLScrollListCell
{
public:
LLScrollListSeparator(S32 width);
virtual ~LLScrollListSeparator() {};
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const; // truncate to given width, if possible
virtual S32 getHeight() const;
virtual BOOL isText() const { return FALSE; }
};
/*
* Cell displaying a text label.
*/
@@ -108,22 +96,27 @@ public:
LLScrollListText( const std::string& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
/*virtual*/ ~LLScrollListText();
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
virtual S32 getContentWidth() const;
virtual S32 getHeight() const;
virtual void setValue(const LLSD& value);
virtual const LLSD getValue() const;
virtual BOOL getVisible() const;
virtual void highlightText(S32 offset, S32 num_chars);
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
/*virtual*/ S32 getContentWidth() const;
/*virtual*/ S32 getHeight() const;
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ const LLSD getValue() const;
/*virtual*/ BOOL getVisible() const;
/*virtual*/ void highlightText(S32 offset, S32 num_chars);
virtual void setColor(const LLColor4&);
virtual BOOL isText() const;
/*virtual*/ void setColor(const LLColor4&);
/*virtual*/ BOOL isText() const;
S32 getTextWidth() const { return mTextWidth;}
void setTextWidth(S32 value) { mTextWidth = value;}
virtual void setWidth(S32 width) { LLScrollListCell::setWidth(width); mTextWidth = width; }
void setText(const LLStringExplicit& text);
void setFontStyle(const U8 font_style) { mFontStyle = font_style; }
void setFontStyle(const U8 font_style);
private:
LLUIString mText;
S32 mTextWidth;
const LLFontGL* mFont;
LLColor4 mColor;
U8 mUseColor;
@@ -138,18 +131,6 @@ private:
static U32 sCount;
};
class LLScrollListDate : public LLScrollListText
{
public:
LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
virtual void setValue(const LLSD& value);
virtual const LLSD getValue() const;
private:
LLDate mDate;
};
/*
* Cell displaying an image.
*/
@@ -159,24 +140,22 @@ public:
LLScrollListIcon( LLUIImagePtr icon, S32 width = 0);
LLScrollListIcon(const LLSD& value, S32 width = 0);
/*virtual*/ ~LLScrollListIcon();
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
virtual S32 getWidth() const;
virtual S32 getHeight() const { return mIcon ? mIcon->getHeight() : 0; }
virtual const LLSD getValue() const { return mIcon.isNull() ? LLStringUtil::null : mIcon->getName(); }
virtual void setColor(const LLColor4&);
virtual BOOL isText()const { return FALSE; }
virtual void setValue(const LLSD& value);
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
/*virtual*/ S32 getWidth() const;
/*virtual*/ S32 getHeight() const;
/*virtual*/ const LLSD getValue() const;
/*virtual*/ void setColor(const LLColor4&);
/*virtual*/ void setValue(const LLSD& value);
// <edit>
void setClickCallback(BOOL (*callback)(void*), void* user_data);
void setClickCallback(boost::function<bool (void)> cb);
virtual BOOL handleClick();
// </edit>
private:
LLUIImagePtr mIcon;
LLPointer<LLUIImage> mIcon;
LLColor4 mColor;
// <edit>
BOOL (*mCallback)(void*);
void* mUserData;
boost::function<bool (void)> mCallback;
// </edit>
};
@@ -188,22 +167,33 @@ class LLScrollListCheck : public LLScrollListCell
public:
LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0);
/*virtual*/ ~LLScrollListCheck();
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const;
virtual S32 getHeight() const { return 0; }
virtual const LLSD getValue() const { return mCheckBox->getValue(); }
virtual void setValue(const LLSD& value) { mCheckBox->setValue(value); }
virtual void onCommit() { mCheckBox->onCommit(); }
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const;
/*virtual*/ S32 getHeight() const { return 0; }
/*virtual*/ const LLSD getValue() const;
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ void onCommit();
virtual BOOL handleClick();
virtual void setEnabled(BOOL enable) { mCheckBox->setEnabled(enable); }
/*virtual*/ BOOL handleClick();
/*virtual*/ void setEnabled(BOOL enable);
LLCheckBoxCtrl* getCheckBox() { return mCheckBox; }
virtual BOOL isText() const { return FALSE; }
private:
LLCheckBoxCtrl* mCheckBox;
};
class LLScrollListDate : public LLScrollListText
{
public:
LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
virtual void setValue(const LLSD& value);
virtual const LLSD getValue() const;
private:
LLDate mDate;
};
// <edit>
class LLScrollListLineEditor : public LLScrollListCell
{
@@ -228,43 +218,12 @@ private:
};
// </edit>
/*
* A simple data class describing a column within a scroll list.
*/
class LLScrollListColumn
class LLScrollListColumn;
class LLScrollColumnHeader : public LLComboBox
{
public:
LLScrollListColumn();
LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent);
void setWidth(S32 width);
S32 getWidth() const { return mWidth; }
// Public data is fine so long as this remains a simple struct-like data class.
// If it ever gets any smarter than that, these should all become private
// with protected or public accessor methods added as needed. -MG
std::string mName;
std::string mSortingColumn;
BOOL mSortAscending;
std::string mLabel;
F32 mRelWidth;
BOOL mDynamicWidth;
S32 mMaxContentWidth;
S32 mIndex;
LLScrollListCtrl* mParentCtrl;
class LLColumnHeader* mHeader;
LLFontGL::HAlign mFontAlignment;
private:
S32 mWidth;
};
class LLColumnHeader : public LLComboBox
{
public:
LLColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL);
~LLColumnHeader();
LLScrollColumnHeader(const std::string& label, const LLRect &rect, LLScrollListColumn* column, const LLFontGL *font = NULL);
~LLScrollColumnHeader();
/*virtual*/ void draw();
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
@@ -301,7 +260,44 @@ private:
LLColor4 mImageOverlayColor;
};
class LLScrollListItem
/*
* A simple data class describing a column within a scroll list.
*/
class LLScrollListColumn
{
public:
typedef enum e_sort_direction
{
DESCENDING,
ASCENDING
} ESortDirection;
LLScrollListColumn();
LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent);
void setWidth(S32 width);
S32 getWidth() const { return mWidth; }
// Public data is fine so long as this remains a simple struct-like data class.
// If it ever gets any smarter than that, these should all become private
// with protected or public accessor methods added as needed. -MG
std::string mName;
std::string mSortingColumn;
ESortDirection mSortDirection;
std::string mLabel;
F32 mRelWidth;
BOOL mDynamicWidth;
S32 mMaxContentWidth;
S32 mIndex;
LLScrollListCtrl* mParentCtrl;
LLScrollColumnHeader* mHeader;
LLFontGL::HAlign mFontAlignment;
private:
S32 mWidth;
};
class LLScrollListItem : public LLHandleProvider<LLScrollListItem>
{
public:
LLScrollListItem( BOOL enabled = TRUE, void* userdata = NULL, const LLUUID& uuid = LLUUID::null )
@@ -314,7 +310,7 @@ public:
void setSelected( BOOL b ) { mSelected = b; }
BOOL getSelected() const { return mSelected; }
void setEnabled( BOOL b );
void setEnabled( BOOL b ) { mEnabled = b; }
BOOL getEnabled() const { return mEnabled; }
void setUserdata( void* userdata ) { mUserdata = userdata; }
@@ -323,9 +319,12 @@ public:
void setToolTip(const std::string tool_tip) { mToolTip=tool_tip; }
std::string getToolTip() { return mToolTip; }
LLUUID getUUID() const { return mItemValue.asUUID(); }
virtual LLUUID getUUID() const { return mItemValue.asUUID(); }
LLSD getValue() const { return mItemValue; }
void setRect(LLRect rect) { mRectangle = rect; }
LLRect getRect() const { return mRectangle; }
// If width = 0, just use the width of the text. Otherwise override with
// specified width in pixels.
void addColumn( const std::string& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, BOOL visible = TRUE)
@@ -341,9 +340,9 @@ public:
void setColumn( S32 column, LLScrollListCell *cell );
S32 getNumColumns() const { return mColumns.size(); }
S32 getNumColumns() const;
LLScrollListCell *getColumn(const S32 i) const { if (0 <= i && i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; }
LLScrollListCell *getColumn(const S32 i) const;
std::string getContentsCSV() const;
@@ -356,42 +355,45 @@ private:
LLSD mItemValue;
std::string mToolTip;
std::vector<LLScrollListCell *> mColumns;
};
/*
* A graphical control representing a scrollable table.
* Cells in the table can be simple text or more complicated things
* such as icons or even interactive elements like check boxes.
*/
class LLScrollListItemComment : public LLScrollListItem
{
public:
LLScrollListItemComment(const std::string& comment_string, const LLColor4& color);
/*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
private:
LLColor4 mColor;
};
class LLScrollListItemSeparator : public LLScrollListItem
{
public:
LLScrollListItemSeparator();
/*virtual*/ void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
LLRect mRectangle;
};
class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
public LLCtrlListInterface, public LLCtrlScrollInterface
{
public:
typedef boost::function<void (void)> callback_t;
template<typename T> struct maximum
{
typedef T result_type;
template<typename InputIterator>
T operator()(InputIterator first, InputIterator last) const
{
// If there are no slots to call, just return the
// default-constructed value
if(first == last ) return T();
T max_value = *first++;
while (first != last) {
if (max_value < *first)
max_value = *first;
++first;
}
return max_value;
}
};
typedef boost::signals2::signal<S32 (S32,const LLScrollListItem*,const LLScrollListItem*),maximum<S32> > sort_signal_t;
LLScrollListCtrl(
const std::string& name,
const LLRect& rect,
void (*commit_callback)(LLUICtrl*, void*),
void* callback_userdata,
BOOL allow_multiple_selection,
BOOL draw_border = TRUE);
BOOL draw_border = TRUE, bool draw_heading = false);
virtual ~LLScrollListCtrl();
@@ -415,6 +417,7 @@ public:
virtual void setColumnLabel(const std::string& column, const std::string& label);
virtual LLScrollListColumn* getColumn(S32 index);
virtual LLScrollListColumn* getColumn(const std::string& name);
virtual S32 getNumColumns() const { return mColumnsIndexed.size(); }
// Adds a single element, from an array of:
@@ -465,10 +468,17 @@ public:
void deleteSelectedItems();
void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change
void highlightNthItem( S32 index );
void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; }
void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; }
void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; }
void clearHighlightedItems();
virtual void mouseOverHighlightNthItem( S32 index );
S32 getHighlightedItemInx() const { return mHighlightedItem; }
void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; }
void setMaximumSelectCallback( callback_t cb ) { mOnMaximumSelectCallback = cb; }
void setSortChangedCallback( callback_t cb ) { mOnSortChangedCallback = cb; }
// Convenience function; *TODO: replace with setter above + boost::bind() in calling code
void setDoubleClickCallback( boost::function<void (void* userdata)> cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); }
void swapWithNext(S32 index);
void swapWithPrevious(S32 index);
@@ -480,7 +490,7 @@ public:
S32 getItemIndex( LLScrollListItem* item ) const;
S32 getItemIndex( const LLUUID& item_id ) const;
LLScrollListItem* addCommentText( const std::string& comment_text, EAddPosition pos = ADD_BOTTOM);
void setCommentText( const std::string& comment_text);
LLScrollListItem* addSeparator(EAddPosition pos);
// "Simple" interface: use this when you're creating a list that contains only unique strings, only
@@ -491,6 +501,7 @@ public:
BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found
BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE);
BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE);
LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
const std::string getSelectedItemLabel(S32 column = 0) const;
LLSD getSelectedValue();
@@ -503,7 +514,8 @@ public:
LLScrollListItem* getFirstSelected() const;
virtual S32 getFirstSelectedIndex() const;
std::vector<LLScrollListItem*> getAllSelected() const;
LLDynamicArray<LLUUID> getSelectedIDs();
uuid_vec_t getSelectedIDs(); //Helper. Much like getAllSelected, but just provides a LLUUID vec
S32 getNumSelected() const;
LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
// iterate over all items
@@ -578,17 +590,26 @@ public:
LLRect getItemListRect() { return mItemListRect; }
/// Returns rect, in local coords, of a given row/column
LLRect getCellRect(S32 row_index, S32 column_index);
// Used "internally" by the scroll bar.
static void onScrollChange( S32 new_pos, LLScrollbar* src, void* userdata );
static void onClickColumn(void *userdata);
void updateColumns();
void calcColumnWidths();
virtual void updateColumns();
S32 calcMaxContentWidth();
bool updateColumnWidths();
S32 getMaxContentWidth() { return mMaxContentWidth; }
void setDisplayHeading(BOOL display);
void setHeadingHeight(S32 heading_height);
/**
* Sets max visible lines without scroolbar, if this value equals to 0,
* then display all items.
*/
void setPageLines(S32 page_lines );
void setCollapseEmptyColumns(BOOL collapse);
LLScrollListItem* hitItem(S32 x,S32 y);
@@ -610,17 +631,37 @@ public:
std::string getSortColumnName();
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
BOOL needsSorting();
BOOL hasSortOrder() const;
void clearSortOrder();
S32 selectMultiple( LLDynamicArray<LLUUID> ids );
void sortItems();
S32 selectMultiple( uuid_vec_t ids );
// conceptually const, but mutates mItemList
void updateSort() const;
// sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example)
void sortOnce(S32 column, BOOL ascending);
// manually call this whenever editing list items in place to flag need for resorting
void setSorted(BOOL sorted) { mSorted = sorted; }
void setNeedsSort(bool val = true) { mSorted = !val; }
void setNeedsSortColumn(S32 col)
{
if(!isSorted())return;
for(std::vector<std::pair<S32, BOOL> >::iterator it=mSortColumns.begin();it!=mSortColumns.end();++it)
{
if((*it).first == col)
{
setNeedsSort();
break;
}
}
}
void dirtyColumns(); // some operation has potentially affected column layout or ordering
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
{
if (!mSortCallback) mSortCallback = new sort_signal_t();
return mSortCallback->connect(cb);
}
protected:
// "Full" interface: use this when you're creating a list that has one or more of the following:
// * contains icons
@@ -642,11 +683,13 @@ protected:
typedef std::deque<LLScrollListItem *> item_list;
item_list& getItemList() { return mItemList; }
void updateLineHeight();
private:
void selectPrevItem(BOOL extend_selection);
void selectNextItem(BOOL extend_selection);
void drawItems();
void updateLineHeight();
void updateLineHeightInsert(LLScrollListItem* item);
void reportInvalidInput();
BOOL isRepeatedChars(const LLWString& string) const;
@@ -654,10 +697,7 @@ private:
void deselectItem(LLScrollListItem* itemp);
void commitIfChanged();
BOOL setSort(S32 column, BOOL ascending);
S32 mCurIndex; // For get[First/Next]Data
S32 mCurSelectedIndex; // For get[First/Next]Selected
S32 getLinesPerPage();
S32 mLineHeight; // the max height of a single line
S32 mScrollLines; // how many lines we've scrolled down
@@ -665,18 +705,19 @@ private:
S32 mHeadingHeight; // the height of the column header buttons, if visible
U32 mMaxSelectable;
LLScrollbar* mScrollbar;
BOOL mAllowMultipleSelection;
BOOL mAllowKeyboardMovement;
BOOL mCommitOnKeyboardMovement;
BOOL mCommitOnSelectionChange;
BOOL mSelectionChanged;
BOOL mNeedsScroll;
BOOL mMouseWheelOpaque;
BOOL mCanSelect;
BOOL mDisplayColumnHeaders;
BOOL mColumnsDirty;
bool mAllowMultipleSelection;
bool mAllowKeyboardMovement;
bool mCommitOnKeyboardMovement;
bool mCommitOnSelectionChange;
bool mSelectionChanged;
bool mNeedsScroll;
bool mMouseWheelOpaque;
bool mCanSelect;
bool mDisplayColumnHeaders;
bool mColumnsDirty;
bool mColumnWidthsDirty;
item_list mItemList;
mutable item_list mItemList;
LLScrollListItem *mLastSelected;
@@ -700,12 +741,14 @@ private:
LLColor4 mDefaultListTextColor;
S32 mBorderThickness;
void (*mOnDoubleClickCallback)(void* userdata);
void (*mOnMaximumSelectCallback)(void* userdata );
void (*mOnSortChangedCallback)(void* userdata);
callback_t mOnDoubleClickCallback;
callback_t mOnMaximumSelectCallback;
callback_t mOnSortChangedCallback;
S32 mHighlightedItem;
class LLViewBorder* mBorder;
LLView *mCommentTextView;
LLWString mSearchString;
LLFrameTimer mSearchTimer;
@@ -715,12 +758,12 @@ private:
S32 mTotalStaticColumnWidth;
S32 mTotalColumnPadding;
BOOL mSorted;
mutable bool mSorted;
typedef std::map<std::string, LLScrollListColumn> column_map_t;
typedef std::map<std::string, LLScrollListColumn*> column_map_t;
column_map_t mColumns;
BOOL mDirty;
bool mDirty;
S32 mOriginalSelection;
typedef std::vector<LLScrollListColumn*> ordered_columns_t;
@@ -729,8 +772,7 @@ private:
typedef std::pair<S32, BOOL> sort_column_t;
std::vector<sort_column_t> mSortColumns;
// HACK: Did we draw one selected item this frame?
BOOL mDrewSelected;
sort_signal_t* mSortCallback;
}; // end class LLScrollListCtrl

View File

@@ -527,10 +527,6 @@ BOOL LLUICtrl::getTentative() const
return mTentative;
}
// virtual
void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) )
{
}
// virtual
void LLUICtrl::setColor(const LLColor4& color)

View File

@@ -37,11 +37,13 @@
#include "llview.h"
#include "llrect.h"
#include "llsd.h"
#include <boost/function.hpp>
#include <boost/signals2.hpp>
#include "llviewmodel.h" // *TODO move dependency to .cpp file
class LLUICtrl
: public LLView
: public LLView, public boost::signals2::trackable
{
public:
typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
@@ -103,7 +105,6 @@ public:
// Default to no-op:
virtual void onTabInto();
virtual void clear();
virtual void setDoubleClickCallback( void (*cb)(void*) );
virtual void setColor(const LLColor4& color);
virtual void setAlpha(F32 alpha);
virtual void setMinValue(LLSD min_value);

Some files were not shown because too many files have changed in this diff Show More