Stop using custom memory allocators.

Fix aliasing errors. Fixes issue 139 in trunk.
Fix build errors under OSX.
pull/216/head
castano 14 years ago
parent 06bf4ea960
commit df13c904b2

@ -60,7 +60,7 @@ struct PseudoIndexWrapper {
// Declare foreach keyword.
#if !defined NV_NO_USE_KEYWORDS
# define foreach NV_FOREACH
# define foreach NV_FOREACH
#endif
@ -340,7 +340,7 @@ namespace nv
// Destruct old elements (if we're shrinking).
for( i = new_size; i < old_size; i++ ) {
(m_buffer+i)->~T(); // Explicit call to the destructor
(m_buffer+i)->~T(); // Explicit call to the destructor
}
if( m_size == 0 ) {
@ -380,7 +380,7 @@ namespace nv
// Destruct old elements (if we're shrinking).
for( i = new_size; i < old_size; i++ ) {
(m_buffer+i)->~T(); // Explicit call to the destructor
(m_buffer+i)->~T(); // Explicit call to the destructor
}
if( m_size == 0 ) {
@ -503,15 +503,14 @@ namespace nv
// free the buffer.
if (m_buffer_size == 0) {
if (m_buffer) {
mem::free( m_buffer );
free( m_buffer );
m_buffer = NULL;
}
}
// realloc the buffer
else {
if (m_buffer) m_buffer = (T *) mem::realloc( m_buffer, sizeof(T) * m_buffer_size );
else m_buffer = (T *) mem::malloc( sizeof(T) * m_buffer_size );
m_buffer = (T *) realloc( m_buffer, sizeof(T) * m_buffer_size );
}
}

@ -10,6 +10,7 @@ SET(CORE_SRCS
DefsGnucWin32.h
DefsVcWin32.h
FileSystem.h FileSystem.cpp
# FileMonitor.h FileMonitor.cpp
Library.h Library.cpp
Memory.h Memory.cpp
Ptr.h

@ -232,7 +232,7 @@ namespace nv
e->clear();
}
}
mem::free(table);
free(table);
table = NULL;
entry_count = 0;
size_mask = -1;
@ -503,7 +503,7 @@ namespace nv
new_size = nextPowerOfTwo(new_size);
HashMap<T, U, H, E> new_hash;
new_hash.table = (Entry *) mem::malloc(sizeof(Entry) * new_size);
new_hash.table = (Entry *) malloc(sizeof(Entry) * new_size);
nvDebugCheck(new_hash.table != NULL);
new_hash.entry_count = 0;
@ -528,7 +528,7 @@ namespace nv
}
// Delete our old data buffer.
mem::free(table);
free(table);
}
// Steal new_hash's data.

@ -15,7 +15,9 @@ extern "C" void EF_free(void * address);
using namespace nv;
void * nv::mem::malloc(size_t size)
#if NV_OVERRIDE_ALLOC
void * malloc(size_t size)
{
#if USE_EFENCE
return EF_malloc(size);
@ -24,7 +26,7 @@ void * nv::mem::malloc(size_t size)
#endif
}
void * nv::mem::malloc(size_t size, const char * file, int line)
void * debug_malloc(size_t size, const char * file, int line)
{
NV_UNUSED(file);
NV_UNUSED(line);
@ -35,7 +37,7 @@ void * nv::mem::malloc(size_t size, const char * file, int line)
#endif
}
void nv::mem::free(const void * ptr)
void free(void * ptr)
{
#if USE_EFENCE
return EF_free(const_cast<void *>(ptr));
@ -44,7 +46,7 @@ void nv::mem::free(const void * ptr)
#endif
}
void * nv::mem::realloc(void * ptr, size_t size)
void * realloc(void * ptr, size_t size)
{
nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior.
#if USE_EFENCE
@ -54,3 +56,63 @@ void * nv::mem::realloc(void * ptr, size_t size)
#endif
}
/* No need to override this unless we want line info.
void * operator new (size_t size) throw()
{
return malloc(size);
}
void operator delete (void *p) throw()
{
free(p);
}
void * operator new [] (size_t size) throw()
{
return malloc(size);
}
void operator delete [] (void * p) throw()
{
free(p);
}
*/
#if 0 // Code from Apple:
void* operator new(std::size_t sz) throw (std::bad_alloc)
{
void *result = std::malloc (sz == 0 ? 1 : sz);
if (result == NULL)
throw std::bad_alloc();
gNewCounter++;
return result;
}
void operator delete(void* p) throw()
{
if (p == NULL)
return;
std::free (p);
gDeleteCounter++;
}
/* These are the 'nothrow' versions of the above operators.
The system version will try to call a std::new_handler if they
fail, but your overriding versions are not required to do this. */
void* operator new(std::size_t sz, const std::nothrow_t&) throw()
{
try {
void * result = ::operator new (sz); // calls our overridden operator new
return result;
} catch (std::bad_alloc &) {
return NULL;
}
}
void operator delete(void* p, const std::nothrow_t&) throw()
{
::operator delete (p);
}
#endif // 0
#endif // NV_OVERRIDE_ALLOC

@ -7,181 +7,42 @@
#include "nvcore.h"
#include <stdlib.h> // malloc(), realloc() and free()
#include <stddef.h> // size_t
#include <stddef.h> // size_t
#include <new> // new and delete
// Custom memory allocator
namespace nv
{
namespace mem
{
NVCORE_API void * malloc(size_t size);
NVCORE_API void * malloc(size_t size, const char * file, int line);
NVCORE_API void free(const void * ptr);
NVCORE_API void * realloc(void * ptr, size_t size);
} // mem namespace
} // nv namespace
// Override new/delete
inline void * operator new (size_t size) throw()
{
return nv::mem::malloc(size);
}
inline void operator delete (void *p) throw()
{
nv::mem::free(p);
}
#define NV_OVERRIDE_ALLOC 0
inline void * operator new [] (size_t size) throw()
{
return nv::mem::malloc(size);
}
#if NV_OVERRIDE_ALLOC
inline void operator delete [] (void * p) throw()
{
nv::mem::free(p);
// Custom memory allocator
extern "C" {
NVCORE_API void * malloc(size_t size);
NVCORE_API void * debug_malloc(size_t size, const char * file, int line);
NVCORE_API void free(void * ptr);
NVCORE_API void * realloc(void * ptr, size_t size);
}
/*
#ifdef _DEBUG
#define new new(__FILE__, __LINE__)
#define malloc(i) malloc(i, __FILE__, __LINE__)
#define malloc(i) debug_malloc(i, __FILE__, __LINE__)
#endif
*/
#if 0
/*
File: main.cpp
Version: 1.0
Abstract: Overrides the C++ 'operator new' and 'operator delete'.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under Apples
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright © 2006 Apple Computer, Inc., All Rights Reserved
*/
/* This sample shows how to override the C++ global 'new' and 'delete' operators. */
#include <new>
#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <locale>
/* Some variables and code to make the example do something. */
namespace {
unsigned long long gNewCounter; // number of times 'new' was called
unsigned long long gDeleteCounter; // number of times 'delete' was called
void printCounters() // print the counters above
{
std::cout << "new was called " << gNewCounter << " times and delete was called " << gDeleteCounter << " times\n";
}
}
/* These are the overridden new and delete routines.
Most applications will want to override at least these four versions of new/delete if they override any of them.
In Mac OS, it's not necessary to override the array versions of operator new and delete if all
they would do is call the non-array versions; the C++ standard library, as an extension
to the C++ standard, does this for you.
Developers should consult the section [lib.support.dynamic] in the C++ standard to see the requirements
on the generic operators new and delete; the system may expect that your overridden operators meet all these
requirements.
#endif
Your operators may be called by the system, even early in start-up before constructors have been executed. */
void* operator new(std::size_t sz) throw (std::bad_alloc)
{
void *result = std::malloc (sz == 0 ? 1 : sz);
if (result == NULL)
throw std::bad_alloc();
gNewCounter++;
return result;
}
void operator delete(void* p) throw()
{
if (p == NULL)
return;
std::free (p);
gDeleteCounter++;
// C++ helpers.
template <typename T> T * malloc(size_t count) {
return (T *)::malloc(sizeof(T) * count);
}
/* These are the 'nothrow' versions of the above operators.
The system version will try to call a std::new_handler if they
fail, but your overriding versions are not required to do this. */
void* operator new(std::size_t sz, const std::nothrow_t&) throw()
{
try {
void * result = ::operator new (sz); // calls our overridden operator new
return result;
} catch (std::bad_alloc &) {
return NULL;
}
}
void operator delete(void* p, const std::nothrow_t&) throw()
{
::operator delete (p);
template <typename T> T * realloc(T * ptr, size_t count) {
return (T *)::realloc(ptr, sizeof(T) * count);
}
/* Bug 4067110 is that if your program has no weak symbols at all, the linker will not set the
WEAK_DEFINES bit in the Mach-O header and as a result the new and delete operators above won't
be seen by system libraries. This is mostly a problem for test programs and small examples,
since almost all real C++ programs complicated enough to override new and delete will have at
least one weak symbol. However, this is a small example, so: */
void __attribute__((weak, visibility("default"))) workaroundFor4067110 () { }
/* This is a simple test program that causes the runtime library to call new and delete. */
int main()
{
atexit (printCounters);
try {
std::locale example("does_not_exist");
} catch (std::runtime_error &x) {
}
return 0;
template <typename T> void free(const T * ptr) {
::free((T *)ptr);
}
#endif // 0
#endif // NV_CORE_MEMORY_H

@ -6,7 +6,7 @@
#include "nvcore.h"
#include "Debug.h"
#include "RefCounted.h"
namespace nv
{

@ -43,7 +43,13 @@ namespace nv
virtual ~StdStream()
{
if( m_fp != NULL && m_autoclose ) {
#if NV_OS_WIN32
_fclose_nolock( m_fp );
#elif NV_OS_LINUX
fclose_unlocked( m_fp );
#else
fclose( m_fp );
#endif
}
}
@ -54,22 +60,46 @@ namespace nv
{
nvDebugCheck(m_fp != NULL);
nvDebugCheck(pos < size());
#if NV_OS_WIN32
_fseek_nolock(m_fp, pos, SEEK_SET);
#elif NV_OS_LINUX
fseek_unlocked(m_fp, pos, SEEK_SET);
#else
fseek(m_fp, pos, SEEK_SET);
#endif
}
virtual uint tell() const
{
nvDebugCheck(m_fp != NULL);
#if NV_OS_WIN32
return _ftell_nolock(m_fp);
#elif NV_OS_LINUX
return ftell_unlocked(m_fp);
#else
return ftell(m_fp);
#endif
}
virtual uint size() const
{
nvDebugCheck(m_fp != NULL);
uint pos = ftell(m_fp);
#if NV_OS_WIN32
uint pos = _ftell_nolock(m_fp);
_fseek_nolock(m_fp, 0, SEEK_END);
uint end = ftell(m_fp);
uint end = _ftell_nolock(m_fp);
_fseek_nolock(m_fp, pos, SEEK_SET);
#elif NV_OS_LINUX
uint pos = ftell_unlocked(m_fp);
fseek_unlocked(m_fp, 0, SEEK_END);
uint end = ftell_unlocked(m_fp);
fseek_unlocked(m_fp, pos, SEEK_SET);
#else
uint pos = ftell(m_fp);
fseek(m_fp, 0, SEEK_END);
uint end = ftell(m_fp);
fseek(m_fp, pos, SEEK_SET);
#endif
return end;
}
@ -123,7 +153,19 @@ namespace nv
{
nvDebugCheck(data != NULL);
nvDebugCheck(m_fp != NULL);
#if NV_OS_WIN32
return (uint)_fwrite_nolock(data, 1, len, m_fp);
#elif NV_OS_LINUX
return (uint)fwrite_unlocked(data, 1, len, m_fp);
#elif NV_OS_DARWIN
// @@ No error checking, always returns len.
for (uint i = 0; i < len; i++) {
putc_unlocked(((char *)data)[i], m_fp);
}
return len;
#else
return (uint)fwrite(data, 1, len, m_fp);
#endif
}
virtual bool isLoading() const
@ -161,7 +203,20 @@ namespace nv
{
nvDebugCheck(data != NULL);
nvDebugCheck(m_fp != NULL);
#if NV_OS_WIN32
return (uint)_fread_nolock(data, 1, len, m_fp);
#elif NV_OS_LINUX
return (uint)fread_unlocked(data, 1, len, m_fp);
#elif NV_OS_DARWIN
// @@ No error checking, always returns len.
for (uint i = 0; i < len; i++) {
((char *)data)[i] = getc_unlocked(m_fp);
}
return len;
#else
return (uint)fread(data, 1, len, m_fp);
#endif
}
virtual bool isLoading() const

@ -15,26 +15,26 @@ namespace
{
static char * strAlloc(uint size)
{
return static_cast<char *>(mem::malloc(size));
return static_cast<char *>(malloc(size));
}
static char * strReAlloc(char * str, uint size)
{
return static_cast<char *>(mem::realloc(str, size));
return static_cast<char *>(realloc(str, size));
}
static void strFree(const char * str)
{
return mem::free(const_cast<char *>(str));
return free(const_cast<char *>(str));
}
/*static char * strDup( const char * str )
/*static char * strDup( const char * str )
{
nvDebugCheck( str != NULL );
uint len = uint(strlen( str ) + 1);
char * dup = strAlloc( len );
memcpy( dup, str, len );
return dup;
nvDebugCheck( str != NULL );
uint len = uint(strlen( str ) + 1);
char * dup = strAlloc( len );
memcpy( dup, str, len );
return dup;
}*/
// helper function for integer to string conversion.

@ -314,7 +314,7 @@ namespace nv
const uint16 count = getRefCount();
setRefCount(count - 1);
if (count - 1 == 0) {
mem::free(data - 2);
free(data - 2);
data = NULL;
}
}
@ -343,7 +343,7 @@ namespace nv
void allocString(const char * str, int len)
{
const char * ptr = static_cast<const char *>(mem::malloc(2 + len + 1));
const char * ptr = static_cast<const char *>(malloc(2 + len + 1));
setData( ptr );
setRefCount( 0 );

@ -138,13 +138,13 @@ void FloatImage::allocate(uint c, uint w, uint h)
m_height = h;
m_componentNum = c;
m_count = w * h * c;
m_mem = reinterpret_cast<float *>(nv::mem::malloc(m_count * sizeof(float)));
m_mem = malloc<float>(m_count);
}
/// Free the image, but don't clear the members.
void FloatImage::free()
{
nv::mem::free( reinterpret_cast<void *>(m_mem) );
::free(m_mem);
m_mem = NULL;
}
@ -152,7 +152,7 @@ void FloatImage::resizeChannelCount(uint c)
{
if (m_componentNum != c) {
uint count = m_width * m_height * c;
nv::mem::realloc(m_mem, count * sizeof(float));
realloc(m_mem, count * sizeof(float));
if (c > m_componentNum) {
memset(m_mem + m_count, 0, (count - m_count) * sizeof(float));

@ -39,10 +39,10 @@ const Image & Image::operator=(const Image & img)
void Image::allocate(uint w, uint h)
{
free();
free();
m_width = w;
m_height = h;
m_data = (Color32 *)nv::mem::realloc(m_data, w * h * sizeof(Color32));
m_data = (Color32 *)realloc(m_data, w * h * sizeof(Color32));
}
bool Image::load(const char * name)
@ -80,7 +80,7 @@ void Image::unwrap()
void Image::free()
{
nv::mem::free(m_data);
::free(m_data);
m_data = NULL;
}

@ -64,7 +64,7 @@ namespace nv
const Vector3 & operator=(Vector3::Arg v);
const Vector2 & xy() const;
Vector2 xy() const;
const scalar * ptr() const;
@ -104,8 +104,8 @@ namespace nv
const Vector4 & operator=(Vector4::Arg v);
const Vector2 & xy() const;
const Vector3 & xyz() const;
Vector2 xy() const;
Vector3 xyz() const;
const scalar * ptr() const;
@ -211,9 +211,9 @@ namespace nv
}
inline const Vector2 & Vector3::xy() const
inline Vector2 Vector3::xy() const
{
return *(Vector2 *)this;
return Vector2(x, y);
}
inline const scalar * Vector3::ptr() const
@ -297,14 +297,14 @@ namespace nv
return *this;
}
inline const Vector2 & Vector4::xy() const
inline Vector2 Vector4::xy() const
{
return *(Vector2 *)this;
return Vector2(x, y);
}
inline const Vector3 & Vector4::xyz() const
inline Vector3 Vector4::xyz() const
{
return *(Vector3 *)this;
return Vector3(x, y, z);
}
inline const scalar * Vector4::ptr() const

@ -5,50 +5,51 @@ ADD_SUBDIRECTORY(bc6h)
#ADD_SUBDIRECTORY(bc7)
SET(NVTT_SRCS
nvtt.h
nvtt.cpp
Context.h
Context.cpp
nvtt_wrapper.h
nvtt_wrapper.cpp
Compressor.h
CompressorDXT.h
CompressorDXT.cpp
CompressorDX9.h
CompressorDX9.cpp
CompressorDX10.h
CompressorDX10.cpp
CompressorDX11.h
CompressorDX11.cpp
CompressorRGB.h
CompressorRGB.cpp
CompressorRGBE.h
CompressorRGBE.cpp
QuickCompressDXT.h
QuickCompressDXT.cpp
OptimalCompressDXT.h
OptimalCompressDXT.cpp
SingleColorLookup.h
CompressionOptions.h
CompressionOptions.cpp
InputOptions.h
InputOptions.cpp
OutputOptions.h
OutputOptions.cpp
TexImage.h TexImage.cpp
cuda/CudaUtils.h
cuda/CudaUtils.cpp
cuda/CudaMath.h
cuda/BitmapTable.h
cuda/CudaCompressorDXT.h
cuda/CudaCompressorDXT.cpp)
nvtt.h
nvtt.cpp
Context.h
Context.cpp
nvtt_wrapper.h
nvtt_wrapper.cpp
Compressor.h
CompressorDXT.h
CompressorDXT.cpp
CompressorDX9.h
CompressorDX9.cpp
CompressorDX10.h
CompressorDX10.cpp
CompressorDX11.h
CompressorDX11.cpp
CompressorRGB.h
CompressorRGB.cpp
CompressorRGBE.h
CompressorRGBE.cpp
QuickCompressDXT.h
QuickCompressDXT.cpp
OptimalCompressDXT.h
OptimalCompressDXT.cpp
SingleColorLookup.h
SingleColorLookup.cpp
CompressionOptions.h
CompressionOptions.cpp
InputOptions.h
InputOptions.cpp
OutputOptions.h
OutputOptions.cpp
TexImage.h TexImage.cpp
cuda/CudaUtils.h
cuda/CudaUtils.cpp
cuda/CudaMath.h
cuda/BitmapTable.h
cuda/CudaCompressorDXT.h
cuda/CudaCompressorDXT.cpp)
IF (CUDA_FOUND)
ADD_DEFINITIONS(-DHAVE_CUDA)
CUDA_COMPILE(CUDA_SRCS cuda/CompressKernel.cu)
SET(NVTT_SRCS ${NVTT_SRCS} ${CUDA_SRCS})
SET(LIBS ${LIBS} ${CUDA_LIBRARIES})
INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS})
ADD_DEFINITIONS(-DHAVE_CUDA)
CUDA_COMPILE(CUDA_SRCS cuda/CompressKernel.cu)
SET(NVTT_SRCS ${NVTT_SRCS} ${CUDA_SRCS})
SET(LIBS ${LIBS} ${CUDA_LIBRARIES})
INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS})
ENDIF (CUDA_FOUND)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
@ -56,17 +57,17 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
ADD_DEFINITIONS(-DNVTT_EXPORTS)
IF(NVTT_SHARED)
ADD_LIBRARY(nvtt SHARED ${NVTT_SRCS})
ADD_LIBRARY(nvtt SHARED ${NVTT_SRCS})
ELSE(NVTT_SHARED)
ADD_LIBRARY(nvtt ${NVTT_SRCS})
ADD_LIBRARY(nvtt ${NVTT_SRCS})
ENDIF(NVTT_SHARED)
TARGET_LINK_LIBRARIES(nvtt ${LIBS} nvcore nvmath nvimage squish bc6h)
INSTALL(TARGETS nvtt
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
INSTALL(FILES nvtt.h DESTINATION include/nvtt)

@ -123,86 +123,86 @@ namespace
void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMode alphaMode, uint w, uint h, const void * data, const nvtt::CompressionOptions::Private & compressionOptions, const nvtt::OutputOptions::Private & outputOptions)
{
uint bitCount;
uint rmask, rshift, rsize;
uint gmask, gshift, gsize;
uint bmask, bshift, bsize;
uint amask, ashift, asize;
uint bitCount;
uint rmask, rshift, rsize;
uint gmask, gshift, gsize;
uint bmask, bshift, bsize;
uint amask, ashift, asize;
if (compressionOptions.pixelType == nvtt::PixelType_Float)
{
rsize = compressionOptions.rsize;
gsize = compressionOptions.gsize;
bsize = compressionOptions.bsize;
asize = compressionOptions.asize;
rsize = compressionOptions.rsize;
gsize = compressionOptions.gsize;
bsize = compressionOptions.bsize;
asize = compressionOptions.asize;
nvCheck(rsize == 0 || rsize == 16 || rsize == 32);
nvCheck(gsize == 0 || gsize == 16 || gsize == 32);
nvCheck(bsize == 0 || bsize == 16 || bsize == 32);
nvCheck(asize == 0 || asize == 16 || asize == 32);
nvCheck(rsize == 0 || rsize == 16 || rsize == 32);
nvCheck(gsize == 0 || gsize == 16 || gsize == 32);
nvCheck(bsize == 0 || bsize == 16 || bsize == 32);
nvCheck(asize == 0 || asize == 16 || asize == 32);
bitCount = rsize + gsize + bsize + asize;
bitCount = rsize + gsize + bsize + asize;
}
else
{
if (compressionOptions.bitcount != 0)
{
bitCount = compressionOptions.bitcount;
nvCheck(bitCount <= 32);
rmask = compressionOptions.rmask;
gmask = compressionOptions.gmask;
bmask = compressionOptions.bmask;
amask = compressionOptions.amask;
PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize);
PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize);
PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize);
PixelFormat::maskShiftAndSize(amask, &ashift, &asize);
}
else
{
rsize = compressionOptions.rsize;
gsize = compressionOptions.gsize;
bsize = compressionOptions.bsize;
asize = compressionOptions.asize;
bitCount = rsize + gsize + bsize + asize;
nvCheck(bitCount <= 32);
ashift = 0;
bshift = ashift + asize;
gshift = bshift + bsize;
rshift = gshift + gsize;
rmask = ((1 << rsize) - 1) << rshift;
gmask = ((1 << gsize) - 1) << gshift;
bmask = ((1 << bsize) - 1) << bshift;
amask = ((1 << asize) - 1) << ashift;
}
if (compressionOptions.bitcount != 0)
{
bitCount = compressionOptions.bitcount;
nvCheck(bitCount <= 32);
rmask = compressionOptions.rmask;
gmask = compressionOptions.gmask;
bmask = compressionOptions.bmask;
amask = compressionOptions.amask;
PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize);
PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize);
PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize);
PixelFormat::maskShiftAndSize(amask, &ashift, &asize);
}
else
{
rsize = compressionOptions.rsize;
gsize = compressionOptions.gsize;
bsize = compressionOptions.bsize;
asize = compressionOptions.asize;
bitCount = rsize + gsize + bsize + asize;
nvCheck(bitCount <= 32);
ashift = 0;
bshift = ashift + asize;
gshift = bshift + bsize;
rshift = gshift + gsize;
rmask = ((1 << rsize) - 1) << rshift;
gmask = ((1 << gsize) - 1) << gshift;
bmask = ((1 << bsize) - 1) << bshift;
amask = ((1 << asize) - 1) << ashift;
}
}
const uint pitch = computePitch(w, bitCount, compressionOptions.pitchAlignment);
const uint wh = w * h;
// Allocate output scanline.
uint8 * const dst = (uint8 *)mem::malloc(pitch);
uint8 * const dst = malloc<uint8>(pitch);
for (uint y = 0; y < h; y++)
{
for (uint y = 0; y < h; y++)
{
const uint * src = (const uint *)data + y * w;
const float * fsrc = (const float *)data + y * w;
if (inputFormat == nvtt::InputFormat_BGRA_8UB && compressionOptions.pixelType == nvtt::PixelType_UnsignedNorm && bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)
{
if (inputFormat == nvtt::InputFormat_BGRA_8UB && compressionOptions.pixelType == nvtt::PixelType_UnsignedNorm && bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)
{
convert_to_a8r8g8b8(src, dst, w);
}
else
{
BitStream stream(dst);
for (uint x = 0; x < w; x++)
{
for (uint x = 0; x < w; x++)
{
float r, g, b, a;
if (inputFormat == nvtt::InputFormat_BGRA_8UB) {
@ -215,29 +215,29 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
else {
nvDebugCheck (inputFormat == nvtt::InputFormat_RGBA_32F);
//r = ((float *)src)[4 * x + 0]; // Color components not interleaved.
//g = ((float *)src)[4 * x + 1];
//b = ((float *)src)[4 * x + 2];
//a = ((float *)src)[4 * x + 3];
r = fsrc[x + 0 * wh];
g = fsrc[x + 1 * wh];
b = fsrc[x + 2 * wh];
a = fsrc[x + 3 * wh];
//r = ((float *)src)[4 * x + 0]; // Color components not interleaved.
//g = ((float *)src)[4 * x + 1];
//b = ((float *)src)[4 * x + 2];
//a = ((float *)src)[4 * x + 3];
r = fsrc[x + 0 * wh];
g = fsrc[x + 1 * wh];
b = fsrc[x + 2 * wh];
a = fsrc[x + 3 * wh];
}
if (compressionOptions.pixelType == nvtt::PixelType_Float)
{
if (rsize == 32) stream.putFloat(r);
else if (rsize == 16) stream.putHalf(r);
if (rsize == 32) stream.putFloat(r);
else if (rsize == 16) stream.putHalf(r);
if (gsize == 32) stream.putFloat(g);
else if (gsize == 16) stream.putHalf(g);
if (gsize == 32) stream.putFloat(g);
else if (gsize == 16) stream.putHalf(g);
if (bsize == 32) stream.putFloat(b);
else if (bsize == 16) stream.putHalf(b);
if (bsize == 32) stream.putFloat(b);
else if (bsize == 16) stream.putHalf(b);
if (asize == 32) stream.putFloat(a);
else if (asize == 16) stream.putHalf(a);
if (asize == 32) stream.putFloat(a);
else if (asize == 16) stream.putHalf(a);
}
else
{
@ -250,34 +250,34 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
}
// @@ Add support for nvtt::PixelType_SignedInt, nvtt::PixelType_SignedNorm, nvtt::PixelType_UnsignedInt
uint p = 0;
p |= PixelFormat::convert(c.r, 8, rsize) << rshift;
p |= PixelFormat::convert(c.g, 8, gsize) << gshift;
p |= PixelFormat::convert(c.b, 8, bsize) << bshift;
p |= PixelFormat::convert(c.a, 8, asize) << ashift;
uint p = 0;
p |= PixelFormat::convert(c.r, 8, rsize) << rshift;
p |= PixelFormat::convert(c.g, 8, gsize) << gshift;
p |= PixelFormat::convert(c.b, 8, bsize) << bshift;
p |= PixelFormat::convert(c.a, 8, asize) << ashift;
stream.putBits(p, bitCount);
// Output one byte at a time.
/*for (uint i = 0; i < byteCount; i++)
{
*(dst + x * byteCount + i) = (p >> (i * 8)) & 0xFF;
}*/
// Output one byte at a time.
/*for (uint i = 0; i < byteCount; i++)
{
*(dst + x * byteCount + i) = (p >> (i * 8)) & 0xFF;
}*/
}
}
// Zero padding.
// Zero padding.
stream.align(compressionOptions.pitchAlignment);
nvDebugCheck(stream.ptr == dst + pitch);
/*for (uint x = w * byteCount; x < pitch; x++)
{
*(dst + x) = 0;
}*/
/*for (uint x = w * byteCount; x < pitch; x++)
{
*(dst + x) = 0;
}*/
}
outputOptions.writeData(dst, pitch);
outputOptions.writeData(dst, pitch);
}
mem::free(dst);
free(dst);
}

@ -60,10 +60,10 @@ int main(int argc, char *argv[])
outputFileNameColor.stripExtension();
outputFileNameColor.append(".dds");
colorOutputOptions.setFileName(outputFileNameColor);
colorOutputOptions.setFileName(outputFileNameColor.str());
// Load normal map.
nvtt::TexImage normalMap;
nvtt::TexImage normalMap = context.createTexImage();
if (inputFileNameNormal != NULL) {
normalMap = context.createTexImage();
if (!normalMap.load(inputFileNameColor)) {
@ -89,7 +89,7 @@ int main(int argc, char *argv[])
outputFileNameNormal.stripExtension();
outputFileNameNormal.append(".dds");
normalOutputOptions.setFileName(outputFileNameNormal);
normalOutputOptions.setFileName(outputFileNameNormal.str());
}

@ -116,7 +116,7 @@ int main(int argc, char *argv[])
}
nv::Image image;
if (!loadImage(image, input)) return 1;
if (!loadImage(image, input.str())) return 1;
nv::ImageIO::ImageMetaData metaData;
metaData.tagMap.add("Thumb::Image::Width", nv::StringBuilder().number (image.width()));
@ -143,13 +143,13 @@ int main(int argc, char *argv[])
nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma));
result->setFormat(nv::Image::Format_ARGB);
nv::StdOutputStream stream(output);
nv::ImageIO::save(output, stream, result.ptr(), &metaData);
nv::StdOutputStream stream(output.str());
nv::ImageIO::save(output.str(), stream, result.ptr(), &metaData);
}
else
{
nv::StdOutputStream stream(output);
nv::ImageIO::save(output, stream, &image, &metaData);
nv::StdOutputStream stream(output.str());
nv::ImageIO::save(output.str(), stream, &image, &metaData);
}
return 0;

Loading…
Cancel
Save