aboutsummaryrefslogtreecommitdiff
path: root/dep/g3dlite/source/BinaryOutput.cpp
diff options
context:
space:
mode:
authorjackpoz <giacomopoz@gmail.com>2014-08-22 16:58:23 +0200
committerjackpoz <giacomopoz@gmail.com>2014-08-22 21:00:56 +0200
commit5e8277e923c5545a15bae7c740ab6afaa597a59f (patch)
tree4cf5212c080588a7e868ee60134fc7fff51e400a /dep/g3dlite/source/BinaryOutput.cpp
parenta63aa858dcb400eafb97eed1f590e34c27d934a4 (diff)
Core/Dependencies: Update G3D to v9.0 r4036
Diffstat (limited to 'dep/g3dlite/source/BinaryOutput.cpp')
-rw-r--r--dep/g3dlite/source/BinaryOutput.cpp109
1 files changed, 62 insertions, 47 deletions
diff --git a/dep/g3dlite/source/BinaryOutput.cpp b/dep/g3dlite/source/BinaryOutput.cpp
index 81fa9822206..b174751c8c3 100644
--- a/dep/g3dlite/source/BinaryOutput.cpp
+++ b/dep/g3dlite/source/BinaryOutput.cpp
@@ -2,7 +2,7 @@
@file BinaryOutput.cpp
@author Morgan McGuire, http://graphics.cs.williams.edu
- Copyright 2002-2010, Morgan McGuire, All rights reserved.
+ Copyright 2002-2011, Morgan McGuire, All rights reserved.
@created 2002-02-20
@edited 2010-03-17
@@ -22,10 +22,6 @@
# include <errno.h>
#endif
-#ifdef __CYGWIN__
-# include <errno.h>
-#endif
-
// Largest memory buffer that the system will use for writing to
// disk. After this (or if the system runs out of memory)
// chunks of the file will be dumped to disk.
@@ -121,10 +117,11 @@ void BinaryOutput::reallocBuffer(size_t bytes, size_t oldBufferLen) {
uint8* newBuffer = NULL;
if ((m_filename == "<memory>") || (newBufferLen < MAX_BINARYOUTPUT_BUFFER_SIZE)) {
- // We're either writing to memory (in which case we *have* to try and allocate)
- // or we've been asked to allocate a reasonable size buffer.
+ // We're either writing to memory (in which case we *have* to
+ // try and allocate) or we've been asked to allocate a
+ // reasonable size buffer.
- //debugPrintf(" realloc(%d)\n", newBufferLen);
+ // debugPrintf(" realloc(%d)\n", newBufferLen);
newBuffer = (uint8*)System::realloc(m_buffer, newBufferLen);
if (newBuffer != NULL) {
m_maxBufferLen = newBufferLen;
@@ -134,9 +131,11 @@ void BinaryOutput::reallocBuffer(size_t bytes, size_t oldBufferLen) {
if ((newBuffer == NULL) && (bytes > 0)) {
// Realloc failed; we're probably out of memory. Back out
// the entire call and try to dump some data to disk.
+ alwaysAssertM(m_filename != "<memory>", "Realloc failed while writing to memory.");
m_bufferLen = oldBufferLen;
reserveBytesWhenOutOfMemory(bytes);
} else {
+ // Realloc succeeded
m_buffer = newBuffer;
debugAssert(isValidHeapPointer(m_buffer));
}
@@ -152,7 +151,7 @@ void BinaryOutput::reserveBytesWhenOutOfMemory(size_t bytes) {
// Dump the contents to disk. In order to enable seeking backwards,
// we keep the last 10 MB in memory.
- int writeBytes = m_bufferLen - 10 * 1024 * 1024;
+ size_t writeBytes = m_bufferLen - 10 * 1024 * 1024;
if (writeBytes < m_bufferLen / 3) {
// We're going to write less than 1/3 of the file;
@@ -164,11 +163,12 @@ void BinaryOutput::reserveBytesWhenOutOfMemory(size_t bytes) {
//debugPrintf("Writing %d bytes to disk\n", writeBytes);
const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
+ alwaysAssertM(m_filename != "<memory>", "Writing memory file");
FILE* file = FileSystem::fopen(m_filename.c_str(), mode);
debugAssert(file);
size_t count = fwrite(m_buffer, 1, writeBytes, file);
- debugAssert((int)count == writeBytes); (void)count;
+ debugAssert(count == writeBytes); (void)count;
fclose(file);
file = NULL;
@@ -181,7 +181,7 @@ void BinaryOutput::reserveBytesWhenOutOfMemory(size_t bytes) {
debugAssert(m_bufferLen < m_maxBufferLen);
debugAssert(m_bufferLen >= 0);
debugAssert(m_pos >= 0);
- debugAssert(m_pos <= m_bufferLen);
+ debugAssert(m_pos <= (int64)m_bufferLen);
// Shift the unwritten data back appropriately in the buffer.
debugAssert(isValidHeapPointer(m_buffer));
@@ -273,45 +273,49 @@ bool BinaryOutput::ok() const {
}
-void BinaryOutput::compress() {
+void BinaryOutput::compress(int level) {
if (m_alreadyWritten > 0) {
throw "Cannot compress huge files (part of this file has already been written to disk).";
}
+ debugAssertM(! m_committed, "Cannot compress after committing.");
+ alwaysAssertM(m_bufferLen < 0xFFFFFFFF, "Compress only works for 32-bit files.");
+
+ // This is the worst-case size, as mandated by zlib
+ unsigned long compressedSize = iCeil(m_bufferLen * 1.001) + 12;
+
+ // Save the old buffer and reallocate to the worst-case size
+ const uint8* src = m_buffer;
+ const uint32 srcSize = (uint32)m_bufferLen;
+
+ // add space for the 4-byte header
+ m_maxBufferLen = compressedSize + 4;
+ m_buffer = (uint8*)System::malloc(m_maxBufferLen);
+
+ // Write the header containing the old buffer size, which is needed for decompression
+ {
+ const uint8* convert = (const uint8*)&srcSize;
+ if (m_swapBytes) {
+ m_buffer[0] = convert[3];
+ m_buffer[1] = convert[2];
+ m_buffer[2] = convert[1];
+ m_buffer[3] = convert[0];
+ } else {
+ m_buffer[0] = convert[0];
+ m_buffer[1] = convert[1];
+ m_buffer[2] = convert[2];
+ m_buffer[3] = convert[3];
+ }
+ }
- // Old buffer size
- int L = m_bufferLen;
- uint8* convert = (uint8*)&L;
-
- // Zlib requires the output buffer to be this big
- unsigned long newSize = iCeil(m_bufferLen * 1.01) + 12;
- uint8* temp = (uint8*)System::malloc(newSize);
- int result = compress2(temp, &newSize, m_buffer, m_bufferLen, 9);
+ // Compress and write after the header
+ int result = compress2(m_buffer + 4, &compressedSize, src, srcSize, iClamp(level, 0, 9));
debugAssert(result == Z_OK); (void)result;
-
- // Write the header
- if (m_swapBytes) {
- m_buffer[0] = convert[3];
- m_buffer[1] = convert[2];
- m_buffer[2] = convert[1];
- m_buffer[3] = convert[0];
- } else {
- m_buffer[0] = convert[0];
- m_buffer[1] = convert[1];
- m_buffer[2] = convert[2];
- m_buffer[3] = convert[3];
- }
-
- // Write the data
- if ((int64)newSize + 4 > (int64)m_maxBufferLen) {
- m_maxBufferLen = newSize + 4;
- m_buffer = (uint8*)System::realloc(m_buffer, m_maxBufferLen);
- }
- m_bufferLen = newSize + 4;
- System::memcpy(m_buffer + 4, temp, newSize);
+ m_bufferLen = compressedSize + 4;
m_pos = m_bufferLen;
- System::free(temp);
+ // Free the old data
+ System::free((void*)src);
}
@@ -320,6 +324,10 @@ void BinaryOutput::commit(bool flush) {
m_committed = true;
debugAssertM(m_beginEndBits == 0, "Missing endBits before commit");
+ if (m_filename == "<memory>") {
+ return;
+ }
+
// Make sure the directory exists.
std::string root, base, ext, path;
Array<std::string> pathArray;
@@ -332,6 +340,7 @@ void BinaryOutput::commit(bool flush) {
const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
+ alwaysAssertM(m_filename != "<memory>", "Writing to memory file");
FILE* file = FileSystem::fopen(m_filename.c_str(), mode);
if (! file) {
@@ -345,7 +354,7 @@ void BinaryOutput::commit(bool flush) {
if (m_buffer != NULL) {
m_alreadyWritten += m_bufferLen;
- int success = fwrite(m_buffer, m_bufferLen, 1, file);
+ size_t success = fwrite(m_buffer, m_bufferLen, 1, file);
(void)success;
debugAssertM(success == 1, std::string("Could not write to '") + m_filename + "'");
}
@@ -427,7 +436,7 @@ void BinaryOutput::writeUInt64(uint64 u) {
void BinaryOutput::writeString(const char* s) {
// +1 is because strlen doesn't count the null
- int len = strlen(s) + 1;
+ size_t len = strlen(s) + 1;
debugAssert(m_beginEndBits == 0);
reserveBytes(len);
@@ -438,7 +447,7 @@ void BinaryOutput::writeString(const char* s) {
void BinaryOutput::writeStringEven(const char* s) {
// +1 is because strlen doesn't count the null
- int len = strlen(s) + 1;
+ size_t len = strlen(s) + 1;
reserveBytes(len);
System::memcpy(m_buffer + m_pos, s, len);
@@ -452,8 +461,14 @@ void BinaryOutput::writeStringEven(const char* s) {
void BinaryOutput::writeString32(const char* s) {
- writeUInt32(strlen(s) + 1);
- writeString(s);
+ // Write the NULL and count it
+ size_t len = strlen(s) + 1;
+ writeUInt32((uint32)len);
+
+ debugAssert(m_beginEndBits == 0);
+ reserveBytes(len);
+ System::memcpy(m_buffer + m_pos, s, len);
+ m_pos += len;
}