--- /dev/null
+Subject: Remove malloc overrides
+Last-Update: 2012-03-31
+Origin, upstream, http://code.google.com/p/nvidia-texture-tools/source/detail?r=1172
+Bug: http://code.google.com/p/nvidia-texture-tools/issues/detail?id=138
+
+diff --git a/src/nvcore/Containers.h b/src/nvcore/Containers.h
+index f0b63d4..3d1d8ee 100644
+--- a/src/nvcore/Containers.h
++++ b/src/nvcore/Containers.h
+@@ -16,9 +16,9 @@ Do not use memmove in insert & remove, use copy ctors instead.
+
+
+ // nvcore
+-#include <nvcore/nvcore.h>
+-#include <nvcore/Memory.h>
+-#include <nvcore/Debug.h>
++#include "nvcore.h"
++#include "Memory.h"
++#include "Debug.h"
+
+ #include <string.h> // memmove
+ #include <new> // for placement new
+@@ -589,15 +589,15 @@ 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 );
++ if( m_buffer ) m_buffer = (T *) realloc(m_buffer, sizeof(T) * m_buffer_size);
++ else m_buffer = (T *) ::malloc(sizeof(T) * m_buffer_size);
+ }
+ }
+
+@@ -778,7 +778,7 @@ namespace nv
+ e->clear();
+ }
+ }
+- mem::free(table);
++ free(table);
+ table = NULL;
+ entry_count = 0;
+ size_mask = -1;
+@@ -1001,7 +1001,7 @@ namespace nv
+ new_size = nextPowerOfTwo(new_size);
+
+ HashMap<T, U, hash_functor> 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;
+@@ -1026,7 +1026,7 @@ namespace nv
+ }
+
+ // Delete our old data buffer.
+- mem::free(table);
++ free(table);
+ }
+
+ // Steal new_hash's data.
+diff --git a/src/nvcore/Memory.cpp b/src/nvcore/Memory.cpp
+index 7ece018..d470580 100644
+--- a/src/nvcore/Memory.cpp
++++ b/src/nvcore/Memory.cpp
+@@ -1,36 +1,118 @@
++// This code is in the public domain -- Ignacio Castaño <castano@gmail.com>
+
+ #include "Memory.h"
+ #include "Debug.h"
+
+-//#if HAVE_MALLOC_H
+-//#include <malloc.h>
+-//#endif
+-
+ #include <stdlib.h>
+
++#define USE_EFENCE 0
++
++#if USE_EFENCE
++extern "C" void *EF_malloc(size_t size);
++extern "C" void *EF_realloc(void * oldBuffer, size_t newSize);
++extern "C" void EF_free(void * address);
++#endif
+
+ 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);
++#else
++ return ::malloc(size);
++#endif
++}
++
++void * debug_malloc(size_t size, const char * file, int line)
++{
++ NV_UNUSED(file);
++ NV_UNUSED(line);
++#if USE_EFENCE
++ return EF_malloc(size);
++#else
++ return ::malloc(size);
++#endif
++}
++
++void free(void * ptr)
+ {
+- return ::malloc(size);
++#if USE_EFENCE
++ return EF_free(const_cast<void *>(ptr));
++#else
++ ::free(const_cast<void *>(ptr));
++#endif
+ }
+
+-void * nv::mem::malloc(size_t size, const char * file, int line)
++void * realloc(void * ptr, size_t size)
+ {
+- NV_UNUSED(file);
+- NV_UNUSED(line);
+- return ::malloc(size);
++ nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior.
++#if USE_EFENCE
++ return EF_realloc(ptr, size);
++#else
++ return ::realloc(ptr, size);
++#endif
+ }
+
+-void nv::mem::free(const void * ptr)
++/* No need to override this unless we want line info.
++void * operator new (size_t size) throw()
+ {
+- ::free(const_cast<void *>(ptr));
++ return malloc(size);
+ }
+
+-void * nv::mem::realloc(void * ptr, size_t size)
++void operator delete (void *p) throw()
+ {
+- nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior.
+- return ::realloc(ptr, size);
++ 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
+diff --git a/src/nvcore/Memory.h b/src/nvcore/Memory.h
+index d699926..897388b 100644
+--- a/src/nvcore/Memory.h
++++ b/src/nvcore/Memory.h
+@@ -1,186 +1,52 @@
+-// This code is in the public domain -- castanyo@yahoo.es
++// This code is in the public domain -- Ignacio Castaño <castano@gmail.com>
+
++#pragma once
+ #ifndef NV_CORE_MEMORY_H
+ #define NV_CORE_MEMORY_H
+
+-#include <nvcore/nvcore.h>
++#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
++#define NV_OVERRIDE_ALLOC 0
+
+-inline void * operator new (size_t size) throw()
+-{
+- return nv::mem::malloc(size);
+-}
+-
+-inline void operator delete (void *p) throw()
+-{
+- nv::mem::free(p);
+-}
++#if NV_OVERRIDE_ALLOC
+
+-inline void * operator new [] (size_t size) throw()
+-{
+- return nv::mem::malloc(size);
+-}
+-
+-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 Apple’s
+- 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.
++#endif
+
+- 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.
++namespace nv {
+
+- 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 () { }
++ template <typename T> void free(const T * ptr) {
++ ::free((void *)ptr);
++ }
+
+-/* 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;
+-}
+-#endif // 0
++} // nv namespace
+
+ #endif // NV_CORE_MEMORY_H
+diff --git a/src/nvcore/StrLib.cpp b/src/nvcore/StrLib.cpp
+index 34cf992..34518d9 100644
+--- a/src/nvcore/StrLib.cpp
++++ b/src/nvcore/StrLib.cpp
+@@ -21,17 +21,17 @@ 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 )
+diff --git a/src/nvcore/StrLib.h b/src/nvcore/StrLib.h
+index 8012271..4164cf5 100644
+--- a/src/nvcore/StrLib.h
++++ b/src/nvcore/StrLib.h
+@@ -294,7 +294,7 @@ namespace nv
+ const uint16 count = getRefCount();
+ setRefCount(count - 1);
+ if (count - 1 == 0) {
+- mem::free(data - 2);
++ free(data - 2);
+ data = NULL;
+ }
+ }
+@@ -323,7 +323,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 );
+diff --git a/src/nvimage/FloatImage.cpp b/src/nvimage/FloatImage.cpp
+index 90818ca..6e82ade 100644
+--- a/src/nvimage/FloatImage.cpp
++++ b/src/nvimage/FloatImage.cpp
+@@ -148,13 +148,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 = reinterpret_cast<float *>(::malloc(m_count * sizeof(float)));
+ }
+
+ /// Free the image, but don't clear the members.
+ void FloatImage::free()
+ {
+- nv::mem::free( reinterpret_cast<void *>(m_mem) );
++ ::free( reinterpret_cast<void *>(m_mem) );
+ m_mem = NULL;
+ }
+
+diff --git a/src/nvimage/Image.cpp b/src/nvimage/Image.cpp
+index 2307d5c..53c0b5f 100644
+--- a/src/nvimage/Image.cpp
++++ b/src/nvimage/Image.cpp
+@@ -78,7 +78,7 @@ void Image::unwrap()
+
+ void Image::free()
+ {
+- nv::mem::free(m_data);
++ ::free(m_data);
+ m_data = NULL;
+ }
+
+diff --git a/src/nvimage/ImageIO.cpp b/src/nvimage/ImageIO.cpp
+index 0b24600..70949ff 100644
+--- a/src/nvimage/ImageIO.cpp
++++ b/src/nvimage/ImageIO.cpp
+@@ -954,7 +954,7 @@ FloatImage * nv::ImageIO::loadFloatTIFF(const char * fileName, Stream & s)
+ fimage->allocate(spp, width, height);
+
+ int linesize = TIFFScanlineSize(tif);
+- tdata_t buf = (::uint8 *)nv::mem::malloc(linesize);
++ tdata_t buf = (::uint8 *)::malloc(linesize);
+
+ for (uint y = 0; y < height; y++)
+ {
+@@ -991,7 +991,7 @@ FloatImage * nv::ImageIO::loadFloatTIFF(const char * fileName, Stream & s)
+ }
+ }
+
+- nv::mem::free(buf);
++ ::free(buf);
+
+ TIFFClose(tif);
+
+diff --git a/src/nvtt/CompressRGB.cpp b/src/nvtt/CompressRGB.cpp
+index 35239c4..7a6564d 100644
+--- a/src/nvtt/CompressRGB.cpp
++++ b/src/nvtt/CompressRGB.cpp
+@@ -1,140 +1,140 @@
+-// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>\r
+-// \r
+-// Permission is hereby granted, free of charge, to any person\r
+-// obtaining a copy of this software and associated documentation\r
+-// files (the "Software"), to deal in the Software without\r
+-// restriction, including without limitation the rights to use,\r
+-// copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+-// copies of the Software, and to permit persons to whom the\r
+-// Software is furnished to do so, subject to the following\r
+-// conditions:\r
+-// \r
+-// The above copyright notice and this permission notice shall be\r
+-// included in all copies or substantial portions of the Software.\r
+-// \r
+-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r
+-// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r
+-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
+-// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r
+-// OTHER DEALINGS IN THE SOFTWARE.\r
+-\r
+-#include <nvcore/Debug.h>\r
+-\r
+-#include <nvimage/Image.h>\r
+-#include <nvimage/PixelFormat.h>\r
+-#include <nvmath/Color.h>\r
+-\r
+-#include "CompressRGB.h"\r
+-#include "CompressionOptions.h"\r
+-#include "OutputOptions.h"\r
+-\r
+-using namespace nv;\r
+-using namespace nvtt;\r
+-\r
+-namespace \r
+-{\r
+-\r
+- inline uint computePitch(uint w, uint bitsize)\r
+- {\r
+- uint p = w * ((bitsize + 7) / 8);\r
+-\r
+- // Align to 32 bits.\r
+- return ((p + 3) / 4) * 4;\r
+- }\r
+-\r
+- inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w)\r
+- {\r
+- memcpy(dst, src, 4 * w);\r
+- }\r
+-\r
+- inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w)\r
+- {\r
+- memcpy(dst, src, 4 * w);\r
+- }\r
+-\r
+-} // namespace\r
+-\r
+-\r
+-// Pixel format converter.\r
+-void nv::compressRGB(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)\r
+-{\r
+- nvCheck(image != NULL);\r
+-\r
+- const uint w = image->width();\r
+- const uint h = image->height();\r
+-\r
+- const uint bitCount = compressionOptions.bitcount;\r
+- nvCheck(bitCount == 8 || bitCount == 16 || bitCount == 24 || bitCount == 32);\r
+-\r
+- const uint byteCount = bitCount / 8;\r
+-\r
+- const uint rmask = compressionOptions.rmask;\r
+- uint rshift, rsize;\r
+- PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize);\r
+- \r
+- const uint gmask = compressionOptions.gmask;\r
+- uint gshift, gsize;\r
+- PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize);\r
+- \r
+- const uint bmask = compressionOptions.bmask;\r
+- uint bshift, bsize;\r
+- PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize);\r
+- \r
+- const uint amask = compressionOptions.amask;\r
+- uint ashift, asize;\r
+- PixelFormat::maskShiftAndSize(amask, &ashift, &asize);\r
+-\r
+- // Determine pitch.\r
+- uint pitch = computePitch(w, compressionOptions.bitcount);\r
+-\r
+- uint8 * dst = (uint8 *)mem::malloc(pitch + 4);\r
+-\r
+- for (uint y = 0; y < h; y++)\r
+- {\r
+- const Color32 * src = image->scanline(y);\r
+-\r
+- if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)\r
+- {\r
+- convert_to_a8r8g8b8(src, dst, w);\r
+- }\r
+- else if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0)\r
+- {\r
+- convert_to_x8r8g8b8(src, dst, w);\r
+- }\r
+- else\r
+- {\r
+- // Generic pixel format conversion.\r
+- for (uint x = 0; x < w; x++)\r
+- {\r
+- uint c = 0;\r
+- c |= PixelFormat::convert(src[x].r, 8, rsize) << rshift;\r
+- c |= PixelFormat::convert(src[x].g, 8, gsize) << gshift;\r
+- c |= PixelFormat::convert(src[x].b, 8, bsize) << bshift;\r
+- c |= PixelFormat::convert(src[x].a, 8, asize) << ashift;\r
+- \r
+- // Output one byte at a time.\r
+- for (uint i = 0; i < byteCount; i++)\r
+- {\r
+- *(dst + x * byteCount + i) = (c >> (i * 8)) & 0xFF;\r
+- }\r
+- }\r
+- \r
+- // Zero padding.\r
+- for (uint x = w * byteCount; x < pitch; x++)\r
+- {\r
+- *(dst + x) = 0;\r
+- }\r
+- }\r
+-\r
+- if (outputOptions.outputHandler != NULL)\r
+- {\r
+- outputOptions.outputHandler->writeData(dst, pitch);\r
+- }\r
+- }\r
+-\r
+- mem::free(dst);\r
+-}\r
+-\r
++// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
++//
++// Permission is hereby granted, free of charge, to any person
++// obtaining a copy of this software and associated documentation
++// files (the "Software"), to deal in the Software without
++// restriction, including without limitation the rights to use,
++// copy, modify, merge, publish, distribute, sublicense, and/or sell
++// copies of the Software, and to permit persons to whom the
++// Software is furnished to do so, subject to the following
++// conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
++// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
++// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++// OTHER DEALINGS IN THE SOFTWARE.
++
++#include <nvcore/Debug.h>
++
++#include <nvimage/Image.h>
++#include <nvimage/PixelFormat.h>
++#include <nvmath/Color.h>
++
++#include "CompressRGB.h"
++#include "CompressionOptions.h"
++#include "OutputOptions.h"
++
++using namespace nv;
++using namespace nvtt;
++
++namespace
++{
++
++ inline uint computePitch(uint w, uint bitsize)
++ {
++ uint p = w * ((bitsize + 7) / 8);
++
++ // Align to 32 bits.
++ return ((p + 3) / 4) * 4;
++ }
++
++ inline void convert_to_a8r8g8b8(const void * src, void * dst, uint w)
++ {
++ memcpy(dst, src, 4 * w);
++ }
++
++ inline void convert_to_x8r8g8b8(const void * src, void * dst, uint w)
++ {
++ memcpy(dst, src, 4 * w);
++ }
++
++} // namespace
++
++
++// Pixel format converter.
++void nv::compressRGB(const Image * image, const OutputOptions::Private & outputOptions, const CompressionOptions::Private & compressionOptions)
++{
++ nvCheck(image != NULL);
++
++ const uint w = image->width();
++ const uint h = image->height();
++
++ const uint bitCount = compressionOptions.bitcount;
++ nvCheck(bitCount == 8 || bitCount == 16 || bitCount == 24 || bitCount == 32);
++
++ const uint byteCount = bitCount / 8;
++
++ const uint rmask = compressionOptions.rmask;
++ uint rshift, rsize;
++ PixelFormat::maskShiftAndSize(rmask, &rshift, &rsize);
++
++ const uint gmask = compressionOptions.gmask;
++ uint gshift, gsize;
++ PixelFormat::maskShiftAndSize(gmask, &gshift, &gsize);
++
++ const uint bmask = compressionOptions.bmask;
++ uint bshift, bsize;
++ PixelFormat::maskShiftAndSize(bmask, &bshift, &bsize);
++
++ const uint amask = compressionOptions.amask;
++ uint ashift, asize;
++ PixelFormat::maskShiftAndSize(amask, &ashift, &asize);
++
++ // Determine pitch.
++ uint pitch = computePitch(w, compressionOptions.bitcount);
++
++ uint8 * dst = (uint8 *)::malloc(pitch + 4);
++
++ for (uint y = 0; y < h; y++)
++ {
++ const Color32 * src = image->scanline(y);
++
++ if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000)
++ {
++ convert_to_a8r8g8b8(src, dst, w);
++ }
++ else if (bitCount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0)
++ {
++ convert_to_x8r8g8b8(src, dst, w);
++ }
++ else
++ {
++ // Generic pixel format conversion.
++ for (uint x = 0; x < w; x++)
++ {
++ uint c = 0;
++ c |= PixelFormat::convert(src[x].r, 8, rsize) << rshift;
++ c |= PixelFormat::convert(src[x].g, 8, gsize) << gshift;
++ c |= PixelFormat::convert(src[x].b, 8, bsize) << bshift;
++ c |= PixelFormat::convert(src[x].a, 8, asize) << ashift;
++
++ // Output one byte at a time.
++ for (uint i = 0; i < byteCount; i++)
++ {
++ *(dst + x * byteCount + i) = (c >> (i * 8)) & 0xFF;
++ }
++ }
++
++ // Zero padding.
++ for (uint x = w * byteCount; x < pitch; x++)
++ {
++ *(dst + x) = 0;
++ }
++ }
++
++ if (outputOptions.outputHandler != NULL)
++ {
++ outputOptions.outputHandler->writeData(dst, pitch);
++ }
++ }
++
++ ::free(dst);
++}
++
+diff --git a/src/nvtt/cuda/CudaCompressDXT.cpp b/src/nvtt/cuda/CudaCompressDXT.cpp
+index c59bedd..6b45ceb 100644
+--- a/src/nvtt/cuda/CudaCompressDXT.cpp
++++ b/src/nvtt/cuda/CudaCompressDXT.cpp
+@@ -137,7 +137,7 @@ void CudaCompressor::compressDXT1(const CompressionOptions::Private & compressio
+ const uint h = (m_image->height() + 3) / 4;
+
+ uint imageSize = w * h * 16 * sizeof(Color32);
+- uint * blockLinearImage = (uint *) malloc(imageSize);
++ uint * blockLinearImage = (uint *) ::malloc(imageSize);
+ convertToBlockLinear(m_image, blockLinearImage); // @@ Do this in parallel with the GPU, or in the GPU!
+
+ const uint blockNum = w * h;
+@@ -207,14 +207,14 @@ void CudaCompressor::compressDXT3(const CompressionOptions::Private & compressio
+ const uint h = (m_image->height() + 3) / 4;
+
+ uint imageSize = w * h * 16 * sizeof(Color32);
+- uint * blockLinearImage = (uint *) malloc(imageSize);
++ uint * blockLinearImage = (uint *) ::malloc(imageSize);
+ convertToBlockLinear(m_image, blockLinearImage);
+
+ const uint blockNum = w * h;
+ const uint compressedSize = blockNum * 8;
+
+ AlphaBlockDXT3 * alphaBlocks = NULL;
+- alphaBlocks = (AlphaBlockDXT3 *)malloc(min(compressedSize, MAX_BLOCKS * 8U));
++ alphaBlocks = (AlphaBlockDXT3 *)::malloc(min(compressedSize, MAX_BLOCKS * 8U));
+
+ setupCompressKernel(compressionOptions.colorWeight.ptr());
+
+@@ -298,14 +298,14 @@ void CudaCompressor::compressDXT5(const CompressionOptions::Private & compressio
+ const uint h = (m_image->height() + 3) / 4;
+
+ uint imageSize = w * h * 16 * sizeof(Color32);
+- uint * blockLinearImage = (uint *) malloc(imageSize);
++ uint * blockLinearImage = (uint *) ::malloc(imageSize);
+ convertToBlockLinear(m_image, blockLinearImage);
+
+ const uint blockNum = w * h;
+ const uint compressedSize = blockNum * 8;
+
+ AlphaBlockDXT5 * alphaBlocks = NULL;
+- alphaBlocks = (AlphaBlockDXT5 *)malloc(min(compressedSize, MAX_BLOCKS * 8U));
++ alphaBlocks = (AlphaBlockDXT5 *)::malloc(min(compressedSize, MAX_BLOCKS * 8U));
+
+ setupCompressKernel(compressionOptions.colorWeight.ptr());
+