Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extern/CMakeLists.txt3
-rw-r--r--extern/SConscript4
-rw-r--r--extern/lzma/7zBuf.c36
-rw-r--r--extern/lzma/7zBuf.h31
-rw-r--r--extern/lzma/7zBuf2.c45
-rw-r--r--extern/lzma/7zCrc.c35
-rw-r--r--extern/lzma/7zCrc.h24
-rw-r--r--extern/lzma/7zFile.c263
-rw-r--r--extern/lzma/7zFile.h74
-rw-r--r--extern/lzma/7zStream.c169
-rw-r--r--extern/lzma/7zVersion.h7
-rw-r--r--extern/lzma/Alloc.c127
-rw-r--r--extern/lzma/Alloc.h32
-rw-r--r--extern/lzma/Bcj2.c132
-rw-r--r--extern/lzma/Bcj2.h30
-rw-r--r--extern/lzma/Bra.c133
-rw-r--r--extern/lzma/Bra.h60
-rw-r--r--extern/lzma/Bra86.c85
-rw-r--r--extern/lzma/BraIA64.c67
-rw-r--r--extern/lzma/CMakeLists.txt34
-rw-r--r--extern/lzma/CpuArch.h69
-rw-r--r--extern/lzma/LzFind.c751
-rw-r--r--extern/lzma/LzFind.h107
-rw-r--r--extern/lzma/LzFindMt.c793
-rw-r--r--extern/lzma/LzFindMt.h97
-rw-r--r--extern/lzma/LzHash.h54
-rw-r--r--extern/lzma/LzmaDec.c1007
-rw-r--r--extern/lzma/LzmaDec.h223
-rw-r--r--extern/lzma/LzmaEnc.c2281
-rw-r--r--extern/lzma/LzmaEnc.h72
-rw-r--r--extern/lzma/LzmaLib.c46
-rw-r--r--extern/lzma/LzmaLib.h135
-rw-r--r--extern/lzma/Threads.c109
-rw-r--r--extern/lzma/Threads.h68
-rw-r--r--extern/lzma/Types.h208
-rw-r--r--extern/lzma/history.txt236
-rw-r--r--extern/lzma/lzma.txt594
-rw-r--r--extern/lzo/CMakeLists.txt34
-rw-r--r--extern/lzo/SConscript9
-rw-r--r--extern/lzo/minilzo/COPYING340
-rw-r--r--extern/lzo/minilzo/Makefile113
-rw-r--r--extern/lzo/minilzo/README.LZO123
-rw-r--r--extern/lzo/minilzo/lzoconf.h417
-rw-r--r--extern/lzo/minilzo/lzodefs.h1807
-rw-r--r--extern/lzo/minilzo/minilzo.c4112
-rw-r--r--extern/lzo/minilzo/minilzo.h112
-rw-r--r--intern/smoke/extern/smoke_API.h15
-rw-r--r--intern/smoke/intern/FLUID_3D.cpp79
-rw-r--r--intern/smoke/intern/FLUID_3D.h17
-rw-r--r--intern/smoke/intern/FLUID_3D_SOLVERS.cpp24
-rw-r--r--intern/smoke/intern/WTURBULENCE.cpp499
-rw-r--r--intern/smoke/intern/WTURBULENCE.h21
-rw-r--r--intern/smoke/intern/smoke_API.cpp51
-rw-r--r--release/ui/buttons_physics_smoke.py205
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h6
-rw-r--r--source/blender/blenkernel/BKE_smoke.h17
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/SConscript2
-rw-r--r--source/blender/blenkernel/intern/modifier.c79
-rw-r--r--source/blender/blenkernel/intern/pointcache.c271
-rw-r--r--source/blender/blenkernel/intern/smoke.c1063
-rw-r--r--source/blender/blenkernel/intern/smokehighres.c137
-rw-r--r--source/blender/blenlib/BLI_winstuff.h30
-rw-r--r--source/blender/blenloader/intern/readfile.c23
-rw-r--r--source/blender/blenloader/intern/writefile.c9
-rw-r--r--source/blender/editors/object/object_modifier.c7
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c12
-rw-r--r--source/blender/editors/space_view3d/drawobject.c362
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c304
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h3
-rw-r--r--source/blender/gpu/GPU_draw.h4
-rw-r--r--source/blender/gpu/GPU_extensions.h1
-rw-r--r--source/blender/gpu/intern/gpu_draw.c19
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c72
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h30
-rw-r--r--source/blender/makesdna/DNA_smoke_types.h34
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c70
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c85
-rw-r--r--source/creator/CMakeLists.txt2
80 files changed, 17365 insertions, 1499 deletions
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index b6cfe3b113e..019cd9de28b 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -37,3 +37,6 @@ ADD_SUBDIRECTORY(glew)
IF(WITH_OPENJPEG)
ADD_SUBDIRECTORY(libopenjpeg)
ENDIF(WITH_OPENJPEG)
+
+ADD_SUBDIRECTORY(lzo)
+ADD_SUBDIRECTORY(lzma)
diff --git a/extern/SConscript b/extern/SConscript
index 175613c3d2b..20604d87e45 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -22,5 +22,5 @@ if env['WITH_BF_REDCODE'] and env['BF_REDCODE_LIB'] == '':
if env['OURPLATFORM'] == 'linux2':
SConscript(['binreloc/SConscript']);
-# FFTW not needed atm - dg
-# SConscript(['fftw/SConscript'])
+SConscript(['lzo/SConscript'])
+SConscript(['lzma/SConscript'])
diff --git a/extern/lzma/7zBuf.c b/extern/lzma/7zBuf.c
new file mode 100644
index 00000000000..14e7f4e2b92
--- /dev/null
+++ b/extern/lzma/7zBuf.c
@@ -0,0 +1,36 @@
+/* 7zBuf.c -- Byte Buffer
+2008-03-28
+Igor Pavlov
+Public domain */
+
+#include "7zBuf.h"
+
+void Buf_Init(CBuf *p)
+{
+ p->data = 0;
+ p->size = 0;
+}
+
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
+{
+ p->size = 0;
+ if (size == 0)
+ {
+ p->data = 0;
+ return 1;
+ }
+ p->data = (Byte *)alloc->Alloc(alloc, size);
+ if (p->data != 0)
+ {
+ p->size = size;
+ return 1;
+ }
+ return 0;
+}
+
+void Buf_Free(CBuf *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->data);
+ p->data = 0;
+ p->size = 0;
+}
diff --git a/extern/lzma/7zBuf.h b/extern/lzma/7zBuf.h
new file mode 100644
index 00000000000..c5bd71879cc
--- /dev/null
+++ b/extern/lzma/7zBuf.h
@@ -0,0 +1,31 @@
+/* 7zBuf.h -- Byte Buffer
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_BUF_H
+#define __7Z_BUF_H
+
+#include "Types.h"
+
+typedef struct
+{
+ Byte *data;
+ size_t size;
+} CBuf;
+
+void Buf_Init(CBuf *p);
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
+void Buf_Free(CBuf *p, ISzAlloc *alloc);
+
+typedef struct
+{
+ Byte *data;
+ size_t size;
+ size_t pos;
+} CDynBuf;
+
+void DynBuf_Construct(CDynBuf *p);
+void DynBuf_SeekToBeg(CDynBuf *p);
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
+
+#endif
diff --git a/extern/lzma/7zBuf2.c b/extern/lzma/7zBuf2.c
new file mode 100644
index 00000000000..8d17e0dcf80
--- /dev/null
+++ b/extern/lzma/7zBuf2.c
@@ -0,0 +1,45 @@
+/* 7zBuf2.c -- Byte Buffer
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include <string.h>
+#include "7zBuf.h"
+
+void DynBuf_Construct(CDynBuf *p)
+{
+ p->data = 0;
+ p->size = 0;
+ p->pos = 0;
+}
+
+void DynBuf_SeekToBeg(CDynBuf *p)
+{
+ p->pos = 0;
+}
+
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
+{
+ if (size > p->size - p->pos)
+ {
+ size_t newSize = p->pos + size;
+ Byte *data;
+ newSize += newSize / 4;
+ data = (Byte *)alloc->Alloc(alloc, newSize);
+ if (data == 0)
+ return 0;
+ p->size = newSize;
+ memcpy(data, p->data, p->pos);
+ alloc->Free(alloc, p->data);
+ p->data = data;
+ }
+ memcpy(p->data + p->pos, buf, size);
+ p->pos += size;
+ return 1;
+}
+
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->data);
+ p->data = 0;
+ p->size = 0;
+ p->pos = 0;
+}
diff --git a/extern/lzma/7zCrc.c b/extern/lzma/7zCrc.c
new file mode 100644
index 00000000000..71962b2c28d
--- /dev/null
+++ b/extern/lzma/7zCrc.c
@@ -0,0 +1,35 @@
+/* 7zCrc.c -- CRC32 calculation
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include "7zCrc.h"
+
+#define kCrcPoly 0xEDB88320
+UInt32 g_CrcTable[256];
+
+void MY_FAST_CALL CrcGenerateTable(void)
+{
+ UInt32 i;
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ int j;
+ for (j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ g_CrcTable[i] = r;
+ }
+}
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 ; size--, p++)
+ v = CRC_UPDATE_BYTE(v, *p);
+ return v;
+}
+
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
+{
+ return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
+}
diff --git a/extern/lzma/7zCrc.h b/extern/lzma/7zCrc.h
new file mode 100644
index 00000000000..00dc29cee3c
--- /dev/null
+++ b/extern/lzma/7zCrc.h
@@ -0,0 +1,24 @@
+/* 7zCrc.h -- CRC32 calculation
+2008-03-13
+Igor Pavlov
+Public domain */
+
+#ifndef __7Z_CRC_H
+#define __7Z_CRC_H
+
+#include <stddef.h>
+
+#include "Types.h"
+
+extern UInt32 g_CrcTable[];
+
+void MY_FAST_CALL CrcGenerateTable(void);
+
+#define CRC_INIT_VAL 0xFFFFFFFF
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
+
+#endif
diff --git a/extern/lzma/7zFile.c b/extern/lzma/7zFile.c
new file mode 100644
index 00000000000..9a44c59ac0c
--- /dev/null
+++ b/extern/lzma/7zFile.c
@@ -0,0 +1,263 @@
+/* 7zFile.c -- File IO
+2008-11-22 : Igor Pavlov : Public domain */
+
+#include "7zFile.h"
+
+#ifndef USE_WINDOWS_FILE
+
+#include <errno.h>
+
+#endif
+
+#ifdef USE_WINDOWS_FILE
+
+/*
+ ReadFile and WriteFile functions in Windows have BUG:
+ If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+ from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+ (Insufficient system resources exist to complete the requested service).
+ Probably in some version of Windows there are problems with other sizes:
+ for 32 MB (maybe also for 16 MB).
+ And message can be "Network connection was lost"
+*/
+
+#define kChunkSizeMax (1 << 22)
+
+#endif
+
+void File_Construct(CSzFile *p)
+{
+ #ifdef USE_WINDOWS_FILE
+ p->handle = INVALID_HANDLE_VALUE;
+ #else
+ p->file = NULL;
+ #endif
+}
+
+static WRes File_Open(CSzFile *p, const char *name, int writeMode)
+{
+ #ifdef USE_WINDOWS_FILE
+ p->handle = CreateFileA(name,
+ writeMode ? GENERIC_WRITE : GENERIC_READ,
+ FILE_SHARE_READ, NULL,
+ writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
+ #else
+ p->file = fopen(name, writeMode ? "wb+" : "rb");
+ return (p->file != 0) ? 0 : errno;
+ #endif
+}
+
+WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
+WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
+
+WRes File_Close(CSzFile *p)
+{
+ #ifdef USE_WINDOWS_FILE
+ if (p->handle != INVALID_HANDLE_VALUE)
+ {
+ if (!CloseHandle(p->handle))
+ return GetLastError();
+ p->handle = INVALID_HANDLE_VALUE;
+ }
+ #else
+ if (p->file != NULL)
+ {
+ int res = fclose(p->file);
+ if (res != 0)
+ return res;
+ p->file = NULL;
+ }
+ #endif
+ return 0;
+}
+
+WRes File_Read(CSzFile *p, void *data, size_t *size)
+{
+ size_t originalSize = *size;
+ if (originalSize == 0)
+ return 0;
+
+ #ifdef USE_WINDOWS_FILE
+
+ *size = 0;
+ do
+ {
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
+ DWORD processed = 0;
+ BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
+ data = (void *)((Byte *)data + processed);
+ originalSize -= processed;
+ *size += processed;
+ if (!res)
+ return GetLastError();
+ if (processed == 0)
+ break;
+ }
+ while (originalSize > 0);
+ return 0;
+
+ #else
+
+ *size = fread(data, 1, originalSize, p->file);
+ if (*size == originalSize)
+ return 0;
+ return ferror(p->file);
+
+ #endif
+}
+
+WRes File_Write(CSzFile *p, const void *data, size_t *size)
+{
+ size_t originalSize = *size;
+ if (originalSize == 0)
+ return 0;
+
+ #ifdef USE_WINDOWS_FILE
+
+ *size = 0;
+ do
+ {
+ DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
+ DWORD processed = 0;
+ BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
+ data = (void *)((Byte *)data + processed);
+ originalSize -= processed;
+ *size += processed;
+ if (!res)
+ return GetLastError();
+ if (processed == 0)
+ break;
+ }
+ while (originalSize > 0);
+ return 0;
+
+ #else
+
+ *size = fwrite(data, 1, originalSize, p->file);
+ if (*size == originalSize)
+ return 0;
+ return ferror(p->file);
+
+ #endif
+}
+
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
+{
+ #ifdef USE_WINDOWS_FILE
+
+ LARGE_INTEGER value;
+ DWORD moveMethod;
+ value.LowPart = (DWORD)*pos;
+ value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
+ switch (origin)
+ {
+ case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
+ case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
+ case SZ_SEEK_END: moveMethod = FILE_END; break;
+ default: return ERROR_INVALID_PARAMETER;
+ }
+ value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
+ if (value.LowPart == 0xFFFFFFFF)
+ {
+ WRes res = GetLastError();
+ if (res != NO_ERROR)
+ return res;
+ }
+ *pos = ((Int64)value.HighPart << 32) | value.LowPart;
+ return 0;
+
+ #else
+
+ int moveMethod;
+ int res;
+ switch (origin)
+ {
+ case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
+ case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
+ case SZ_SEEK_END: moveMethod = SEEK_END; break;
+ default: return 1;
+ }
+ res = fseek(p->file, (long)*pos, moveMethod);
+ *pos = ftell(p->file);
+ return res;
+
+ #endif
+}
+
+WRes File_GetLength(CSzFile *p, UInt64 *length)
+{
+ #ifdef USE_WINDOWS_FILE
+
+ DWORD sizeHigh;
+ DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
+ if (sizeLow == 0xFFFFFFFF)
+ {
+ DWORD res = GetLastError();
+ if (res != NO_ERROR)
+ return res;
+ }
+ *length = (((UInt64)sizeHigh) << 32) + sizeLow;
+ return 0;
+
+ #else
+
+ long pos = ftell(p->file);
+ int res = fseek(p->file, 0, SEEK_END);
+ *length = ftell(p->file);
+ fseek(p->file, pos, SEEK_SET);
+ return res;
+
+ #endif
+}
+
+
+/* ---------- FileSeqInStream ---------- */
+
+static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
+{
+ CFileSeqInStream *p = (CFileSeqInStream *)pp;
+ return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
+}
+
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
+{
+ p->s.Read = FileSeqInStream_Read;
+}
+
+
+/* ---------- FileInStream ---------- */
+
+static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
+{
+ CFileInStream *p = (CFileInStream *)pp;
+ return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
+}
+
+static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
+{
+ CFileInStream *p = (CFileInStream *)pp;
+ return File_Seek(&p->file, pos, origin);
+}
+
+void FileInStream_CreateVTable(CFileInStream *p)
+{
+ p->s.Read = FileInStream_Read;
+ p->s.Seek = FileInStream_Seek;
+}
+
+
+/* ---------- FileOutStream ---------- */
+
+static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
+{
+ CFileOutStream *p = (CFileOutStream *)pp;
+ File_Write(&p->file, data, &size);
+ return size;
+}
+
+void FileOutStream_CreateVTable(CFileOutStream *p)
+{
+ p->s.Write = FileOutStream_Write;
+}
diff --git a/extern/lzma/7zFile.h b/extern/lzma/7zFile.h
new file mode 100644
index 00000000000..fbef6837f86
--- /dev/null
+++ b/extern/lzma/7zFile.h
@@ -0,0 +1,74 @@
+/* 7zFile.h -- File IO
+2008-11-22 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_FILE_H
+#define __7Z_FILE_H
+
+#ifdef _WIN32
+#define USE_WINDOWS_FILE
+#endif
+
+#ifdef USE_WINDOWS_FILE
+#include <windows.h>
+#else
+#include <stdio.h>
+#endif
+
+#include "Types.h"
+
+
+/* ---------- File ---------- */
+
+typedef struct
+{
+ #ifdef USE_WINDOWS_FILE
+ HANDLE handle;
+ #else
+ FILE *file;
+ #endif
+} CSzFile;
+
+void File_Construct(CSzFile *p);
+WRes InFile_Open(CSzFile *p, const char *name);
+WRes OutFile_Open(CSzFile *p, const char *name);
+WRes File_Close(CSzFile *p);
+
+/* reads max(*size, remain file's size) bytes */
+WRes File_Read(CSzFile *p, void *data, size_t *size);
+
+/* writes *size bytes */
+WRes File_Write(CSzFile *p, const void *data, size_t *size);
+
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
+WRes File_GetLength(CSzFile *p, UInt64 *length);
+
+
+/* ---------- FileInStream ---------- */
+
+typedef struct
+{
+ ISeqInStream s;
+ CSzFile file;
+} CFileSeqInStream;
+
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
+
+
+typedef struct
+{
+ ISeekInStream s;
+ CSzFile file;
+} CFileInStream;
+
+void FileInStream_CreateVTable(CFileInStream *p);
+
+
+typedef struct
+{
+ ISeqOutStream s;
+ CSzFile file;
+} CFileOutStream;
+
+void FileOutStream_CreateVTable(CFileOutStream *p);
+
+#endif
diff --git a/extern/lzma/7zStream.c b/extern/lzma/7zStream.c
new file mode 100644
index 00000000000..86232aa3411
--- /dev/null
+++ b/extern/lzma/7zStream.c
@@ -0,0 +1,169 @@
+/* 7zStream.c -- 7z Stream functions
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "Types.h"
+
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
+{
+ while (size != 0)
+ {
+ size_t processed = size;
+ RINOK(stream->Read(stream, buf, &processed));
+ if (processed == 0)
+ return errorType;
+ buf = (void *)((Byte *)buf + processed);
+ size -= processed;
+ }
+ return SZ_OK;
+}
+
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
+{
+ return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
+{
+ size_t processed = 1;
+ RINOK(stream->Read(stream, buf, &processed));
+ return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
+}
+
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
+{
+ Int64 t = offset;
+ return stream->Seek(stream, &t, SZ_SEEK_SET);
+}
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
+{
+ void *lookBuf;
+ if (*size == 0)
+ return SZ_OK;
+ RINOK(stream->Look(stream, &lookBuf, size));
+ memcpy(buf, lookBuf, *size);
+ return stream->Skip(stream, *size);
+}
+
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
+{
+ while (size != 0)
+ {
+ size_t processed = size;
+ RINOK(stream->Read(stream, buf, &processed));
+ if (processed == 0)
+ return errorType;
+ buf = (void *)((Byte *)buf + processed);
+ size -= processed;
+ }
+ return SZ_OK;
+}
+
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
+{
+ return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
+{
+ SRes res = SZ_OK;
+ CLookToRead *p = (CLookToRead *)pp;
+ size_t size2 = p->size - p->pos;
+ if (size2 == 0 && *size > 0)
+ {
+ p->pos = 0;
+ size2 = LookToRead_BUF_SIZE;
+ res = p->realStream->Read(p->realStream, p->buf, &size2);
+ p->size = size2;
+ }
+ if (size2 < *size)
+ *size = size2;
+ *buf = p->buf + p->pos;
+ return res;
+}
+
+static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size)
+{
+ SRes res = SZ_OK;
+ CLookToRead *p = (CLookToRead *)pp;
+ size_t size2 = p->size - p->pos;
+ if (size2 == 0 && *size > 0)
+ {
+ p->pos = 0;
+ if (*size > LookToRead_BUF_SIZE)
+ *size = LookToRead_BUF_SIZE;
+ res = p->realStream->Read(p->realStream, p->buf, size);
+ size2 = p->size = *size;
+ }
+ if (size2 < *size)
+ *size = size2;
+ *buf = p->buf + p->pos;
+ return res;
+}
+
+static SRes LookToRead_Skip(void *pp, size_t offset)
+{
+ CLookToRead *p = (CLookToRead *)pp;
+ p->pos += offset;
+ return SZ_OK;
+}
+
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
+{
+ CLookToRead *p = (CLookToRead *)pp;
+ size_t rem = p->size - p->pos;
+ if (rem == 0)
+ return p->realStream->Read(p->realStream, buf, size);
+ if (rem > *size)
+ rem = *size;
+ memcpy(buf, p->buf + p->pos, rem);
+ p->pos += rem;
+ *size = rem;
+ return SZ_OK;
+}
+
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
+{
+ CLookToRead *p = (CLookToRead *)pp;
+ p->pos = p->size = 0;
+ return p->realStream->Seek(p->realStream, pos, origin);
+}
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
+{
+ p->s.Look = lookahead ?
+ LookToRead_Look_Lookahead :
+ LookToRead_Look_Exact;
+ p->s.Skip = LookToRead_Skip;
+ p->s.Read = LookToRead_Read;
+ p->s.Seek = LookToRead_Seek;
+}
+
+void LookToRead_Init(CLookToRead *p)
+{
+ p->pos = p->size = 0;
+}
+
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
+{
+ CSecToLook *p = (CSecToLook *)pp;
+ return LookInStream_LookRead(p->realStream, buf, size);
+}
+
+void SecToLook_CreateVTable(CSecToLook *p)
+{
+ p->s.Read = SecToLook_Read;
+}
+
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
+{
+ CSecToRead *p = (CSecToRead *)pp;
+ return p->realStream->Read(p->realStream, buf, size);
+}
+
+void SecToRead_CreateVTable(CSecToRead *p)
+{
+ p->s.Read = SecToRead_Read;
+}
diff --git a/extern/lzma/7zVersion.h b/extern/lzma/7zVersion.h
new file mode 100644
index 00000000000..b7eb235548f
--- /dev/null
+++ b/extern/lzma/7zVersion.h
@@ -0,0 +1,7 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 65
+#define MY_VER_BUILD 0
+#define MY_VERSION "4.65"
+#define MY_DATE "2009-02-03"
+#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
diff --git a/extern/lzma/Alloc.c b/extern/lzma/Alloc.c
new file mode 100644
index 00000000000..358a7b52650
--- /dev/null
+++ b/extern/lzma/Alloc.c
@@ -0,0 +1,127 @@
+/* Alloc.c -- Memory allocation functions
+2008-09-24
+Igor Pavlov
+Public domain */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#include <stdlib.h>
+
+#include "Alloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+#ifdef _SZ_ALLOC_DEBUG
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountMid = 0;
+int g_allocCountBig = 0;
+#endif
+
+void *MyAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ {
+ void *p = malloc(size);
+ fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
+ return p;
+ }
+ #else
+ return malloc(size);
+ #endif
+}
+
+void MyFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
+ #endif
+ free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
+ #endif
+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void MidFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
+ #endif
+ if (address == 0)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#ifndef MEM_LARGE_PAGES
+#undef _7ZIP_LARGE_PAGES
+#endif
+
+#ifdef _7ZIP_LARGE_PAGES
+SIZE_T g_LargePageSize = 0;
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+#endif
+
+void SetLargePageSize()
+{
+ #ifdef _7ZIP_LARGE_PAGES
+ SIZE_T size = 0;
+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+ if (largePageMinimum == 0)
+ return;
+ size = largePageMinimum();
+ if (size == 0 || (size & (size - 1)) != 0)
+ return;
+ g_LargePageSize = size;
+ #endif
+}
+
+
+void *BigAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
+ #endif
+
+ #ifdef _7ZIP_LARGE_PAGES
+ if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
+ {
+ void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
+ MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
+ if (res != 0)
+ return res;
+ }
+ #endif
+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
+ #endif
+
+ if (address == 0)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#endif
diff --git a/extern/lzma/Alloc.h b/extern/lzma/Alloc.h
new file mode 100644
index 00000000000..ff0669cad8d
--- /dev/null
+++ b/extern/lzma/Alloc.h
@@ -0,0 +1,32 @@
+/* Alloc.h -- Memory allocation functions
+2008-03-13
+Igor Pavlov
+Public domain */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+void *MyAlloc(size_t size);
+void MyFree(void *address);
+
+#ifdef _WIN32
+
+void SetLargePageSize();
+
+void *MidAlloc(size_t size);
+void MidFree(void *address);
+void *BigAlloc(size_t size);
+void BigFree(void *address);
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+#endif
diff --git a/extern/lzma/Bcj2.c b/extern/lzma/Bcj2.c
new file mode 100644
index 00000000000..20199ce5659
--- /dev/null
+++ b/extern/lzma/Bcj2.c
@@ -0,0 +1,132 @@
+/* Bcj2.c -- Converter for x86 code (BCJ2)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bcj2.h"
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*buffer++)
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
+#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
+ { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
+
+#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
+
+#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
+
+int Bcj2_Decode(
+ const Byte *buf0, SizeT size0,
+ const Byte *buf1, SizeT size1,
+ const Byte *buf2, SizeT size2,
+ const Byte *buf3, SizeT size3,
+ Byte *outBuf, SizeT outSize)
+{
+ CProb p[256 + 2];
+ SizeT inPos = 0, outPos = 0;
+
+ const Byte *buffer, *bufferLim;
+ UInt32 range, code;
+ Byte prevByte = 0;
+
+ unsigned int i;
+ for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
+ p[i] = kBitModelTotal >> 1;
+
+ buffer = buf3;
+ bufferLim = buffer + size3;
+ RC_INIT2
+
+ if (outSize == 0)
+ return SZ_OK;
+
+ for (;;)
+ {
+ Byte b;
+ CProb *prob;
+ UInt32 bound;
+ UInt32 ttt;
+
+ SizeT limit = size0 - inPos;
+ if (outSize - outPos < limit)
+ limit = outSize - outPos;
+ while (limit != 0)
+ {
+ Byte b = buf0[inPos];
+ outBuf[outPos++] = b;
+ if (IsJ(prevByte, b))
+ break;
+ inPos++;
+ prevByte = b;
+ limit--;
+ }
+
+ if (limit == 0 || outPos == outSize)
+ break;
+
+ b = buf0[inPos++];
+
+ if (b == 0xE8)
+ prob = p + prevByte;
+ else if (b == 0xE9)
+ prob = p + 256;
+ else
+ prob = p + 257;
+
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob)
+ prevByte = b;
+ }
+ else
+ {
+ UInt32 dest;
+ const Byte *v;
+ UPDATE_1(prob)
+ if (b == 0xE8)
+ {
+ v = buf1;
+ if (size1 < 4)
+ return SZ_ERROR_DATA;
+ buf1 += 4;
+ size1 -= 4;
+ }
+ else
+ {
+ v = buf2;
+ if (size2 < 4)
+ return SZ_ERROR_DATA;
+ buf2 += 4;
+ size2 -= 4;
+ }
+ dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
+ ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
+ outBuf[outPos++] = (Byte)dest;
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = (Byte)(dest >> 8);
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = (Byte)(dest >> 16);
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
+ }
+ }
+ return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
+}
diff --git a/extern/lzma/Bcj2.h b/extern/lzma/Bcj2.h
new file mode 100644
index 00000000000..32d450b3b99
--- /dev/null
+++ b/extern/lzma/Bcj2.h
@@ -0,0 +1,30 @@
+/* Bcj2.h -- Converter for x86 code (BCJ2)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __BCJ2_H
+#define __BCJ2_H
+
+#include "Types.h"
+
+/*
+Conditions:
+ outSize <= FullOutputSize,
+ where FullOutputSize is full size of output stream of x86_2 filter.
+
+If buf0 overlaps outBuf, there are two required conditions:
+ 1) (buf0 >= outBuf)
+ 2) (buf0 + size0 >= outBuf + FullOutputSize).
+
+Returns:
+ SZ_OK
+ SZ_ERROR_DATA - Data error
+*/
+
+int Bcj2_Decode(
+ const Byte *buf0, SizeT size0,
+ const Byte *buf1, SizeT size1,
+ const Byte *buf2, SizeT size2,
+ const Byte *buf3, SizeT size3,
+ Byte *outBuf, SizeT outSize);
+
+#endif
diff --git a/extern/lzma/Bra.c b/extern/lzma/Bra.c
new file mode 100644
index 00000000000..5e5469592db
--- /dev/null
+++ b/extern/lzma/Bra.c
@@ -0,0 +1,133 @@
+/* Bra.c -- Converters for RISC code
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ SizeT i;
+ if (size < 4)
+ return 0;
+ size -= 4;
+ ip += 8;
+ for (i = 0; i <= size; i += 4)
+ {
+ if (data[i + 3] == 0xEB)
+ {
+ UInt32 dest;
+ UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
+ src <<= 2;
+ if (encoding)
+ dest = ip + (UInt32)i + src;
+ else
+ dest = src - (ip + (UInt32)i);
+ dest >>= 2;
+ data[i + 2] = (Byte)(dest >> 16);
+ data[i + 1] = (Byte)(dest >> 8);
+ data[i + 0] = (Byte)dest;
+ }
+ }
+ return i;
+}
+
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ SizeT i;
+ if (size < 4)
+ return 0;
+ size -= 4;
+ ip += 4;
+ for (i = 0; i <= size; i += 2)
+ {
+ if ((data[i + 1] & 0xF8) == 0xF0 &&
+ (data[i + 3] & 0xF8) == 0xF8)
+ {
+ UInt32 dest;
+ UInt32 src =
+ (((UInt32)data[i + 1] & 0x7) << 19) |
+ ((UInt32)data[i + 0] << 11) |
+ (((UInt32)data[i + 3] & 0x7) << 8) |
+ (data[i + 2]);
+
+ src <<= 1;
+ if (encoding)
+ dest = ip + (UInt32)i + src;
+ else
+ dest = src - (ip + (UInt32)i);
+ dest >>= 1;
+
+ data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
+ data[i + 0] = (Byte)(dest >> 11);
+ data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
+ data[i + 2] = (Byte)dest;
+ i += 2;
+ }
+ }
+ return i;
+}
+
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ SizeT i;
+ if (size < 4)
+ return 0;
+ size -= 4;
+ for (i = 0; i <= size; i += 4)
+ {
+ if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
+ {
+ UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
+ ((UInt32)data[i + 1] << 16) |
+ ((UInt32)data[i + 2] << 8) |
+ ((UInt32)data[i + 3] & (~3));
+
+ UInt32 dest;
+ if (encoding)
+ dest = ip + (UInt32)i + src;
+ else
+ dest = src - (ip + (UInt32)i);
+ data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
+ data[i + 1] = (Byte)(dest >> 16);
+ data[i + 2] = (Byte)(dest >> 8);
+ data[i + 3] &= 0x3;
+ data[i + 3] |= dest;
+ }
+ }
+ return i;
+}
+
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ UInt32 i;
+ if (size < 4)
+ return 0;
+ size -= 4;
+ for (i = 0; i <= size; i += 4)
+ {
+ if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
+ data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
+ {
+ UInt32 src =
+ ((UInt32)data[i + 0] << 24) |
+ ((UInt32)data[i + 1] << 16) |
+ ((UInt32)data[i + 2] << 8) |
+ ((UInt32)data[i + 3]);
+ UInt32 dest;
+
+ src <<= 2;
+ if (encoding)
+ dest = ip + i + src;
+ else
+ dest = src - (ip + i);
+ dest >>= 2;
+
+ dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
+
+ data[i + 0] = (Byte)(dest >> 24);
+ data[i + 1] = (Byte)(dest >> 16);
+ data[i + 2] = (Byte)(dest >> 8);
+ data[i + 3] = (Byte)dest;
+ }
+ }
+ return i;
+}
diff --git a/extern/lzma/Bra.h b/extern/lzma/Bra.h
new file mode 100644
index 00000000000..45e231e8496
--- /dev/null
+++ b/extern/lzma/Bra.h
@@ -0,0 +1,60 @@
+/* Bra.h -- Branch converters for executables
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __BRA_H
+#define __BRA_H
+
+#include "Types.h"
+
+/*
+These functions convert relative addresses to absolute addresses
+in CALL instructions to increase the compression ratio.
+
+ In:
+ data - data buffer
+ size - size of data
+ ip - current virtual Instruction Pinter (IP) value
+ state - state variable for x86 converter
+ encoding - 0 (for decoding), 1 (for encoding)
+
+ Out:
+ state - state variable for x86 converter
+
+ Returns:
+ The number of processed bytes. If you call these functions with multiple calls,
+ you must start next call with first byte after block of processed bytes.
+
+ Type Endian Alignment LookAhead
+
+ x86 little 1 4
+ ARMT little 2 2
+ ARM little 4 0
+ PPC big 4 0
+ SPARC big 4 0
+ IA64 little 16 0
+
+ size must be >= Alignment + LookAhead, if it's not last block.
+ If (size < Alignment + LookAhead), converter returns 0.
+
+ Example:
+
+ UInt32 ip = 0;
+ for ()
+ {
+ ; size must be >= Alignment + LookAhead, if it's not last block
+ SizeT processed = Convert(data, size, ip, 1);
+ data += processed;
+ size -= processed;
+ ip += processed;
+ }
+*/
+
+#define x86_Convert_Init(state) { state = 0; }
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+#endif
diff --git a/extern/lzma/Bra86.c b/extern/lzma/Bra86.c
new file mode 100644
index 00000000000..1ee0e709b88
--- /dev/null
+++ b/extern/lzma/Bra86.c
@@ -0,0 +1,85 @@
+/* Bra86.c -- Converter for x86 code (BCJ)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
+{
+ SizeT bufferPos = 0, prevPosT;
+ UInt32 prevMask = *state & 0x7;
+ if (size < 5)
+ return 0;
+ ip += 5;
+ prevPosT = (SizeT)0 - 1;
+
+ for (;;)
+ {
+ Byte *p = data + bufferPos;
+ Byte *limit = data + size - 4;
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+ bufferPos = (SizeT)(p - data);
+ if (p >= limit)
+ break;
+ prevPosT = bufferPos - prevPosT;
+ if (prevPosT > 3)
+ prevMask = 0;
+ else
+ {
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+ if (prevMask != 0)
+ {
+ Byte b = p[4 - kMaskToBitNumber[prevMask]];
+ if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+ {
+ prevPosT = bufferPos;
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ continue;
+ }
+ }
+ }
+ prevPosT = bufferPos;
+
+ if (Test86MSByte(p[4]))
+ {
+ UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+ UInt32 dest;
+ for (;;)
+ {
+ Byte b;
+ int index;
+ if (encoding)
+ dest = (ip + (UInt32)bufferPos) + src;
+ else
+ dest = src - (ip + (UInt32)bufferPos);
+ if (prevMask == 0)
+ break;
+ index = kMaskToBitNumber[prevMask] * 8;
+ b = (Byte)(dest >> (24 - index));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ ((1 << (32 - index)) - 1);
+ }
+ p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
+ p[3] = (Byte)(dest >> 16);
+ p[2] = (Byte)(dest >> 8);
+ p[1] = (Byte)dest;
+ bufferPos += 5;
+ }
+ else
+ {
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ }
+ }
+ prevPosT = bufferPos - prevPosT;
+ *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
+ return bufferPos;
+}
diff --git a/extern/lzma/BraIA64.c b/extern/lzma/BraIA64.c
new file mode 100644
index 00000000000..0b4ee85bc76
--- /dev/null
+++ b/extern/lzma/BraIA64.c
@@ -0,0 +1,67 @@
+/* BraIA64.c -- Converter for IA-64 code
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+static const Byte kBranchTable[32] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 6, 6, 0, 0, 7, 7,
+ 4, 4, 0, 0, 4, 4, 0, 0
+};
+
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+ SizeT i;
+ if (size < 16)
+ return 0;
+ size -= 16;
+ for (i = 0; i <= size; i += 16)
+ {
+ UInt32 instrTemplate = data[i] & 0x1F;
+ UInt32 mask = kBranchTable[instrTemplate];
+ UInt32 bitPos = 5;
+ int slot;
+ for (slot = 0; slot < 3; slot++, bitPos += 41)
+ {
+ UInt32 bytePos, bitRes;
+ UInt64 instruction, instNorm;
+ int j;
+ if (((mask >> slot) & 1) == 0)
+ continue;
+ bytePos = (bitPos >> 3);
+ bitRes = bitPos & 0x7;
+ instruction = 0;
+ for (j = 0; j < 6; j++)
+ instruction += (UInt64)data[i + j + bytePos] << (8 * j);
+
+ instNorm = instruction >> bitRes;
+ if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
+ {
+ UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
+ UInt32 dest;
+ src |= ((UInt32)(instNorm >> 36) & 1) << 20;
+
+ src <<= 4;
+
+ if (encoding)
+ dest = ip + (UInt32)i + src;
+ else
+ dest = src - (ip + (UInt32)i);
+
+ dest >>= 4;
+
+ instNorm &= ~((UInt64)(0x8FFFFF) << 13);
+ instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
+ instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
+
+ instruction &= (1 << bitRes) - 1;
+ instruction |= (instNorm << bitRes);
+ for (j = 0; j < 6; j++)
+ data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
+ }
+ }
+ }
+ return i;
+}
diff --git a/extern/lzma/CMakeLists.txt b/extern/lzma/CMakeLists.txt
new file mode 100644
index 00000000000..235cd8c7f8e
--- /dev/null
+++ b/extern/lzma/CMakeLists.txt
@@ -0,0 +1,34 @@
+# $Id$
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Daniel Genrich
+#
+# ***** END GPL LICENSE BLOCK *****
+
+SET(INC . )
+
+FILE(GLOB SRC ./*.c)
+
+
+
+BLENDERLIB(bf_lzma "${SRC}" "${INC}")
+#, libtype='blender', priority = 0 )
diff --git a/extern/lzma/CpuArch.h b/extern/lzma/CpuArch.h
new file mode 100644
index 00000000000..7384b0c32ae
--- /dev/null
+++ b/extern/lzma/CpuArch.h
@@ -0,0 +1,69 @@
+/* CpuArch.h
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __CPUARCH_H
+#define __CPUARCH_H
+
+/*
+LITTLE_ENDIAN_UNALIGN means:
+ 1) CPU is LITTLE_ENDIAN
+ 2) it's allowed to make unaligned memory accesses
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
+about these properties of platform.
+*/
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
+#define LITTLE_ENDIAN_UNALIGN
+#endif
+
+#ifdef LITTLE_ENDIAN_UNALIGN
+
+#define GetUi16(p) (*(const UInt16 *)(p))
+#define GetUi32(p) (*(const UInt32 *)(p))
+#define GetUi64(p) (*(const UInt64 *)(p))
+#define SetUi32(p, d) *(UInt32 *)(p) = (d);
+
+#else
+
+#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
+
+#define GetUi32(p) ( \
+ ((const Byte *)(p))[0] | \
+ ((UInt32)((const Byte *)(p))[1] << 8) | \
+ ((UInt32)((const Byte *)(p))[2] << 16) | \
+ ((UInt32)((const Byte *)(p))[3] << 24))
+
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
+
+#define SetUi32(p, d) { UInt32 _x_ = (d); \
+ ((Byte *)(p))[0] = (Byte)_x_; \
+ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
+ ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
+ ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
+
+#endif
+
+#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
+
+#pragma intrinsic(_byteswap_ulong)
+#pragma intrinsic(_byteswap_uint64)
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+
+#else
+
+#define GetBe32(p) ( \
+ ((UInt32)((const Byte *)(p))[0] << 24) | \
+ ((UInt32)((const Byte *)(p))[1] << 16) | \
+ ((UInt32)((const Byte *)(p))[2] << 8) | \
+ ((const Byte *)(p))[3] )
+
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
+
+#endif
+
+#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
+
+#endif
diff --git a/extern/lzma/LzFind.c b/extern/lzma/LzFind.c
new file mode 100644
index 00000000000..34f4f09ea58
--- /dev/null
+++ b/extern/lzma/LzFind.c
@@ -0,0 +1,751 @@
+/* LzFind.c -- Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "LzFind.h"
+#include "LzHash.h"
+
+#define kEmptyHashValue 0
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
+#define kNormalizeMask (~(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)3 << 30)
+
+#define kStartMaxLen 3
+
+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+ if (!p->directInput)
+ {
+ alloc->Free(alloc, p->bufferBase);
+ p->bufferBase = 0;
+ }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+{
+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
+ if (p->directInput)
+ {
+ p->blockSize = blockSize;
+ return 1;
+ }
+ if (p->bufferBase == 0 || p->blockSize != blockSize)
+ {
+ LzInWindow_Free(p, alloc);
+ p->blockSize = blockSize;
+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
+ }
+ return (p->bufferBase != 0);
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
+
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
+ p->posLimit -= subValue;
+ p->pos -= subValue;
+ p->streamPos -= subValue;
+}
+
+static void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+ if (p->streamEndWasReached || p->result != SZ_OK)
+ return;
+ for (;;)
+ {
+ Byte *dest = p->buffer + (p->streamPos - p->pos);
+ size_t size = (p->bufferBase + p->blockSize - dest);
+ if (size == 0)
+ return;
+ p->result = p->stream->Read(p->stream, dest, &size);
+ if (p->result != SZ_OK)
+ return;
+ if (size == 0)
+ {
+ p->streamEndWasReached = 1;
+ return;
+ }
+ p->streamPos += (UInt32)size;
+ if (p->streamPos - p->pos > p->keepSizeAfter)
+ return;
+ }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+ memmove(p->bufferBase,
+ p->buffer - p->keepSizeBefore,
+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
+ p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+ /* if (p->streamEndWasReached) return 0; */
+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
+}
+
+void MatchFinder_ReadIfRequired(CMatchFinder *p)
+{
+ if (p->streamEndWasReached)
+ return;
+ if (p->keepSizeAfter >= p->streamPos - p->pos)
+ MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+ if (MatchFinder_NeedMove(p))
+ MatchFinder_MoveBlock(p);
+ MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+ p->cutValue = 32;
+ p->btMode = 1;
+ p->numHashBytes = 4;
+ /* p->skipModeBits = 0; */
+ p->directInput = 0;
+ p->bigHash = 0;
+}
+
+#define kCrcPoly 0xEDB88320
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+ UInt32 i;
+ p->bufferBase = 0;
+ p->directInput = 0;
+ p->hash = 0;
+ MatchFinder_SetDefaultSettings(p);
+
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ int j;
+ for (j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ p->crc[i] = r;
+ }
+}
+
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->hash);
+ p->hash = 0;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ LzInWindow_Free(p, alloc);
+}
+
+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+{
+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
+ if (sizeInBytes / sizeof(CLzRef) != num)
+ return 0;
+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
+}
+
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAlloc *alloc)
+{
+ UInt32 sizeReserv;
+ if (historySize > kMaxHistorySize)
+ {
+ MatchFinder_Free(p, alloc);
+ return 0;
+ }
+ sizeReserv = historySize >> 1;
+ if (historySize > ((UInt32)2 << 30))
+ sizeReserv = historySize >> 2;
+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
+
+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+ if (LzInWindow_Create(p, sizeReserv, alloc))
+ {
+ UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
+ UInt32 hs;
+ p->matchMaxLen = matchMaxLen;
+ {
+ p->fixedHashSize = 0;
+ if (p->numHashBytes == 2)
+ hs = (1 << 16) - 1;
+ else
+ {
+ hs = historySize - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ /* hs >>= p->skipModeBits; */
+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
+ if (hs > (1 << 24))
+ {
+ if (p->numHashBytes == 3)
+ hs = (1 << 24) - 1;
+ else
+ hs >>= 1;
+ }
+ }
+ p->hashMask = hs;
+ hs++;
+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
+ hs += p->fixedHashSize;
+ }
+
+ {
+ UInt32 prevSize = p->hashSizeSum + p->numSons;
+ UInt32 newSize;
+ p->historySize = historySize;
+ p->hashSizeSum = hs;
+ p->cyclicBufferSize = newCyclicBufferSize;
+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
+ newSize = p->hashSizeSum + p->numSons;
+ if (p->hash != 0 && prevSize == newSize)
+ return 1;
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ p->hash = AllocRefs(newSize, alloc);
+ if (p->hash != 0)
+ {
+ p->son = p->hash + p->hashSizeSum;
+ return 1;
+ }
+ }
+ }
+ MatchFinder_Free(p, alloc);
+ return 0;
+}
+
+static void MatchFinder_SetLimits(CMatchFinder *p)
+{
+ UInt32 limit = kMaxValForNormalize - p->pos;
+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+ if (limit2 < limit)
+ limit = limit2;
+ limit2 = p->streamPos - p->pos;
+ if (limit2 <= p->keepSizeAfter)
+ {
+ if (limit2 > 0)
+ limit2 = 1;
+ }
+ else
+ limit2 -= p->keepSizeAfter;
+ if (limit2 < limit)
+ limit = limit2;
+ {
+ UInt32 lenLimit = p->streamPos - p->pos;
+ if (lenLimit > p->matchMaxLen)
+ lenLimit = p->matchMaxLen;
+ p->lenLimit = lenLimit;
+ }
+ p->posLimit = p->pos + limit;
+}
+
+void MatchFinder_Init(CMatchFinder *p)
+{
+ UInt32 i;
+ for (i = 0; i < p->hashSizeSum; i++)
+ p->hash[i] = kEmptyHashValue;
+ p->cyclicBufferPos = 0;
+ p->buffer = p->bufferBase;
+ p->pos = p->streamPos = p->cyclicBufferSize;
+ p->result = SZ_OK;
+ p->streamEndWasReached = 0;
+ MatchFinder_ReadBlock(p);
+ MatchFinder_SetLimits(p);
+}
+
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
+{
+ return (p->pos - p->historySize - 1) & kNormalizeMask;
+}
+
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+{
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+}
+
+static void MatchFinder_Normalize(CMatchFinder *p)
+{
+ UInt32 subValue = MatchFinder_GetSubValue(p);
+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+ MatchFinder_ReduceOffsets(p, subValue);
+}
+
+static void MatchFinder_CheckLimits(CMatchFinder *p)
+{
+ if (p->pos == kMaxValForNormalize)
+ MatchFinder_Normalize(p);
+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
+ MatchFinder_CheckAndMoveAndRead(p);
+ if (p->cyclicBufferPos == p->cyclicBufferSize)
+ p->cyclicBufferPos = 0;
+ MatchFinder_SetLimits(p);
+}
+
+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, UInt32 maxLen)
+{
+ son[_cyclicBufferPos] = curMatch;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ return distances;
+ {
+ const Byte *pb = cur - delta;
+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+ if (pb[maxLen] == cur[maxLen] && *pb == *cur)
+ {
+ UInt32 len = 0;
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ return distances;
+ }
+ }
+ }
+ }
+}
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, UInt32 maxLen)
+{
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return distances;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ if (++len != lenLimit && pb[len] == cur[len])
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return distances;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
+{
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ {
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+#define MOVE_POS \
+ ++p->cyclicBufferPos; \
+ p->buffer++; \
+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
+
+#define MOVE_POS_RET MOVE_POS return offset;
+
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
+
+#define GET_MATCHES_HEADER2(minLen, ret_op) \
+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+ cur = p->buffer;
+
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
+
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+
+#define GET_MATCHES_FOOTER(offset, maxLen) \
+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
+ distances + offset, maxLen) - distances); MOVE_POS_RET;
+
+#define SKIP_FOOTER \
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 1)
+}
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 2)
+}
+
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, delta2, maxLen, offset;
+ GET_MATCHES_HEADER(3)
+
+ HASH3_CALC;
+
+ delta2 = p->pos - p->hash[hash2Value];
+ curMatch = p->hash[kFix3HashSize + hashValue];
+
+ p->hash[hash2Value] =
+ p->hash[kFix3HashSize + hashValue] = p->pos;
+
+
+ maxLen = 2;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+ break;
+ distances[0] = maxLen;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ delta2 = p->pos - p->hash[ hash2Value];
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+ curMatch = p->hash[kFix4HashSize + hashValue];
+
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+
+ maxLen = 1;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ }
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+ {
+ maxLen = 3;
+ distances[offset + 1] = delta3 - 1;
+ offset += 2;
+ delta2 = delta3;
+ }
+ if (offset != 0)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+ break;
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+ if (maxLen < 3)
+ maxLen = 3;
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ delta2 = p->pos - p->hash[ hash2Value];
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+ curMatch = p->hash[kFix4HashSize + hashValue];
+
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+
+ maxLen = 1;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ }
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+ {
+ maxLen = 3;
+ distances[offset + 1] = delta3 - 1;
+ offset += 2;
+ delta2 = delta3;
+ }
+ if (offset != 0)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+ break;
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS_RET;
+ }
+ }
+ if (maxLen < 3)
+ maxLen = 3;
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances + offset, maxLen) - (distances));
+ MOVE_POS_RET
+}
+
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances, 2) - (distances));
+ MOVE_POS_RET
+}
+
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value;
+ SKIP_HEADER(3)
+ HASH3_CALC;
+ curMatch = p->hash[kFix3HashSize + hashValue];
+ p->hash[hash2Value] =
+ p->hash[kFix3HashSize + hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value, hash3Value;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ curMatch = p->hash[kFix4HashSize + hashValue];
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] = p->pos;
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value, hash3Value;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ curMatch = p->hash[kFix4HashSize + hashValue];
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
+{
+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+ if (!p->btMode)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ }
+ else if (p->numHashBytes == 2)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+ }
+ else if (p->numHashBytes == 3)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+ }
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+ }
+}
diff --git a/extern/lzma/LzFind.h b/extern/lzma/LzFind.h
new file mode 100644
index 00000000000..5b9cebfdffe
--- /dev/null
+++ b/extern/lzma/LzFind.h
@@ -0,0 +1,107 @@
+/* LzFind.h -- Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZFIND_H
+#define __LZFIND_H
+
+#include "Types.h"
+
+typedef UInt32 CLzRef;
+
+typedef struct _CMatchFinder
+{
+ Byte *buffer;
+ UInt32 pos;
+ UInt32 posLimit;
+ UInt32 streamPos;
+ UInt32 lenLimit;
+
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+
+ UInt32 matchMaxLen;
+ CLzRef *hash;
+ CLzRef *son;
+ UInt32 hashMask;
+ UInt32 cutValue;
+
+ Byte *bufferBase;
+ ISeqInStream *stream;
+ int streamEndWasReached;
+
+ UInt32 blockSize;
+ UInt32 keepSizeBefore;
+ UInt32 keepSizeAfter;
+
+ UInt32 numHashBytes;
+ int directInput;
+ int btMode;
+ /* int skipModeBits; */
+ int bigHash;
+ UInt32 historySize;
+ UInt32 fixedHashSize;
+ UInt32 hashSizeSum;
+ UInt32 numSons;
+ SRes result;
+ UInt32 crc[256];
+} CMatchFinder;
+
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
+
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+
+int MatchFinder_NeedMove(CMatchFinder *p);
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
+void MatchFinder_MoveBlock(CMatchFinder *p);
+void MatchFinder_ReadIfRequired(CMatchFinder *p);
+
+void MatchFinder_Construct(CMatchFinder *p);
+
+/* Conditions:
+ historySize <= 3 GB
+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
+*/
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAlloc *alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+ UInt32 *distances, UInt32 maxLen);
+
+/*
+Conditions:
+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
+*/
+
+typedef void (*Mf_Init_Func)(void *object);
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
+typedef void (*Mf_Skip_Func)(void *object, UInt32);
+
+typedef struct _IMatchFinder
+{
+ Mf_Init_Func Init;
+ Mf_GetIndexByte_Func GetIndexByte;
+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
+ Mf_GetMatches_Func GetMatches;
+ Mf_Skip_Func Skip;
+} IMatchFinder;
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+
+void MatchFinder_Init(CMatchFinder *p);
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+
+#endif
diff --git a/extern/lzma/LzFindMt.c b/extern/lzma/LzFindMt.c
new file mode 100644
index 00000000000..b49cd76b294
--- /dev/null
+++ b/extern/lzma/LzFindMt.c
@@ -0,0 +1,793 @@
+/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "LzHash.h"
+
+#include "LzFindMt.h"
+
+void MtSync_Construct(CMtSync *p)
+{
+ p->wasCreated = False;
+ p->csWasInitialized = False;
+ p->csWasEntered = False;
+ Thread_Construct(&p->thread);
+ Event_Construct(&p->canStart);
+ Event_Construct(&p->wasStarted);
+ Event_Construct(&p->wasStopped);
+ Semaphore_Construct(&p->freeSemaphore);
+ Semaphore_Construct(&p->filledSemaphore);
+}
+
+void MtSync_GetNextBlock(CMtSync *p)
+{
+ if (p->needStart)
+ {
+ p->numProcessedBlocks = 1;
+ p->needStart = False;
+ p->stopWriting = False;
+ p->exit = False;
+ Event_Reset(&p->wasStarted);
+ Event_Reset(&p->wasStopped);
+
+ Event_Set(&p->canStart);
+ Event_Wait(&p->wasStarted);
+ }
+ else
+ {
+ CriticalSection_Leave(&p->cs);
+ p->csWasEntered = False;
+ p->numProcessedBlocks++;
+ Semaphore_Release1(&p->freeSemaphore);
+ }
+ Semaphore_Wait(&p->filledSemaphore);
+ CriticalSection_Enter(&p->cs);
+ p->csWasEntered = True;
+}
+
+/* MtSync_StopWriting must be called if Writing was started */
+
+void MtSync_StopWriting(CMtSync *p)
+{
+ UInt32 myNumBlocks = p->numProcessedBlocks;
+ if (!Thread_WasCreated(&p->thread) || p->needStart)
+ return;
+ p->stopWriting = True;
+ if (p->csWasEntered)
+ {
+ CriticalSection_Leave(&p->cs);
+ p->csWasEntered = False;
+ }
+ Semaphore_Release1(&p->freeSemaphore);
+
+ Event_Wait(&p->wasStopped);
+
+ while (myNumBlocks++ != p->numProcessedBlocks)
+ {
+ Semaphore_Wait(&p->filledSemaphore);
+ Semaphore_Release1(&p->freeSemaphore);
+ }
+ p->needStart = True;
+}
+
+void MtSync_Destruct(CMtSync *p)
+{
+ if (Thread_WasCreated(&p->thread))
+ {
+ MtSync_StopWriting(p);
+ p->exit = True;
+ if (p->needStart)
+ Event_Set(&p->canStart);
+ Thread_Wait(&p->thread);
+ Thread_Close(&p->thread);
+ }
+ if (p->csWasInitialized)
+ {
+ CriticalSection_Delete(&p->cs);
+ p->csWasInitialized = False;
+ }
+
+ Event_Close(&p->canStart);
+ Event_Close(&p->wasStarted);
+ Event_Close(&p->wasStopped);
+ Semaphore_Close(&p->freeSemaphore);
+ Semaphore_Close(&p->filledSemaphore);
+
+ p->wasCreated = False;
+}
+
+#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
+
+static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+ if (p->wasCreated)
+ return SZ_OK;
+
+ RINOK_THREAD(CriticalSection_Init(&p->cs));
+ p->csWasInitialized = True;
+
+ RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
+ RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
+ RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
+
+ RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
+ RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
+
+ p->needStart = True;
+
+ RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
+ p->wasCreated = True;
+ return SZ_OK;
+}
+
+static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+ SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
+ if (res != SZ_OK)
+ MtSync_Destruct(p);
+ return res;
+}
+
+void MtSync_Init(CMtSync *p) { p->needStart = True; }
+
+#define kMtMaxValForNormalize 0xFFFFFFFF
+
+#define DEF_GetHeads2(name, v, action) \
+static void GetHeads ## name(const Byte *p, UInt32 pos, \
+UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
+{ action; for (; numHeads != 0; numHeads--) { \
+const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
+
+#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
+
+DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
+DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
+DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
+DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
+DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask)
+
+void HashThreadFunc(CMatchFinderMt *mt)
+{
+ CMtSync *p = &mt->hashSync;
+ for (;;)
+ {
+ UInt32 numProcessedBlocks = 0;
+ Event_Wait(&p->canStart);
+ Event_Set(&p->wasStarted);
+ for (;;)
+ {
+ if (p->exit)
+ return;
+ if (p->stopWriting)
+ {
+ p->numProcessedBlocks = numProcessedBlocks;
+ Event_Set(&p->wasStopped);
+ break;
+ }
+
+ {
+ CMatchFinder *mf = mt->MatchFinder;
+ if (MatchFinder_NeedMove(mf))
+ {
+ CriticalSection_Enter(&mt->btSync.cs);
+ CriticalSection_Enter(&mt->hashSync.cs);
+ {
+ const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
+ const Byte *afterPtr;
+ MatchFinder_MoveBlock(mf);
+ afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
+ mt->pointerToCurPos -= beforePtr - afterPtr;
+ mt->buffer -= beforePtr - afterPtr;
+ }
+ CriticalSection_Leave(&mt->btSync.cs);
+ CriticalSection_Leave(&mt->hashSync.cs);
+ continue;
+ }
+
+ Semaphore_Wait(&p->freeSemaphore);
+
+ MatchFinder_ReadIfRequired(mf);
+ if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
+ {
+ UInt32 subValue = (mf->pos - mf->historySize - 1);
+ MatchFinder_ReduceOffsets(mf, subValue);
+ MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
+ }
+ {
+ UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+ UInt32 num = mf->streamPos - mf->pos;
+ heads[0] = 2;
+ heads[1] = num;
+ if (num >= mf->numHashBytes)
+ {
+ num = num - mf->numHashBytes + 1;
+ if (num > kMtHashBlockSize - 2)
+ num = kMtHashBlockSize - 2;
+ mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
+ heads[0] += num;
+ }
+ mf->pos += num;
+ mf->buffer += num;
+ }
+ }
+
+ Semaphore_Release1(&p->filledSemaphore);
+ }
+ }
+}
+
+void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
+{
+ MtSync_GetNextBlock(&p->hashSync);
+ p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+ p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
+ p->hashNumAvail = p->hashBuf[p->hashBufPos++];
+}
+
+#define kEmptyHashValue 0
+
+/* #define MFMT_GM_INLINE */
+
+#ifdef MFMT_GM_INLINE
+
+#define NO_INLINE MY_FAST_CALL
+
+Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+ UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
+{
+ do
+ {
+ UInt32 *distances = _distances + 1;
+ UInt32 curMatch = pos - *hash++;
+
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ UInt32 cutValue = _cutValue;
+ UInt32 maxLen = _maxLen;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ break;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ if (++len != lenLimit && pb[len] == cur[len])
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ break;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+ pos++;
+ _cyclicBufferPos++;
+ cur++;
+ {
+ UInt32 num = (UInt32)(distances - _distances);
+ *_distances = num - 1;
+ _distances += num;
+ limit -= num;
+ }
+ }
+ while (limit > 0 && --size != 0);
+ *posRes = pos;
+ return limit;
+}
+
+#endif
+
+void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ UInt32 numProcessed = 0;
+ UInt32 curPos = 2;
+ UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
+ distances[1] = p->hashNumAvail;
+ while (curPos < limit)
+ {
+ if (p->hashBufPos == p->hashBufPosLimit)
+ {
+ MatchFinderMt_GetNextBlock_Hash(p);
+ distances[1] = numProcessed + p->hashNumAvail;
+ if (p->hashNumAvail >= p->numHashBytes)
+ continue;
+ for (; p->hashNumAvail != 0; p->hashNumAvail--)
+ distances[curPos++] = 0;
+ break;
+ }
+ {
+ UInt32 size = p->hashBufPosLimit - p->hashBufPos;
+ UInt32 lenLimit = p->matchMaxLen;
+ UInt32 pos = p->pos;
+ UInt32 cyclicBufferPos = p->cyclicBufferPos;
+ if (lenLimit >= p->hashNumAvail)
+ lenLimit = p->hashNumAvail;
+ {
+ UInt32 size2 = p->hashNumAvail - lenLimit + 1;
+ if (size2 < size)
+ size = size2;
+ size2 = p->cyclicBufferSize - cyclicBufferPos;
+ if (size2 < size)
+ size = size2;
+ }
+ #ifndef MFMT_GM_INLINE
+ while (curPos < limit && size-- != 0)
+ {
+ UInt32 *startDistances = distances + curPos;
+ UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
+ pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ startDistances + 1, p->numHashBytes - 1) - startDistances);
+ *startDistances = num - 1;
+ curPos += num;
+ cyclicBufferPos++;
+ pos++;
+ p->buffer++;
+ }
+ #else
+ {
+ UInt32 posRes;
+ curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
+ p->hashBufPos += posRes - pos;
+ cyclicBufferPos += posRes - pos;
+ p->buffer += posRes - pos;
+ pos = posRes;
+ }
+ #endif
+
+ numProcessed += pos - p->pos;
+ p->hashNumAvail -= pos - p->pos;
+ p->pos = pos;
+ if (cyclicBufferPos == p->cyclicBufferSize)
+ cyclicBufferPos = 0;
+ p->cyclicBufferPos = cyclicBufferPos;
+ }
+ }
+ distances[0] = curPos;
+}
+
+void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
+{
+ CMtSync *sync = &p->hashSync;
+ if (!sync->needStart)
+ {
+ CriticalSection_Enter(&sync->cs);
+ sync->csWasEntered = True;
+ }
+
+ BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
+
+ if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
+ {
+ UInt32 subValue = p->pos - p->cyclicBufferSize;
+ MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
+ p->pos -= subValue;
+ }
+
+ if (!sync->needStart)
+ {
+ CriticalSection_Leave(&sync->cs);
+ sync->csWasEntered = False;
+ }
+}
+
+void BtThreadFunc(CMatchFinderMt *mt)
+{
+ CMtSync *p = &mt->btSync;
+ for (;;)
+ {
+ UInt32 blockIndex = 0;
+ Event_Wait(&p->canStart);
+ Event_Set(&p->wasStarted);
+ for (;;)
+ {
+ if (p->exit)
+ return;
+ if (p->stopWriting)
+ {
+ p->numProcessedBlocks = blockIndex;
+ MtSync_StopWriting(&mt->hashSync);
+ Event_Set(&p->wasStopped);
+ break;
+ }
+ Semaphore_Wait(&p->freeSemaphore);
+ BtFillBlock(mt, blockIndex++);
+ Semaphore_Release1(&p->filledSemaphore);
+ }
+ }
+}
+
+void MatchFinderMt_Construct(CMatchFinderMt *p)
+{
+ p->hashBuf = 0;
+ MtSync_Construct(&p->hashSync);
+ MtSync_Construct(&p->btSync);
+}
+
+void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->hashBuf);
+ p->hashBuf = 0;
+}
+
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
+{
+ MtSync_Destruct(&p->hashSync);
+ MtSync_Destruct(&p->btSync);
+ MatchFinderMt_FreeMem(p, alloc);
+}
+
+#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
+#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
+
+static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
+static unsigned MY_STD_CALL BtThreadFunc2(void *p)
+{
+ Byte allocaDummy[0x180];
+ int i = 0;
+ for (i = 0; i < 16; i++)
+ allocaDummy[i] = (Byte)i;
+ BtThreadFunc((CMatchFinderMt *)p);
+ return 0;
+}
+
+SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
+{
+ CMatchFinder *mf = p->MatchFinder;
+ p->historySize = historySize;
+ if (kMtBtBlockSize <= matchMaxLen * 4)
+ return SZ_ERROR_PARAM;
+ if (p->hashBuf == 0)
+ {
+ p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
+ if (p->hashBuf == 0)
+ return SZ_ERROR_MEM;
+ p->btBuf = p->hashBuf + kHashBufferSize;
+ }
+ keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
+ keepAddBufferAfter += kMtHashBlockSize;
+ if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
+ return SZ_ERROR_MEM;
+
+ RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
+ RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
+ return SZ_OK;
+}
+
+/* Call it after ReleaseStream / SetStream */
+void MatchFinderMt_Init(CMatchFinderMt *p)
+{
+ CMatchFinder *mf = p->MatchFinder;
+ p->btBufPos = p->btBufPosLimit = 0;
+ p->hashBufPos = p->hashBufPosLimit = 0;
+ MatchFinder_Init(mf);
+ p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
+ p->btNumAvailBytes = 0;
+ p->lzPos = p->historySize + 1;
+
+ p->hash = mf->hash;
+ p->fixedHashSize = mf->fixedHashSize;
+ p->crc = mf->crc;
+
+ p->son = mf->son;
+ p->matchMaxLen = mf->matchMaxLen;
+ p->numHashBytes = mf->numHashBytes;
+ p->pos = mf->pos;
+ p->buffer = mf->buffer;
+ p->cyclicBufferPos = mf->cyclicBufferPos;
+ p->cyclicBufferSize = mf->cyclicBufferSize;
+ p->cutValue = mf->cutValue;
+}
+
+/* ReleaseStream is required to finish multithreading */
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
+{
+ MtSync_StopWriting(&p->btSync);
+ /* p->MatchFinder->ReleaseStream(); */
+}
+
+void MatchFinderMt_Normalize(CMatchFinderMt *p)
+{
+ MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
+ p->lzPos = p->historySize + 1;
+}
+
+void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
+{
+ UInt32 blockIndex;
+ MtSync_GetNextBlock(&p->btSync);
+ blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
+ p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
+ p->btBufPosLimit += p->btBuf[p->btBufPos++];
+ p->btNumAvailBytes = p->btBuf[p->btBufPos++];
+ if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
+ MatchFinderMt_Normalize(p);
+}
+
+const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
+{
+ return p->pointerToCurPos;
+}
+
+#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
+
+UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
+{
+ GET_NEXT_BLOCK_IF_REQUIRED;
+ return p->btNumAvailBytes;
+}
+
+Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
+{
+ return p->pointerToCurPos[index];
+}
+
+UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 hash2Value, curMatch2;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH2_CALC
+
+ curMatch2 = hash[hash2Value];
+ hash[hash2Value] = lzPos;
+
+ if (curMatch2 >= matchMinPos)
+ if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ *distances++ = 2;
+ *distances++ = lzPos - curMatch2 - 1;
+ }
+ return distances;
+}
+
+UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH3_CALC
+
+ curMatch2 = hash[ hash2Value];
+ curMatch3 = hash[kFix3HashSize + hash3Value];
+
+ hash[ hash2Value] =
+ hash[kFix3HashSize + hash3Value] =
+ lzPos;
+
+ if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch2 - 1;
+ if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+ {
+ distances[0] = 3;
+ return distances + 2;
+ }
+ distances[0] = 2;
+ distances += 2;
+ }
+ if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+ {
+ *distances++ = 3;
+ *distances++ = lzPos - curMatch3 - 1;
+ }
+ return distances;
+}
+
+/*
+UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
+ UInt32 *hash = p->hash;
+ const Byte *cur = p->pointerToCurPos;
+ UInt32 lzPos = p->lzPos;
+ MT_HASH4_CALC
+
+ curMatch2 = hash[ hash2Value];
+ curMatch3 = hash[kFix3HashSize + hash3Value];
+ curMatch4 = hash[kFix4HashSize + hash4Value];
+
+ hash[ hash2Value] =
+ hash[kFix3HashSize + hash3Value] =
+ hash[kFix4HashSize + hash4Value] =
+ lzPos;
+
+ if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch2 - 1;
+ if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+ {
+ distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
+ return distances + 2;
+ }
+ distances[0] = 2;
+ distances += 2;
+ }
+ if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+ {
+ distances[1] = lzPos - curMatch3 - 1;
+ if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
+ {
+ distances[0] = 4;
+ return distances + 2;
+ }
+ distances[0] = 3;
+ distances += 2;
+ }
+
+ if (curMatch4 >= matchMinPos)
+ if (
+ cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
+ cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
+ )
+ {
+ *distances++ = 4;
+ *distances++ = lzPos - curMatch4 - 1;
+ }
+ return distances;
+}
+*/
+
+#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
+
+UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ const UInt32 *btBuf = p->btBuf + p->btBufPos;
+ UInt32 len = *btBuf++;
+ p->btBufPos += 1 + len;
+ p->btNumAvailBytes--;
+ {
+ UInt32 i;
+ for (i = 0; i < len; i += 2)
+ {
+ *distances++ = *btBuf++;
+ *distances++ = *btBuf++;
+ }
+ }
+ INCREASE_LZ_POS
+ return len;
+}
+
+UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+ const UInt32 *btBuf = p->btBuf + p->btBufPos;
+ UInt32 len = *btBuf++;
+ p->btBufPos += 1 + len;
+
+ if (len == 0)
+ {
+ if (p->btNumAvailBytes-- >= 4)
+ len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
+ }
+ else
+ {
+ /* Condition: there are matches in btBuf with length < p->numHashBytes */
+ UInt32 *distances2;
+ p->btNumAvailBytes--;
+ distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
+ do
+ {
+ *distances2++ = *btBuf++;
+ *distances2++ = *btBuf++;
+ }
+ while ((len -= 2) != 0);
+ len = (UInt32)(distances2 - (distances));
+ }
+ INCREASE_LZ_POS
+ return len;
+}
+
+#define SKIP_HEADER2 do { GET_NEXT_BLOCK_IF_REQUIRED
+#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
+#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
+
+void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER2 { p->btNumAvailBytes--;
+ SKIP_FOOTER
+}
+
+void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(2)
+ UInt32 hash2Value;
+ MT_HASH2_CALC
+ hash[hash2Value] = p->lzPos;
+ SKIP_FOOTER
+}
+
+void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(3)
+ UInt32 hash2Value, hash3Value;
+ MT_HASH3_CALC
+ hash[kFix3HashSize + hash3Value] =
+ hash[ hash2Value] =
+ p->lzPos;
+ SKIP_FOOTER
+}
+
+/*
+void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
+{
+ SKIP_HEADER(4)
+ UInt32 hash2Value, hash3Value, hash4Value;
+ MT_HASH4_CALC
+ hash[kFix4HashSize + hash4Value] =
+ hash[kFix3HashSize + hash3Value] =
+ hash[ hash2Value] =
+ p->lzPos;
+ SKIP_FOOTER
+}
+*/
+
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
+{
+ vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
+ vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
+ switch(p->MatchFinder->numHashBytes)
+ {
+ case 2:
+ p->GetHeadsFunc = GetHeads2;
+ p->MixMatchesFunc = (Mf_Mix_Matches)0;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
+ vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
+ break;
+ case 3:
+ p->GetHeadsFunc = GetHeads3;
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
+ break;
+ default:
+ /* case 4: */
+ p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
+ /* p->GetHeadsFunc = GetHeads4; */
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
+ break;
+ /*
+ default:
+ p->GetHeadsFunc = GetHeads5;
+ p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
+ vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
+ break;
+ */
+ }
+}
diff --git a/extern/lzma/LzFindMt.h b/extern/lzma/LzFindMt.h
new file mode 100644
index 00000000000..2c7e462d592
--- /dev/null
+++ b/extern/lzma/LzFindMt.h
@@ -0,0 +1,97 @@
+/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZFINDMT_H
+#define __LZFINDMT_H
+
+#include "Threads.h"
+#include "LzFind.h"
+
+#define kMtHashBlockSize (1 << 13)
+#define kMtHashNumBlocks (1 << 3)
+#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
+
+#define kMtBtBlockSize (1 << 14)
+#define kMtBtNumBlocks (1 << 6)
+#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
+
+typedef struct _CMtSync
+{
+ Bool wasCreated;
+ Bool needStart;
+ Bool exit;
+ Bool stopWriting;
+
+ CThread thread;
+ CAutoResetEvent canStart;
+ CAutoResetEvent wasStarted;
+ CAutoResetEvent wasStopped;
+ CSemaphore freeSemaphore;
+ CSemaphore filledSemaphore;
+ Bool csWasInitialized;
+ Bool csWasEntered;
+ CCriticalSection cs;
+ UInt32 numProcessedBlocks;
+} CMtSync;
+
+typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
+
+/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
+#define kMtCacheLineDummy 128
+
+typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
+ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
+
+typedef struct _CMatchFinderMt
+{
+ /* LZ */
+ const Byte *pointerToCurPos;
+ UInt32 *btBuf;
+ UInt32 btBufPos;
+ UInt32 btBufPosLimit;
+ UInt32 lzPos;
+ UInt32 btNumAvailBytes;
+
+ UInt32 *hash;
+ UInt32 fixedHashSize;
+ UInt32 historySize;
+ const UInt32 *crc;
+
+ Mf_Mix_Matches MixMatchesFunc;
+
+ /* LZ + BT */
+ CMtSync btSync;
+ Byte btDummy[kMtCacheLineDummy];
+
+ /* BT */
+ UInt32 *hashBuf;
+ UInt32 hashBufPos;
+ UInt32 hashBufPosLimit;
+ UInt32 hashNumAvail;
+
+ CLzRef *son;
+ UInt32 matchMaxLen;
+ UInt32 numHashBytes;
+ UInt32 pos;
+ Byte *buffer;
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be historySize + 1 */
+ UInt32 cutValue;
+
+ /* BT + Hash */
+ CMtSync hashSync;
+ /* Byte hashDummy[kMtCacheLineDummy]; */
+
+ /* Hash */
+ Mf_GetHeads GetHeadsFunc;
+ CMatchFinder *MatchFinder;
+} CMatchFinderMt;
+
+void MatchFinderMt_Construct(CMatchFinderMt *p);
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
+SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
+
+#endif
diff --git a/extern/lzma/LzHash.h b/extern/lzma/LzHash.h
new file mode 100644
index 00000000000..9f4173e7e33
--- /dev/null
+++ b/extern/lzma/LzHash.h
@@ -0,0 +1,54 @@
+/* LzHash.h -- HASH functions for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZHASH_H
+#define __LZHASH_H
+
+#define kHash2Size (1 << 10)
+#define kHash3Size (1 << 16)
+#define kHash4Size (1 << 20)
+
+#define kFix3HashSize (kHash2Size)
+#define kFix4HashSize (kHash2Size + kHash3Size)
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
+
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
+
+#define HASH3_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+
+#define HASH4_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
+
+#define HASH5_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
+ hash4Value &= (kHash4Size - 1); }
+
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
+
+
+#define MT_HASH2_CALC \
+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+
+#define MT_HASH3_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+
+#define MT_HASH4_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+
+#endif
diff --git a/extern/lzma/LzmaDec.c b/extern/lzma/LzmaDec.c
new file mode 100644
index 00000000000..d87eb1914ea
--- /dev/null
+++ b/extern/lzma/LzmaDec.c
@@ -0,0 +1,1007 @@
+/* LzmaDec.c -- LZMA Decoder
+2008-11-06 : Igor Pavlov : Public domain */
+
+#include "LzmaDec.h"
+
+#include <string.h>
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+ { UPDATE_0(p); i = (i + i); A0; } else \
+ { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+ { i = 1; \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+ { UPDATE_0_CHECK; i = (i + i); A0; } else \
+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+static const Byte kLiteralNextStates[kNumStates * 2] =
+{
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
+ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+ Result:
+ SZ_OK - OK
+ SZ_ERROR_DATA - Error
+ p->remainLen:
+ < kMatchSpecLenStart : normal remain
+ = kMatchSpecLenStart : finished
+ = kMatchSpecLenStart + 1 : Flush marker
+ = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ CLzmaProb *probs = p->probs;
+
+ unsigned state = p->state;
+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+ unsigned lc = p->prop.lc;
+
+ Byte *dic = p->dic;
+ SizeT dicBufSize = p->dicBufSize;
+ SizeT dicPos = p->dicPos;
+
+ UInt32 processedPos = p->processedPos;
+ UInt32 checkDicSize = p->checkDicSize;
+ unsigned len = 0;
+
+ const Byte *buf = p->buf;
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+
+ do
+ {
+ CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = processedPos & pbMask;
+
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0(prob)
+ {
+ unsigned symbol;
+ UPDATE_0(prob);
+ prob = probs + Literal;
+ if (checkDicSize != 0 || processedPos != 0)
+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+
+ if (state < kNumLitStates)
+ {
+ symbol = 1;
+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+ }
+ else
+ {
+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ unsigned offs = 0x100;
+ symbol = 1;
+ do
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & offs);
+ probLit = prob + offs + bit + symbol;
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+ }
+ while (symbol < 0x100);
+ }
+ dic[dicPos++] = (Byte)symbol;
+ processedPos++;
+
+ state = kLiteralNextStates[state];
+ /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+ continue;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRep + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ state += kNumStates;
+ prob = probs + LenCoder;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ if (checkDicSize == 0 && processedPos == 0)
+ return SZ_ERROR_DATA;
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dicPos++;
+ processedPos++;
+ state = state < kNumLitStates ? 9 : 11;
+ continue;
+ }
+ UPDATE_1(prob);
+ }
+ else
+ {
+ UInt32 distance;
+ UPDATE_1(prob);
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = probs + RepLenCoder;
+ }
+ {
+ unsigned limit, offset;
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ limit = (1 << kLenNumLowBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenChoice2;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ limit = (1 << kLenNumMidBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ limit = (1 << kLenNumHighBits);
+ }
+ }
+ TREE_DECODE(probLen, limit, len);
+ len += offset;
+ }
+
+ if (state >= kNumStates)
+ {
+ UInt32 distance;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+ TREE_6_DECODE(prob, distance);
+ if (distance >= kStartPosModelIndex)
+ {
+ unsigned posSlot = (unsigned)distance;
+ int numDirectBits = (int)(((distance >> 1) - 1));
+ distance = (2 | (distance & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ distance <<= numDirectBits;
+ prob = probs + SpecPos + distance - posSlot - 1;
+ {
+ UInt32 mask = 1;
+ unsigned i = 1;
+ do
+ {
+ GET_BIT2(prob + i, i, ; , distance |= mask);
+ mask <<= 1;
+ }
+ while (--numDirectBits != 0);
+ }
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE
+ range >>= 1;
+
+ {
+ UInt32 t;
+ code -= range;
+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+ distance = (distance << 1) + (t + 1);
+ code += range & t;
+ }
+ /*
+ distance <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ distance |= 1;
+ }
+ */
+ }
+ while (--numDirectBits != 0);
+ prob = probs + Align;
+ distance <<= kNumAlignBits;
+ {
+ unsigned i = 1;
+ GET_BIT2(prob + i, i, ; , distance |= 1);
+ GET_BIT2(prob + i, i, ; , distance |= 2);
+ GET_BIT2(prob + i, i, ; , distance |= 4);
+ GET_BIT2(prob + i, i, ; , distance |= 8);
+ }
+ if (distance == (UInt32)0xFFFFFFFF)
+ {
+ len += kMatchSpecLenStart;
+ state -= kNumStates;
+ break;
+ }
+ }
+ }
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = distance + 1;
+ if (checkDicSize == 0)
+ {
+ if (distance >= processedPos)
+ return SZ_ERROR_DATA;
+ }
+ else if (distance >= checkDicSize)
+ return SZ_ERROR_DATA;
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+ /* state = kLiteralNextStates[state]; */
+ }
+
+ len += kMatchMinLen;
+
+ if (limit == dicPos)
+ return SZ_ERROR_DATA;
+ {
+ SizeT rem = limit - dicPos;
+ unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+ processedPos += curLen;
+
+ len -= curLen;
+ if (pos + curLen <= dicBufSize)
+ {
+ Byte *dest = dic + dicPos;
+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+ const Byte *lim = dest + curLen;
+ dicPos += curLen;
+ do
+ *(dest) = (Byte)*(dest + src);
+ while (++dest != lim);
+ }
+ else
+ {
+ do
+ {
+ dic[dicPos++] = dic[pos];
+ if (++pos == dicBufSize)
+ pos = 0;
+ }
+ while (--curLen != 0);
+ }
+ }
+ }
+ }
+ while (dicPos < limit && buf < bufLimit);
+ NORMALIZE;
+ p->buf = buf;
+ p->range = range;
+ p->code = code;
+ p->remainLen = len;
+ p->dicPos = dicPos;
+ p->processedPos = processedPos;
+ p->reps[0] = rep0;
+ p->reps[1] = rep1;
+ p->reps[2] = rep2;
+ p->reps[3] = rep3;
+ p->state = state;
+
+ return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+ {
+ Byte *dic = p->dic;
+ SizeT dicPos = p->dicPos;
+ SizeT dicBufSize = p->dicBufSize;
+ unsigned len = p->remainLen;
+ UInt32 rep0 = p->reps[0];
+ if (limit - dicPos < len)
+ len = (unsigned)(limit - dicPos);
+
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+ p->checkDicSize = p->prop.dicSize;
+
+ p->processedPos += len;
+ p->remainLen -= len;
+ while (len-- != 0)
+ {
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dicPos++;
+ }
+ p->dicPos = dicPos;
+ }
+}
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ do
+ {
+ SizeT limit2 = limit;
+ if (p->checkDicSize == 0)
+ {
+ UInt32 rem = p->prop.dicSize - p->processedPos;
+ if (limit - p->dicPos > rem)
+ limit2 = p->dicPos + rem;
+ }
+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+ if (p->processedPos >= p->prop.dicSize)
+ p->checkDicSize = p->prop.dicSize;
+ LzmaDec_WriteRem(p, limit);
+ }
+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+ if (p->remainLen > kMatchSpecLenStart)
+ {
+ p->remainLen = kMatchSpecLenStart;
+ }
+ return 0;
+}
+
+typedef enum
+{
+ DUMMY_ERROR, /* unexpected end of input stream */
+ DUMMY_LIT,
+ DUMMY_MATCH,
+ DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+ const Byte *bufLimit = buf + inSize;
+ CLzmaProb *probs = p->probs;
+ unsigned state = p->state;
+ ELzmaDummy res;
+
+ {
+ CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
+
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK
+
+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+ prob = probs + Literal;
+ if (p->checkDicSize != 0 || p->processedPos != 0)
+ prob += (LZMA_LIT_SIZE *
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+ if (state < kNumLitStates)
+ {
+ unsigned symbol = 1;
+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+ }
+ else
+ {
+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+ unsigned offs = 0x100;
+ unsigned symbol = 1;
+ do
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & offs);
+ probLit = prob + offs + bit + symbol;
+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+ }
+ while (symbol < 0x100);
+ }
+ res = DUMMY_LIT;
+ }
+ else
+ {
+ unsigned len;
+ UPDATE_1_CHECK;
+
+ prob = probs + IsRep + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ state = 0;
+ prob = probs + LenCoder;
+ res = DUMMY_MATCH;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ res = DUMMY_REP;
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ NORMALIZE_CHECK;
+ return DUMMY_REP;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ }
+ state = kNumStates;
+ prob = probs + RepLenCoder;
+ }
+ {
+ unsigned limit, offset;
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ limit = 1 << kLenNumLowBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenChoice2;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ limit = 1 << kLenNumMidBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ limit = 1 << kLenNumHighBits;
+ }
+ }
+ TREE_DECODE_CHECK(probLen, limit, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ unsigned posSlot;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+
+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+ if (posSlot < kEndPosModelIndex)
+ {
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE_CHECK
+ range >>= 1;
+ code -= range & (((code - range) >> 31) - 1);
+ /* if (code >= range) code -= range; */
+ }
+ while (--numDirectBits != 0);
+ prob = probs + Align;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ unsigned i = 1;
+ do
+ {
+ GET_BIT_CHECK(prob + i, i);
+ }
+ while (--numDirectBits != 0);
+ }
+ }
+ }
+ }
+ }
+ NORMALIZE_CHECK;
+ return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+ p->range = 0xFFFFFFFF;
+ p->needFlush = 0;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+ p->needFlush = 1;
+ p->remainLen = 0;
+ p->tempBufSize = 0;
+
+ if (initDic)
+ {
+ p->processedPos = 0;
+ p->checkDicSize = 0;
+ p->needInitState = 1;
+ }
+ if (initState)
+ p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+ p->dicPos = 0;
+ LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+ UInt32 i;
+ CLzmaProb *probs = p->probs;
+ for (i = 0; i < numProbs; i++)
+ probs[i] = kBitModelTotal >> 1;
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+ p->state = 0;
+ p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+ ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT inSize = *srcLen;
+ (*srcLen) = 0;
+ LzmaDec_WriteRem(p, dicLimit);
+
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+
+ while (p->remainLen != kMatchSpecLenStart)
+ {
+ int checkEndMarkNow;
+
+ if (p->needFlush != 0)
+ {
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+ p->tempBuf[p->tempBufSize++] = *src++;
+ if (p->tempBufSize < RC_INIT_SIZE)
+ {
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (p->tempBuf[0] != 0)
+ return SZ_ERROR_DATA;
+
+ LzmaDec_InitRc(p, p->tempBuf);
+ p->tempBufSize = 0;
+ }
+
+ checkEndMarkNow = 0;
+ if (p->dicPos >= dicLimit)
+ {
+ if (p->remainLen == 0 && p->code == 0)
+ {
+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+ return SZ_OK;
+ }
+ if (finishMode == LZMA_FINISH_ANY)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_OK;
+ }
+ if (p->remainLen != 0)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ checkEndMarkNow = 1;
+ }
+
+ if (p->needInitState)
+ LzmaDec_InitStateReal(p);
+
+ if (p->tempBufSize == 0)
+ {
+ SizeT processed;
+ const Byte *bufLimit;
+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ memcpy(p->tempBuf, src, inSize);
+ p->tempBufSize = (unsigned)inSize;
+ (*srcLen) += inSize;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ bufLimit = src;
+ }
+ else
+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+ p->buf = src;
+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+ return SZ_ERROR_DATA;
+ processed = (SizeT)(p->buf - src);
+ (*srcLen) += processed;
+ src += processed;
+ inSize -= processed;
+ }
+ else
+ {
+ unsigned rem = p->tempBufSize, lookAhead = 0;
+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+ p->tempBuf[rem++] = src[lookAhead++];
+ p->tempBufSize = rem;
+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ (*srcLen) += lookAhead;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ }
+ p->buf = p->tempBuf;
+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+ return SZ_ERROR_DATA;
+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+ (*srcLen) += lookAhead;
+ src += lookAhead;
+ inSize -= lookAhead;
+ p->tempBufSize = 0;
+ }
+ }
+ if (p->code == 0)
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT outSize = *destLen;
+ SizeT inSize = *srcLen;
+ *srcLen = *destLen = 0;
+ for (;;)
+ {
+ SizeT inSizeCur = inSize, outSizeCur, dicPos;
+ ELzmaFinishMode curFinishMode;
+ SRes res;
+ if (p->dicPos == p->dicBufSize)
+ p->dicPos = 0;
+ dicPos = p->dicPos;
+ if (outSize > p->dicBufSize - dicPos)
+ {
+ outSizeCur = p->dicBufSize;
+ curFinishMode = LZMA_FINISH_ANY;
+ }
+ else
+ {
+ outSizeCur = dicPos + outSize;
+ curFinishMode = finishMode;
+ }
+
+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+ src += inSizeCur;
+ inSize -= inSizeCur;
+ *srcLen += inSizeCur;
+ outSizeCur = p->dicPos - dicPos;
+ memcpy(dest, p->dic + dicPos, outSizeCur);
+ dest += outSizeCur;
+ outSize -= outSizeCur;
+ *destLen += outSizeCur;
+ if (res != 0)
+ return res;
+ if (outSizeCur == 0 || outSize == 0)
+ return SZ_OK;
+ }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->probs);
+ p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->dic);
+ p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+ LzmaDec_FreeProbs(p, alloc);
+ LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+ UInt32 dicSize;
+ Byte d;
+
+ if (size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_UNSUPPORTED;
+ else
+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+
+ if (dicSize < LZMA_DIC_MIN)
+ dicSize = LZMA_DIC_MIN;
+ p->dicSize = dicSize;
+
+ d = data[0];
+ if (d >= (9 * 5 * 5))
+ return SZ_ERROR_UNSUPPORTED;
+
+ p->lc = d % 9;
+ d /= 9;
+ p->pb = d / 5;
+ p->lp = d % 5;
+
+ return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+ if (p->probs == 0 || numProbs != p->numProbs)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+ p->numProbs = numProbs;
+ if (p->probs == 0)
+ return SZ_ERROR_MEM;
+ }
+ return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+ CLzmaProps propNew;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+ CLzmaProps propNew;
+ SizeT dicBufSize;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+ dicBufSize = propNew.dicSize;
+ if (p->dic == 0 || dicBufSize != p->dicBufSize)
+ {
+ LzmaDec_FreeDict(p, alloc);
+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+ if (p->dic == 0)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ }
+ p->dicBufSize = dicBufSize;
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAlloc *alloc)
+{
+ CLzmaDec p;
+ SRes res;
+ SizeT inSize = *srcLen;
+ SizeT outSize = *destLen;
+ *srcLen = *destLen = 0;
+ if (inSize < RC_INIT_SIZE)
+ return SZ_ERROR_INPUT_EOF;
+
+ LzmaDec_Construct(&p);
+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+ if (res != 0)
+ return res;
+ p.dic = dest;
+ p.dicBufSize = outSize;
+
+ LzmaDec_Init(&p);
+
+ *srcLen = inSize;
+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ res = SZ_ERROR_INPUT_EOF;
+
+ (*destLen) = p.dicPos;
+ LzmaDec_FreeProbs(&p, alloc);
+ return res;
+}
diff --git a/extern/lzma/LzmaDec.h b/extern/lzma/LzmaDec.h
new file mode 100644
index 00000000000..98cdbe94949
--- /dev/null
+++ b/extern/lzma/LzmaDec.h
@@ -0,0 +1,223 @@
+/* LzmaDec.h -- LZMA Decoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMADEC_H
+#define __LZMADEC_H
+
+#include "Types.h"
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+ but memory usage for CLzmaDec::probs will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+ unsigned lc, lp, pb;
+ UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+ SZ_OK
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct
+{
+ CLzmaProps prop;
+ CLzmaProb *probs;
+ Byte *dic;
+ const Byte *buf;
+ UInt32 range, code;
+ SizeT dicPos;
+ SizeT dicBufSize;
+ UInt32 processedPos;
+ UInt32 checkDicSize;
+ unsigned state;
+ UInt32 reps[4];
+ unsigned remainLen;
+ int needFlush;
+ int needInitState;
+ UInt32 numProbs;
+ unsigned tempBufSize;
+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum
+{
+ LZMA_FINISH_ANY, /* finish at any point */
+ LZMA_FINISH_END /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+ You must use LZMA_FINISH_END, when you know that current output buffer
+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+ and output value of destLen will be less than output buffer size limit.
+ You can check status result also.
+
+ You can use multiple checks to test data integrity after full decompression:
+ 1) Check Result and "status" variable.
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+ You must use correct finish mode in that case. */
+
+typedef enum
+{
+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+ 1) Dictionary Interface
+ 2) Buffer Interface
+ 3) One Call Interface
+ You can select any of these interfaces, but don't mix functions from different
+ groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+ 1) LzmaDec_Allocate / LzmaDec_Free
+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+ You can use variant 2, if you set dictionary buffer manually.
+ For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+ SZ_OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+ dictionary to some other external buffer.
+ You must work with CLzmaDec variables directly in this interface.
+
+ STEPS:
+ LzmaDec_Constr()
+ LzmaDec_Allocate()
+ for (each new stream)
+ {
+ LzmaDec_Init()
+ while (it needs more decompression)
+ {
+ LzmaDec_DecodeToDic()
+ use data from CLzmaDec::dic and update CLzmaDec::dicPos
+ }
+ }
+ LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+
+ The decoding to internal dictionary buffer (CLzmaDec::dic).
+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (dicLimit).
+ LZMA_FINISH_ANY - Decode just dicLimit bytes.
+ LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_NEEDS_MORE_INPUT
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+ See LzmaDec_DecodeToDic description for information about STEPS and return results,
+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+ to work with CLzmaDec variables manually.
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAlloc *alloc);
+
+#endif
diff --git a/extern/lzma/LzmaEnc.c b/extern/lzma/LzmaEnc.c
new file mode 100644
index 00000000000..9196c43f64b
--- /dev/null
+++ b/extern/lzma/LzmaEnc.c
@@ -0,0 +1,2281 @@
+/* LzmaEnc.c -- LZMA Encoder
+2009-02-02 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+/* #define SHOW_STAT */
+/* #define SHOW_STAT2 */
+
+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
+#include <stdio.h>
+#endif
+
+#include "LzmaEnc.h"
+
+#include "LzFind.h"
+#ifdef COMPRESS_MF_MT
+#include "LzFindMt.h"
+#endif
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
+
+#define kBlockSize (9 << 10)
+#define kUnpackBlockSize (1 << 18)
+#define kMatchArraySize (1 << 21)
+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
+
+#define kNumMaxDirectBits (31)
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+#define kProbInitValue (kBitModelTotal >> 1)
+
+#define kNumMoveReducingBits 4
+#define kNumBitPriceShiftBits 4
+#define kBitPrice (1 << kNumBitPriceShiftBits)
+
+void LzmaEncProps_Init(CLzmaEncProps *p)
+{
+ p->level = 5;
+ p->dictSize = p->mc = 0;
+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
+ p->writeEndMark = 0;
+}
+
+void LzmaEncProps_Normalize(CLzmaEncProps *p)
+{
+ int level = p->level;
+ if (level < 0) level = 5;
+ p->level = level;
+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
+ if (p->lc < 0) p->lc = 3;
+ if (p->lp < 0) p->lp = 0;
+ if (p->pb < 0) p->pb = 2;
+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
+ if (p->numHashBytes < 0) p->numHashBytes = 4;
+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+ if (p->numThreads < 0)
+ p->numThreads =
+ #ifdef COMPRESS_MF_MT
+ ((p->btMode && p->algo) ? 2 : 1);
+ #else
+ 1;
+ #endif
+}
+
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
+{
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+ return props.dictSize;
+}
+
+/* #define LZMA_LOG_BSR */
+/* Define it for Intel's CPU */
+
+
+#ifdef LZMA_LOG_BSR
+
+#define kDicLogSizeMaxCompress 30
+
+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
+
+UInt32 GetPosSlot1(UInt32 pos)
+{
+ UInt32 res;
+ BSR2_RET(pos, res);
+ return res;
+}
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
+
+#else
+
+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
+
+void LzmaEnc_FastPosInit(Byte *g_FastPos)
+{
+ int c = 2, slotFast;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+
+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
+ {
+ UInt32 k = (1 << ((slotFast >> 1) - 1));
+ UInt32 j;
+ for (j = 0; j < k; j++, c++)
+ g_FastPos[c] = (Byte)slotFast;
+ }
+}
+
+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
+ res = p->g_FastPos[pos >> i] + (i * 2); }
+/*
+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
+ p->g_FastPos[pos >> 6] + 12 : \
+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
+*/
+
+#define GetPosSlot1(pos) p->g_FastPos[pos]
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
+
+#endif
+
+
+#define LZMA_NUM_REPS 4
+
+typedef unsigned CState;
+
+typedef struct _COptimal
+{
+ UInt32 price;
+
+ CState state;
+ int prev1IsChar;
+ int prev2;
+
+ UInt32 posPrev2;
+ UInt32 backPrev2;
+
+ UInt32 posPrev;
+ UInt32 backPrev;
+ UInt32 backs[LZMA_NUM_REPS];
+} COptimal;
+
+#define kNumOpts (1 << 12)
+
+#define kNumLenToPosStates 4
+#define kNumPosSlotBits 6
+#define kDicLogSizeMin 0
+#define kDicLogSizeMax 32
+#define kDistTableSizeMax (kDicLogSizeMax * 2)
+
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+#define kAlignMask (kAlignTableSize - 1)
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
+
+#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+#define LZMA_PB_MAX 4
+#define LZMA_LC_MAX 8
+#define LZMA_LP_MAX 4
+
+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
+
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define LZMA_MATCH_LEN_MIN 2
+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
+
+#define kNumStates 12
+
+typedef struct
+{
+ CLzmaProb choice;
+ CLzmaProb choice2;
+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
+ CLzmaProb high[kLenNumHighSymbols];
+} CLenEnc;
+
+typedef struct
+{
+ CLenEnc p;
+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
+ UInt32 tableSize;
+ UInt32 counters[LZMA_NUM_PB_STATES_MAX];
+} CLenPriceEnc;
+
+typedef struct _CRangeEnc
+{
+ UInt32 range;
+ Byte cache;
+ UInt64 low;
+ UInt64 cacheSize;
+ Byte *buf;
+ Byte *bufLim;
+ Byte *bufBase;
+ ISeqOutStream *outStream;
+ UInt64 processed;
+ SRes res;
+} CRangeEnc;
+
+typedef struct _CSeqInStreamBuf
+{
+ ISeqInStream funcTable;
+ const Byte *data;
+ SizeT rem;
+} CSeqInStreamBuf;
+
+static SRes MyRead(void *pp, void *data, size_t *size)
+{
+ size_t curSize = *size;
+ CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
+ if (p->rem < curSize)
+ curSize = p->rem;
+ memcpy(data, p->data, curSize);
+ p->rem -= curSize;
+ p->data += curSize;
+ *size = curSize;
+ return SZ_OK;
+}
+
+typedef struct
+{
+ CLzmaProb *litProbs;
+
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+ CLenPriceEnc lenEnc;
+ CLenPriceEnc repLenEnc;
+
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+} CSaveState;
+
+typedef struct _CLzmaEnc
+{
+ IMatchFinder matchFinder;
+ void *matchFinderObj;
+
+ #ifdef COMPRESS_MF_MT
+ Bool mtMode;
+ CMatchFinderMt matchFinderMt;
+ #endif
+
+ CMatchFinder matchFinderBase;
+
+ #ifdef COMPRESS_MF_MT
+ Byte pad[128];
+ #endif
+
+ UInt32 optimumEndIndex;
+ UInt32 optimumCurrentIndex;
+
+ UInt32 longestMatchLength;
+ UInt32 numPairs;
+ UInt32 numAvail;
+ COptimal opt[kNumOpts];
+
+ #ifndef LZMA_LOG_BSR
+ Byte g_FastPos[1 << kNumLogBits];
+ #endif
+
+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
+ UInt32 numFastBytes;
+ UInt32 additionalOffset;
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+
+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
+ UInt32 alignPrices[kAlignTableSize];
+ UInt32 alignPriceCount;
+
+ UInt32 distTableSize;
+
+ unsigned lc, lp, pb;
+ unsigned lpMask, pbMask;
+
+ CLzmaProb *litProbs;
+
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+ CLenPriceEnc lenEnc;
+ CLenPriceEnc repLenEnc;
+
+ unsigned lclp;
+
+ Bool fastMode;
+
+ CRangeEnc rc;
+
+ Bool writeEndMark;
+ UInt64 nowPos64;
+ UInt32 matchPriceCount;
+ Bool finished;
+ Bool multiThread;
+
+ SRes result;
+ UInt32 dictSize;
+ UInt32 matchFinderCycles;
+
+ ISeqInStream *inStream;
+ CSeqInStreamBuf seqBufInStream;
+
+ CSaveState saveState;
+} CLzmaEnc;
+
+void LzmaEnc_SaveState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CSaveState *dest = &p->saveState;
+ int i;
+ dest->lenEnc = p->lenEnc;
+ dest->repLenEnc = p->repLenEnc;
+ dest->state = p->state;
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+ }
+ for (i = 0; i < kNumLenToPosStates; i++)
+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+ memcpy(dest->reps, p->reps, sizeof(p->reps));
+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+}
+
+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *dest = (CLzmaEnc *)pp;
+ const CSaveState *p = &dest->saveState;
+ int i;
+ dest->lenEnc = p->lenEnc;
+ dest->repLenEnc = p->repLenEnc;
+ dest->state = p->state;
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+ }
+ for (i = 0; i < kNumLenToPosStates; i++)
+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+ memcpy(dest->reps, p->reps, sizeof(p->reps));
+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
+}
+
+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+
+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
+ return SZ_ERROR_PARAM;
+ p->dictSize = props.dictSize;
+ p->matchFinderCycles = props.mc;
+ {
+ unsigned fb = props.fb;
+ if (fb < 5)
+ fb = 5;
+ if (fb > LZMA_MATCH_LEN_MAX)
+ fb = LZMA_MATCH_LEN_MAX;
+ p->numFastBytes = fb;
+ }
+ p->lc = props.lc;
+ p->lp = props.lp;
+ p->pb = props.pb;
+ p->fastMode = (props.algo == 0);
+ p->matchFinderBase.btMode = props.btMode;
+ {
+ UInt32 numHashBytes = 4;
+ if (props.btMode)
+ {
+ if (props.numHashBytes < 2)
+ numHashBytes = 2;
+ else if (props.numHashBytes < 4)
+ numHashBytes = props.numHashBytes;
+ }
+ p->matchFinderBase.numHashBytes = numHashBytes;
+ }
+
+ p->matchFinderBase.cutValue = props.mc;
+
+ p->writeEndMark = props.writeEndMark;
+
+ #ifdef COMPRESS_MF_MT
+ /*
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ */
+ p->multiThread = (props.numThreads > 1);
+ #endif
+
+ return SZ_OK;
+}
+
+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+#define IsCharState(s) ((s) < 7)
+
+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
+
+#define kInfinityPrice (1 << 30)
+
+static void RangeEnc_Construct(CRangeEnc *p)
+{
+ p->outStream = 0;
+ p->bufBase = 0;
+}
+
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
+
+#define RC_BUF_SIZE (1 << 16)
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
+{
+ if (p->bufBase == 0)
+ {
+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
+ if (p->bufBase == 0)
+ return 0;
+ p->bufLim = p->bufBase + RC_BUF_SIZE;
+ }
+ return 1;
+}
+
+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->bufBase);
+ p->bufBase = 0;
+}
+
+static void RangeEnc_Init(CRangeEnc *p)
+{
+ /* Stream.Init(); */
+ p->low = 0;
+ p->range = 0xFFFFFFFF;
+ p->cacheSize = 1;
+ p->cache = 0;
+
+ p->buf = p->bufBase;
+
+ p->processed = 0;
+ p->res = SZ_OK;
+}
+
+static void RangeEnc_FlushStream(CRangeEnc *p)
+{
+ size_t num;
+ if (p->res != SZ_OK)
+ return;
+ num = p->buf - p->bufBase;
+ if (num != p->outStream->Write(p->outStream, p->bufBase, num))
+ p->res = SZ_ERROR_WRITE;
+ p->processed += num;
+ p->buf = p->bufBase;
+}
+
+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
+{
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
+ {
+ Byte temp = p->cache;
+ do
+ {
+ Byte *buf = p->buf;
+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
+ p->buf = buf;
+ if (buf == p->bufLim)
+ RangeEnc_FlushStream(p);
+ temp = 0xFF;
+ }
+ while (--p->cacheSize != 0);
+ p->cache = (Byte)((UInt32)p->low >> 24);
+ }
+ p->cacheSize++;
+ p->low = (UInt32)p->low << 8;
+}
+
+static void RangeEnc_FlushData(CRangeEnc *p)
+{
+ int i;
+ for (i = 0; i < 5; i++)
+ RangeEnc_ShiftLow(p);
+}
+
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
+{
+ do
+ {
+ p->range >>= 1;
+ p->low += p->range & (0 - ((value >> --numBits) & 1));
+ if (p->range < kTopValue)
+ {
+ p->range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+ }
+ while (numBits != 0);
+}
+
+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
+{
+ UInt32 ttt = *prob;
+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
+ if (symbol == 0)
+ {
+ p->range = newBound;
+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
+ }
+ else
+ {
+ p->low += newBound;
+ p->range -= newBound;
+ ttt -= ttt >> kNumMoveBits;
+ }
+ *prob = (CLzmaProb)ttt;
+ if (p->range < kTopValue)
+ {
+ p->range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
+{
+ symbol |= 0x100;
+ do
+ {
+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
+ symbol <<= 1;
+ }
+ while (symbol < 0x10000);
+}
+
+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
+{
+ UInt32 offs = 0x100;
+ symbol |= 0x100;
+ do
+ {
+ matchByte <<= 1;
+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
+ symbol <<= 1;
+ offs &= ~(matchByte ^ symbol);
+ }
+ while (symbol < 0x10000);
+}
+
+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+{
+ UInt32 i;
+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
+ {
+ const int kCyclesBits = kNumBitPriceShiftBits;
+ UInt32 w = i;
+ UInt32 bitCount = 0;
+ int j;
+ for (j = 0; j < kCyclesBits; j++)
+ {
+ w = w * w;
+ bitCount <<= 1;
+ while (w >= ((UInt32)1 << 16))
+ {
+ w >>= 1;
+ bitCount++;
+ }
+ }
+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
+ }
+}
+
+
+#define GET_PRICE(prob, symbol) \
+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICEa(prob, symbol) \
+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ symbol |= 0x100;
+ do
+ {
+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
+ symbol <<= 1;
+ }
+ while (symbol < 0x10000);
+ return price;
+}
+
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ UInt32 offs = 0x100;
+ symbol |= 0x100;
+ do
+ {
+ matchByte <<= 1;
+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
+ symbol <<= 1;
+ offs &= ~(matchByte ^ symbol);
+ }
+ while (symbol < 0x10000);
+ return price;
+}
+
+
+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+ UInt32 m = 1;
+ int i;
+ for (i = numBitLevels; i != 0;)
+ {
+ UInt32 bit;
+ i--;
+ bit = (symbol >> i) & 1;
+ RangeEnc_EncodeBit(rc, probs + m, bit);
+ m = (m << 1) | bit;
+ }
+}
+
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+ UInt32 m = 1;
+ int i;
+ for (i = 0; i < numBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ RangeEnc_EncodeBit(rc, probs + m, bit);
+ m = (m << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ symbol |= (1 << numBitLevels);
+ while (symbol != 1)
+ {
+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+}
+
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ UInt32 m = 1;
+ int i;
+ for (i = numBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += GET_PRICEa(probs[m], bit);
+ m = (m << 1) | bit;
+ }
+ return price;
+}
+
+
+static void LenEnc_Init(CLenEnc *p)
+{
+ unsigned i;
+ p->choice = p->choice2 = kProbInitValue;
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
+ p->low[i] = kProbInitValue;
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
+ p->mid[i] = kProbInitValue;
+ for (i = 0; i < kLenNumHighSymbols; i++)
+ p->high[i] = kProbInitValue;
+}
+
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
+{
+ if (symbol < kLenNumLowSymbols)
+ {
+ RangeEnc_EncodeBit(rc, &p->choice, 0);
+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
+ }
+ else
+ {
+ RangeEnc_EncodeBit(rc, &p->choice, 1);
+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
+ {
+ RangeEnc_EncodeBit(rc, &p->choice2, 0);
+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
+ }
+ else
+ {
+ RangeEnc_EncodeBit(rc, &p->choice2, 1);
+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
+ }
+ }
+}
+
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
+{
+ UInt32 a0 = GET_PRICE_0a(p->choice);
+ UInt32 a1 = GET_PRICE_1a(p->choice);
+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
+ UInt32 i = 0;
+ for (i = 0; i < kLenNumLowSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
+ }
+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
+ }
+ for (; i < numSymbols; i++)
+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
+}
+
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
+{
+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
+ p->counters[posState] = p->tableSize;
+}
+
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
+{
+ UInt32 posState;
+ for (posState = 0; posState < numPosStates; posState++)
+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
+{
+ LenEnc_Encode(&p->p, rc, symbol, posState);
+ if (updatePrice)
+ if (--p->counters[posState] == 0)
+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+
+
+
+static void MovePos(CLzmaEnc *p, UInt32 num)
+{
+ #ifdef SHOW_STAT
+ ttt += num;
+ printf("\n MovePos %d", num);
+ #endif
+ if (num != 0)
+ {
+ p->additionalOffset += num;
+ p->matchFinder.Skip(p->matchFinderObj, num);
+ }
+}
+
+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
+{
+ UInt32 lenRes = 0, numPairs;
+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
+ #ifdef SHOW_STAT
+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
+ ttt++;
+ {
+ UInt32 i;
+ for (i = 0; i < numPairs; i += 2)
+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
+ }
+ #endif
+ if (numPairs > 0)
+ {
+ lenRes = p->matches[numPairs - 2];
+ if (lenRes == p->numFastBytes)
+ {
+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ UInt32 distance = p->matches[numPairs - 1] + 1;
+ UInt32 numAvail = p->numAvail;
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ {
+ const Byte *pby2 = pby - distance;
+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+ }
+ }
+ }
+ p->additionalOffset++;
+ *numDistancePairsRes = numPairs;
+ return lenRes;
+}
+
+
+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
+#define IsShortRep(p) ((p)->backPrev == 0)
+
+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
+{
+ return
+ GET_PRICE_0(p->isRepG0[state]) +
+ GET_PRICE_0(p->isRep0Long[state][posState]);
+}
+
+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
+{
+ UInt32 price;
+ if (repIndex == 0)
+ {
+ price = GET_PRICE_0(p->isRepG0[state]);
+ price += GET_PRICE_1(p->isRep0Long[state][posState]);
+ }
+ else
+ {
+ price = GET_PRICE_1(p->isRepG0[state]);
+ if (repIndex == 1)
+ price += GET_PRICE_0(p->isRepG1[state]);
+ else
+ {
+ price += GET_PRICE_1(p->isRepG1[state]);
+ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
+ }
+ }
+ return price;
+}
+
+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
+{
+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
+ GetPureRepPrice(p, repIndex, state, posState);
+}
+
+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
+{
+ UInt32 posMem = p->opt[cur].posPrev;
+ UInt32 backMem = p->opt[cur].backPrev;
+ p->optimumEndIndex = cur;
+ do
+ {
+ if (p->opt[cur].prev1IsChar)
+ {
+ MakeAsChar(&p->opt[posMem])
+ p->opt[posMem].posPrev = posMem - 1;
+ if (p->opt[cur].prev2)
+ {
+ p->opt[posMem - 1].prev1IsChar = False;
+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
+ }
+ }
+ {
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = p->opt[posPrev].backPrev;
+ posMem = p->opt[posPrev].posPrev;
+
+ p->opt[posPrev].backPrev = backCur;
+ p->opt[posPrev].posPrev = cur;
+ cur = posPrev;
+ }
+ }
+ while (cur != 0);
+ *backRes = p->opt[0].backPrev;
+ p->optimumCurrentIndex = p->opt[0].posPrev;
+ return p->optimumCurrentIndex;
+}
+
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
+
+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
+{
+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
+ UInt32 matchPrice, repMatchPrice, normalMatchPrice;
+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
+ UInt32 *matches;
+ const Byte *data;
+ Byte curByte, matchByte;
+ if (p->optimumEndIndex != p->optimumCurrentIndex)
+ {
+ const COptimal *opt = &p->opt[p->optimumCurrentIndex];
+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
+ *backRes = opt->backPrev;
+ p->optimumCurrentIndex = opt->posPrev;
+ return lenRes;
+ }
+ p->optimumCurrentIndex = p->optimumEndIndex = 0;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
+ {
+ mainLen = p->longestMatchLength;
+ numPairs = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ if (numAvail < 2)
+ {
+ *backRes = (UInt32)(-1);
+ return 1;
+ }
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ repMaxIndex = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 lenTest;
+ const Byte *data2;
+ reps[i] = p->reps[i];
+ data2 = data - (reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
+ repLens[i] = lenTest;
+ if (lenTest > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if (repLens[repMaxIndex] >= p->numFastBytes)
+ {
+ UInt32 lenRes;
+ *backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ MovePos(p, lenRes - 1);
+ return lenRes;
+ }
+
+ matches = p->matches;
+ if (mainLen >= p->numFastBytes)
+ {
+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 1);
+ return mainLen;
+ }
+ curByte = *data;
+ matchByte = *(data - (reps[0] + 1));
+
+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ *backRes = (UInt32)-1;
+ return 1;
+ }
+
+ p->opt[0].state = (CState)p->state;
+
+ posState = (position & p->pbMask);
+
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
+ (!IsCharState(p->state) ?
+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+ }
+
+ MakeAsChar(&p->opt[1]);
+
+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
+
+ if (matchByte == curByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
+ if (shortRepPrice < p->opt[1].price)
+ {
+ p->opt[1].price = shortRepPrice;
+ MakeAsShortRep(&p->opt[1]);
+ }
+ }
+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
+
+ if (lenEnd < 2)
+ {
+ *backRes = p->opt[1].backPrev;
+ return 1;
+ }
+
+ p->opt[1].posPrev = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ p->opt[0].backs[i] = reps[i];
+
+ len = lenEnd;
+ do
+ p->opt[len--].price = kInfinityPrice;
+ while (len >= 2);
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 repLen = repLens[i];
+ UInt32 price;
+ if (repLen < 2)
+ continue;
+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
+ COptimal *opt = &p->opt[repLen];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = 0;
+ opt->backPrev = i;
+ opt->prev1IsChar = False;
+ }
+ }
+ while (--repLen >= 2);
+ }
+
+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= mainLen)
+ {
+ UInt32 offs = 0;
+ while (len > matches[offs])
+ offs += 2;
+ for (; ; len++)
+ {
+ COptimal *opt;
+ UInt32 distance = matches[offs + 1];
+
+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (distance < kNumFullDistances)
+ curAndLenPrice += p->distancesPrices[lenToPosState][distance];
+ else
+ {
+ UInt32 slot;
+ GetPosSlot2(distance, slot);
+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
+ }
+ opt = &p->opt[len];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = 0;
+ opt->backPrev = distance + LZMA_NUM_REPS;
+ opt->prev1IsChar = False;
+ }
+ if (len == matches[offs])
+ {
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ }
+ }
+ }
+
+ cur = 0;
+
+ #ifdef SHOW_STAT2
+ if (position >= 0)
+ {
+ unsigned i;
+ printf("\n pos = %4X", position);
+ for (i = cur; i <= lenEnd; i++)
+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
+ }
+ #endif
+
+ for (;;)
+ {
+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
+ Bool nextIsChar;
+ Byte curByte, matchByte;
+ const Byte *data;
+ COptimal *curOpt;
+ COptimal *nextOpt;
+
+ cur++;
+ if (cur == lenEnd)
+ return Backward(p, backRes, cur);
+
+ newLen = ReadMatchDistances(p, &numPairs);
+ if (newLen >= p->numFastBytes)
+ {
+ p->numPairs = numPairs;
+ p->longestMatchLength = newLen;
+ return Backward(p, backRes, cur);
+ }
+ position++;
+ curOpt = &p->opt[cur];
+ posPrev = curOpt->posPrev;
+ if (curOpt->prev1IsChar)
+ {
+ posPrev--;
+ if (curOpt->prev2)
+ {
+ state = p->opt[curOpt->posPrev2].state;
+ if (curOpt->backPrev2 < LZMA_NUM_REPS)
+ state = kRepNextStates[state];
+ else
+ state = kMatchNextStates[state];
+ }
+ else
+ state = p->opt[posPrev].state;
+ state = kLiteralNextStates[state];
+ }
+ else
+ state = p->opt[posPrev].state;
+ if (posPrev == cur - 1)
+ {
+ if (IsShortRep(curOpt))
+ state = kShortRepNextStates[state];
+ else
+ state = kLiteralNextStates[state];
+ }
+ else
+ {
+ UInt32 pos;
+ const COptimal *prevOpt;
+ if (curOpt->prev1IsChar && curOpt->prev2)
+ {
+ posPrev = curOpt->posPrev2;
+ pos = curOpt->backPrev2;
+ state = kRepNextStates[state];
+ }
+ else
+ {
+ pos = curOpt->backPrev;
+ if (pos < LZMA_NUM_REPS)
+ state = kRepNextStates[state];
+ else
+ state = kMatchNextStates[state];
+ }
+ prevOpt = &p->opt[posPrev];
+ if (pos < LZMA_NUM_REPS)
+ {
+ UInt32 i;
+ reps[0] = prevOpt->backs[pos];
+ for (i = 1; i <= pos; i++)
+ reps[i] = prevOpt->backs[i - 1];
+ for (; i < LZMA_NUM_REPS; i++)
+ reps[i] = prevOpt->backs[i];
+ }
+ else
+ {
+ UInt32 i;
+ reps[0] = (pos - LZMA_NUM_REPS);
+ for (i = 1; i < LZMA_NUM_REPS; i++)
+ reps[i] = prevOpt->backs[i - 1];
+ }
+ }
+ curOpt->state = (CState)state;
+
+ curOpt->backs[0] = reps[0];
+ curOpt->backs[1] = reps[1];
+ curOpt->backs[2] = reps[2];
+ curOpt->backs[3] = reps[3];
+
+ curPrice = curOpt->price;
+ nextIsChar = False;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ curByte = *data;
+ matchByte = *(data - (reps[0] + 1));
+
+ posState = (position & p->pbMask);
+
+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ curAnd1Price +=
+ (!IsCharState(state) ?
+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+ }
+
+ nextOpt = &p->opt[cur + 1];
+
+ if (curAnd1Price < nextOpt->price)
+ {
+ nextOpt->price = curAnd1Price;
+ nextOpt->posPrev = cur;
+ MakeAsChar(nextOpt);
+ nextIsChar = True;
+ }
+
+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
+
+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
+ if (shortRepPrice <= nextOpt->price)
+ {
+ nextOpt->price = shortRepPrice;
+ nextOpt->posPrev = cur;
+ MakeAsShortRep(nextOpt);
+ nextIsChar = True;
+ }
+ }
+ numAvailFull = p->numAvail;
+ {
+ UInt32 temp = kNumOpts - 1 - cur;
+ if (temp < numAvailFull)
+ numAvailFull = temp;
+ }
+
+ if (numAvailFull < 2)
+ continue;
+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
+
+ if (!nextIsChar && matchByte != curByte) /* speed optimization */
+ {
+ /* try Literal + rep0 */
+ UInt32 temp;
+ UInt32 lenTest2;
+ const Byte *data2 = data - (reps[0] + 1);
+ UInt32 limit = p->numFastBytes + 1;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+
+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
+ lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = kLiteralNextStates[state];
+ UInt32 posStateNext = (position + 1) & p->pbMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ UInt32 offset = cur + 1 + lenTest2;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = False;
+ }
+ }
+ }
+ }
+
+ startLen = 2; /* speed optimization */
+ {
+ UInt32 repIndex;
+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
+ {
+ UInt32 lenTest;
+ UInt32 lenTestTemp;
+ UInt32 price;
+ const Byte *data2 = data - (reps[repIndex] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
+ while (lenEnd < cur + lenTest)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ lenTestTemp = lenTest;
+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
+ COptimal *opt = &p->opt[cur + lenTest];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur;
+ opt->backPrev = repIndex;
+ opt->prev1IsChar = False;
+ }
+ }
+ while (--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ /* if (_maxMode) */
+ {
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = lenTest2 + p->numFastBytes;
+ UInt32 nextRepMatchPrice;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = kRepNextStates[state];
+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
+ UInt32 curAndLenCharPrice =
+ price + p->repLenEnc.prices[posState][lenTest - 2] +
+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ data[lenTest], data2[lenTest], p->ProbPrices);
+ state2 = kLiteralNextStates[state2];
+ posStateNext = (position + lenTest + 1) & p->pbMask;
+ nextRepMatchPrice = curAndLenCharPrice +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + lenTest + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = True;
+ opt->posPrev2 = cur;
+ opt->backPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+ }
+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
+ if (newLen > numAvail)
+ {
+ newLen = numAvail;
+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
+ matches[numPairs] = newLen;
+ numPairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
+ UInt32 offs, curBack, posSlot;
+ UInt32 lenTest;
+ while (lenEnd < cur + newLen)
+ p->opt[++lenEnd].price = kInfinityPrice;
+
+ offs = 0;
+ while (startLen > matches[offs])
+ offs += 2;
+ curBack = matches[offs + 1];
+ GetPosSlot2(curBack, posSlot);
+ for (lenTest = /*2*/ startLen; ; lenTest++)
+ {
+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+ UInt32 lenToPosState = GetLenToPosState(lenTest);
+ COptimal *opt;
+ if (curBack < kNumFullDistances)
+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
+ else
+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
+
+ opt = &p->opt[cur + lenTest];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur;
+ opt->backPrev = curBack + LZMA_NUM_REPS;
+ opt->prev1IsChar = False;
+ }
+
+ if (/*_maxMode && */lenTest == matches[offs])
+ {
+ /* Try Match + Literal + Rep0 */
+ const Byte *data2 = data - (curBack + 1);
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = lenTest2 + p->numFastBytes;
+ UInt32 nextRepMatchPrice;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = kMatchNextStates[state];
+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice +
+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ data[lenTest], data2[lenTest], p->ProbPrices);
+ state2 = kLiteralNextStates[state2];
+ posStateNext = (posStateNext + 1) & p->pbMask;
+ nextRepMatchPrice = curAndLenCharPrice +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + lenTest + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = True;
+ opt->posPrev2 = cur;
+ opt->backPrev2 = curBack + LZMA_NUM_REPS;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ curBack = matches[offs + 1];
+ if (curBack >= kNumFullDistances)
+ GetPosSlot2(curBack, posSlot);
+ }
+ }
+ }
+ }
+}
+
+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
+
+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
+{
+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
+ const Byte *data;
+ const UInt32 *matches;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
+ {
+ mainLen = p->longestMatchLength;
+ numPairs = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ *backRes = (UInt32)-1;
+ if (numAvail < 2)
+ return 1;
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+
+ repLen = repIndex = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 len;
+ const Byte *data2 = data - (p->reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
+ if (len >= p->numFastBytes)
+ {
+ *backRes = i;
+ MovePos(p, len - 1);
+ return len;
+ }
+ if (len > repLen)
+ {
+ repIndex = i;
+ repLen = len;
+ }
+ }
+
+ matches = p->matches;
+ if (mainLen >= p->numFastBytes)
+ {
+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 1);
+ return mainLen;
+ }
+
+ mainDist = 0; /* for GCC */
+ if (mainLen >= 2)
+ {
+ mainDist = matches[numPairs - 1];
+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
+ {
+ if (!ChangePair(matches[numPairs - 3], mainDist))
+ break;
+ numPairs -= 2;
+ mainLen = matches[numPairs - 2];
+ mainDist = matches[numPairs - 1];
+ }
+ if (mainLen == 2 && mainDist >= 0x80)
+ mainLen = 1;
+ }
+
+ if (repLen >= 2 && (
+ (repLen + 1 >= mainLen) ||
+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
+ (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
+ {
+ *backRes = repIndex;
+ MovePos(p, repLen - 1);
+ return repLen;
+ }
+
+ if (mainLen < 2 || numAvail <= 2)
+ return 1;
+
+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
+ if (p->longestMatchLength >= 2)
+ {
+ UInt32 newDistance = matches[p->numPairs - 1];
+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
+ (p->longestMatchLength > mainLen + 1) ||
+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
+ return 1;
+ }
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 len, limit;
+ const Byte *data2 = data - (p->reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ limit = mainLen - 1;
+ for (len = 2; len < limit && data[len] == data2[len]; len++);
+ if (len >= limit)
+ return 1;
+ }
+ *backRes = mainDist + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 2);
+ return mainLen;
+}
+
+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
+{
+ UInt32 len;
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ p->state = kMatchNextStates[p->state];
+ len = LZMA_MATCH_LEN_MIN;
+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+}
+
+static SRes CheckErrors(CLzmaEnc *p)
+{
+ if (p->result != SZ_OK)
+ return p->result;
+ if (p->rc.res != SZ_OK)
+ p->result = SZ_ERROR_WRITE;
+ if (p->matchFinderBase.result != SZ_OK)
+ p->result = SZ_ERROR_READ;
+ if (p->result != SZ_OK)
+ p->finished = True;
+ return p->result;
+}
+
+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
+{
+ /* ReleaseMFStream(); */
+ p->finished = True;
+ if (p->writeEndMark)
+ WriteEndMarker(p, nowPos & p->pbMask);
+ RangeEnc_FlushData(&p->rc);
+ RangeEnc_FlushStream(&p->rc);
+ return CheckErrors(p);
+}
+
+static void FillAlignPrices(CLzmaEnc *p)
+{
+ UInt32 i;
+ for (i = 0; i < kAlignTableSize; i++)
+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+ p->alignPriceCount = 0;
+}
+
+static void FillDistancesPrices(CLzmaEnc *p)
+{
+ UInt32 tempPrices[kNumFullDistances];
+ UInt32 i, lenToPosState;
+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
+ {
+ UInt32 posSlot = GetPosSlot1(i);
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
+ }
+
+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
+
+ {
+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
+ UInt32 i;
+ for (i = 0; i < kStartPosModelIndex; i++)
+ distancesPrices[i] = posSlotPrices[i];
+ for (; i < kNumFullDistances; i++)
+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
+ }
+ }
+ p->matchPriceCount = 0;
+}
+
+void LzmaEnc_Construct(CLzmaEnc *p)
+{
+ RangeEnc_Construct(&p->rc);
+ MatchFinder_Construct(&p->matchFinderBase);
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Construct(&p->matchFinderMt);
+ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
+ #endif
+
+ {
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+ LzmaEnc_SetProps(p, &props);
+ }
+
+ #ifndef LZMA_LOG_BSR
+ LzmaEnc_FastPosInit(p->g_FastPos);
+ #endif
+
+ LzmaEnc_InitPriceTables(p->ProbPrices);
+ p->litProbs = 0;
+ p->saveState.litProbs = 0;
+}
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
+{
+ void *p;
+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
+ if (p != 0)
+ LzmaEnc_Construct((CLzmaEnc *)p);
+ return p;
+}
+
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->litProbs);
+ alloc->Free(alloc, p->saveState.litProbs);
+ p->litProbs = 0;
+ p->saveState.litProbs = 0;
+}
+
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
+ #endif
+ MatchFinder_Free(&p->matchFinderBase, allocBig);
+ LzmaEnc_FreeLits(p, alloc);
+ RangeEnc_Free(&p->rc, alloc);
+}
+
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
+ alloc->Free(alloc, p);
+}
+
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
+{
+ UInt32 nowPos32, startPos32;
+ if (p->inStream != 0)
+ {
+ p->matchFinderBase.stream = p->inStream;
+ p->matchFinder.Init(p->matchFinderObj);
+ p->inStream = 0;
+ }
+
+ if (p->finished)
+ return p->result;
+ RINOK(CheckErrors(p));
+
+ nowPos32 = (UInt32)p->nowPos64;
+ startPos32 = nowPos32;
+
+ if (p->nowPos64 == 0)
+ {
+ UInt32 numPairs;
+ Byte curByte;
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ return Flush(p, nowPos32);
+ ReadMatchDistances(p, &numPairs);
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
+ p->state = kLiteralNextStates[p->state];
+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
+ LitEnc_Encode(&p->rc, p->litProbs, curByte);
+ p->additionalOffset--;
+ nowPos32++;
+ }
+
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
+ for (;;)
+ {
+ UInt32 pos, len, posState;
+
+ if (p->fastMode)
+ len = GetOptimumFast(p, &pos);
+ else
+ len = GetOptimum(p, nowPos32, &pos);
+
+ #ifdef SHOW_STAT2
+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
+ #endif
+
+ posState = nowPos32 & p->pbMask;
+ if (len == 1 && pos == (UInt32)-1)
+ {
+ Byte curByte;
+ CLzmaProb *probs;
+ const Byte *data;
+
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+ curByte = *data;
+ probs = LIT_PROBS(nowPos32, *(data - 1));
+ if (IsCharState(p->state))
+ LitEnc_Encode(&p->rc, probs, curByte);
+ else
+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
+ p->state = kLiteralNextStates[p->state];
+ }
+ else
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+ if (pos < LZMA_NUM_REPS)
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
+ if (pos == 0)
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
+ }
+ else
+ {
+ UInt32 distance = p->reps[pos];
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
+ if (pos == 1)
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
+ else
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
+ if (pos == 3)
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ }
+ p->reps[1] = p->reps[0];
+ p->reps[0] = distance;
+ }
+ if (len == 1)
+ p->state = kShortRepNextStates[p->state];
+ else
+ {
+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ p->state = kRepNextStates[p->state];
+ }
+ }
+ else
+ {
+ UInt32 posSlot;
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ p->state = kMatchNextStates[p->state];
+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ pos -= LZMA_NUM_REPS;
+ GetPosSlot(pos, posSlot);
+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - base;
+
+ if (posSlot < kEndPosModelIndex)
+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
+ else
+ {
+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
+ p->alignPriceCount++;
+ }
+ }
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ p->reps[1] = p->reps[0];
+ p->reps[0] = pos;
+ p->matchPriceCount++;
+ }
+ }
+ p->additionalOffset -= len;
+ nowPos32 += len;
+ if (p->additionalOffset == 0)
+ {
+ UInt32 processed;
+ if (!p->fastMode)
+ {
+ if (p->matchPriceCount >= (1 << 7))
+ FillDistancesPrices(p);
+ if (p->alignPriceCount >= kAlignTableSize)
+ FillAlignPrices(p);
+ }
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ break;
+ processed = nowPos32 - startPos32;
+ if (useLimits)
+ {
+ if (processed + kNumOpts + 300 >= maxUnpackSize ||
+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
+ break;
+ }
+ else if (processed >= (1 << 15))
+ {
+ p->nowPos64 += nowPos32 - startPos32;
+ return CheckErrors(p);
+ }
+ }
+ }
+ p->nowPos64 += nowPos32 - startPos32;
+ return Flush(p, nowPos32);
+}
+
+#define kBigHashDicLimit ((UInt32)1 << 24)
+
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ UInt32 beforeSize = kNumOpts;
+ Bool btMode;
+ if (!RangeEnc_Alloc(&p->rc, alloc))
+ return SZ_ERROR_MEM;
+ btMode = (p->matchFinderBase.btMode != 0);
+ #ifdef COMPRESS_MF_MT
+ p->mtMode = (p->multiThread && !p->fastMode && btMode);
+ #endif
+
+ {
+ unsigned lclp = p->lc + p->lp;
+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+ if (p->litProbs == 0 || p->saveState.litProbs == 0)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ p->lclp = lclp;
+ }
+ }
+
+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
+
+ if (beforeSize + p->dictSize < keepWindowSize)
+ beforeSize = keepWindowSize - p->dictSize;
+
+ #ifdef COMPRESS_MF_MT
+ if (p->mtMode)
+ {
+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
+ p->matchFinderObj = &p->matchFinderMt;
+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
+ }
+ else
+ #endif
+ {
+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
+ return SZ_ERROR_MEM;
+ p->matchFinderObj = &p->matchFinderBase;
+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
+ }
+ return SZ_OK;
+}
+
+void LzmaEnc_Init(CLzmaEnc *p)
+{
+ UInt32 i;
+ p->state = 0;
+ for (i = 0 ; i < LZMA_NUM_REPS; i++)
+ p->reps[i] = 0;
+
+ RangeEnc_Init(&p->rc);
+
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ UInt32 j;
+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
+ {
+ p->isMatch[i][j] = kProbInitValue;
+ p->isRep0Long[i][j] = kProbInitValue;
+ }
+ p->isRep[i] = kProbInitValue;
+ p->isRepG0[i] = kProbInitValue;
+ p->isRepG1[i] = kProbInitValue;
+ p->isRepG2[i] = kProbInitValue;
+ }
+
+ {
+ UInt32 num = 0x300 << (p->lp + p->lc);
+ for (i = 0; i < num; i++)
+ p->litProbs[i] = kProbInitValue;
+ }
+
+ {
+ for (i = 0; i < kNumLenToPosStates; i++)
+ {
+ CLzmaProb *probs = p->posSlotEncoder[i];
+ UInt32 j;
+ for (j = 0; j < (1 << kNumPosSlotBits); j++)
+ probs[j] = kProbInitValue;
+ }
+ }
+ {
+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ p->posEncoders[i] = kProbInitValue;
+ }
+
+ LenEnc_Init(&p->lenEnc.p);
+ LenEnc_Init(&p->repLenEnc.p);
+
+ for (i = 0; i < (1 << kNumAlignBits); i++)
+ p->posAlignEncoder[i] = kProbInitValue;
+
+ p->optimumEndIndex = 0;
+ p->optimumCurrentIndex = 0;
+ p->additionalOffset = 0;
+
+ p->pbMask = (1 << p->pb) - 1;
+ p->lpMask = (1 << p->lp) - 1;
+}
+
+void LzmaEnc_InitPrices(CLzmaEnc *p)
+{
+ if (!p->fastMode)
+ {
+ FillDistancesPrices(p);
+ FillAlignPrices(p);
+ }
+
+ p->lenEnc.tableSize =
+ p->repLenEnc.tableSize =
+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
+}
+
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ UInt32 i;
+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
+ if (p->dictSize <= ((UInt32)1 << i))
+ break;
+ p->distTableSize = i * 2;
+
+ p->finished = False;
+ p->result = SZ_OK;
+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+ p->nowPos64 = 0;
+ return SZ_OK;
+}
+
+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->inStream = inStream;
+ p->rc.outStream = outStream;
+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
+}
+
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
+ ISeqInStream *inStream, UInt32 keepWindowSize,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->inStream = inStream;
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
+{
+ p->seqBufInStream.funcTable.Read = MyRead;
+ p->seqBufInStream.data = src;
+ p->seqBufInStream.rem = srcLen;
+}
+
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ LzmaEnc_SetInputBuf(p, src, srcLen);
+ p->inStream = &p->seqBufInStream.funcTable;
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+void LzmaEnc_Finish(CLzmaEncHandle pp)
+{
+ #ifdef COMPRESS_MF_MT
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ if (p->mtMode)
+ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
+ #else
+ pp = pp;
+ #endif
+}
+
+typedef struct _CSeqOutStreamBuf
+{
+ ISeqOutStream funcTable;
+ Byte *data;
+ SizeT rem;
+ Bool overflow;
+} CSeqOutStreamBuf;
+
+static size_t MyWrite(void *pp, const void *data, size_t size)
+{
+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
+ if (p->rem < size)
+ {
+ size = p->rem;
+ p->overflow = True;
+ }
+ memcpy(p->data, data, size);
+ p->rem -= size;
+ p->data += size;
+ return size;
+}
+
+
+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+}
+
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+}
+
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ UInt64 nowPos64;
+ SRes res;
+ CSeqOutStreamBuf outStream;
+
+ outStream.funcTable.Write = MyWrite;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = False;
+ p->finished = False;
+ p->result = SZ_OK;
+
+ if (reInit)
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+ nowPos64 = p->nowPos64;
+ RangeEnc_Init(&p->rc);
+ p->rc.outStream = &outStream.funcTable;
+
+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
+
+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+
+ return res;
+}
+
+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ SRes res = SZ_OK;
+
+ #ifdef COMPRESS_MF_MT
+ Byte allocaDummy[0x300];
+ int i = 0;
+ for (i = 0; i < 16; i++)
+ allocaDummy[i] = (Byte)i;
+ #endif
+
+ RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
+
+ for (;;)
+ {
+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
+ if (res != SZ_OK || p->finished != 0)
+ break;
+ if (progress != 0)
+ {
+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
+ if (res != SZ_OK)
+ {
+ res = SZ_ERROR_PROGRESS;
+ break;
+ }
+ }
+ }
+ LzmaEnc_Finish(pp);
+ return res;
+}
+
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ int i;
+ UInt32 dictSize = p->dictSize;
+ if (*size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_PARAM;
+ *size = LZMA_PROPS_SIZE;
+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
+
+ for (i = 11; i <= 30; i++)
+ {
+ if (dictSize <= ((UInt32)2 << i))
+ {
+ dictSize = (2 << i);
+ break;
+ }
+ if (dictSize <= ((UInt32)3 << i))
+ {
+ dictSize = (3 << i);
+ break;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ props[1 + i] = (Byte)(dictSize >> (8 * i));
+ return SZ_OK;
+}
+
+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ SRes res;
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+
+ CSeqOutStreamBuf outStream;
+
+ LzmaEnc_SetInputBuf(p, src, srcLen);
+
+ outStream.funcTable.Write = MyWrite;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = writeEndMark;
+ res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
+ progress, alloc, allocBig);
+
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+ return res;
+}
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
+ SRes res;
+ if (p == 0)
+ return SZ_ERROR_MEM;
+
+ res = LzmaEnc_SetProps(p, props);
+ if (res == SZ_OK)
+ {
+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
+ if (res == SZ_OK)
+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
+ writeEndMark, progress, alloc, allocBig);
+ }
+
+ LzmaEnc_Destroy(p, alloc, allocBig);
+ return res;
+}
diff --git a/extern/lzma/LzmaEnc.h b/extern/lzma/LzmaEnc.h
new file mode 100644
index 00000000000..bfbc7d2b9c3
--- /dev/null
+++ b/extern/lzma/LzmaEnc.h
@@ -0,0 +1,72 @@
+/* LzmaEnc.h -- LZMA Encoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMAENC_H
+#define __LZMAENC_H
+
+#include "Types.h"
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaEncProps
+{
+ int level; /* 0 <= level <= 9 */
+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
+ default = (1 << 24) */
+ int lc; /* 0 <= lc <= 8, default = 3 */
+ int lp; /* 0 <= lp <= 4, default = 0 */
+ int pb; /* 0 <= pb <= 4, default = 2 */
+ int algo; /* 0 - fast, 1 - normal, default = 1 */
+ int fb; /* 5 <= fb <= 273, default = 32 */
+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
+ int numHashBytes; /* 2, 3 or 4, default = 4 */
+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
+ int numThreads; /* 1 or 2, default = 2 */
+} CLzmaEncProps;
+
+void LzmaEncProps_Init(CLzmaEncProps *p);
+void LzmaEncProps_Normalize(CLzmaEncProps *p);
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
+
+
+/* ---------- CLzmaEncHandle Interface ---------- */
+
+/* LzmaEnc_* functions can return the following exit codes:
+Returns:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater in props
+ SZ_ERROR_WRITE - Write callback error.
+ SZ_ERROR_PROGRESS - some break from progress callback
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+typedef void * CLzmaEncHandle;
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaEncode
+Return code:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+#endif
diff --git a/extern/lzma/LzmaLib.c b/extern/lzma/LzmaLib.c
new file mode 100644
index 00000000000..02a511857c9
--- /dev/null
+++ b/extern/lzma/LzmaLib.c
@@ -0,0 +1,46 @@
+/* LzmaLib.c -- LZMA library wrapper
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include "LzmaEnc.h"
+#include "LzmaDec.h"
+#include "Alloc.h"
+#include "LzmaLib.h"
+
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
+ unsigned char *outProps, size_t *outPropsSize,
+ int level, /* 0 <= level <= 9, default = 5 */
+ unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
+ int lc, /* 0 <= lc <= 8, default = 3 */
+ int lp, /* 0 <= lp <= 4, default = 0 */
+ int pb, /* 0 <= pb <= 4, default = 2 */
+ int fb, /* 5 <= fb <= 273, default = 32 */
+ int numThreads /* 1 or 2, default = 2 */
+)
+{
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+ props.level = level;
+ props.dictSize = dictSize;
+ props.lc = lc;
+ props.lp = lp;
+ props.pb = pb;
+ props.fb = fb;
+ props.numThreads = numThreads;
+
+ return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
+ NULL, &g_Alloc, &g_Alloc);
+}
+
+
+MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
+ const unsigned char *props, size_t propsSize)
+{
+ ELzmaStatus status;
+ return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
+}
diff --git a/extern/lzma/LzmaLib.h b/extern/lzma/LzmaLib.h
new file mode 100644
index 00000000000..5c9eeec73ca
--- /dev/null
+++ b/extern/lzma/LzmaLib.h
@@ -0,0 +1,135 @@
+/* LzmaLib.h -- LZMA library interface
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __LZMALIB_H
+#define __LZMALIB_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+ #define MY_EXTERN_C extern "C"
+#else
+ #define MY_EXTERN_C extern
+#endif
+
+#define MY_STDAPI MY_EXTERN_C int MY_STD_CALL
+
+#define LZMA_PROPS_SIZE 5
+
+/*
+RAM requirements for LZMA:
+ for compression: (dictSize * 11.5 + 6 MB) + state_size
+ for decompression: dictSize + state_size
+ state_size = (4 + (1.5 << (lc + lp))) KB
+ by default (lc=3, lp=0), state_size = 16 KB.
+
+LZMA properties (5 bytes) format
+ Offset Size Description
+ 0 1 lc, lp and pb in encoded form.
+ 1 4 dictSize (little endian).
+*/
+
+/*
+LzmaCompress
+------------
+
+outPropsSize -
+ In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
+ Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
+
+ LZMA Encoder will use defult values for any parameter, if it is
+ -1 for any from: level, loc, lp, pb, fb, numThreads
+ 0 for dictSize
+
+level - compression level: 0 <= level <= 9;
+
+ level dictSize algo fb
+ 0: 16 KB 0 32
+ 1: 64 KB 0 32
+ 2: 256 KB 0 32
+ 3: 1 MB 0 32
+ 4: 4 MB 0 32
+ 5: 16 MB 1 32
+ 6: 32 MB 1 32
+ 7+: 64 MB 1 64
+
+ The default value for "level" is 5.
+
+ algo = 0 means fast method
+ algo = 1 means normal method
+
+dictSize - The dictionary size in bytes. The maximum value is
+ 128 MB = (1 << 27) bytes for 32-bit version
+ 1 GB = (1 << 30) bytes for 64-bit version
+ The default value is 16 MB = (1 << 24) bytes.
+ It's recommended to use the dictionary that is larger than 4 KB and
+ that can be calculated as (1 << N) or (3 << N) sizes.
+
+lc - The number of literal context bits (high bits of previous literal).
+ It can be in the range from 0 to 8. The default value is 3.
+ Sometimes lc=4 gives the gain for big files.
+
+lp - The number of literal pos bits (low bits of current position for literals).
+ It can be in the range from 0 to 4. The default value is 0.
+ The lp switch is intended for periodical data when the period is equal to 2^lp.
+ For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
+ better to set lc=0, if you change lp switch.
+
+pb - The number of pos bits (low bits of current position).
+ It can be in the range from 0 to 4. The default value is 2.
+ The pb switch is intended for periodical data when the period is equal 2^pb.
+
+fb - Word size (the number of fast bytes).
+ It can be in the range from 5 to 273. The default value is 32.
+ Usually, a big number gives a little bit better compression ratio and
+ slower compression process.
+
+numThreads - The number of thereads. 1 or 2. The default value is 2.
+ Fast mode (algo = 0) can use only 1 thread.
+
+Out:
+ destLen - processed output size
+Returns:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
+ unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
+ int level, /* 0 <= level <= 9, default = 5 */
+ unsigned dictSize, /* default = (1 << 24) */
+ int lc, /* 0 <= lc <= 8, default = 3 */
+ int lp, /* 0 <= lp <= 4, default = 0 */
+ int pb, /* 0 <= pb <= 4, default = 2 */
+ int fb, /* 5 <= fb <= 273, default = 32 */
+ int numThreads /* 1 or 2, default = 2 */
+ );
+
+/*
+LzmaUncompress
+--------------
+In:
+ dest - output data
+ destLen - output data size
+ src - input data
+ srcLen - input data size
+Out:
+ destLen - processed output size
+ srcLen - processed input size
+Returns:
+ SZ_OK - OK
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation arror
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+ SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
+*/
+
+MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
+ const unsigned char *props, size_t propsSize);
+
+#endif
diff --git a/extern/lzma/Threads.c b/extern/lzma/Threads.c
new file mode 100644
index 00000000000..4fdd69b0d5c
--- /dev/null
+++ b/extern/lzma/Threads.c
@@ -0,0 +1,109 @@
+/* Threads.c -- multithreading library
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include "Threads.h"
+#include <process.h>
+
+static WRes GetError()
+{
+ DWORD res = GetLastError();
+ return (res) ? (WRes)(res) : 1;
+}
+
+WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
+WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
+
+static WRes MyCloseHandle(HANDLE *h)
+{
+ if (*h != NULL)
+ if (!CloseHandle(*h))
+ return GetError();
+ *h = NULL;
+ return 0;
+}
+
+WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
+{
+ unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
+ thread->handle =
+ /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
+ (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
+ /* maybe we must use errno here, but probably GetLastError() is also OK. */
+ return HandleToWRes(thread->handle);
+}
+
+WRes WaitObject(HANDLE h)
+{
+ return (WRes)WaitForSingleObject(h, INFINITE);
+}
+
+WRes Thread_Wait(CThread *thread)
+{
+ if (thread->handle == NULL)
+ return 1;
+ return WaitObject(thread->handle);
+}
+
+WRes Thread_Close(CThread *thread)
+{
+ return MyCloseHandle(&thread->handle);
+}
+
+WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
+{
+ p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
+ return HandleToWRes(p->handle);
+}
+
+WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
+ { return Event_Create(p, TRUE, initialSignaled); }
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
+ { return ManualResetEvent_Create(p, 0); }
+
+WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
+ { return Event_Create(p, FALSE, initialSignaled); }
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
+ { return AutoResetEvent_Create(p, 0); }
+
+WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); }
+WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); }
+WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
+WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
+
+
+WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
+{
+ p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
+ return HandleToWRes(p->handle);
+}
+
+WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
+{
+ return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
+}
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
+{
+ return Semaphore_Release(p, (LONG)releaseCount, NULL);
+}
+WRes Semaphore_Release1(CSemaphore *p)
+{
+ return Semaphore_ReleaseN(p, 1);
+}
+
+WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
+WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
+
+WRes CriticalSection_Init(CCriticalSection *p)
+{
+ /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
+ __try
+ {
+ InitializeCriticalSection(p);
+ /* InitializeCriticalSectionAndSpinCount(p, 0); */
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
+ return 0;
+}
+
diff --git a/extern/lzma/Threads.h b/extern/lzma/Threads.h
new file mode 100644
index 00000000000..a823e57858a
--- /dev/null
+++ b/extern/lzma/Threads.h
@@ -0,0 +1,68 @@
+/* Threads.h -- multithreading library
+2008-11-22 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_THRESDS_H
+#define __7Z_THRESDS_H
+
+#include "Types.h"
+
+typedef struct _CThread
+{
+ HANDLE handle;
+} CThread;
+
+#define Thread_Construct(thread) (thread)->handle = NULL
+#define Thread_WasCreated(thread) ((thread)->handle != NULL)
+
+typedef unsigned THREAD_FUNC_RET_TYPE;
+#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
+#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
+
+WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
+WRes Thread_Wait(CThread *thread);
+WRes Thread_Close(CThread *thread);
+
+typedef struct _CEvent
+{
+ HANDLE handle;
+} CEvent;
+
+typedef CEvent CAutoResetEvent;
+typedef CEvent CManualResetEvent;
+
+#define Event_Construct(event) (event)->handle = NULL
+#define Event_IsCreated(event) ((event)->handle != NULL)
+
+WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
+WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
+WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
+WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
+WRes Event_Set(CEvent *event);
+WRes Event_Reset(CEvent *event);
+WRes Event_Wait(CEvent *event);
+WRes Event_Close(CEvent *event);
+
+
+typedef struct _CSemaphore
+{
+ HANDLE handle;
+} CSemaphore;
+
+#define Semaphore_Construct(p) (p)->handle = NULL
+
+WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
+WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
+WRes Semaphore_Release1(CSemaphore *p);
+WRes Semaphore_Wait(CSemaphore *p);
+WRes Semaphore_Close(CSemaphore *p);
+
+
+typedef CRITICAL_SECTION CCriticalSection;
+
+WRes CriticalSection_Init(CCriticalSection *p);
+#define CriticalSection_Delete(p) DeleteCriticalSection(p)
+#define CriticalSection_Enter(p) EnterCriticalSection(p)
+#define CriticalSection_Leave(p) LeaveCriticalSection(p)
+
+#endif
+
diff --git a/extern/lzma/Types.h b/extern/lzma/Types.h
new file mode 100644
index 00000000000..1af5cfc4d86
--- /dev/null
+++ b/extern/lzma/Types.h
@@ -0,0 +1,208 @@
+/* Types.h -- Basic types
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#include <stddef.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifdef _WIN32
+typedef DWORD WRes;
+#else
+typedef int WRes;
+#endif
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+ NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+ SRes (*Read)(void *p, void *buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+/* it can return SZ_ERROR_INPUT_EOF */
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+
+typedef struct
+{
+ size_t (*Write)(void *p, const void *buf, size_t size);
+ /* Returns: result - the number of actually written bytes.
+ (result < size) means error */
+} ISeqOutStream;
+
+typedef enum
+{
+ SZ_SEEK_SET = 0,
+ SZ_SEEK_CUR = 1,
+ SZ_SEEK_END = 2
+} ESzSeek;
+
+typedef struct
+{
+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ISeekInStream;
+
+typedef struct
+{
+ SRes (*Look)(void *p, void **buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) > input(*size)) is not allowed
+ (output(*size) < input(*size)) is allowed */
+ SRes (*Skip)(void *p, size_t offset);
+ /* offset must be <= output(*size) of Look */
+
+ SRes (*Read)(void *p, void *buf, size_t *size);
+ /* reads directly (without buffer). It's same as ISeqInStream::Read */
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ILookInStream;
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+
+/* reads via ILookInStream::Read */
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+
+#define LookToRead_BUF_SIZE (1 << 14)
+
+typedef struct
+{
+ ILookInStream s;
+ ISeekInStream *realStream;
+ size_t pos;
+ size_t size;
+ Byte buf[LookToRead_BUF_SIZE];
+} CLookToRead;
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
+void LookToRead_Init(CLookToRead *p);
+
+typedef struct
+{
+ ISeqInStream s;
+ ILookInStream *realStream;
+} CSecToLook;
+
+void SecToLook_CreateVTable(CSecToLook *p);
+
+typedef struct
+{
+ ISeqInStream s;
+ ILookInStream *realStream;
+} CSecToRead;
+
+void SecToRead_CreateVTable(CSecToRead *p);
+
+typedef struct
+{
+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+ /* Returns: result. (result != SZ_OK) means break.
+ Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct
+{
+ void *(*Alloc)(void *p, size_t size);
+ void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#endif
diff --git a/extern/lzma/history.txt b/extern/lzma/history.txt
new file mode 100644
index 00000000000..014186717da
--- /dev/null
+++ b/extern/lzma/history.txt
@@ -0,0 +1,236 @@
+HISTORY of the LZMA SDK
+-----------------------
+
+4.65 2009-02-03
+-------------------------
+- Some minor fixes
+
+
+4.63 2008-12-31
+-------------------------
+- Some minor fixes
+
+
+4.61 beta 2008-11-23
+-------------------------
+- The bug in ANSI-C LZMA Decoder was fixed:
+ If encoded stream was corrupted, decoder could access memory
+ outside of allocated range.
+- Some changes in ANSI-C 7z Decoder interfaces.
+- LZMA SDK is placed in the public domain.
+
+
+4.60 beta 2008-08-19
+-------------------------
+- Some minor fixes.
+
+
+4.59 beta 2008-08-13
+-------------------------
+- The bug was fixed:
+ LZMA Encoder in fast compression mode could access memory outside of
+ allocated range in some rare cases.
+
+
+4.58 beta 2008-05-05
+-------------------------
+- ANSI-C LZMA Decoder was rewritten for speed optimizations.
+- ANSI-C LZMA Encoder was included to LZMA SDK.
+- C++ LZMA code now is just wrapper over ANSI-C code.
+
+
+4.57 2007-12-12
+-------------------------
+- Speed optimizations in Ñ++ LZMA Decoder.
+- Small changes for more compatibility with some C/C++ compilers.
+
+
+4.49 beta 2007-07-05
+-------------------------
+- .7z ANSI-C Decoder:
+ - now it supports BCJ and BCJ2 filters
+ - now it supports files larger than 4 GB.
+ - now it supports "Last Write Time" field for files.
+- C++ code for .7z archives compressing/decompressing from 7-zip
+ was included to LZMA SDK.
+
+
+4.43 2006-06-04
+-------------------------
+- Small changes for more compatibility with some C/C++ compilers.
+
+
+4.42 2006-05-15
+-------------------------
+- Small changes in .h files in ANSI-C version.
+
+
+4.39 beta 2006-04-14
+-------------------------
+- The bug in versions 4.33b:4.38b was fixed:
+ C++ version of LZMA encoder could not correctly compress
+ files larger than 2 GB with HC4 match finder (-mfhc4).
+
+
+4.37 beta 2005-04-06
+-------------------------
+- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
+
+
+4.35 beta 2005-03-02
+-------------------------
+- The bug was fixed in C++ version of LZMA Decoder:
+ If encoded stream was corrupted, decoder could access memory
+ outside of allocated range.
+
+
+4.34 beta 2006-02-27
+-------------------------
+- Compressing speed and memory requirements for compressing were increased
+- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
+
+
+4.32 2005-12-09
+-------------------------
+- Java version of LZMA SDK was included
+
+
+4.30 2005-11-20
+-------------------------
+- Compression ratio was improved in -a2 mode
+- Speed optimizations for compressing in -a2 mode
+- -fb switch now supports values up to 273
+- The bug in 7z_C (7zIn.c) was fixed:
+ It used Alloc/Free functions from different memory pools.
+ So if program used two memory pools, it worked incorrectly.
+- 7z_C: .7z format supporting was improved
+- LZMA# SDK (C#.NET version) was included
+
+
+4.27 (Updated) 2005-09-21
+-------------------------
+- Some GUIDs/interfaces in C++ were changed.
+ IStream.h:
+ ISequentialInStream::Read now works as old ReadPart
+ ISequentialOutStream::Write now works as old WritePart
+
+
+4.27 2005-08-07
+-------------------------
+- The bug in LzmaDecodeSize.c was fixed:
+ if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
+ decompressing worked incorrectly.
+
+
+4.26 2005-08-05
+-------------------------
+- Fixes in 7z_C code and LzmaTest.c:
+ previous versions could work incorrectly,
+ if malloc(0) returns 0
+
+
+4.23 2005-06-29
+-------------------------
+- Small fixes in C++ code
+
+
+4.22 2005-06-10
+-------------------------
+- Small fixes
+
+
+4.21 2005-06-08
+-------------------------
+- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
+- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
+ - LzmaStateDecode.h
+ - LzmaStateDecode.c
+ - LzmaStateTest.c
+- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
+
+
+4.17 2005-04-18
+-------------------------
+- New example for RAM->RAM compressing/decompressing:
+ LZMA + BCJ (filter for x86 code):
+ - LzmaRam.h
+ - LzmaRam.cpp
+ - LzmaRamDecode.h
+ - LzmaRamDecode.c
+ - -f86 switch for lzma.exe
+
+
+4.16 2005-03-29
+-------------------------
+- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
+ If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
+ decoder could access memory outside of allocated range.
+- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
+ Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
+ LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
+- Small speed optimization in LZMA C++ code
+- filter for SPARC's code was added
+- Simplified version of .7z ANSI-C Decoder was included
+
+
+4.06 2004-09-05
+-------------------------
+- The bug in v4.05 was fixed:
+ LZMA-Encoder didn't release output stream in some cases.
+
+
+4.05 2004-08-25
+-------------------------
+- Source code of filters for x86, IA-64, ARM, ARM-Thumb
+ and PowerPC code was included to SDK
+- Some internal minor changes
+
+
+4.04 2004-07-28
+-------------------------
+- More compatibility with some C++ compilers
+
+
+4.03 2004-06-18
+-------------------------
+- "Benchmark" command was added. It measures compressing
+ and decompressing speed and shows rating values.
+ Also it checks hardware errors.
+
+
+4.02 2004-06-10
+-------------------------
+- C++ LZMA Encoder/Decoder code now is more portable
+ and it can be compiled by GCC on Linux.
+
+
+4.01 2004-02-15
+-------------------------
+- Some detection of data corruption was enabled.
+ LzmaDecode.c / RangeDecoderReadByte
+ .....
+ {
+ rd->ExtraBytes = 1;
+ return 0xFF;
+ }
+
+
+4.00 2004-02-13
+-------------------------
+- Original version of LZMA SDK
+
+
+
+HISTORY of the LZMA
+-------------------
+ 2001-2008: Improvements to LZMA compressing/decompressing code,
+ keeping compatibility with original LZMA format
+ 1996-2001: Development of LZMA compression format
+
+ Some milestones:
+
+ 2001-08-30: LZMA compression was added to 7-Zip
+ 1999-01-02: First version of 7-Zip was released
+
+
+End of document
diff --git a/extern/lzma/lzma.txt b/extern/lzma/lzma.txt
new file mode 100644
index 00000000000..715792d6c17
--- /dev/null
+++ b/extern/lzma/lzma.txt
@@ -0,0 +1,594 @@
+LZMA SDK 4.65
+-------------
+
+LZMA SDK provides the documentation, samples, header files, libraries,
+and tools you need to develop applications that use LZMA compression.
+
+LZMA is default and general compression method of 7z format
+in 7-Zip compression program (www.7-zip.org). LZMA provides high
+compression ratio and very fast decompression.
+
+LZMA is an improved version of famous LZ77 compression algorithm.
+It was improved in way of maximum increasing of compression ratio,
+keeping high decompression speed and low memory requirements for
+decompressing.
+
+
+
+LICENSE
+-------
+
+LZMA SDK is written and placed in the public domain by Igor Pavlov.
+
+
+LZMA SDK Contents
+-----------------
+
+LZMA SDK includes:
+
+ - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing
+ - Compiled file->file LZMA compressing/decompressing program for Windows system
+
+
+UNIX/Linux version
+------------------
+To compile C++ version of file->file LZMA encoding, go to directory
+C++/7zip/Compress/LZMA_Alone
+and call make to recompile it:
+ make -f makefile.gcc clean all
+
+In some UNIX/Linux versions you must compile LZMA with static libraries.
+To compile with static libraries, you can use
+LIB = -lm -static
+
+
+Files
+---------------------
+lzma.txt - LZMA SDK description (this file)
+7zFormat.txt - 7z Format description
+7zC.txt - 7z ANSI-C Decoder description
+methods.txt - Compression method IDs for .7z
+lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
+history.txt - history of the LZMA SDK
+
+
+Source code structure
+---------------------
+
+C/ - C files
+ 7zCrc*.* - CRC code
+ Alloc.* - Memory allocation functions
+ Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+ LzFind.* - Match finder for LZ (LZMA) encoders
+ LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding
+ LzHash.h - Additional file for LZ match finder
+ LzmaDec.* - LZMA decoding
+ LzmaEnc.* - LZMA encoding
+ LzmaLib.* - LZMA Library for DLL calling
+ Types.h - Basic types for another .c files
+ Threads.* - The code for multithreading.
+
+ LzmaLib - LZMA Library (.DLL for Windows)
+
+ LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).
+
+ Archive - files related to archiving
+ 7z - 7z ANSI-C Decoder
+
+CPP/ -- CPP files
+
+ Common - common files for C++ projects
+ Windows - common files for Windows related code
+
+ 7zip - files related to 7-Zip Project
+
+ Common - common files for 7-Zip
+
+ Compress - files related to compression/decompression
+
+ Copy - Copy coder
+ RangeCoder - Range Coder (special code of compression/decompression)
+ LZMA - LZMA compression/decompression on C++
+ LZMA_Alone - file->file LZMA compression/decompression
+ Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+
+ Archive - files related to archiving
+
+ Common - common files for archive handling
+ 7z - 7z C++ Encoder/Decoder
+
+ Bundles - Modules that are bundles of other modules
+
+ Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
+ Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
+ Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
+
+ UI - User Interface files
+
+ Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
+ Common - Common UI files
+ Console - Code for console archiver
+
+
+
+CS/ - C# files
+ 7zip
+ Common - some common files for 7-Zip
+ Compress - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ LzmaAlone - file->file LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+Java/ - Java files
+ SevenZip
+ Compression - files related to compression/decompression
+ LZ - files related to LZ (Lempel-Ziv) compression algorithm
+ LZMA - LZMA compression/decompression
+ RangeCoder - Range Coder (special code of compression/decompression)
+
+
+C/C++ source code of LZMA SDK is part of 7-Zip project.
+7-Zip source code can be downloaded from 7-Zip's SourceForge page:
+
+ http://sourceforge.net/projects/sevenzip/
+
+
+
+LZMA features
+-------------
+ - Variable dictionary size (up to 1 GB)
+ - Estimated compressing speed: about 2 MB/s on 2 GHz CPU
+ - Estimated decompressing speed:
+ - 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64
+ - 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC
+ - Small memory requirements for decompressing (16 KB + DictionarySize)
+ - Small code size for decompressing: 5-8 KB
+
+LZMA decoder uses only integer operations and can be
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
+
+Some critical operations that affect the speed of LZMA decompression:
+ 1) 32*16 bit integer multiply
+ 2) Misspredicted branches (penalty mostly depends from pipeline length)
+ 3) 32-bit shift and arithmetic operations
+
+The speed of LZMA decompressing mostly depends from CPU speed.
+Memory speed has no big meaning. But if your CPU has small data cache,
+overall weight of memory speed will slightly increase.
+
+
+How To Use
+----------
+
+Using LZMA encoder/decoder executable
+--------------------------------------
+
+Usage: LZMA <e|d> inputFile outputFile [<switches>...]
+
+ e: encode file
+
+ d: decode file
+
+ b: Benchmark. There are two tests: compressing and decompressing
+ with LZMA method. Benchmark shows rating in MIPS (million
+ instructions per second). Rating value is calculated from
+ measured speed and it is normalized with Intel's Core 2 results.
+ Also Benchmark checks possible hardware errors (RAM
+ errors in most cases). Benchmark uses these settings:
+ (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
+ Also you can change the number of iterations. Example for 30 iterations:
+ LZMA b 30
+ Default number of iterations is 10.
+
+<Switches>
+
+
+ -a{N}: set compression mode 0 = fast, 1 = normal
+ default: 1 (normal)
+
+ d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
+ The maximum value for dictionary size is 1 GB = 2^30 bytes.
+ Dictionary size is calculated as DictionarySize = 2^N bytes.
+ For decompressing file compressed by LZMA method with dictionary
+ size D = 2^N you need about D bytes of memory (RAM).
+
+ -fb{N}: set number of fast bytes - [5, 273], default: 128
+ Usually big number gives a little bit better compression ratio
+ and slower compression process.
+
+ -lc{N}: set number of literal context bits - [0, 8], default: 3
+ Sometimes lc=4 gives gain for big files.
+
+ -lp{N}: set number of literal pos bits - [0, 4], default: 0
+ lp switch is intended for periodical data when period is
+ equal 2^N. For example, for 32-bit (4 bytes)
+ periodical data you can use lp=2. Often it's better to set lc0,
+ if you change lp switch.
+
+ -pb{N}: set number of pos bits - [0, 4], default: 2
+ pb switch is intended for periodical data
+ when period is equal 2^N.
+
+ -mf{MF_ID}: set Match Finder. Default: bt4.
+ Algorithms from hc* group doesn't provide good compression
+ ratio, but they often works pretty fast in combination with
+ fast mode (-a0).
+
+ Memory requirements depend from dictionary size
+ (parameter "d" in table below).
+
+ MF_ID Memory Description
+
+ bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
+ bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
+ bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
+ hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
+
+ -eos: write End Of Stream marker. By default LZMA doesn't write
+ eos marker, since LZMA decoder knows uncompressed size
+ stored in .lzma file header.
+
+ -si: Read data from stdin (it will write End Of Stream marker).
+ -so: Write data to stdout
+
+
+Examples:
+
+1) LZMA e file.bin file.lzma -d16 -lc0
+
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
+and 0 literal context bits. -lc0 allows to reduce memory requirements
+for decompression.
+
+
+2) LZMA e file.bin file.lzma -lc0 -lp2
+
+compresses file.bin to file.lzma with settings suitable
+for 32-bit periodical data (for example, ARM or MIPS code).
+
+3) LZMA d file.lzma file.bin
+
+decompresses file.lzma to file.bin.
+
+
+Compression ratio hints
+-----------------------
+
+Recommendations
+---------------
+
+To increase the compression ratio for LZMA compressing it's desirable
+to have aligned data (if it's possible) and also it's desirable to locate
+data in such order, where code is grouped in one place and data is
+grouped in other place (it's better than such mixing: code, data, code,
+data, ...).
+
+
+Filters
+-------
+You can increase the compression ratio for some data types, using
+special filters before compressing. For example, it's possible to
+increase the compression ratio on 5-10% for code for those CPU ISAs:
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
+
+You can find C source code of such filters in C/Bra*.* files
+
+You can check the compression ratio gain of these filters with such
+7-Zip commands (example for ARM code):
+No filter:
+ 7z a a1.7z a.bin -m0=lzma
+
+With filter for little-endian ARM code:
+ 7z a a2.7z a.bin -m0=arm -m1=lzma
+
+It works in such manner:
+Compressing = Filter_encoding + LZMA_encoding
+Decompressing = LZMA_decoding + Filter_decoding
+
+Compressing and decompressing speed of such filters is very high,
+so it will not increase decompressing time too much.
+Moreover, it reduces decompression time for LZMA_decoding,
+since compression ratio with filtering is higher.
+
+These filters convert CALL (calling procedure) instructions
+from relative offsets to absolute addresses, so such data becomes more
+compressible.
+
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
+
+
+LZMA compressed file format
+---------------------------
+Offset Size Description
+ 0 1 Special LZMA properties (lc,lp, pb in encoded form)
+ 1 4 Dictionary size (little endian)
+ 5 8 Uncompressed size (little endian). -1 means unknown size
+ 13 Compressed data
+
+
+ANSI-C LZMA Decoder
+~~~~~~~~~~~~~~~~~~~
+
+Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
+If you want to use old interfaces you can download previous version of LZMA SDK
+from sourceforge.net site.
+
+To use ANSI-C LZMA Decoder you need the following files:
+1) LzmaDec.h + LzmaDec.c + Types.h
+LzmaUtil/LzmaUtil.c is example application that uses these files.
+
+
+Memory requirements for LZMA decoding
+-------------------------------------
+
+Stack usage of LZMA decoding function for local variables is not
+larger than 200-400 bytes.
+
+LZMA Decoder uses dictionary buffer and internal state structure.
+Internal state structure consumes
+ state_size = (4 + (1.5 << (lc + lp))) KB
+by default (lc=3, lp=0), state_size = 16 KB.
+
+
+How To decompress data
+----------------------
+
+LZMA Decoder (ANSI-C version) now supports 2 interfaces:
+1) Single-call Decompressing
+2) Multi-call State Decompressing (zlib-like interface)
+
+You must use external allocator:
+Example:
+void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
+void SzFree(void *p, void *address) { p = p; free(address); }
+ISzAlloc alloc = { SzAlloc, SzFree };
+
+You can use p = p; operator to disable compiler warnings.
+
+
+Single-call Decompressing
+-------------------------
+When to use: RAM->RAM decompressing
+Compile files: LzmaDec.h + LzmaDec.c + Types.h
+Compile defines: no defines
+Memory Requirements:
+ - Input buffer: compressed size
+ - Output buffer: uncompressed size
+ - LZMA Internal Structures: state_size (16 KB for default settings)
+
+Interface:
+ int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAlloc *alloc);
+ In:
+ dest - output data
+ destLen - output data size
+ src - input data
+ srcLen - input data size
+ propData - LZMA properties (5 bytes)
+ propSize - size of propData buffer (5 bytes)
+ finishMode - It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+ You can use LZMA_FINISH_END, when you know that
+ current output buffer covers last bytes of stream.
+ alloc - Memory allocator.
+
+ Out:
+ destLen - processed output size
+ srcLen - processed input size
+
+ Output:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+
+ If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
+ and output value of destLen will be less than output buffer size limit.
+
+ You can use multiple checks to test data integrity after full decompression:
+ 1) Check Result and "status" variable.
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+ You must use correct finish mode in that case. */
+
+
+Multi-call State Decompressing (zlib-like interface)
+----------------------------------------------------
+
+When to use: file->file decompressing
+Compile files: LzmaDec.h + LzmaDec.c + Types.h
+
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures: state_size (16 KB for default settings)
+ - LZMA dictionary (dictionary size is encoded in LZMA properties header)
+
+1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
+ unsigned char header[LZMA_PROPS_SIZE + 8];
+ ReadFile(inFile, header, sizeof(header)
+
+2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
+
+ CLzmaDec state;
+ LzmaDec_Constr(&state);
+ res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
+ if (res != SZ_OK)
+ return res;
+
+3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
+
+ LzmaDec_Init(&state);
+ for (;;)
+ {
+ ...
+ int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
+ ...
+ }
+
+
+4) Free all allocated structures
+ LzmaDec_Free(&state, &g_Alloc);
+
+For full code example, look at C/LzmaUtil/LzmaUtil.c code.
+
+
+How To compress data
+--------------------
+
+Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
+LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h
+
+Memory Requirements:
+ - (dictSize * 11.5 + 6 MB) + state_size
+
+Lzma Encoder can use two memory allocators:
+1) alloc - for small arrays.
+2) allocBig - for big arrays.
+
+For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
+better compression speed. Note that Windows has bad implementation for
+Large RAM Pages.
+It's OK to use same allocator for alloc and allocBig.
+
+
+Single-call Compression with callbacks
+--------------------------------------
+
+Check C/LzmaUtil/LzmaUtil.c as example,
+
+When to use: file->file decompressing
+
+1) you must implement callback structures for interfaces:
+ISeqInStream
+ISeqOutStream
+ICompressProgress
+ISzAlloc
+
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+ CFileSeqInStream inStream;
+ CFileSeqOutStream outStream;
+
+ inStream.funcTable.Read = MyRead;
+ inStream.file = inFile;
+ outStream.funcTable.Write = MyWrite;
+ outStream.file = outFile;
+
+
+2) Create CLzmaEncHandle object;
+
+ CLzmaEncHandle enc;
+
+ enc = LzmaEnc_Create(&g_Alloc);
+ if (enc == 0)
+ return SZ_ERROR_MEM;
+
+
+3) initialize CLzmaEncProps properties;
+
+ LzmaEncProps_Init(&props);
+
+ Then you can change some properties in that structure.
+
+4) Send LZMA properties to LZMA Encoder
+
+ res = LzmaEnc_SetProps(enc, &props);
+
+5) Write encoded properties to header
+
+ Byte header[LZMA_PROPS_SIZE + 8];
+ size_t headerSize = LZMA_PROPS_SIZE;
+ UInt64 fileSize;
+ int i;
+
+ res = LzmaEnc_WriteProperties(enc, header, &headerSize);
+ fileSize = MyGetFileLength(inFile);
+ for (i = 0; i < 8; i++)
+ header[headerSize++] = (Byte)(fileSize >> (8 * i));
+ MyWriteFileAndCheck(outFile, header, headerSize)
+
+6) Call encoding function:
+ res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
+ NULL, &g_Alloc, &g_Alloc);
+
+7) Destroy LZMA Encoder Object
+ LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
+
+
+If callback function return some error code, LzmaEnc_Encode also returns that code.
+
+
+Single-call RAM->RAM Compression
+--------------------------------
+
+Single-call RAM->RAM Compression is similar to Compression with callbacks,
+but you provide pointers to buffers instead of pointers to stream callbacks:
+
+HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+Return code:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+
+
+
+LZMA Defines
+------------
+
+_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
+
+_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
+ some structures will be doubled in that case.
+
+_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
+
+_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
+
+
+C++ LZMA Encoder/Decoder
+~~~~~~~~~~~~~~~~~~~~~~~~
+C++ LZMA code use COM-like interfaces. So if you want to use it,
+you can study basics of COM/OLE.
+C++ LZMA code is just wrapper over ANSI-C code.
+
+
+C++ Notes
+~~~~~~~~~~~~~~~~~~~~~~~~
+If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
+you must check that you correctly work with "new" operator.
+7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
+So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
+operator new(size_t size)
+{
+ void *p = ::malloc(size);
+ if (p == 0)
+ throw CNewException();
+ return p;
+}
+If you use MSCV that throws exception for "new" operator, you can compile without
+"NewHandler.cpp". So standard exception will be used. Actually some code of
+7-Zip catches any exception in internal code and converts it to HRESULT code.
+So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/sdk.html
+http://www.7-zip.org/support.html
diff --git a/extern/lzo/CMakeLists.txt b/extern/lzo/CMakeLists.txt
new file mode 100644
index 00000000000..b640cf658da
--- /dev/null
+++ b/extern/lzo/CMakeLists.txt
@@ -0,0 +1,34 @@
+# $Id$
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Daniel Genrich
+#
+# ***** END GPL LICENSE BLOCK *****
+
+SET(INC include)
+
+FILE(GLOB SRC minilzo/*.c)
+
+
+
+BLENDERLIB(bf_minilzo "${SRC}" "${INC}")
+#, libtype='blender', priority = 0 )
diff --git a/extern/lzo/SConscript b/extern/lzo/SConscript
new file mode 100644
index 00000000000..81bedad25d8
--- /dev/null
+++ b/extern/lzo/SConscript
@@ -0,0 +1,9 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('minilzo/*.c')
+
+defs = ''
+incs = ' include '
+
+env.BlenderLib ('bf_minilzo', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
diff --git a/extern/lzo/minilzo/COPYING b/extern/lzo/minilzo/COPYING
new file mode 100644
index 00000000000..5ee49f42e91
--- /dev/null
+++ b/extern/lzo/minilzo/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/extern/lzo/minilzo/Makefile b/extern/lzo/minilzo/Makefile
new file mode 100644
index 00000000000..a6ee373e8bc
--- /dev/null
+++ b/extern/lzo/minilzo/Makefile
@@ -0,0 +1,113 @@
+#
+# a very simple Makefile for miniLZO
+#
+# Copyright (C) 1996-2008 Markus F.X.J. Oberhumer
+#
+
+PROGRAM = testmini
+SOURCES = testmini.c minilzo.c
+
+default:
+ @echo "Please choose one of the following targets:"
+ @echo " gcc: gcc"
+ @echo " unix: hpux hpux9"
+ @echo " win32: win32-bc win32-cygwin win32-dm win32-lccwin32"
+ @echo " win32-intelc win32-mingw win32-vc win32-watcomc"
+ @echo " dos16: dos16-bc dos16-mc dos16-wc"
+ @echo " dos32: dos32-djgpp2 dos32-wc"
+
+
+# Make sure that minilzo.h, lzoconf.h and lzodefs.h are in the
+# current dircectory. Otherwise you may want to adjust CPPFLAGS.
+##CPPFLAGS = -I../include/lzo -I.
+
+GCC_CFLAGS = -s -Wall -O2 -fomit-frame-pointer
+
+
+#
+# gcc (generic)
+#
+
+gcc:
+ gcc $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM) $(SOURCES)
+
+cc:
+ cc $(CPPFLAGS) -o $(PROGRAM) $(SOURCES)
+
+
+#
+# UNIX
+#
+
+hpux:
+ cc -Ae $(CPPFLAGS) -o $(PROGRAM) $(SOURCES)
+
+hpux9:
+ cc -Aa -D_HPUX_SOURCE $(CPPFLAGS) -o $(PROGRAM) $(SOURCES)
+
+
+#
+# Windows (32-bit)
+#
+
+win32-borlandc win32-bc:
+ bcc32 -O2 -d -w -w-aus $(CPPFLAGS) $(SOURCES)
+
+win32-cygwin32 win32-cygwin:
+ gcc -mcygwin $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM).exe $(SOURCES)
+
+win32-digitalmars win32-dm:
+ dmc -mn -o -w- $(CPPFLAGS) $(SOURCES)
+
+win32-intelc win32-ic:
+ icl -nologo -MD -W3 -O2 -GF $(CPPFLAGS) $(SOURCES)
+
+win32-lccwin32:
+ @echo "NOTE: need lcc 2002-07-25 or newer, older versions have bugs"
+ lc -A -unused -O $(CPPFLAGS) $(SOURCES)
+
+win32-mingw32 win32-mingw:
+ gcc -mno-cygwin $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM).exe $(SOURCES)
+
+win32-visualc win32-vc:
+ cl -nologo -MD -W3 -O2 -GF $(CPPFLAGS) $(SOURCES)
+
+win32-watcomc win32-wc:
+ wcl386 -bt=nt -zq -mf -5r -zc -w5 -oneatx $(CPPFLAGS) $(SOURCES)
+
+
+#
+# DOS (16-bit)
+#
+
+dos16-borlandc dos16-bc:
+ bcc -ml -w -d -O -4 $(CPPFLAGS) $(SOURCES)
+
+dos16-microsoftc dos16-msc dos16-mc:
+ cl -nologo -f- -AL -O -G2 -W3 $(CPPFLAGS) $(SOURCES)
+
+dos16-watcomc dos16-wc:
+ wcl -zq -ml -bt=dos -l=dos -ox -w5 $(CPPFLAGS) $(SOURCES)
+
+
+#
+# DOS (32-bit)
+#
+
+dos32-djgpp2 dos32-dj2:
+ gcc $(CPPFLAGS) $(GCC_CFLAGS) -o $(PROGRAM).exe $(SOURCES)
+
+dos32-watcomc dos32-wc:
+ wcl386 -zq -mf -bt=dos -l=dos4g -5r -ox -zc $(CPPFLAGS) $(SOURCES)
+
+
+#
+# other targets
+#
+
+clean:
+ rm -f $(PROGRAM) $(PROGRAM).exe $(PROGRAM).map $(PROGRAM).tds
+ rm -f *.err *.o *.obj
+
+.PHONY: default clean
+
diff --git a/extern/lzo/minilzo/README.LZO b/extern/lzo/minilzo/README.LZO
new file mode 100644
index 00000000000..3700f28e310
--- /dev/null
+++ b/extern/lzo/minilzo/README.LZO
@@ -0,0 +1,123 @@
+
+ ============================================================================
+ miniLZO -- mini subset of the LZO real-time data compression library
+ ============================================================================
+
+ Author : Markus Franz Xaver Johannes Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ Version : 2.03
+ Date : 30 Apr 2008
+
+ I've created miniLZO for projects where it is inconvenient to
+ include (or require) the full LZO source code just because you
+ want to add a little bit of data compression to your application.
+
+ miniLZO implements the LZO1X-1 compressor and both the standard and
+ safe LZO1X decompressor. Apart from fast compression it also useful
+ for situations where you want to use pre-compressed data files (which
+ must have been compressed with LZO1X-999).
+
+ miniLZO consists of one C source file and three header files:
+ minilzo.c
+ minilzo.h, lzoconf.h, lzodefs.h
+
+ To use miniLZO just copy these files into your source directory, add
+ minilzo.c to your Makefile and #include minilzo.h from your program.
+ Note: you also must distribute this file (`README.LZO') with your project.
+
+ minilzo.o compiles to about 6 kB (using gcc or Visual C on a i386), and
+ the sources are about 30 kB when packed with zip - so there's no more
+ excuse that your application doesn't support data compression :-)
+
+ For more information, documentation, example programs and other support
+ files (like Makefiles and build scripts) please download the full LZO
+ package from
+ http://www.oberhumer.com/opensource/lzo/
+
+ Have fun,
+ Markus
+
+
+ P.S. minilzo.c is generated automatically from the LZO sources and
+ therefore functionality is completely identical
+
+
+ Appendix A: building miniLZO
+ ----------------------------
+ miniLZO is written such a way that it should compile and run
+ out-of-the-box on most machines.
+
+ If you are running on a very unusual architecture and lzo_init() fails then
+ you should first recompile with `-DLZO_DEBUG' to see what causes the failure.
+ The most probable case is something like `sizeof(char *) != sizeof(long)'.
+ After identifying the problem you can compile by adding some defines
+ like `-DSIZEOF_CHAR_P=8' to your Makefile.
+
+ The best solution is (of course) using Autoconf - if your project uses
+ Autoconf anyway just add `-DMINILZO_HAVE_CONFIG_H' to your compiler
+ flags when compiling minilzo.c. See the LZO distribution for an example
+ how to set up configure.in.
+
+
+ Appendix B: list of public functions available in miniLZO
+ ---------------------------------------------------------
+ Library initialization
+ lzo_init()
+
+ Compression
+ lzo1x_1_compress()
+
+ Decompression
+ lzo1x_decompress()
+ lzo1x_decompress_safe()
+
+ Checksum functions
+ lzo_adler32()
+
+ Version functions
+ lzo_version()
+ lzo_version_string()
+ lzo_version_date()
+
+ Portable (but slow) string functions
+ lzo_memcmp()
+ lzo_memcpy()
+ lzo_memmove()
+ lzo_memset()
+
+
+ Appendix C: suggested macros for `configure.in' when using Autoconf
+ -------------------------------------------------------------------
+ Checks for typedefs and structures
+ AC_CHECK_TYPE(ptrdiff_t,long)
+ AC_TYPE_SIZE_T
+ AC_CHECK_SIZEOF(short)
+ AC_CHECK_SIZEOF(int)
+ AC_CHECK_SIZEOF(long)
+ AC_CHECK_SIZEOF(long long)
+ AC_CHECK_SIZEOF(__int64)
+ AC_CHECK_SIZEOF(void *)
+ AC_CHECK_SIZEOF(size_t)
+ AC_CHECK_SIZEOF(ptrdiff_t)
+
+ Checks for compiler characteristics
+ AC_C_CONST
+
+ Checks for library functions
+ AC_CHECK_FUNCS(memcmp memcpy memmove memset)
+
+
+ Appendix D: Copyright
+ ---------------------
+ LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004, 2005, 2006, 2007, 2008 Markus Franz Xaver Johannes Oberhumer
+
+ LZO and miniLZO are distributed under the terms of the GNU General
+ Public License (GPL). See the file COPYING.
+
+ Special licenses for commercial and other applications which
+ are not willing to accept the GNU General Public License
+ are available by contacting the author.
+
+
diff --git a/extern/lzo/minilzo/lzoconf.h b/extern/lzo/minilzo/lzoconf.h
new file mode 100644
index 00000000000..cc437f1ebfe
--- /dev/null
+++ b/extern/lzo/minilzo/lzoconf.h
@@ -0,0 +1,417 @@
+/* lzoconf.h -- configuration for the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+
+#ifndef __LZOCONF_H_INCLUDED
+#define __LZOCONF_H_INCLUDED
+
+#define LZO_VERSION 0x2030
+#define LZO_VERSION_STRING "2.03"
+#define LZO_VERSION_DATE "Apr 30 2008"
+
+/* internal Autoconf configuration file - only used when building LZO */
+#if defined(LZO_HAVE_CONFIG_H)
+# include <config.h>
+#endif
+#include <limits.h>
+#include <stddef.h>
+
+
+/***********************************************************************
+// LZO requires a conforming <limits.h>
+************************************************************************/
+
+#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
+# error "invalid CHAR_BIT"
+#endif
+#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
+# error "check your compiler installation"
+#endif
+#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
+# error "your limits.h macros are broken"
+#endif
+
+/* get OS and architecture defines */
+#ifndef __LZODEFS_H_INCLUDED
+#include "lzodefs.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***********************************************************************
+// some core defines
+************************************************************************/
+
+#if !defined(LZO_UINT32_C)
+# if (UINT_MAX < LZO_0xffffffffL)
+# define LZO_UINT32_C(c) c ## UL
+# else
+# define LZO_UINT32_C(c) ((c) + 0U)
+# endif
+#endif
+
+/* memory checkers */
+#if !defined(__LZO_CHECKER)
+# if defined(__BOUNDS_CHECKING_ON)
+# define __LZO_CHECKER 1
+# elif defined(__CHECKER__)
+# define __LZO_CHECKER 1
+# elif defined(__INSURE__)
+# define __LZO_CHECKER 1
+# elif defined(__PURIFY__)
+# define __LZO_CHECKER 1
+# endif
+#endif
+
+
+/***********************************************************************
+// integral and pointer types
+************************************************************************/
+
+/* lzo_uint should match size_t */
+#if !defined(LZO_UINT_MAX)
+# if defined(LZO_ABI_LLP64) /* WIN64 */
+# if defined(LZO_OS_WIN64)
+ typedef unsigned __int64 lzo_uint;
+ typedef __int64 lzo_int;
+# else
+ typedef unsigned long long lzo_uint;
+ typedef long long lzo_int;
+# endif
+# define LZO_UINT_MAX 0xffffffffffffffffull
+# define LZO_INT_MAX 9223372036854775807LL
+# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
+# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */
+ typedef unsigned int lzo_uint;
+ typedef int lzo_int;
+# define LZO_UINT_MAX UINT_MAX
+# define LZO_INT_MAX INT_MAX
+# define LZO_INT_MIN INT_MIN
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+ typedef unsigned long lzo_uint;
+ typedef long lzo_int;
+# define LZO_UINT_MAX ULONG_MAX
+# define LZO_INT_MAX LONG_MAX
+# define LZO_INT_MIN LONG_MIN
+# else
+# error "lzo_uint"
+# endif
+#endif
+
+/* Integral types with 32 bits or more. */
+#if !defined(LZO_UINT32_MAX)
+# if (UINT_MAX >= LZO_0xffffffffL)
+ typedef unsigned int lzo_uint32;
+ typedef int lzo_int32;
+# define LZO_UINT32_MAX UINT_MAX
+# define LZO_INT32_MAX INT_MAX
+# define LZO_INT32_MIN INT_MIN
+# elif (ULONG_MAX >= LZO_0xffffffffL)
+ typedef unsigned long lzo_uint32;
+ typedef long lzo_int32;
+# define LZO_UINT32_MAX ULONG_MAX
+# define LZO_INT32_MAX LONG_MAX
+# define LZO_INT32_MIN LONG_MIN
+# else
+# error "lzo_uint32"
+# endif
+#endif
+
+/* The larger type of lzo_uint and lzo_uint32. */
+#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
+# define lzo_xint lzo_uint
+#else
+# define lzo_xint lzo_uint32
+#endif
+
+/* Memory model that allows to access memory at offsets of lzo_uint. */
+#if !defined(__LZO_MMODEL)
+# if (LZO_UINT_MAX <= UINT_MAX)
+# define __LZO_MMODEL
+# elif defined(LZO_HAVE_MM_HUGE_PTR)
+# define __LZO_MMODEL_HUGE 1
+# define __LZO_MMODEL __huge
+# else
+# define __LZO_MMODEL
+# endif
+#endif
+
+/* no typedef here because of const-pointer issues */
+#define lzo_bytep unsigned char __LZO_MMODEL *
+#define lzo_charp char __LZO_MMODEL *
+#define lzo_voidp void __LZO_MMODEL *
+#define lzo_shortp short __LZO_MMODEL *
+#define lzo_ushortp unsigned short __LZO_MMODEL *
+#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
+#define lzo_int32p lzo_int32 __LZO_MMODEL *
+#define lzo_uintp lzo_uint __LZO_MMODEL *
+#define lzo_intp lzo_int __LZO_MMODEL *
+#define lzo_xintp lzo_xint __LZO_MMODEL *
+#define lzo_voidpp lzo_voidp __LZO_MMODEL *
+#define lzo_bytepp lzo_bytep __LZO_MMODEL *
+/* deprecated - use `lzo_bytep' instead of `lzo_byte *' */
+#define lzo_byte unsigned char __LZO_MMODEL
+
+typedef int lzo_bool;
+
+
+/***********************************************************************
+// function types
+************************************************************************/
+
+/* name mangling */
+#if !defined(__LZO_EXTERN_C)
+# ifdef __cplusplus
+# define __LZO_EXTERN_C extern "C"
+# else
+# define __LZO_EXTERN_C extern
+# endif
+#endif
+
+/* calling convention */
+#if !defined(__LZO_CDECL)
+# define __LZO_CDECL __lzo_cdecl
+#endif
+
+/* DLL export information */
+#if !defined(__LZO_EXPORT1)
+# define __LZO_EXPORT1
+#endif
+#if !defined(__LZO_EXPORT2)
+# define __LZO_EXPORT2
+#endif
+
+/* __cdecl calling convention for public C and assembly functions */
+#if !defined(LZO_PUBLIC)
+# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
+#endif
+#if !defined(LZO_EXTERN)
+# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
+#endif
+#if !defined(LZO_PRIVATE)
+# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL
+#endif
+
+/* function types */
+typedef int
+(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+typedef int
+(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem,
+ const lzo_bytep dict, lzo_uint dict_len );
+
+typedef int
+(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem,
+ const lzo_bytep dict, lzo_uint dict_len );
+
+
+/* Callback interface. Currently only the progress indicator ("nprogress")
+ * is used, but this may change in a future release. */
+
+struct lzo_callback_t;
+typedef struct lzo_callback_t lzo_callback_t;
+#define lzo_callback_p lzo_callback_t __LZO_MMODEL *
+
+/* malloc & free function types */
+typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t)
+ (lzo_callback_p self, lzo_uint items, lzo_uint size);
+typedef void (__LZO_CDECL *lzo_free_func_t)
+ (lzo_callback_p self, lzo_voidp ptr);
+
+/* a progress indicator callback function */
+typedef void (__LZO_CDECL *lzo_progress_func_t)
+ (lzo_callback_p, lzo_uint, lzo_uint, int);
+
+struct lzo_callback_t
+{
+ /* custom allocators (set to 0 to disable) */
+ lzo_alloc_func_t nalloc; /* [not used right now] */
+ lzo_free_func_t nfree; /* [not used right now] */
+
+ /* a progress indicator callback function (set to 0 to disable) */
+ lzo_progress_func_t nprogress;
+
+ /* NOTE: the first parameter "self" of the nalloc/nfree/nprogress
+ * callbacks points back to this struct, so you are free to store
+ * some extra info in the following variables. */
+ lzo_voidp user1;
+ lzo_xint user2;
+ lzo_xint user3;
+};
+
+
+/***********************************************************************
+// error codes and prototypes
+************************************************************************/
+
+/* Error codes for the compression/decompression functions. Negative
+ * values are errors, positive values will be used for special but
+ * normal events.
+ */
+#define LZO_E_OK 0
+#define LZO_E_ERROR (-1)
+#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */
+#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
+#define LZO_E_INPUT_OVERRUN (-4)
+#define LZO_E_OUTPUT_OVERRUN (-5)
+#define LZO_E_LOOKBEHIND_OVERRUN (-6)
+#define LZO_E_EOF_NOT_FOUND (-7)
+#define LZO_E_INPUT_NOT_CONSUMED (-8)
+#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
+
+
+#ifndef lzo_sizeof_dict_t
+# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep))
+#endif
+
+/* lzo_init() should be the first function you call.
+ * Check the return code !
+ *
+ * lzo_init() is a macro to allow checking that the library and the
+ * compiler's view of various types are consistent.
+ */
+#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
+ (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
+ (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
+ (int)sizeof(lzo_callback_t))
+LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
+
+/* version functions (useful for shared libraries) */
+LZO_EXTERN(unsigned) lzo_version(void);
+LZO_EXTERN(const char *) lzo_version_string(void);
+LZO_EXTERN(const char *) lzo_version_date(void);
+LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
+LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
+
+/* string functions */
+LZO_EXTERN(int)
+lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len);
+LZO_EXTERN(lzo_voidp)
+lzo_memset(lzo_voidp _s, int _c, lzo_uint _len);
+
+/* checksum functions */
+LZO_EXTERN(lzo_uint32)
+lzo_adler32(lzo_uint32 _adler, const lzo_bytep _buf, lzo_uint _len);
+LZO_EXTERN(lzo_uint32)
+lzo_crc32(lzo_uint32 _c, const lzo_bytep _buf, lzo_uint _len);
+LZO_EXTERN(const lzo_uint32p)
+lzo_get_crc32_table(void);
+
+/* misc. */
+LZO_EXTERN(int) _lzo_config_check(void);
+typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
+typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
+typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t;
+
+/* align a char pointer on a boundary that is a multiple of `size' */
+LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size);
+#define LZO_PTR_ALIGN_UP(_ptr,_size) \
+ ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size)))
+
+
+/***********************************************************************
+// deprecated macros - only for backward compatibility with LZO v1.xx
+************************************************************************/
+
+#if defined(LZO_CFG_COMPAT)
+
+#define __LZOCONF_H 1
+
+#if defined(LZO_ARCH_I086)
+# define __LZO_i386 1
+#elif defined(LZO_ARCH_I386)
+# define __LZO_i386 1
+#endif
+
+#if defined(LZO_OS_DOS16)
+# define __LZO_DOS 1
+# define __LZO_DOS16 1
+#elif defined(LZO_OS_DOS32)
+# define __LZO_DOS 1
+#elif defined(LZO_OS_WIN16)
+# define __LZO_WIN 1
+# define __LZO_WIN16 1
+#elif defined(LZO_OS_WIN32)
+# define __LZO_WIN 1
+#endif
+
+#define __LZO_CMODEL
+#define __LZO_DMODEL
+#define __LZO_ENTRY __LZO_CDECL
+#define LZO_EXTERN_CDECL LZO_EXTERN
+#define LZO_ALIGN LZO_PTR_ALIGN_UP
+
+#define lzo_compress_asm_t lzo_compress_t
+#define lzo_decompress_asm_t lzo_decompress_t
+
+#endif /* LZO_CFG_COMPAT */
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* already included */
+
+
+/* vim:set ts=4 et: */
diff --git a/extern/lzo/minilzo/lzodefs.h b/extern/lzo/minilzo/lzodefs.h
new file mode 100644
index 00000000000..180563723e5
--- /dev/null
+++ b/extern/lzo/minilzo/lzodefs.h
@@ -0,0 +1,1807 @@
+/* lzodefs.h -- architecture, OS and compiler specific defines
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+
+#ifndef __LZODEFS_H_INCLUDED
+#define __LZODEFS_H_INCLUDED 1
+
+#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
+# define __CYGWIN__ __CYGWIN32__
+#endif
+#if defined(__IBMCPP__) && !defined(__IBMC__)
+# define __IBMC__ __IBMCPP__
+#endif
+#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER)
+# define __INTEL_COMPILER __ICL
+#endif
+#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE)
+# define _ALL_SOURCE 1
+#endif
+#if defined(__mips__) && defined(__R5900__)
+# if !defined(__LONG_MAX__)
+# define __LONG_MAX__ 9223372036854775807L
+# endif
+#endif
+#if defined(__INTEL_COMPILER) && defined(__linux__)
+# pragma warning(disable: 193)
+#endif
+#if defined(__KEIL__) && defined(__C166__)
+# pragma warning disable = 322
+#elif 0 && defined(__C251__)
+# pragma warning disable = 322
+#endif
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
+# if (_MSC_VER >= 1300)
+# pragma warning(disable: 4668)
+# endif
+#endif
+#if 0 && defined(__WATCOMC__)
+# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060)
+# pragma warning 203 9
+# endif
+#endif
+#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__)
+# pragma option -h
+#endif
+#if 0
+#define LZO_0xffffL 0xfffful
+#define LZO_0xffffffffL 0xfffffffful
+#else
+#define LZO_0xffffL 65535ul
+#define LZO_0xffffffffL 4294967295ul
+#endif
+#if (LZO_0xffffL == LZO_0xffffffffL)
+# error "your preprocessor is broken 1"
+#endif
+#if (16ul * 16384ul != 262144ul)
+# error "your preprocessor is broken 2"
+#endif
+#if 0
+#if (32767 >= 4294967295ul)
+# error "your preprocessor is broken 3"
+#endif
+#if (65535u >= 4294967295ul)
+# error "your preprocessor is broken 4"
+#endif
+#endif
+#if (UINT_MAX == LZO_0xffffL)
+#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__)
+# if !defined(MSDOS)
+# define MSDOS 1
+# endif
+# if !defined(_MSDOS)
+# define _MSDOS 1
+# endif
+#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX)
+# if (__VERSION == 520) && (MB_LEN_MAX == 1)
+# if !defined(__AZTEC_C__)
+# define __AZTEC_C__ __VERSION
+# endif
+# if !defined(__DOS__)
+# define __DOS__ 1
+# endif
+# endif
+#endif
+#endif
+#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL)
+# define ptrdiff_t long
+# define _PTRDIFF_T_DEFINED
+#endif
+#if (UINT_MAX == LZO_0xffffL)
+# undef __LZO_RENAME_A
+# undef __LZO_RENAME_B
+# if defined(__AZTEC_C__) && defined(__DOS__)
+# define __LZO_RENAME_A 1
+# elif defined(_MSC_VER) && defined(MSDOS)
+# if (_MSC_VER < 600)
+# define __LZO_RENAME_A 1
+# elif (_MSC_VER < 700)
+# define __LZO_RENAME_B 1
+# endif
+# elif defined(__TSC__) && defined(__OS2__)
+# define __LZO_RENAME_A 1
+# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410)
+# define __LZO_RENAME_A 1
+# elif defined(__PACIFIC__) && defined(DOS)
+# if !defined(__far)
+# define __far far
+# endif
+# if !defined(__near)
+# define __near near
+# endif
+# endif
+# if defined(__LZO_RENAME_A)
+# if !defined(__cdecl)
+# define __cdecl cdecl
+# endif
+# if !defined(__far)
+# define __far far
+# endif
+# if !defined(__huge)
+# define __huge huge
+# endif
+# if !defined(__near)
+# define __near near
+# endif
+# if !defined(__pascal)
+# define __pascal pascal
+# endif
+# if !defined(__huge)
+# define __huge huge
+# endif
+# elif defined(__LZO_RENAME_B)
+# if !defined(__cdecl)
+# define __cdecl _cdecl
+# endif
+# if !defined(__far)
+# define __far _far
+# endif
+# if !defined(__huge)
+# define __huge _huge
+# endif
+# if !defined(__near)
+# define __near _near
+# endif
+# if !defined(__pascal)
+# define __pascal _pascal
+# endif
+# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__)
+# if !defined(__cdecl)
+# define __cdecl cdecl
+# endif
+# if !defined(__pascal)
+# define __pascal pascal
+# endif
+# endif
+# undef __LZO_RENAME_A
+# undef __LZO_RENAME_B
+#endif
+#if (UINT_MAX == LZO_0xffffL)
+#if defined(__AZTEC_C__) && defined(__DOS__)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+#elif defined(_MSC_VER) && defined(MSDOS)
+# if (_MSC_VER < 600)
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+# endif
+# if (_MSC_VER < 700)
+# define LZO_BROKEN_INTEGRAL_PROMOTION 1
+# define LZO_BROKEN_SIZEOF 1
+# endif
+#elif defined(__PACIFIC__) && defined(DOS)
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+#elif defined(__TURBOC__) && defined(__MSDOS__)
+# if (__TURBOC__ < 0x0150)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+# define LZO_BROKEN_INTEGRAL_PROMOTION 1
+# endif
+# if (__TURBOC__ < 0x0200)
+# define LZO_BROKEN_SIZEOF 1
+# endif
+# if (__TURBOC__ < 0x0400) && defined(__cplusplus)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+# endif
+#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+# define LZO_BROKEN_SIZEOF 1
+#endif
+#endif
+#if defined(__WATCOMC__) && (__WATCOMC__ < 900)
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+#endif
+#if defined(_CRAY) && defined(_CRAY1)
+# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1
+#endif
+#define LZO_PP_STRINGIZE(x) #x
+#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x)
+#define LZO_PP_CONCAT2(a,b) a ## b
+#define LZO_PP_CONCAT3(a,b,c) a ## b ## c
+#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d
+#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b)
+#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c)
+#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d)
+#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e)
+#if 1
+#define LZO_CPP_STRINGIZE(x) #x
+#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x)
+#define LZO_CPP_CONCAT2(a,b) a ## b
+#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c
+#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d
+#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b)
+#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c)
+#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d)
+#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e)
+#endif
+#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
+#if 1 && defined(__cplusplus)
+# if !defined(__STDC_CONSTANT_MACROS)
+# define __STDC_CONSTANT_MACROS 1
+# endif
+# if !defined(__STDC_LIMIT_MACROS)
+# define __STDC_LIMIT_MACROS 1
+# endif
+#endif
+#if defined(__cplusplus)
+# define LZO_EXTERN_C extern "C"
+#else
+# define LZO_EXTERN_C extern
+#endif
+#if !defined(__LZO_OS_OVERRIDE)
+#if defined(LZO_OS_FREESTANDING)
+# define LZO_INFO_OS "freestanding"
+#elif defined(LZO_OS_EMBEDDED)
+# define LZO_INFO_OS "embedded"
+#elif 1 && defined(__IAR_SYSTEMS_ICC__)
+# define LZO_OS_EMBEDDED 1
+# define LZO_INFO_OS "embedded"
+#elif defined(__CYGWIN__) && defined(__GNUC__)
+# define LZO_OS_CYGWIN 1
+# define LZO_INFO_OS "cygwin"
+#elif defined(__EMX__) && defined(__GNUC__)
+# define LZO_OS_EMX 1
+# define LZO_INFO_OS "emx"
+#elif defined(__BEOS__)
+# define LZO_OS_BEOS 1
+# define LZO_INFO_OS "beos"
+#elif defined(__Lynx__)
+# define LZO_OS_LYNXOS 1
+# define LZO_INFO_OS "lynxos"
+#elif defined(__OS400__)
+# define LZO_OS_OS400 1
+# define LZO_INFO_OS "os400"
+#elif defined(__QNX__)
+# define LZO_OS_QNX 1
+# define LZO_INFO_OS "qnx"
+#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460)
+# define LZO_OS_DOS32 1
+# define LZO_INFO_OS "dos32"
+#elif defined(__BORLANDC__) && defined(__DPMI16__)
+# define LZO_OS_DOS16 1
+# define LZO_INFO_OS "dos16"
+#elif defined(__ZTC__) && defined(DOS386)
+# define LZO_OS_DOS32 1
+# define LZO_INFO_OS "dos32"
+#elif defined(__OS2__) || defined(__OS2V2__)
+# if (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_OS216 1
+# define LZO_INFO_OS "os216"
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_OS_OS2 1
+# define LZO_INFO_OS "os2"
+# else
+# error "check your limits.h header"
+# endif
+#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64)
+# define LZO_OS_WIN64 1
+# define LZO_INFO_OS "win64"
+#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+#elif defined(__MWERKS__) && defined(__INTEL__)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows)
+# if (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_WIN16 1
+# define LZO_INFO_OS "win16"
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+# else
+# error "check your limits.h header"
+# endif
+#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS))
+# if (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_DOS16 1
+# define LZO_INFO_OS "dos16"
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_OS_DOS32 1
+# define LZO_INFO_OS "dos32"
+# else
+# error "check your limits.h header"
+# endif
+#elif defined(__WATCOMC__)
+# if defined(__NT__) && (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_DOS16 1
+# define LZO_INFO_OS "dos16"
+# elif defined(__NT__) && (__WATCOMC__ < 1100)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+# elif defined(__linux__) || defined(__LINUX__)
+# define LZO_OS_POSIX 1
+# define LZO_INFO_OS "posix"
+# else
+# error "please specify a target using the -bt compiler option"
+# endif
+#elif defined(__palmos__)
+# define LZO_OS_PALMOS 1
+# define LZO_INFO_OS "palmos"
+#elif defined(__TOS__) || defined(__atarist__)
+# define LZO_OS_TOS 1
+# define LZO_INFO_OS "tos"
+#elif defined(macintosh) && !defined(__ppc__)
+# define LZO_OS_MACCLASSIC 1
+# define LZO_INFO_OS "macclassic"
+#elif defined(__VMS)
+# define LZO_OS_VMS 1
+# define LZO_INFO_OS "vms"
+#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+# define LZO_OS_CONSOLE 1
+# define LZO_OS_CONSOLE_PS2 1
+# define LZO_INFO_OS "console"
+# define LZO_INFO_OS_CONSOLE "ps2"
+#elif (defined(__mips__) && defined(__psp__))
+# define LZO_OS_CONSOLE 1
+# define LZO_OS_CONSOLE_PSP 1
+# define LZO_INFO_OS "console"
+# define LZO_INFO_OS_CONSOLE "psp"
+#else
+# define LZO_OS_POSIX 1
+# define LZO_INFO_OS "posix"
+#endif
+#if (LZO_OS_POSIX)
+# if defined(_AIX) || defined(__AIX__) || defined(__aix__)
+# define LZO_OS_POSIX_AIX 1
+# define LZO_INFO_OS_POSIX "aix"
+# elif defined(__FreeBSD__)
+# define LZO_OS_POSIX_FREEBSD 1
+# define LZO_INFO_OS_POSIX "freebsd"
+# elif defined(__hpux__) || defined(__hpux)
+# define LZO_OS_POSIX_HPUX 1
+# define LZO_INFO_OS_POSIX "hpux"
+# elif defined(__INTERIX)
+# define LZO_OS_POSIX_INTERIX 1
+# define LZO_INFO_OS_POSIX "interix"
+# elif defined(__IRIX__) || defined(__irix__)
+# define LZO_OS_POSIX_IRIX 1
+# define LZO_INFO_OS_POSIX "irix"
+# elif defined(__linux__) || defined(__linux) || defined(__LINUX__)
+# define LZO_OS_POSIX_LINUX 1
+# define LZO_INFO_OS_POSIX "linux"
+# elif defined(__APPLE__) || defined(__MACOS__)
+# define LZO_OS_POSIX_MACOSX 1
+# define LZO_INFO_OS_POSIX "macosx"
+# elif defined(__minix__) || defined(__minix)
+# define LZO_OS_POSIX_MINIX 1
+# define LZO_INFO_OS_POSIX "minix"
+# elif defined(__NetBSD__)
+# define LZO_OS_POSIX_NETBSD 1
+# define LZO_INFO_OS_POSIX "netbsd"
+# elif defined(__OpenBSD__)
+# define LZO_OS_POSIX_OPENBSD 1
+# define LZO_INFO_OS_POSIX "openbsd"
+# elif defined(__osf__)
+# define LZO_OS_POSIX_OSF 1
+# define LZO_INFO_OS_POSIX "osf"
+# elif defined(__solaris__) || defined(__sun)
+# if defined(__SVR4) || defined(__svr4__)
+# define LZO_OS_POSIX_SOLARIS 1
+# define LZO_INFO_OS_POSIX "solaris"
+# else
+# define LZO_OS_POSIX_SUNOS 1
+# define LZO_INFO_OS_POSIX "sunos"
+# endif
+# elif defined(__ultrix__) || defined(__ultrix)
+# define LZO_OS_POSIX_ULTRIX 1
+# define LZO_INFO_OS_POSIX "ultrix"
+# elif defined(_UNICOS)
+# define LZO_OS_POSIX_UNICOS 1
+# define LZO_INFO_OS_POSIX "unicos"
+# else
+# define LZO_OS_POSIX_UNKNOWN 1
+# define LZO_INFO_OS_POSIX "unknown"
+# endif
+#endif
+#endif
+#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
+# if (UINT_MAX != LZO_0xffffL)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (UINT_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__)
+# define LZO_CC_CILLY 1
+# define LZO_INFO_CC "Cilly"
+# if defined(__CILLY__)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__)
+# else
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__)
+# define LZO_CC_SDCC 1
+# define LZO_INFO_CC "sdcc"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC)
+#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
+# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
+# define LZO_INFO_CC "Pathscale C"
+# define LZO_INFO_CCVER __PATHSCALE__
+#elif defined(__INTEL_COMPILER)
+# define LZO_CC_INTELC 1
+# define LZO_INFO_CC "Intel C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER)
+# if defined(_WIN32) || defined(_WIN64)
+# define LZO_CC_SYNTAX_MSC 1
+# else
+# define LZO_CC_SYNTAX_GNUC 1
+# endif
+#elif defined(__POCC__) && defined(_WIN32)
+# define LZO_CC_PELLESC 1
+# define LZO_INFO_CC "Pelles C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__)
+#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
+# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# else
+# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# endif
+# define LZO_INFO_CC "llvm-gcc"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__GNUC__) && defined(__VERSION__)
+# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# elif defined(__GNUC_MINOR__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# else
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L)
+# endif
+# define LZO_INFO_CC "gcc"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__ACK__) && defined(_ACK)
+# define LZO_CC_ACK 1
+# define LZO_INFO_CC "Amsterdam Compiler Kit C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__AZTEC_C__)
+# define LZO_CC_AZTECC 1
+# define LZO_INFO_CC "Aztec C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__)
+#elif defined(__BORLANDC__)
+# define LZO_CC_BORLANDC 1
+# define LZO_INFO_CC "Borland C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__)
+#elif defined(_CRAYC) && defined(_RELEASE)
+# define LZO_CC_CRAYC 1
+# define LZO_INFO_CC "Cray C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE)
+#elif defined(__DMC__) && defined(__SC__)
+# define LZO_CC_DMC 1
+# define LZO_INFO_CC "Digital Mars C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__)
+#elif defined(__DECC)
+# define LZO_CC_DECC 1
+# define LZO_INFO_CC "DEC C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC)
+#elif defined(__HIGHC__)
+# define LZO_CC_HIGHC 1
+# define LZO_INFO_CC "MetaWare High C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__IAR_SYSTEMS_ICC__)
+# define LZO_CC_IARC 1
+# define LZO_INFO_CC "IAR C"
+# if defined(__VER__)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__)
+# else
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(__IBMC__)
+# define LZO_CC_IBMC 1
+# define LZO_INFO_CC "IBM C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__)
+#elif defined(__KEIL__) && defined(__C166__)
+# define LZO_CC_KEILC 1
+# define LZO_INFO_CC "Keil C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__)
+#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL)
+# define LZO_CC_LCCWIN32 1
+# define LZO_INFO_CC "lcc-win32"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__LCC__)
+# define LZO_CC_LCC 1
+# define LZO_INFO_CC "lcc"
+# if defined(__LCC_VERSION__)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__)
+# else
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(_MSC_VER)
+# define LZO_CC_MSC 1
+# define LZO_INFO_CC "Microsoft C"
+# if defined(_MSC_FULL_VER)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER)
+# else
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER)
+# endif
+#elif defined(__MWERKS__)
+# define LZO_CC_MWERKS 1
+# define LZO_INFO_CC "Metrowerks C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__)
+#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
+# define LZO_CC_NDPC 1
+# define LZO_INFO_CC "Microway NDP C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__PACIFIC__)
+# define LZO_CC_PACIFICC 1
+# define LZO_INFO_CC "Pacific C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__)
+#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
+# define LZO_CC_PGI 1
+# define LZO_INFO_CC "Portland Group PGI C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__PUREC__) && defined(__TOS__)
+# define LZO_CC_PUREC 1
+# define LZO_INFO_CC "Pure C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__)
+#elif defined(__SC__) && defined(__ZTC__)
+# define LZO_CC_SYMANTECC 1
+# define LZO_INFO_CC "Symantec C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__)
+#elif defined(__SUNPRO_C)
+# define LZO_INFO_CC "SunPro C"
+# if ((__SUNPRO_C)+0 > 0)
+# define LZO_CC_SUNPROC __SUNPRO_C
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C)
+# else
+# define LZO_CC_SUNPROC 1
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(__SUNPRO_CC)
+# define LZO_INFO_CC "SunPro C"
+# if ((__SUNPRO_CC)+0 > 0)
+# define LZO_CC_SUNPROC __SUNPRO_CC
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC)
+# else
+# define LZO_CC_SUNPROC 1
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(__TINYC__)
+# define LZO_CC_TINYC 1
+# define LZO_INFO_CC "Tiny C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__)
+#elif defined(__TSC__)
+# define LZO_CC_TOPSPEEDC 1
+# define LZO_INFO_CC "TopSpeed C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__)
+#elif defined(__WATCOMC__)
+# define LZO_CC_WATCOMC 1
+# define LZO_INFO_CC "Watcom C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__)
+#elif defined(__TURBOC__)
+# define LZO_CC_TURBOC 1
+# define LZO_INFO_CC "Turbo C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__)
+#elif defined(__ZTC__)
+# define LZO_CC_ZORTECHC 1
+# define LZO_INFO_CC "Zortech C"
+# if (__ZTC__ == 0x310)
+# define LZO_INFO_CCVER "0x310"
+# else
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__)
+# endif
+#else
+# define LZO_CC_UNKNOWN 1
+# define LZO_INFO_CC "unknown"
+# define LZO_INFO_CCVER "unknown"
+#endif
+#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER)
+# error "LZO_CC_MSC: _MSC_FULL_VER is not defined"
+#endif
+#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY)
+# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY)
+# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E)
+# define LZO_ARCH_CRAY_MPP 1
+# elif defined(_CRAY1)
+# define LZO_ARCH_CRAY_PVP 1
+# endif
+# endif
+#endif
+#if !defined(__LZO_ARCH_OVERRIDE)
+#if defined(LZO_ARCH_GENERIC)
+# define LZO_INFO_ARCH "generic"
+#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
+# define LZO_ARCH_I086 1
+# define LZO_ARCH_IA16 1
+# define LZO_INFO_ARCH "i086"
+#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
+# define LZO_ARCH_ALPHA 1
+# define LZO_INFO_ARCH "alpha"
+#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E))
+# define LZO_ARCH_ALPHA 1
+# define LZO_INFO_ARCH "alpha"
+#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64)
+# define LZO_ARCH_AMD64 1
+# define LZO_INFO_ARCH "amd64"
+#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB))
+# define LZO_ARCH_ARM 1
+# define LZO_ARCH_ARM_THUMB 1
+# define LZO_INFO_ARCH "arm_thumb"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__)
+# define LZO_ARCH_ARM 1
+# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1)
+# define LZO_ARCH_ARM_THUMB 1
+# define LZO_INFO_ARCH "arm_thumb"
+# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2)
+# define LZO_INFO_ARCH "arm"
+# else
+# define LZO_INFO_ARCH "arm"
+# endif
+#elif defined(__arm__) || defined(_M_ARM)
+# define LZO_ARCH_ARM 1
+# define LZO_INFO_ARCH "arm"
+#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__)
+# define LZO_ARCH_AVR 1
+# define LZO_INFO_ARCH "avr"
+#elif defined(__bfin__)
+# define LZO_ARCH_BLACKFIN 1
+# define LZO_INFO_ARCH "blackfin"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__)
+# define LZO_ARCH_C166 1
+# define LZO_INFO_ARCH "c166"
+#elif defined(__cris__)
+# define LZO_ARCH_CRIS 1
+# define LZO_INFO_ARCH "cris"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__)
+# define LZO_ARCH_EZ80 1
+# define LZO_INFO_ARCH "ez80"
+#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
+# define LZO_ARCH_H8300 1
+# define LZO_INFO_ARCH "h8300"
+#elif defined(__hppa__) || defined(__hppa)
+# define LZO_ARCH_HPPA 1
+# define LZO_INFO_ARCH "hppa"
+#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386)
+# define LZO_ARCH_I386 1
+# define LZO_ARCH_IA32 1
+# define LZO_INFO_ARCH "i386"
+#elif (LZO_CC_ZORTECHC && defined(__I86__))
+# define LZO_ARCH_I386 1
+# define LZO_ARCH_IA32 1
+# define LZO_INFO_ARCH "i386"
+#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386)
+# define LZO_ARCH_I386 1
+# define LZO_ARCH_IA32 1
+# define LZO_INFO_ARCH "i386"
+#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
+# define LZO_ARCH_IA64 1
+# define LZO_INFO_ARCH "ia64"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__)
+# define LZO_ARCH_M16C 1
+# define LZO_INFO_ARCH "m16c"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__)
+# define LZO_ARCH_M16C 1
+# define LZO_INFO_ARCH "m16c"
+#elif defined(__m32r__)
+# define LZO_ARCH_M32R 1
+# define LZO_INFO_ARCH "m32r"
+#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K)
+# define LZO_ARCH_M68K 1
+# define LZO_INFO_ARCH "m68k"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__)
+# define LZO_ARCH_MCS251 1
+# define LZO_INFO_ARCH "mcs251"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__)
+# define LZO_ARCH_MCS51 1
+# define LZO_INFO_ARCH "mcs51"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__)
+# define LZO_ARCH_MCS51 1
+# define LZO_INFO_ARCH "mcs51"
+#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000)
+# define LZO_ARCH_MIPS 1
+# define LZO_INFO_ARCH "mips"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__)
+# define LZO_ARCH_MSP430 1
+# define LZO_INFO_ARCH "msp430"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__)
+# define LZO_ARCH_MSP430 1
+# define LZO_INFO_ARCH "msp430"
+#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR)
+# define LZO_ARCH_POWERPC 1
+# define LZO_INFO_ARCH "powerpc"
+#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x)
+# define LZO_ARCH_S390 1
+# define LZO_INFO_ARCH "s390"
+#elif defined(__sh__) || defined(_M_SH)
+# define LZO_ARCH_SH 1
+# define LZO_INFO_ARCH "sh"
+#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8)
+# define LZO_ARCH_SPARC 1
+# define LZO_INFO_ARCH "sparc"
+#elif defined(__SPU__)
+# define LZO_ARCH_SPU 1
+# define LZO_INFO_ARCH "spu"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__z80)
+# define LZO_ARCH_Z80 1
+# define LZO_INFO_ARCH "z80"
+#elif (LZO_ARCH_CRAY_PVP)
+# if defined(_CRAYSV1)
+# define LZO_ARCH_CRAY_SV1 1
+# define LZO_INFO_ARCH "cray_sv1"
+# elif (_ADDR64)
+# define LZO_ARCH_CRAY_T90 1
+# define LZO_INFO_ARCH "cray_t90"
+# elif (_ADDR32)
+# define LZO_ARCH_CRAY_YMP 1
+# define LZO_INFO_ARCH "cray_ymp"
+# else
+# define LZO_ARCH_CRAY_XMP 1
+# define LZO_INFO_ARCH "cray_xmp"
+# endif
+#else
+# define LZO_ARCH_UNKNOWN 1
+# define LZO_INFO_ARCH "unknown"
+#endif
+#endif
+#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2)
+# error "FIXME - missing define for CPU architecture"
+#endif
+#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32)
+# error "FIXME - missing WIN32 define for CPU architecture"
+#endif
+#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64)
+# error "FIXME - missing WIN64 define for CPU architecture"
+#endif
+#if (LZO_OS_OS216 || LZO_OS_WIN16)
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#elif 1 && (LZO_OS_DOS16 && defined(BLX286))
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#elif 1 && (LZO_OS_DOS16 && defined(DOSX286))
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__))
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#endif
+#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM)
+# error "this should not happen"
+#endif
+#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086)
+# error "this should not happen"
+#endif
+#if (LZO_ARCH_I086)
+# if (UINT_MAX != LZO_0xffffL)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if (LZO_ARCH_I386)
+# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__)
+# error "this should not happen"
+# endif
+# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if !defined(__LZO_MM_OVERRIDE)
+#if (LZO_ARCH_I086)
+#if (UINT_MAX != LZO_0xffffL)
+# error "this should not happen"
+#endif
+#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM)
+# define LZO_MM_TINY 1
+#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM)
+# define LZO_MM_HUGE 1
+#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL)
+# define LZO_MM_SMALL 1
+#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM)
+# define LZO_MM_MEDIUM 1
+#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM)
+# define LZO_MM_COMPACT 1
+#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL)
+# define LZO_MM_LARGE 1
+#elif (LZO_CC_AZTECC)
+# if defined(_LARGE_CODE) && defined(_LARGE_DATA)
+# define LZO_MM_LARGE 1
+# elif defined(_LARGE_CODE)
+# define LZO_MM_MEDIUM 1
+# elif defined(_LARGE_DATA)
+# define LZO_MM_COMPACT 1
+# else
+# define LZO_MM_SMALL 1
+# endif
+#elif (LZO_CC_ZORTECHC && defined(__VCM__))
+# define LZO_MM_LARGE 1
+#else
+# error "unknown memory model"
+#endif
+#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
+#define LZO_HAVE_MM_HUGE_PTR 1
+#define LZO_HAVE_MM_HUGE_ARRAY 1
+#if (LZO_MM_TINY)
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#endif
+#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC)
+# undef LZO_HAVE_MM_HUGE_PTR
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#elif (LZO_CC_MSC && defined(_QC))
+# undef LZO_HAVE_MM_HUGE_ARRAY
+# if (_MSC_VER < 600)
+# undef LZO_HAVE_MM_HUGE_PTR
+# endif
+#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295))
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#endif
+#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR)
+# if (LZO_OS_DOS16)
+# error "this should not happen"
+# elif (LZO_CC_ZORTECHC)
+# else
+# error "this should not happen"
+# endif
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200))
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC)
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295))
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16)
+# define LZO_MM_AHSHIFT 12
+#elif (LZO_CC_WATCOMC)
+ extern unsigned char _HShift;
+# define LZO_MM_AHSHIFT ((unsigned) _HShift)
+#else
+# error "FIXME - implement LZO_MM_AHSHIFT"
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+#elif (LZO_ARCH_C166)
+#if !defined(__MODEL__)
+# error "FIXME - C166 __MODEL__"
+#elif ((__MODEL__) == 0)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 1)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 2)
+# define LZO_MM_LARGE 1
+#elif ((__MODEL__) == 3)
+# define LZO_MM_TINY 1
+#elif ((__MODEL__) == 4)
+# define LZO_MM_XTINY 1
+#elif ((__MODEL__) == 5)
+# define LZO_MM_XSMALL 1
+#else
+# error "FIXME - C166 __MODEL__"
+#endif
+#elif (LZO_ARCH_MCS251)
+#if !defined(__MODEL__)
+# error "FIXME - MCS251 __MODEL__"
+#elif ((__MODEL__) == 0)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 2)
+# define LZO_MM_LARGE 1
+#elif ((__MODEL__) == 3)
+# define LZO_MM_TINY 1
+#elif ((__MODEL__) == 4)
+# define LZO_MM_XTINY 1
+#elif ((__MODEL__) == 5)
+# define LZO_MM_XSMALL 1
+#else
+# error "FIXME - MCS251 __MODEL__"
+#endif
+#elif (LZO_ARCH_MCS51)
+#if !defined(__MODEL__)
+# error "FIXME - MCS51 __MODEL__"
+#elif ((__MODEL__) == 1)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 2)
+# define LZO_MM_LARGE 1
+#elif ((__MODEL__) == 3)
+# define LZO_MM_TINY 1
+#elif ((__MODEL__) == 4)
+# define LZO_MM_XTINY 1
+#elif ((__MODEL__) == 5)
+# define LZO_MM_XSMALL 1
+#else
+# error "FIXME - MCS51 __MODEL__"
+#endif
+#elif (LZO_ARCH_CRAY_PVP)
+# define LZO_MM_PVP 1
+#else
+# define LZO_MM_FLAT 1
+#endif
+#if (LZO_MM_COMPACT)
+# define LZO_INFO_MM "compact"
+#elif (LZO_MM_FLAT)
+# define LZO_INFO_MM "flat"
+#elif (LZO_MM_HUGE)
+# define LZO_INFO_MM "huge"
+#elif (LZO_MM_LARGE)
+# define LZO_INFO_MM "large"
+#elif (LZO_MM_MEDIUM)
+# define LZO_INFO_MM "medium"
+#elif (LZO_MM_PVP)
+# define LZO_INFO_MM "pvp"
+#elif (LZO_MM_SMALL)
+# define LZO_INFO_MM "small"
+#elif (LZO_MM_TINY)
+# define LZO_INFO_MM "tiny"
+#else
+# error "unknown memory model"
+#endif
+#endif
+#if defined(SIZEOF_SHORT)
+# define LZO_SIZEOF_SHORT (SIZEOF_SHORT)
+#endif
+#if defined(SIZEOF_INT)
+# define LZO_SIZEOF_INT (SIZEOF_INT)
+#endif
+#if defined(SIZEOF_LONG)
+# define LZO_SIZEOF_LONG (SIZEOF_LONG)
+#endif
+#if defined(SIZEOF_LONG_LONG)
+# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG)
+#endif
+#if defined(SIZEOF___INT16)
+# define LZO_SIZEOF___INT16 (SIZEOF___INT16)
+#endif
+#if defined(SIZEOF___INT32)
+# define LZO_SIZEOF___INT32 (SIZEOF___INT32)
+#endif
+#if defined(SIZEOF___INT64)
+# define LZO_SIZEOF___INT64 (SIZEOF___INT64)
+#endif
+#if defined(SIZEOF_VOID_P)
+# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P)
+#endif
+#if defined(SIZEOF_SIZE_T)
+# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T)
+#endif
+#if defined(SIZEOF_PTRDIFF_T)
+# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T)
+#endif
+#define __LZO_LSR(x,b) (((x)+0ul) >> (b))
+#if !defined(LZO_SIZEOF_SHORT)
+# if (LZO_ARCH_CRAY_PVP)
+# define LZO_SIZEOF_SHORT 8
+# elif (USHRT_MAX == LZO_0xffffL)
+# define LZO_SIZEOF_SHORT 2
+# elif (__LZO_LSR(USHRT_MAX,7) == 1)
+# define LZO_SIZEOF_SHORT 1
+# elif (__LZO_LSR(USHRT_MAX,15) == 1)
+# define LZO_SIZEOF_SHORT 2
+# elif (__LZO_LSR(USHRT_MAX,31) == 1)
+# define LZO_SIZEOF_SHORT 4
+# elif (__LZO_LSR(USHRT_MAX,63) == 1)
+# define LZO_SIZEOF_SHORT 8
+# elif (__LZO_LSR(USHRT_MAX,127) == 1)
+# define LZO_SIZEOF_SHORT 16
+# else
+# error "LZO_SIZEOF_SHORT"
+# endif
+#endif
+#if !defined(LZO_SIZEOF_INT)
+# if (LZO_ARCH_CRAY_PVP)
+# define LZO_SIZEOF_INT 8
+# elif (UINT_MAX == LZO_0xffffL)
+# define LZO_SIZEOF_INT 2
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_SIZEOF_INT 4
+# elif (__LZO_LSR(UINT_MAX,7) == 1)
+# define LZO_SIZEOF_INT 1
+# elif (__LZO_LSR(UINT_MAX,15) == 1)
+# define LZO_SIZEOF_INT 2
+# elif (__LZO_LSR(UINT_MAX,31) == 1)
+# define LZO_SIZEOF_INT 4
+# elif (__LZO_LSR(UINT_MAX,63) == 1)
+# define LZO_SIZEOF_INT 8
+# elif (__LZO_LSR(UINT_MAX,127) == 1)
+# define LZO_SIZEOF_INT 16
+# else
+# error "LZO_SIZEOF_INT"
+# endif
+#endif
+#if !defined(LZO_SIZEOF_LONG)
+# if (ULONG_MAX == LZO_0xffffffffL)
+# define LZO_SIZEOF_LONG 4
+# elif (__LZO_LSR(ULONG_MAX,7) == 1)
+# define LZO_SIZEOF_LONG 1
+# elif (__LZO_LSR(ULONG_MAX,15) == 1)
+# define LZO_SIZEOF_LONG 2
+# elif (__LZO_LSR(ULONG_MAX,31) == 1)
+# define LZO_SIZEOF_LONG 4
+# elif (__LZO_LSR(ULONG_MAX,63) == 1)
+# define LZO_SIZEOF_LONG 8
+# elif (__LZO_LSR(ULONG_MAX,127) == 1)
+# define LZO_SIZEOF_LONG 16
+# else
+# error "LZO_SIZEOF_LONG"
+# endif
+#endif
+#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64)
+#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8)
+# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__)
+# if (LZO_CC_GNUC >= 0x030300ul)
+# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0)
+# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG
+# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1)
+# define LZO_SIZEOF_LONG_LONG 4
+# endif
+# endif
+# endif
+#endif
+#endif
+#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64)
+#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8)
+#if (LZO_ARCH_I086 && LZO_CC_DMC)
+#elif (LZO_CC_CILLY) && defined(__GNUC__)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_OS_WIN64 || defined(_WIN64))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_ARCH_I386 && (LZO_CC_DMC))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700)))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__)))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC))
+# define LZO_SIZEOF___INT64 8
+#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520)))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100)))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2)
+#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define LZO_SIZEOF_LONG_LONG 8
+#endif
+#endif
+#endif
+#if defined(__cplusplus) && defined(LZO_CC_GNUC)
+# if (LZO_CC_GNUC < 0x020800ul)
+# undef LZO_SIZEOF_LONG_LONG
+# endif
+#endif
+#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
+# undef LZO_SIZEOF_LONG_LONG
+#endif
+#if !defined(LZO_SIZEOF_VOID_P)
+#if (LZO_ARCH_I086)
+# define __LZO_WORDSIZE 2
+# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM)
+# define LZO_SIZEOF_VOID_P 2
+# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE)
+# define LZO_SIZEOF_VOID_P 4
+# else
+# error "LZO_MM"
+# endif
+#elif (LZO_ARCH_AVR || LZO_ARCH_Z80)
+# define __LZO_WORDSIZE 1
+# define LZO_SIZEOF_VOID_P 2
+#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430)
+# define LZO_SIZEOF_VOID_P 2
+#elif (LZO_ARCH_H8300)
+# if defined(__NORMAL_MODE__)
+# define __LZO_WORDSIZE 4
+# define LZO_SIZEOF_VOID_P 2
+# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
+# define __LZO_WORDSIZE 4
+# define LZO_SIZEOF_VOID_P 4
+# else
+# define __LZO_WORDSIZE 2
+# define LZO_SIZEOF_VOID_P 2
+# endif
+# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4)
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT
+# endif
+#elif (LZO_ARCH_M16C)
+# define __LZO_WORDSIZE 2
+# if defined(__m32c_cpu__) || defined(__m32cm_cpu__)
+# define LZO_SIZEOF_VOID_P 4
+# else
+# define LZO_SIZEOF_VOID_P 2
+# endif
+#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+# define __LZO_WORDSIZE 8
+# define LZO_SIZEOF_VOID_P 4
+#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64)
+# define __LZO_WORDSIZE 8
+# define LZO_SIZEOF_VOID_P 8
+#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
+# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+#elif (LZO_OS_OS400 || defined(__OS400__))
+# define __LZO_WORDSIZE LZO_SIZEOF_LONG
+# define LZO_SIZEOF_VOID_P 16
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+# define LZO_SIZEOF_VOID_P 8
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+#elif (LZO_ARCH_SPU)
+# if 0
+# define __LZO_WORDSIZE 16
+# endif
+# define LZO_SIZEOF_VOID_P 4
+#else
+# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
+#endif
+#endif
+#if !defined(LZO_WORDSIZE)
+# if defined(__LZO_WORDSIZE)
+# define LZO_WORDSIZE __LZO_WORDSIZE
+# else
+# define LZO_WORDSIZE LZO_SIZEOF_VOID_P
+# endif
+#endif
+#if !defined(LZO_SIZEOF_SIZE_T)
+#if (LZO_ARCH_I086 || LZO_ARCH_M16C)
+# define LZO_SIZEOF_SIZE_T 2
+#else
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P
+#endif
+#endif
+#if !defined(LZO_SIZEOF_PTRDIFF_T)
+#if (LZO_ARCH_I086)
+# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE)
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P
+# elif (LZO_MM_COMPACT || LZO_MM_LARGE)
+# if (LZO_CC_BORLANDC || LZO_CC_TURBOC)
+# define LZO_SIZEOF_PTRDIFF_T 4
+# else
+# define LZO_SIZEOF_PTRDIFF_T 2
+# endif
+# else
+# error "LZO_MM"
+# endif
+#else
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T
+#endif
+#endif
+#if defined(LZO_ABI_NEUTRAL_ENDIAN)
+# undef LZO_ABI_BIG_ENDIAN
+# undef LZO_ABI_LITTLE_ENDIAN
+#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN)
+#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif (LZO_ARCH_M68K || LZO_ARCH_S390)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__)
+# if (__LITTLE_ENDIAN__ == 1)
+# define LZO_ABI_LITTLE_ENDIAN 1
+# else
+# define LZO_ABI_BIG_ENDIAN 1
+# endif
+#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#endif
+#endif
+#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN)
+# error "this should not happen"
+#endif
+#if defined(LZO_ABI_BIG_ENDIAN)
+# define LZO_INFO_ABI_ENDIAN "be"
+#elif defined(LZO_ABI_LITTLE_ENDIAN)
+# define LZO_INFO_ABI_ENDIAN "le"
+#elif defined(LZO_ABI_NEUTRAL_ENDIAN)
+# define LZO_INFO_ABI_ENDIAN "neutral"
+#endif
+#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
+# define LZO_ABI_I8LP16 1
+# define LZO_INFO_ABI_PM "i8lp16"
+#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
+# define LZO_ABI_ILP16 1
+# define LZO_INFO_ABI_PM "ilp16"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4)
+# define LZO_ABI_ILP32 1
+# define LZO_INFO_ABI_PM "ilp32"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8)
+# define LZO_ABI_LLP64 1
+# define LZO_INFO_ABI_PM "llp64"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8)
+# define LZO_ABI_LP64 1
+# define LZO_INFO_ABI_PM "lp64"
+#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8)
+# define LZO_ABI_ILP64 1
+# define LZO_INFO_ABI_PM "ilp64"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4)
+# define LZO_ABI_IP32L64 1
+# define LZO_INFO_ABI_PM "ip32l64"
+#endif
+#if !defined(__LZO_LIBC_OVERRIDE)
+#if defined(LZO_LIBC_NAKED)
+# define LZO_INFO_LIBC "naked"
+#elif defined(LZO_LIBC_FREESTANDING)
+# define LZO_INFO_LIBC "freestanding"
+#elif defined(LZO_LIBC_MOSTLY_FREESTANDING)
+# define LZO_INFO_LIBC "mfreestanding"
+#elif defined(LZO_LIBC_ISOC90)
+# define LZO_INFO_LIBC "isoc90"
+#elif defined(LZO_LIBC_ISOC99)
+# define LZO_INFO_LIBC "isoc99"
+#elif defined(__dietlibc__)
+# define LZO_LIBC_DIETLIBC 1
+# define LZO_INFO_LIBC "dietlibc"
+#elif defined(_NEWLIB_VERSION)
+# define LZO_LIBC_NEWLIB 1
+# define LZO_INFO_LIBC "newlib"
+#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__)
+# if defined(__UCLIBC_SUBLEVEL__)
+# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__)
+# else
+# define LZO_LIBC_UCLIBC 0x00090bL
+# endif
+# define LZO_INFO_LIBC "uclibc"
+#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100)
+# define LZO_INFO_LIBC "glibc"
+#elif (LZO_CC_MWERKS) && defined(__MSL__)
+# define LZO_LIBC_MSL __MSL__
+# define LZO_INFO_LIBC "msl"
+#elif 1 && defined(__IAR_SYSTEMS_ICC__)
+# define LZO_LIBC_ISOC90 1
+# define LZO_INFO_LIBC "isoc90"
+#else
+# define LZO_LIBC_DEFAULT 1
+# define LZO_INFO_LIBC "default"
+#endif
+#endif
+#if !defined(__lzo_gnuc_extension__)
+#if (LZO_CC_GNUC >= 0x020800ul)
+# define __lzo_gnuc_extension__ __extension__
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_gnuc_extension__ __extension__
+#else
+# define __lzo_gnuc_extension__
+#endif
+#endif
+#if !defined(__lzo_ua_volatile)
+# define __lzo_ua_volatile volatile
+#endif
+#if !defined(__lzo_alignof)
+#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_alignof(e) __alignof(e)
+#endif
+#endif
+#if defined(__lzo_alignof)
+# define __lzo_HAVE_alignof 1
+#endif
+#if !defined(__lzo_constructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_constructor __attribute__((__constructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_constructor __attribute__((__constructor__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_constructor __attribute__((__constructor__))
+#endif
+#endif
+#if defined(__lzo_constructor)
+# define __lzo_HAVE_constructor 1
+#endif
+#if !defined(__lzo_destructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_destructor __attribute__((__destructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_destructor __attribute__((__destructor__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_destructor __attribute__((__destructor__))
+#endif
+#endif
+#if defined(__lzo_destructor)
+# define __lzo_HAVE_destructor 1
+#endif
+#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor)
+# error "this should not happen"
+#endif
+#if !defined(__lzo_inline)
+#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295))
+#elif defined(__cplusplus)
+# define __lzo_inline inline
+#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
+# define __lzo_inline __inline
+#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_inline __inline__
+#elif (LZO_CC_DMC)
+# define __lzo_inline __inline
+#elif (LZO_CC_INTELC)
+# define __lzo_inline __inline
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405))
+# define __lzo_inline __inline
+#elif (LZO_CC_MSC && (_MSC_VER >= 900))
+# define __lzo_inline __inline
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define __lzo_inline inline
+#endif
+#endif
+#if defined(__lzo_inline)
+# define __lzo_HAVE_inline 1
+#else
+# define __lzo_inline
+#endif
+#if !defined(__lzo_forceinline)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
+# define __lzo_forceinline __forceinline
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_forceinline __forceinline
+#endif
+#endif
+#if defined(__lzo_forceinline)
+# define __lzo_HAVE_forceinline 1
+#else
+# define __lzo_forceinline
+#endif
+#if !defined(__lzo_noinline)
+#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
+# define __lzo_noinline __attribute__((__noinline__,__used__))
+#elif (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC)
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64))
+# if defined(__cplusplus)
+# else
+# define __lzo_noinline __declspec(noinline)
+# endif
+#endif
+#endif
+#if defined(__lzo_noinline)
+# define __lzo_HAVE_noinline 1
+#else
+# define __lzo_noinline
+#endif
+#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline)
+# error "this should not happen"
+#endif
+#if !defined(__lzo_noreturn)
+#if (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
+# define __lzo_noreturn __declspec(noreturn)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_noreturn __declspec(noreturn)
+#endif
+#endif
+#if defined(__lzo_noreturn)
+# define __lzo_HAVE_noreturn 1
+#else
+# define __lzo_noreturn
+#endif
+#if !defined(__lzo_nothrow)
+#if (LZO_CC_GNUC >= 0x030300ul)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#endif
+#endif
+#if defined(__lzo_nothrow)
+# define __lzo_HAVE_nothrow 1
+#else
+# define __lzo_nothrow
+#endif
+#if !defined(__lzo_restrict)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_LLVM)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
+# define __lzo_restrict __restrict
+#endif
+#endif
+#if defined(__lzo_restrict)
+# define __lzo_HAVE_restrict 1
+#else
+# define __lzo_restrict
+#endif
+#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#endif
+#endif
+#if defined(__lzo_likely)
+# define __lzo_HAVE_likely 1
+#else
+# define __lzo_likely(e) (e)
+#endif
+#if defined(__lzo_unlikely)
+# define __lzo_HAVE_unlikely 1
+#else
+# define __lzo_unlikely(e) (e)
+#endif
+#if !defined(LZO_UNUSED)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED(var) ((void) &var)
+# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNUSED(var) ((void) var)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_KEILC)
+# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];}
+# elif (LZO_CC_PACIFICC)
+# define LZO_UNUSED(var) ((void) sizeof(var))
+# elif (LZO_CC_WATCOMC) && defined(__cplusplus)
+# define LZO_UNUSED(var) ((void) var)
+# else
+# define LZO_UNUSED(var) ((void) &var)
+# endif
+#endif
+#if !defined(LZO_UNUSED_FUNC)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_LLVM)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_MSC)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_KEILC || LZO_CC_PELLESC)
+# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];}
+# else
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# endif
+#endif
+#if !defined(LZO_UNUSED_LABEL)
+# if (LZO_CC_WATCOMC) && defined(__cplusplus)
+# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
+# elif (LZO_CC_INTELC || LZO_CC_WATCOMC)
+# define LZO_UNUSED_LABEL(l) if (0) goto l
+# else
+# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
+# endif
+#endif
+#if !defined(LZO_DEFINE_UNINITIALIZED_VAR)
+# if 0
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
+# elif 0 && (LZO_CC_GNUC)
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
+# else
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
+# endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
+# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)];
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
+# else
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)];
+# endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT)
+# if (LZO_CC_AZTECC)
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];}
+# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# else
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];}
+# endif
+#endif
+#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit
+# define __lzo_cdecl_main __cdecl
+# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_qsort __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_qsort _stdcall
+# else
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# elif (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+# else
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit __cdecl
+# define __lzo_cdecl_main __cdecl
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC)
+# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_sighandler __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_sighandler _stdcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE)
+# define __lzo_cdecl_sighandler __clrcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700))
+# if defined(_DLL)
+# define __lzo_cdecl_sighandler _far _cdecl _loadds
+# elif defined(_MT)
+# define __lzo_cdecl_sighandler _far _cdecl
+# else
+# define __lzo_cdecl_sighandler _cdecl
+# endif
+# else
+# define __lzo_cdecl_sighandler __cdecl
+# endif
+#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC))
+# define __lzo_cdecl cdecl
+#endif
+#if !defined(__lzo_cdecl)
+# define __lzo_cdecl
+#endif
+#if !defined(__lzo_cdecl_atexit)
+# define __lzo_cdecl_atexit
+#endif
+#if !defined(__lzo_cdecl_main)
+# define __lzo_cdecl_main
+#endif
+#if !defined(__lzo_cdecl_qsort)
+# define __lzo_cdecl_qsort
+#endif
+#if !defined(__lzo_cdecl_sighandler)
+# define __lzo_cdecl_sighandler
+#endif
+#if !defined(__lzo_cdecl_va)
+# define __lzo_cdecl_va __lzo_cdecl
+#endif
+#if !defined(LZO_CFG_NO_WINDOWS_H)
+#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
+# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
+# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul)))
+# else
+# define LZO_HAVE_WINDOWS_H 1
+# endif
+#endif
+#endif
+#if (LZO_ARCH_ALPHA)
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_AVOID_SHORT 1
+# define LZO_OPT_AVOID_USHORT 1
+#elif (LZO_ARCH_AMD64)
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# define LZO_OPT_UNALIGNED64 1
+#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB)
+#elif (LZO_ARCH_ARM)
+# define LZO_OPT_AVOID_SHORT 1
+# define LZO_OPT_AVOID_USHORT 1
+#elif (LZO_ARCH_CRIS)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+#elif (LZO_ARCH_I386)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+#elif (LZO_ARCH_IA64)
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_PREFER_POSTINC 1
+#elif (LZO_ARCH_M68K)
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
+# if defined(__mc68020__) && !defined(__mcoldfire__)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# endif
+#elif (LZO_ARCH_MIPS)
+# define LZO_OPT_AVOID_UINT_INDEX 1
+#elif (LZO_ARCH_POWERPC)
+# define LZO_OPT_PREFER_PREINC 1
+# define LZO_OPT_PREFER_PREDEC 1
+# if defined(LZO_ABI_BIG_ENDIAN)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# endif
+#elif (LZO_ARCH_S390)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# if (LZO_SIZEOF_SIZE_T == 8)
+# define LZO_OPT_UNALIGNED64 1
+# endif
+#elif (LZO_ARCH_SH)
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
+#endif
+#if !defined(LZO_CFG_NO_INLINE_ASM)
+#if defined(LZO_CC_LLVM)
+# define LZO_CFG_NO_INLINE_ASM 1
+#endif
+#endif
+#if !defined(LZO_CFG_NO_UNALIGNED)
+#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC)
+# define LZO_CFG_NO_UNALIGNED 1
+#endif
+#endif
+#if defined(LZO_CFG_NO_UNALIGNED)
+# undef LZO_OPT_UNALIGNED16
+# undef LZO_OPT_UNALIGNED32
+# undef LZO_OPT_UNALIGNED64
+#endif
+#if defined(LZO_CFG_NO_INLINE_ASM)
+#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+# define LZO_ASM_SYNTAX_MSC 1
+#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#endif
+#if (LZO_ASM_SYNTAX_GNUC)
+#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul))
+# define __LZO_ASM_CLOBBER "ax"
+#elif (LZO_CC_INTELC)
+# define __LZO_ASM_CLOBBER "memory"
+#else
+# define __LZO_ASM_CLOBBER "cc", "memory"
+#endif
+#endif
+#if defined(__LZO_INFOSTR_MM)
+#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM))
+# define __LZO_INFOSTR_MM ""
+#elif defined(LZO_INFO_MM)
+# define __LZO_INFOSTR_MM "." LZO_INFO_MM
+#else
+# define __LZO_INFOSTR_MM ""
+#endif
+#if defined(__LZO_INFOSTR_PM)
+#elif defined(LZO_INFO_ABI_PM)
+# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM
+#else
+# define __LZO_INFOSTR_PM ""
+#endif
+#if defined(__LZO_INFOSTR_ENDIAN)
+#elif defined(LZO_INFO_ABI_ENDIAN)
+# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN
+#else
+# define __LZO_INFOSTR_ENDIAN ""
+#endif
+#if defined(__LZO_INFOSTR_OSNAME)
+#elif defined(LZO_INFO_OS_CONSOLE)
+# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE
+#elif defined(LZO_INFO_OS_POSIX)
+# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX
+#else
+# define __LZO_INFOSTR_OSNAME LZO_INFO_OS
+#endif
+#if defined(__LZO_INFOSTR_LIBC)
+#elif defined(LZO_INFO_LIBC)
+# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC
+#else
+# define __LZO_INFOSTR_LIBC ""
+#endif
+#if defined(__LZO_INFOSTR_CCVER)
+#elif defined(LZO_INFO_CCVER)
+# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER
+#else
+# define __LZO_INFOSTR_CCVER ""
+#endif
+#define LZO_INFO_STRING \
+ LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \
+ " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER
+
+#endif /* already included */
+
+/* vim:set ts=4 et: */
diff --git a/extern/lzo/minilzo/minilzo.c b/extern/lzo/minilzo/minilzo.c
new file mode 100644
index 00000000000..6a62b31b94a
--- /dev/null
+++ b/extern/lzo/minilzo/minilzo.c
@@ -0,0 +1,4112 @@
+/* minilzo.c -- mini subset of the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+/*
+ * NOTE:
+ * the full LZO package can be found at
+ * http://www.oberhumer.com/opensource/lzo/
+ */
+
+#define __LZO_IN_MINILZO
+#define LZO_BUILD
+
+#if defined(LZO_CFG_FREESTANDING)
+# undef MINILZO_HAVE_CONFIG_H
+# define LZO_LIBC_FREESTANDING 1
+# define LZO_OS_FREESTANDING 1
+#endif
+
+#ifdef MINILZO_HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <limits.h>
+#include <stddef.h>
+#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS)
+
+#ifndef __LZODEFS_H_INCLUDED
+#define __LZODEFS_H_INCLUDED 1
+
+#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
+# define __CYGWIN__ __CYGWIN32__
+#endif
+#if defined(__IBMCPP__) && !defined(__IBMC__)
+# define __IBMC__ __IBMCPP__
+#endif
+#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER)
+# define __INTEL_COMPILER __ICL
+#endif
+#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE)
+# define _ALL_SOURCE 1
+#endif
+#if defined(__mips__) && defined(__R5900__)
+# if !defined(__LONG_MAX__)
+# define __LONG_MAX__ 9223372036854775807L
+# endif
+#endif
+#if defined(__INTEL_COMPILER) && defined(__linux__)
+# pragma warning(disable: 193)
+#endif
+#if defined(__KEIL__) && defined(__C166__)
+# pragma warning disable = 322
+#elif 0 && defined(__C251__)
+# pragma warning disable = 322
+#endif
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
+# if (_MSC_VER >= 1300)
+# pragma warning(disable: 4668)
+# endif
+#endif
+#if 0 && defined(__WATCOMC__)
+# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060)
+# pragma warning 203 9
+# endif
+#endif
+#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__)
+# pragma option -h
+#endif
+#if 0
+#define LZO_0xffffL 0xfffful
+#define LZO_0xffffffffL 0xfffffffful
+#else
+#define LZO_0xffffL 65535ul
+#define LZO_0xffffffffL 4294967295ul
+#endif
+#if (LZO_0xffffL == LZO_0xffffffffL)
+# error "your preprocessor is broken 1"
+#endif
+#if (16ul * 16384ul != 262144ul)
+# error "your preprocessor is broken 2"
+#endif
+#if 0
+#if (32767 >= 4294967295ul)
+# error "your preprocessor is broken 3"
+#endif
+#if (65535u >= 4294967295ul)
+# error "your preprocessor is broken 4"
+#endif
+#endif
+#if (UINT_MAX == LZO_0xffffL)
+#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__)
+# if !defined(MSDOS)
+# define MSDOS 1
+# endif
+# if !defined(_MSDOS)
+# define _MSDOS 1
+# endif
+#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX)
+# if (__VERSION == 520) && (MB_LEN_MAX == 1)
+# if !defined(__AZTEC_C__)
+# define __AZTEC_C__ __VERSION
+# endif
+# if !defined(__DOS__)
+# define __DOS__ 1
+# endif
+# endif
+#endif
+#endif
+#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL)
+# define ptrdiff_t long
+# define _PTRDIFF_T_DEFINED
+#endif
+#if (UINT_MAX == LZO_0xffffL)
+# undef __LZO_RENAME_A
+# undef __LZO_RENAME_B
+# if defined(__AZTEC_C__) && defined(__DOS__)
+# define __LZO_RENAME_A 1
+# elif defined(_MSC_VER) && defined(MSDOS)
+# if (_MSC_VER < 600)
+# define __LZO_RENAME_A 1
+# elif (_MSC_VER < 700)
+# define __LZO_RENAME_B 1
+# endif
+# elif defined(__TSC__) && defined(__OS2__)
+# define __LZO_RENAME_A 1
+# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410)
+# define __LZO_RENAME_A 1
+# elif defined(__PACIFIC__) && defined(DOS)
+# if !defined(__far)
+# define __far far
+# endif
+# if !defined(__near)
+# define __near near
+# endif
+# endif
+# if defined(__LZO_RENAME_A)
+# if !defined(__cdecl)
+# define __cdecl cdecl
+# endif
+# if !defined(__far)
+# define __far far
+# endif
+# if !defined(__huge)
+# define __huge huge
+# endif
+# if !defined(__near)
+# define __near near
+# endif
+# if !defined(__pascal)
+# define __pascal pascal
+# endif
+# if !defined(__huge)
+# define __huge huge
+# endif
+# elif defined(__LZO_RENAME_B)
+# if !defined(__cdecl)
+# define __cdecl _cdecl
+# endif
+# if !defined(__far)
+# define __far _far
+# endif
+# if !defined(__huge)
+# define __huge _huge
+# endif
+# if !defined(__near)
+# define __near _near
+# endif
+# if !defined(__pascal)
+# define __pascal _pascal
+# endif
+# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__)
+# if !defined(__cdecl)
+# define __cdecl cdecl
+# endif
+# if !defined(__pascal)
+# define __pascal pascal
+# endif
+# endif
+# undef __LZO_RENAME_A
+# undef __LZO_RENAME_B
+#endif
+#if (UINT_MAX == LZO_0xffffL)
+#if defined(__AZTEC_C__) && defined(__DOS__)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+#elif defined(_MSC_VER) && defined(MSDOS)
+# if (_MSC_VER < 600)
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+# endif
+# if (_MSC_VER < 700)
+# define LZO_BROKEN_INTEGRAL_PROMOTION 1
+# define LZO_BROKEN_SIZEOF 1
+# endif
+#elif defined(__PACIFIC__) && defined(DOS)
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+#elif defined(__TURBOC__) && defined(__MSDOS__)
+# if (__TURBOC__ < 0x0150)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+# define LZO_BROKEN_INTEGRAL_PROMOTION 1
+# endif
+# if (__TURBOC__ < 0x0200)
+# define LZO_BROKEN_SIZEOF 1
+# endif
+# if (__TURBOC__ < 0x0400) && defined(__cplusplus)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+# endif
+#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__)
+# define LZO_BROKEN_CDECL_ALT_SYNTAX 1
+# define LZO_BROKEN_SIZEOF 1
+#endif
+#endif
+#if defined(__WATCOMC__) && (__WATCOMC__ < 900)
+# define LZO_BROKEN_INTEGRAL_CONSTANTS 1
+#endif
+#if defined(_CRAY) && defined(_CRAY1)
+# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1
+#endif
+#define LZO_PP_STRINGIZE(x) #x
+#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x)
+#define LZO_PP_CONCAT2(a,b) a ## b
+#define LZO_PP_CONCAT3(a,b,c) a ## b ## c
+#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d
+#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b)
+#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c)
+#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d)
+#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e)
+#if 1
+#define LZO_CPP_STRINGIZE(x) #x
+#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x)
+#define LZO_CPP_CONCAT2(a,b) a ## b
+#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c
+#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d
+#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b)
+#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c)
+#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d)
+#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e)
+#endif
+#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
+#if 1 && defined(__cplusplus)
+# if !defined(__STDC_CONSTANT_MACROS)
+# define __STDC_CONSTANT_MACROS 1
+# endif
+# if !defined(__STDC_LIMIT_MACROS)
+# define __STDC_LIMIT_MACROS 1
+# endif
+#endif
+#if defined(__cplusplus)
+# define LZO_EXTERN_C extern "C"
+#else
+# define LZO_EXTERN_C extern
+#endif
+#if !defined(__LZO_OS_OVERRIDE)
+#if defined(LZO_OS_FREESTANDING)
+# define LZO_INFO_OS "freestanding"
+#elif defined(LZO_OS_EMBEDDED)
+# define LZO_INFO_OS "embedded"
+#elif 1 && defined(__IAR_SYSTEMS_ICC__)
+# define LZO_OS_EMBEDDED 1
+# define LZO_INFO_OS "embedded"
+#elif defined(__CYGWIN__) && defined(__GNUC__)
+# define LZO_OS_CYGWIN 1
+# define LZO_INFO_OS "cygwin"
+#elif defined(__EMX__) && defined(__GNUC__)
+# define LZO_OS_EMX 1
+# define LZO_INFO_OS "emx"
+#elif defined(__BEOS__)
+# define LZO_OS_BEOS 1
+# define LZO_INFO_OS "beos"
+#elif defined(__Lynx__)
+# define LZO_OS_LYNXOS 1
+# define LZO_INFO_OS "lynxos"
+#elif defined(__OS400__)
+# define LZO_OS_OS400 1
+# define LZO_INFO_OS "os400"
+#elif defined(__QNX__)
+# define LZO_OS_QNX 1
+# define LZO_INFO_OS "qnx"
+#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460)
+# define LZO_OS_DOS32 1
+# define LZO_INFO_OS "dos32"
+#elif defined(__BORLANDC__) && defined(__DPMI16__)
+# define LZO_OS_DOS16 1
+# define LZO_INFO_OS "dos16"
+#elif defined(__ZTC__) && defined(DOS386)
+# define LZO_OS_DOS32 1
+# define LZO_INFO_OS "dos32"
+#elif defined(__OS2__) || defined(__OS2V2__)
+# if (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_OS216 1
+# define LZO_INFO_OS "os216"
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_OS_OS2 1
+# define LZO_INFO_OS "os2"
+# else
+# error "check your limits.h header"
+# endif
+#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64)
+# define LZO_OS_WIN64 1
+# define LZO_INFO_OS "win64"
+#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+#elif defined(__MWERKS__) && defined(__INTEL__)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows)
+# if (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_WIN16 1
+# define LZO_INFO_OS "win16"
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+# else
+# error "check your limits.h header"
+# endif
+#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS))
+# if (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_DOS16 1
+# define LZO_INFO_OS "dos16"
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_OS_DOS32 1
+# define LZO_INFO_OS "dos32"
+# else
+# error "check your limits.h header"
+# endif
+#elif defined(__WATCOMC__)
+# if defined(__NT__) && (UINT_MAX == LZO_0xffffL)
+# define LZO_OS_DOS16 1
+# define LZO_INFO_OS "dos16"
+# elif defined(__NT__) && (__WATCOMC__ < 1100)
+# define LZO_OS_WIN32 1
+# define LZO_INFO_OS "win32"
+# elif defined(__linux__) || defined(__LINUX__)
+# define LZO_OS_POSIX 1
+# define LZO_INFO_OS "posix"
+# else
+# error "please specify a target using the -bt compiler option"
+# endif
+#elif defined(__palmos__)
+# define LZO_OS_PALMOS 1
+# define LZO_INFO_OS "palmos"
+#elif defined(__TOS__) || defined(__atarist__)
+# define LZO_OS_TOS 1
+# define LZO_INFO_OS "tos"
+#elif defined(macintosh) && !defined(__ppc__)
+# define LZO_OS_MACCLASSIC 1
+# define LZO_INFO_OS "macclassic"
+#elif defined(__VMS)
+# define LZO_OS_VMS 1
+# define LZO_INFO_OS "vms"
+#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+# define LZO_OS_CONSOLE 1
+# define LZO_OS_CONSOLE_PS2 1
+# define LZO_INFO_OS "console"
+# define LZO_INFO_OS_CONSOLE "ps2"
+#elif (defined(__mips__) && defined(__psp__))
+# define LZO_OS_CONSOLE 1
+# define LZO_OS_CONSOLE_PSP 1
+# define LZO_INFO_OS "console"
+# define LZO_INFO_OS_CONSOLE "psp"
+#else
+# define LZO_OS_POSIX 1
+# define LZO_INFO_OS "posix"
+#endif
+#if (LZO_OS_POSIX)
+# if defined(_AIX) || defined(__AIX__) || defined(__aix__)
+# define LZO_OS_POSIX_AIX 1
+# define LZO_INFO_OS_POSIX "aix"
+# elif defined(__FreeBSD__)
+# define LZO_OS_POSIX_FREEBSD 1
+# define LZO_INFO_OS_POSIX "freebsd"
+# elif defined(__hpux__) || defined(__hpux)
+# define LZO_OS_POSIX_HPUX 1
+# define LZO_INFO_OS_POSIX "hpux"
+# elif defined(__INTERIX)
+# define LZO_OS_POSIX_INTERIX 1
+# define LZO_INFO_OS_POSIX "interix"
+# elif defined(__IRIX__) || defined(__irix__)
+# define LZO_OS_POSIX_IRIX 1
+# define LZO_INFO_OS_POSIX "irix"
+# elif defined(__linux__) || defined(__linux) || defined(__LINUX__)
+# define LZO_OS_POSIX_LINUX 1
+# define LZO_INFO_OS_POSIX "linux"
+# elif defined(__APPLE__) || defined(__MACOS__)
+# define LZO_OS_POSIX_MACOSX 1
+# define LZO_INFO_OS_POSIX "macosx"
+# elif defined(__minix__) || defined(__minix)
+# define LZO_OS_POSIX_MINIX 1
+# define LZO_INFO_OS_POSIX "minix"
+# elif defined(__NetBSD__)
+# define LZO_OS_POSIX_NETBSD 1
+# define LZO_INFO_OS_POSIX "netbsd"
+# elif defined(__OpenBSD__)
+# define LZO_OS_POSIX_OPENBSD 1
+# define LZO_INFO_OS_POSIX "openbsd"
+# elif defined(__osf__)
+# define LZO_OS_POSIX_OSF 1
+# define LZO_INFO_OS_POSIX "osf"
+# elif defined(__solaris__) || defined(__sun)
+# if defined(__SVR4) || defined(__svr4__)
+# define LZO_OS_POSIX_SOLARIS 1
+# define LZO_INFO_OS_POSIX "solaris"
+# else
+# define LZO_OS_POSIX_SUNOS 1
+# define LZO_INFO_OS_POSIX "sunos"
+# endif
+# elif defined(__ultrix__) || defined(__ultrix)
+# define LZO_OS_POSIX_ULTRIX 1
+# define LZO_INFO_OS_POSIX "ultrix"
+# elif defined(_UNICOS)
+# define LZO_OS_POSIX_UNICOS 1
+# define LZO_INFO_OS_POSIX "unicos"
+# else
+# define LZO_OS_POSIX_UNKNOWN 1
+# define LZO_INFO_OS_POSIX "unknown"
+# endif
+#endif
+#endif
+#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
+# if (UINT_MAX != LZO_0xffffL)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (UINT_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__)
+# define LZO_CC_CILLY 1
+# define LZO_INFO_CC "Cilly"
+# if defined(__CILLY__)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__)
+# else
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__)
+# define LZO_CC_SDCC 1
+# define LZO_INFO_CC "sdcc"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC)
+#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
+# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
+# define LZO_INFO_CC "Pathscale C"
+# define LZO_INFO_CCVER __PATHSCALE__
+#elif defined(__INTEL_COMPILER)
+# define LZO_CC_INTELC 1
+# define LZO_INFO_CC "Intel C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER)
+# if defined(_WIN32) || defined(_WIN64)
+# define LZO_CC_SYNTAX_MSC 1
+# else
+# define LZO_CC_SYNTAX_GNUC 1
+# endif
+#elif defined(__POCC__) && defined(_WIN32)
+# define LZO_CC_PELLESC 1
+# define LZO_INFO_CC "Pelles C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__)
+#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__)
+# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# else
+# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# endif
+# define LZO_INFO_CC "llvm-gcc"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__GNUC__) && defined(__VERSION__)
+# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# elif defined(__GNUC_MINOR__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# else
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L)
+# endif
+# define LZO_INFO_CC "gcc"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__ACK__) && defined(_ACK)
+# define LZO_CC_ACK 1
+# define LZO_INFO_CC "Amsterdam Compiler Kit C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__AZTEC_C__)
+# define LZO_CC_AZTECC 1
+# define LZO_INFO_CC "Aztec C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__)
+#elif defined(__BORLANDC__)
+# define LZO_CC_BORLANDC 1
+# define LZO_INFO_CC "Borland C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__)
+#elif defined(_CRAYC) && defined(_RELEASE)
+# define LZO_CC_CRAYC 1
+# define LZO_INFO_CC "Cray C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE)
+#elif defined(__DMC__) && defined(__SC__)
+# define LZO_CC_DMC 1
+# define LZO_INFO_CC "Digital Mars C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__)
+#elif defined(__DECC)
+# define LZO_CC_DECC 1
+# define LZO_INFO_CC "DEC C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC)
+#elif defined(__HIGHC__)
+# define LZO_CC_HIGHC 1
+# define LZO_INFO_CC "MetaWare High C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__IAR_SYSTEMS_ICC__)
+# define LZO_CC_IARC 1
+# define LZO_INFO_CC "IAR C"
+# if defined(__VER__)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__)
+# else
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(__IBMC__)
+# define LZO_CC_IBMC 1
+# define LZO_INFO_CC "IBM C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__)
+#elif defined(__KEIL__) && defined(__C166__)
+# define LZO_CC_KEILC 1
+# define LZO_INFO_CC "Keil C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__)
+#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL)
+# define LZO_CC_LCCWIN32 1
+# define LZO_INFO_CC "lcc-win32"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__LCC__)
+# define LZO_CC_LCC 1
+# define LZO_INFO_CC "lcc"
+# if defined(__LCC_VERSION__)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__)
+# else
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(_MSC_VER)
+# define LZO_CC_MSC 1
+# define LZO_INFO_CC "Microsoft C"
+# if defined(_MSC_FULL_VER)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER)
+# else
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER)
+# endif
+#elif defined(__MWERKS__)
+# define LZO_CC_MWERKS 1
+# define LZO_INFO_CC "Metrowerks C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__)
+#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
+# define LZO_CC_NDPC 1
+# define LZO_INFO_CC "Microway NDP C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__PACIFIC__)
+# define LZO_CC_PACIFICC 1
+# define LZO_INFO_CC "Pacific C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__)
+#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
+# define LZO_CC_PGI 1
+# define LZO_INFO_CC "Portland Group PGI C"
+# define LZO_INFO_CCVER "unknown"
+#elif defined(__PUREC__) && defined(__TOS__)
+# define LZO_CC_PUREC 1
+# define LZO_INFO_CC "Pure C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__)
+#elif defined(__SC__) && defined(__ZTC__)
+# define LZO_CC_SYMANTECC 1
+# define LZO_INFO_CC "Symantec C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__)
+#elif defined(__SUNPRO_C)
+# define LZO_INFO_CC "SunPro C"
+# if ((__SUNPRO_C)+0 > 0)
+# define LZO_CC_SUNPROC __SUNPRO_C
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C)
+# else
+# define LZO_CC_SUNPROC 1
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(__SUNPRO_CC)
+# define LZO_INFO_CC "SunPro C"
+# if ((__SUNPRO_CC)+0 > 0)
+# define LZO_CC_SUNPROC __SUNPRO_CC
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC)
+# else
+# define LZO_CC_SUNPROC 1
+# define LZO_INFO_CCVER "unknown"
+# endif
+#elif defined(__TINYC__)
+# define LZO_CC_TINYC 1
+# define LZO_INFO_CC "Tiny C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__)
+#elif defined(__TSC__)
+# define LZO_CC_TOPSPEEDC 1
+# define LZO_INFO_CC "TopSpeed C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__)
+#elif defined(__WATCOMC__)
+# define LZO_CC_WATCOMC 1
+# define LZO_INFO_CC "Watcom C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__)
+#elif defined(__TURBOC__)
+# define LZO_CC_TURBOC 1
+# define LZO_INFO_CC "Turbo C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__)
+#elif defined(__ZTC__)
+# define LZO_CC_ZORTECHC 1
+# define LZO_INFO_CC "Zortech C"
+# if (__ZTC__ == 0x310)
+# define LZO_INFO_CCVER "0x310"
+# else
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__)
+# endif
+#else
+# define LZO_CC_UNKNOWN 1
+# define LZO_INFO_CC "unknown"
+# define LZO_INFO_CCVER "unknown"
+#endif
+#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER)
+# error "LZO_CC_MSC: _MSC_FULL_VER is not defined"
+#endif
+#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY)
+# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY)
+# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E)
+# define LZO_ARCH_CRAY_MPP 1
+# elif defined(_CRAY1)
+# define LZO_ARCH_CRAY_PVP 1
+# endif
+# endif
+#endif
+#if !defined(__LZO_ARCH_OVERRIDE)
+#if defined(LZO_ARCH_GENERIC)
+# define LZO_INFO_ARCH "generic"
+#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
+# define LZO_ARCH_I086 1
+# define LZO_ARCH_IA16 1
+# define LZO_INFO_ARCH "i086"
+#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
+# define LZO_ARCH_ALPHA 1
+# define LZO_INFO_ARCH "alpha"
+#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E))
+# define LZO_ARCH_ALPHA 1
+# define LZO_INFO_ARCH "alpha"
+#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64)
+# define LZO_ARCH_AMD64 1
+# define LZO_INFO_ARCH "amd64"
+#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB))
+# define LZO_ARCH_ARM 1
+# define LZO_ARCH_ARM_THUMB 1
+# define LZO_INFO_ARCH "arm_thumb"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__)
+# define LZO_ARCH_ARM 1
+# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1)
+# define LZO_ARCH_ARM_THUMB 1
+# define LZO_INFO_ARCH "arm_thumb"
+# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2)
+# define LZO_INFO_ARCH "arm"
+# else
+# define LZO_INFO_ARCH "arm"
+# endif
+#elif defined(__arm__) || defined(_M_ARM)
+# define LZO_ARCH_ARM 1
+# define LZO_INFO_ARCH "arm"
+#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__)
+# define LZO_ARCH_AVR 1
+# define LZO_INFO_ARCH "avr"
+#elif defined(__bfin__)
+# define LZO_ARCH_BLACKFIN 1
+# define LZO_INFO_ARCH "blackfin"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__)
+# define LZO_ARCH_C166 1
+# define LZO_INFO_ARCH "c166"
+#elif defined(__cris__)
+# define LZO_ARCH_CRIS 1
+# define LZO_INFO_ARCH "cris"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__)
+# define LZO_ARCH_EZ80 1
+# define LZO_INFO_ARCH "ez80"
+#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
+# define LZO_ARCH_H8300 1
+# define LZO_INFO_ARCH "h8300"
+#elif defined(__hppa__) || defined(__hppa)
+# define LZO_ARCH_HPPA 1
+# define LZO_INFO_ARCH "hppa"
+#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386)
+# define LZO_ARCH_I386 1
+# define LZO_ARCH_IA32 1
+# define LZO_INFO_ARCH "i386"
+#elif (LZO_CC_ZORTECHC && defined(__I86__))
+# define LZO_ARCH_I386 1
+# define LZO_ARCH_IA32 1
+# define LZO_INFO_ARCH "i386"
+#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386)
+# define LZO_ARCH_I386 1
+# define LZO_ARCH_IA32 1
+# define LZO_INFO_ARCH "i386"
+#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
+# define LZO_ARCH_IA64 1
+# define LZO_INFO_ARCH "ia64"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__)
+# define LZO_ARCH_M16C 1
+# define LZO_INFO_ARCH "m16c"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__)
+# define LZO_ARCH_M16C 1
+# define LZO_INFO_ARCH "m16c"
+#elif defined(__m32r__)
+# define LZO_ARCH_M32R 1
+# define LZO_INFO_ARCH "m32r"
+#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K)
+# define LZO_ARCH_M68K 1
+# define LZO_INFO_ARCH "m68k"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__)
+# define LZO_ARCH_MCS251 1
+# define LZO_INFO_ARCH "mcs251"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__)
+# define LZO_ARCH_MCS51 1
+# define LZO_INFO_ARCH "mcs51"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__)
+# define LZO_ARCH_MCS51 1
+# define LZO_INFO_ARCH "mcs51"
+#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000)
+# define LZO_ARCH_MIPS 1
+# define LZO_INFO_ARCH "mips"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__)
+# define LZO_ARCH_MSP430 1
+# define LZO_INFO_ARCH "msp430"
+#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__)
+# define LZO_ARCH_MSP430 1
+# define LZO_INFO_ARCH "msp430"
+#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR)
+# define LZO_ARCH_POWERPC 1
+# define LZO_INFO_ARCH "powerpc"
+#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x)
+# define LZO_ARCH_S390 1
+# define LZO_INFO_ARCH "s390"
+#elif defined(__sh__) || defined(_M_SH)
+# define LZO_ARCH_SH 1
+# define LZO_INFO_ARCH "sh"
+#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8)
+# define LZO_ARCH_SPARC 1
+# define LZO_INFO_ARCH "sparc"
+#elif defined(__SPU__)
+# define LZO_ARCH_SPU 1
+# define LZO_INFO_ARCH "spu"
+#elif (UINT_MAX == LZO_0xffffL) && defined(__z80)
+# define LZO_ARCH_Z80 1
+# define LZO_INFO_ARCH "z80"
+#elif (LZO_ARCH_CRAY_PVP)
+# if defined(_CRAYSV1)
+# define LZO_ARCH_CRAY_SV1 1
+# define LZO_INFO_ARCH "cray_sv1"
+# elif (_ADDR64)
+# define LZO_ARCH_CRAY_T90 1
+# define LZO_INFO_ARCH "cray_t90"
+# elif (_ADDR32)
+# define LZO_ARCH_CRAY_YMP 1
+# define LZO_INFO_ARCH "cray_ymp"
+# else
+# define LZO_ARCH_CRAY_XMP 1
+# define LZO_INFO_ARCH "cray_xmp"
+# endif
+#else
+# define LZO_ARCH_UNKNOWN 1
+# define LZO_INFO_ARCH "unknown"
+#endif
+#endif
+#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2)
+# error "FIXME - missing define for CPU architecture"
+#endif
+#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32)
+# error "FIXME - missing WIN32 define for CPU architecture"
+#endif
+#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64)
+# error "FIXME - missing WIN64 define for CPU architecture"
+#endif
+#if (LZO_OS_OS216 || LZO_OS_WIN16)
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#elif 1 && (LZO_OS_DOS16 && defined(BLX286))
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#elif 1 && (LZO_OS_DOS16 && defined(DOSX286))
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__))
+# define LZO_ARCH_I086PM 1
+# define LZO_ARCH_IA16PM 1
+#endif
+#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM)
+# error "this should not happen"
+#endif
+#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086)
+# error "this should not happen"
+#endif
+#if (LZO_ARCH_I086)
+# if (UINT_MAX != LZO_0xffffL)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if (LZO_ARCH_I386)
+# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__)
+# error "this should not happen"
+# endif
+# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__)
+# error "this should not happen"
+# endif
+# if (ULONG_MAX != LZO_0xffffffffL)
+# error "this should not happen"
+# endif
+#endif
+#if !defined(__LZO_MM_OVERRIDE)
+#if (LZO_ARCH_I086)
+#if (UINT_MAX != LZO_0xffffL)
+# error "this should not happen"
+#endif
+#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM)
+# define LZO_MM_TINY 1
+#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM)
+# define LZO_MM_HUGE 1
+#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL)
+# define LZO_MM_SMALL 1
+#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM)
+# define LZO_MM_MEDIUM 1
+#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM)
+# define LZO_MM_COMPACT 1
+#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL)
+# define LZO_MM_LARGE 1
+#elif (LZO_CC_AZTECC)
+# if defined(_LARGE_CODE) && defined(_LARGE_DATA)
+# define LZO_MM_LARGE 1
+# elif defined(_LARGE_CODE)
+# define LZO_MM_MEDIUM 1
+# elif defined(_LARGE_DATA)
+# define LZO_MM_COMPACT 1
+# else
+# define LZO_MM_SMALL 1
+# endif
+#elif (LZO_CC_ZORTECHC && defined(__VCM__))
+# define LZO_MM_LARGE 1
+#else
+# error "unknown memory model"
+#endif
+#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
+#define LZO_HAVE_MM_HUGE_PTR 1
+#define LZO_HAVE_MM_HUGE_ARRAY 1
+#if (LZO_MM_TINY)
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#endif
+#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC)
+# undef LZO_HAVE_MM_HUGE_PTR
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#elif (LZO_CC_MSC && defined(_QC))
+# undef LZO_HAVE_MM_HUGE_ARRAY
+# if (_MSC_VER < 600)
+# undef LZO_HAVE_MM_HUGE_PTR
+# endif
+#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295))
+# undef LZO_HAVE_MM_HUGE_ARRAY
+#endif
+#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR)
+# if (LZO_OS_DOS16)
+# error "this should not happen"
+# elif (LZO_CC_ZORTECHC)
+# else
+# error "this should not happen"
+# endif
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200))
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC)
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295))
+ extern void __near __cdecl _AHSHIFT(void);
+# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT)
+#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16)
+# define LZO_MM_AHSHIFT 12
+#elif (LZO_CC_WATCOMC)
+ extern unsigned char _HShift;
+# define LZO_MM_AHSHIFT ((unsigned) _HShift)
+#else
+# error "FIXME - implement LZO_MM_AHSHIFT"
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+#elif (LZO_ARCH_C166)
+#if !defined(__MODEL__)
+# error "FIXME - C166 __MODEL__"
+#elif ((__MODEL__) == 0)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 1)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 2)
+# define LZO_MM_LARGE 1
+#elif ((__MODEL__) == 3)
+# define LZO_MM_TINY 1
+#elif ((__MODEL__) == 4)
+# define LZO_MM_XTINY 1
+#elif ((__MODEL__) == 5)
+# define LZO_MM_XSMALL 1
+#else
+# error "FIXME - C166 __MODEL__"
+#endif
+#elif (LZO_ARCH_MCS251)
+#if !defined(__MODEL__)
+# error "FIXME - MCS251 __MODEL__"
+#elif ((__MODEL__) == 0)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 2)
+# define LZO_MM_LARGE 1
+#elif ((__MODEL__) == 3)
+# define LZO_MM_TINY 1
+#elif ((__MODEL__) == 4)
+# define LZO_MM_XTINY 1
+#elif ((__MODEL__) == 5)
+# define LZO_MM_XSMALL 1
+#else
+# error "FIXME - MCS251 __MODEL__"
+#endif
+#elif (LZO_ARCH_MCS51)
+#if !defined(__MODEL__)
+# error "FIXME - MCS51 __MODEL__"
+#elif ((__MODEL__) == 1)
+# define LZO_MM_SMALL 1
+#elif ((__MODEL__) == 2)
+# define LZO_MM_LARGE 1
+#elif ((__MODEL__) == 3)
+# define LZO_MM_TINY 1
+#elif ((__MODEL__) == 4)
+# define LZO_MM_XTINY 1
+#elif ((__MODEL__) == 5)
+# define LZO_MM_XSMALL 1
+#else
+# error "FIXME - MCS51 __MODEL__"
+#endif
+#elif (LZO_ARCH_CRAY_PVP)
+# define LZO_MM_PVP 1
+#else
+# define LZO_MM_FLAT 1
+#endif
+#if (LZO_MM_COMPACT)
+# define LZO_INFO_MM "compact"
+#elif (LZO_MM_FLAT)
+# define LZO_INFO_MM "flat"
+#elif (LZO_MM_HUGE)
+# define LZO_INFO_MM "huge"
+#elif (LZO_MM_LARGE)
+# define LZO_INFO_MM "large"
+#elif (LZO_MM_MEDIUM)
+# define LZO_INFO_MM "medium"
+#elif (LZO_MM_PVP)
+# define LZO_INFO_MM "pvp"
+#elif (LZO_MM_SMALL)
+# define LZO_INFO_MM "small"
+#elif (LZO_MM_TINY)
+# define LZO_INFO_MM "tiny"
+#else
+# error "unknown memory model"
+#endif
+#endif
+#if defined(SIZEOF_SHORT)
+# define LZO_SIZEOF_SHORT (SIZEOF_SHORT)
+#endif
+#if defined(SIZEOF_INT)
+# define LZO_SIZEOF_INT (SIZEOF_INT)
+#endif
+#if defined(SIZEOF_LONG)
+# define LZO_SIZEOF_LONG (SIZEOF_LONG)
+#endif
+#if defined(SIZEOF_LONG_LONG)
+# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG)
+#endif
+#if defined(SIZEOF___INT16)
+# define LZO_SIZEOF___INT16 (SIZEOF___INT16)
+#endif
+#if defined(SIZEOF___INT32)
+# define LZO_SIZEOF___INT32 (SIZEOF___INT32)
+#endif
+#if defined(SIZEOF___INT64)
+# define LZO_SIZEOF___INT64 (SIZEOF___INT64)
+#endif
+#if defined(SIZEOF_VOID_P)
+# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P)
+#endif
+#if defined(SIZEOF_SIZE_T)
+# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T)
+#endif
+#if defined(SIZEOF_PTRDIFF_T)
+# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T)
+#endif
+#define __LZO_LSR(x,b) (((x)+0ul) >> (b))
+#if !defined(LZO_SIZEOF_SHORT)
+# if (LZO_ARCH_CRAY_PVP)
+# define LZO_SIZEOF_SHORT 8
+# elif (USHRT_MAX == LZO_0xffffL)
+# define LZO_SIZEOF_SHORT 2
+# elif (__LZO_LSR(USHRT_MAX,7) == 1)
+# define LZO_SIZEOF_SHORT 1
+# elif (__LZO_LSR(USHRT_MAX,15) == 1)
+# define LZO_SIZEOF_SHORT 2
+# elif (__LZO_LSR(USHRT_MAX,31) == 1)
+# define LZO_SIZEOF_SHORT 4
+# elif (__LZO_LSR(USHRT_MAX,63) == 1)
+# define LZO_SIZEOF_SHORT 8
+# elif (__LZO_LSR(USHRT_MAX,127) == 1)
+# define LZO_SIZEOF_SHORT 16
+# else
+# error "LZO_SIZEOF_SHORT"
+# endif
+#endif
+#if !defined(LZO_SIZEOF_INT)
+# if (LZO_ARCH_CRAY_PVP)
+# define LZO_SIZEOF_INT 8
+# elif (UINT_MAX == LZO_0xffffL)
+# define LZO_SIZEOF_INT 2
+# elif (UINT_MAX == LZO_0xffffffffL)
+# define LZO_SIZEOF_INT 4
+# elif (__LZO_LSR(UINT_MAX,7) == 1)
+# define LZO_SIZEOF_INT 1
+# elif (__LZO_LSR(UINT_MAX,15) == 1)
+# define LZO_SIZEOF_INT 2
+# elif (__LZO_LSR(UINT_MAX,31) == 1)
+# define LZO_SIZEOF_INT 4
+# elif (__LZO_LSR(UINT_MAX,63) == 1)
+# define LZO_SIZEOF_INT 8
+# elif (__LZO_LSR(UINT_MAX,127) == 1)
+# define LZO_SIZEOF_INT 16
+# else
+# error "LZO_SIZEOF_INT"
+# endif
+#endif
+#if !defined(LZO_SIZEOF_LONG)
+# if (ULONG_MAX == LZO_0xffffffffL)
+# define LZO_SIZEOF_LONG 4
+# elif (__LZO_LSR(ULONG_MAX,7) == 1)
+# define LZO_SIZEOF_LONG 1
+# elif (__LZO_LSR(ULONG_MAX,15) == 1)
+# define LZO_SIZEOF_LONG 2
+# elif (__LZO_LSR(ULONG_MAX,31) == 1)
+# define LZO_SIZEOF_LONG 4
+# elif (__LZO_LSR(ULONG_MAX,63) == 1)
+# define LZO_SIZEOF_LONG 8
+# elif (__LZO_LSR(ULONG_MAX,127) == 1)
+# define LZO_SIZEOF_LONG 16
+# else
+# error "LZO_SIZEOF_LONG"
+# endif
+#endif
+#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64)
+#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8)
+# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__)
+# if (LZO_CC_GNUC >= 0x030300ul)
+# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0)
+# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG
+# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1)
+# define LZO_SIZEOF_LONG_LONG 4
+# endif
+# endif
+# endif
+#endif
+#endif
+#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64)
+#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8)
+#if (LZO_ARCH_I086 && LZO_CC_DMC)
+#elif (LZO_CC_CILLY) && defined(__GNUC__)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_OS_WIN64 || defined(_WIN64))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_ARCH_I386 && (LZO_CC_DMC))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700)))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__)))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC))
+# define LZO_SIZEOF___INT64 8
+#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520)))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100)))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64))
+# define LZO_SIZEOF___INT64 8
+#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2)
+#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define LZO_SIZEOF_LONG_LONG 8
+#endif
+#endif
+#endif
+#if defined(__cplusplus) && defined(LZO_CC_GNUC)
+# if (LZO_CC_GNUC < 0x020800ul)
+# undef LZO_SIZEOF_LONG_LONG
+# endif
+#endif
+#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
+# undef LZO_SIZEOF_LONG_LONG
+#endif
+#if !defined(LZO_SIZEOF_VOID_P)
+#if (LZO_ARCH_I086)
+# define __LZO_WORDSIZE 2
+# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM)
+# define LZO_SIZEOF_VOID_P 2
+# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE)
+# define LZO_SIZEOF_VOID_P 4
+# else
+# error "LZO_MM"
+# endif
+#elif (LZO_ARCH_AVR || LZO_ARCH_Z80)
+# define __LZO_WORDSIZE 1
+# define LZO_SIZEOF_VOID_P 2
+#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430)
+# define LZO_SIZEOF_VOID_P 2
+#elif (LZO_ARCH_H8300)
+# if defined(__NORMAL_MODE__)
+# define __LZO_WORDSIZE 4
+# define LZO_SIZEOF_VOID_P 2
+# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
+# define __LZO_WORDSIZE 4
+# define LZO_SIZEOF_VOID_P 4
+# else
+# define __LZO_WORDSIZE 2
+# define LZO_SIZEOF_VOID_P 2
+# endif
+# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4)
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT
+# endif
+#elif (LZO_ARCH_M16C)
+# define __LZO_WORDSIZE 2
+# if defined(__m32c_cpu__) || defined(__m32cm_cpu__)
+# define LZO_SIZEOF_VOID_P 4
+# else
+# define LZO_SIZEOF_VOID_P 2
+# endif
+#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+# define __LZO_WORDSIZE 8
+# define LZO_SIZEOF_VOID_P 4
+#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64)
+# define __LZO_WORDSIZE 8
+# define LZO_SIZEOF_VOID_P 8
+#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
+# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+#elif (LZO_OS_OS400 || defined(__OS400__))
+# define __LZO_WORDSIZE LZO_SIZEOF_LONG
+# define LZO_SIZEOF_VOID_P 16
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+# define LZO_SIZEOF_VOID_P 8
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+#elif (LZO_ARCH_SPU)
+# if 0
+# define __LZO_WORDSIZE 16
+# endif
+# define LZO_SIZEOF_VOID_P 4
+#else
+# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
+#endif
+#endif
+#if !defined(LZO_WORDSIZE)
+# if defined(__LZO_WORDSIZE)
+# define LZO_WORDSIZE __LZO_WORDSIZE
+# else
+# define LZO_WORDSIZE LZO_SIZEOF_VOID_P
+# endif
+#endif
+#if !defined(LZO_SIZEOF_SIZE_T)
+#if (LZO_ARCH_I086 || LZO_ARCH_M16C)
+# define LZO_SIZEOF_SIZE_T 2
+#else
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P
+#endif
+#endif
+#if !defined(LZO_SIZEOF_PTRDIFF_T)
+#if (LZO_ARCH_I086)
+# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE)
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P
+# elif (LZO_MM_COMPACT || LZO_MM_LARGE)
+# if (LZO_CC_BORLANDC || LZO_CC_TURBOC)
+# define LZO_SIZEOF_PTRDIFF_T 4
+# else
+# define LZO_SIZEOF_PTRDIFF_T 2
+# endif
+# else
+# error "LZO_MM"
+# endif
+#else
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T
+#endif
+#endif
+#if defined(LZO_ABI_NEUTRAL_ENDIAN)
+# undef LZO_ABI_BIG_ENDIAN
+# undef LZO_ABI_LITTLE_ENDIAN
+#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN)
+#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif (LZO_ARCH_M68K || LZO_ARCH_S390)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__)
+# if (__LITTLE_ENDIAN__ == 1)
+# define LZO_ABI_LITTLE_ENDIAN 1
+# else
+# define LZO_ABI_BIG_ENDIAN 1
+# endif
+#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
+# define LZO_ABI_LITTLE_ENDIAN 1
+#endif
+#endif
+#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN)
+# error "this should not happen"
+#endif
+#if defined(LZO_ABI_BIG_ENDIAN)
+# define LZO_INFO_ABI_ENDIAN "be"
+#elif defined(LZO_ABI_LITTLE_ENDIAN)
+# define LZO_INFO_ABI_ENDIAN "le"
+#elif defined(LZO_ABI_NEUTRAL_ENDIAN)
+# define LZO_INFO_ABI_ENDIAN "neutral"
+#endif
+#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
+# define LZO_ABI_I8LP16 1
+# define LZO_INFO_ABI_PM "i8lp16"
+#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
+# define LZO_ABI_ILP16 1
+# define LZO_INFO_ABI_PM "ilp16"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4)
+# define LZO_ABI_ILP32 1
+# define LZO_INFO_ABI_PM "ilp32"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8)
+# define LZO_ABI_LLP64 1
+# define LZO_INFO_ABI_PM "llp64"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8)
+# define LZO_ABI_LP64 1
+# define LZO_INFO_ABI_PM "lp64"
+#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8)
+# define LZO_ABI_ILP64 1
+# define LZO_INFO_ABI_PM "ilp64"
+#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4)
+# define LZO_ABI_IP32L64 1
+# define LZO_INFO_ABI_PM "ip32l64"
+#endif
+#if !defined(__LZO_LIBC_OVERRIDE)
+#if defined(LZO_LIBC_NAKED)
+# define LZO_INFO_LIBC "naked"
+#elif defined(LZO_LIBC_FREESTANDING)
+# define LZO_INFO_LIBC "freestanding"
+#elif defined(LZO_LIBC_MOSTLY_FREESTANDING)
+# define LZO_INFO_LIBC "mfreestanding"
+#elif defined(LZO_LIBC_ISOC90)
+# define LZO_INFO_LIBC "isoc90"
+#elif defined(LZO_LIBC_ISOC99)
+# define LZO_INFO_LIBC "isoc99"
+#elif defined(__dietlibc__)
+# define LZO_LIBC_DIETLIBC 1
+# define LZO_INFO_LIBC "dietlibc"
+#elif defined(_NEWLIB_VERSION)
+# define LZO_LIBC_NEWLIB 1
+# define LZO_INFO_LIBC "newlib"
+#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__)
+# if defined(__UCLIBC_SUBLEVEL__)
+# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__)
+# else
+# define LZO_LIBC_UCLIBC 0x00090bL
+# endif
+# define LZO_INFO_LIBC "uclibc"
+#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100)
+# define LZO_INFO_LIBC "glibc"
+#elif (LZO_CC_MWERKS) && defined(__MSL__)
+# define LZO_LIBC_MSL __MSL__
+# define LZO_INFO_LIBC "msl"
+#elif 1 && defined(__IAR_SYSTEMS_ICC__)
+# define LZO_LIBC_ISOC90 1
+# define LZO_INFO_LIBC "isoc90"
+#else
+# define LZO_LIBC_DEFAULT 1
+# define LZO_INFO_LIBC "default"
+#endif
+#endif
+#if !defined(__lzo_gnuc_extension__)
+#if (LZO_CC_GNUC >= 0x020800ul)
+# define __lzo_gnuc_extension__ __extension__
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_gnuc_extension__ __extension__
+#else
+# define __lzo_gnuc_extension__
+#endif
+#endif
+#if !defined(__lzo_ua_volatile)
+# define __lzo_ua_volatile volatile
+#endif
+#if !defined(__lzo_alignof)
+#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_alignof(e) __alignof(e)
+#endif
+#endif
+#if defined(__lzo_alignof)
+# define __lzo_HAVE_alignof 1
+#endif
+#if !defined(__lzo_constructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_constructor __attribute__((__constructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_constructor __attribute__((__constructor__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_constructor __attribute__((__constructor__))
+#endif
+#endif
+#if defined(__lzo_constructor)
+# define __lzo_HAVE_constructor 1
+#endif
+#if !defined(__lzo_destructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_destructor __attribute__((__destructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_destructor __attribute__((__destructor__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_destructor __attribute__((__destructor__))
+#endif
+#endif
+#if defined(__lzo_destructor)
+# define __lzo_HAVE_destructor 1
+#endif
+#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor)
+# error "this should not happen"
+#endif
+#if !defined(__lzo_inline)
+#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295))
+#elif defined(__cplusplus)
+# define __lzo_inline inline
+#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
+# define __lzo_inline __inline
+#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_inline __inline__
+#elif (LZO_CC_DMC)
+# define __lzo_inline __inline
+#elif (LZO_CC_INTELC)
+# define __lzo_inline __inline
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405))
+# define __lzo_inline __inline
+#elif (LZO_CC_MSC && (_MSC_VER >= 900))
+# define __lzo_inline __inline
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define __lzo_inline inline
+#endif
+#endif
+#if defined(__lzo_inline)
+# define __lzo_HAVE_inline 1
+#else
+# define __lzo_inline
+#endif
+#if !defined(__lzo_forceinline)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
+# define __lzo_forceinline __forceinline
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_forceinline __forceinline
+#endif
+#endif
+#if defined(__lzo_forceinline)
+# define __lzo_HAVE_forceinline 1
+#else
+# define __lzo_forceinline
+#endif
+#if !defined(__lzo_noinline)
+#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
+# define __lzo_noinline __attribute__((__noinline__,__used__))
+#elif (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC)
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64))
+# if defined(__cplusplus)
+# else
+# define __lzo_noinline __declspec(noinline)
+# endif
+#endif
+#endif
+#if defined(__lzo_noinline)
+# define __lzo_HAVE_noinline 1
+#else
+# define __lzo_noinline
+#endif
+#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline)
+# error "this should not happen"
+#endif
+#if !defined(__lzo_noreturn)
+#if (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
+# define __lzo_noreturn __declspec(noreturn)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_noreturn __declspec(noreturn)
+#endif
+#endif
+#if defined(__lzo_noreturn)
+# define __lzo_HAVE_noreturn 1
+#else
+# define __lzo_noreturn
+#endif
+#if !defined(__lzo_nothrow)
+#if (LZO_CC_GNUC >= 0x030300ul)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#endif
+#endif
+#if defined(__lzo_nothrow)
+# define __lzo_HAVE_nothrow 1
+#else
+# define __lzo_nothrow
+#endif
+#if !defined(__lzo_restrict)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_LLVM)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
+# define __lzo_restrict __restrict
+#endif
+#endif
+#if defined(__lzo_restrict)
+# define __lzo_HAVE_restrict 1
+#else
+# define __lzo_restrict
+#endif
+#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#endif
+#endif
+#if defined(__lzo_likely)
+# define __lzo_HAVE_likely 1
+#else
+# define __lzo_likely(e) (e)
+#endif
+#if defined(__lzo_unlikely)
+# define __lzo_HAVE_unlikely 1
+#else
+# define __lzo_unlikely(e) (e)
+#endif
+#if !defined(LZO_UNUSED)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED(var) ((void) &var)
+# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNUSED(var) ((void) var)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_KEILC)
+# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];}
+# elif (LZO_CC_PACIFICC)
+# define LZO_UNUSED(var) ((void) sizeof(var))
+# elif (LZO_CC_WATCOMC) && defined(__cplusplus)
+# define LZO_UNUSED(var) ((void) var)
+# else
+# define LZO_UNUSED(var) ((void) &var)
+# endif
+#endif
+#if !defined(LZO_UNUSED_FUNC)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_LLVM)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_MSC)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_KEILC || LZO_CC_PELLESC)
+# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];}
+# else
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# endif
+#endif
+#if !defined(LZO_UNUSED_LABEL)
+# if (LZO_CC_WATCOMC) && defined(__cplusplus)
+# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
+# elif (LZO_CC_INTELC || LZO_CC_WATCOMC)
+# define LZO_UNUSED_LABEL(l) if (0) goto l
+# else
+# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
+# endif
+#endif
+#if !defined(LZO_DEFINE_UNINITIALIZED_VAR)
+# if 0
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
+# elif 0 && (LZO_CC_GNUC)
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
+# else
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
+# endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
+# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)];
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
+# else
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)];
+# endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT)
+# if (LZO_CC_AZTECC)
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];}
+# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# else
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];}
+# endif
+#endif
+#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit
+# define __lzo_cdecl_main __cdecl
+# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_qsort __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_qsort _stdcall
+# else
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# elif (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+# else
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit __cdecl
+# define __lzo_cdecl_main __cdecl
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC)
+# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_sighandler __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_sighandler _stdcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE)
+# define __lzo_cdecl_sighandler __clrcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700))
+# if defined(_DLL)
+# define __lzo_cdecl_sighandler _far _cdecl _loadds
+# elif defined(_MT)
+# define __lzo_cdecl_sighandler _far _cdecl
+# else
+# define __lzo_cdecl_sighandler _cdecl
+# endif
+# else
+# define __lzo_cdecl_sighandler __cdecl
+# endif
+#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC))
+# define __lzo_cdecl cdecl
+#endif
+#if !defined(__lzo_cdecl)
+# define __lzo_cdecl
+#endif
+#if !defined(__lzo_cdecl_atexit)
+# define __lzo_cdecl_atexit
+#endif
+#if !defined(__lzo_cdecl_main)
+# define __lzo_cdecl_main
+#endif
+#if !defined(__lzo_cdecl_qsort)
+# define __lzo_cdecl_qsort
+#endif
+#if !defined(__lzo_cdecl_sighandler)
+# define __lzo_cdecl_sighandler
+#endif
+#if !defined(__lzo_cdecl_va)
+# define __lzo_cdecl_va __lzo_cdecl
+#endif
+#if !defined(LZO_CFG_NO_WINDOWS_H)
+#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
+# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
+# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul)))
+# else
+# define LZO_HAVE_WINDOWS_H 1
+# endif
+#endif
+#endif
+#if (LZO_ARCH_ALPHA)
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_AVOID_SHORT 1
+# define LZO_OPT_AVOID_USHORT 1
+#elif (LZO_ARCH_AMD64)
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# define LZO_OPT_UNALIGNED64 1
+#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB)
+#elif (LZO_ARCH_ARM)
+# define LZO_OPT_AVOID_SHORT 1
+# define LZO_OPT_AVOID_USHORT 1
+#elif (LZO_ARCH_CRIS)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+#elif (LZO_ARCH_I386)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+#elif (LZO_ARCH_IA64)
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_PREFER_POSTINC 1
+#elif (LZO_ARCH_M68K)
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
+# if defined(__mc68020__) && !defined(__mcoldfire__)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# endif
+#elif (LZO_ARCH_MIPS)
+# define LZO_OPT_AVOID_UINT_INDEX 1
+#elif (LZO_ARCH_POWERPC)
+# define LZO_OPT_PREFER_PREINC 1
+# define LZO_OPT_PREFER_PREDEC 1
+# if defined(LZO_ABI_BIG_ENDIAN)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# endif
+#elif (LZO_ARCH_S390)
+# define LZO_OPT_UNALIGNED16 1
+# define LZO_OPT_UNALIGNED32 1
+# if (LZO_SIZEOF_SIZE_T == 8)
+# define LZO_OPT_UNALIGNED64 1
+# endif
+#elif (LZO_ARCH_SH)
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
+#endif
+#if !defined(LZO_CFG_NO_INLINE_ASM)
+#if defined(LZO_CC_LLVM)
+# define LZO_CFG_NO_INLINE_ASM 1
+#endif
+#endif
+#if !defined(LZO_CFG_NO_UNALIGNED)
+#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC)
+# define LZO_CFG_NO_UNALIGNED 1
+#endif
+#endif
+#if defined(LZO_CFG_NO_UNALIGNED)
+# undef LZO_OPT_UNALIGNED16
+# undef LZO_OPT_UNALIGNED32
+# undef LZO_OPT_UNALIGNED64
+#endif
+#if defined(LZO_CFG_NO_INLINE_ASM)
+#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+# define LZO_ASM_SYNTAX_MSC 1
+#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#endif
+#if (LZO_ASM_SYNTAX_GNUC)
+#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul))
+# define __LZO_ASM_CLOBBER "ax"
+#elif (LZO_CC_INTELC)
+# define __LZO_ASM_CLOBBER "memory"
+#else
+# define __LZO_ASM_CLOBBER "cc", "memory"
+#endif
+#endif
+#if defined(__LZO_INFOSTR_MM)
+#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM))
+# define __LZO_INFOSTR_MM ""
+#elif defined(LZO_INFO_MM)
+# define __LZO_INFOSTR_MM "." LZO_INFO_MM
+#else
+# define __LZO_INFOSTR_MM ""
+#endif
+#if defined(__LZO_INFOSTR_PM)
+#elif defined(LZO_INFO_ABI_PM)
+# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM
+#else
+# define __LZO_INFOSTR_PM ""
+#endif
+#if defined(__LZO_INFOSTR_ENDIAN)
+#elif defined(LZO_INFO_ABI_ENDIAN)
+# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN
+#else
+# define __LZO_INFOSTR_ENDIAN ""
+#endif
+#if defined(__LZO_INFOSTR_OSNAME)
+#elif defined(LZO_INFO_OS_CONSOLE)
+# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE
+#elif defined(LZO_INFO_OS_POSIX)
+# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX
+#else
+# define __LZO_INFOSTR_OSNAME LZO_INFO_OS
+#endif
+#if defined(__LZO_INFOSTR_LIBC)
+#elif defined(LZO_INFO_LIBC)
+# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC
+#else
+# define __LZO_INFOSTR_LIBC ""
+#endif
+#if defined(__LZO_INFOSTR_CCVER)
+#elif defined(LZO_INFO_CCVER)
+# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER
+#else
+# define __LZO_INFOSTR_CCVER ""
+#endif
+#define LZO_INFO_STRING \
+ LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \
+ " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER
+
+#endif
+
+#endif
+
+#undef LZO_HAVE_CONFIG_H
+#include "minilzo.h"
+
+#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2030)
+# error "version mismatch in miniLZO source files"
+#endif
+
+#ifdef MINILZO_HAVE_CONFIG_H
+# define LZO_HAVE_CONFIG_H
+#endif
+
+#ifndef __LZO_CONF_H
+#define __LZO_CONF_H
+
+#if !defined(__LZO_IN_MINILZO)
+#if defined(LZO_CFG_FREESTANDING)
+# define LZO_LIBC_FREESTANDING 1
+# define LZO_OS_FREESTANDING 1
+# define ACC_LIBC_FREESTANDING 1
+# define ACC_OS_FREESTANDING 1
+#endif
+#if defined(LZO_CFG_NO_UNALIGNED)
+# define ACC_CFG_NO_UNALIGNED 1
+#endif
+#if defined(LZO_ARCH_GENERIC)
+# define ACC_ARCH_GENERIC 1
+#endif
+#if defined(LZO_ABI_NEUTRAL_ENDIAN)
+# define ACC_ABI_NEUTRAL_ENDIAN 1
+#endif
+#if defined(LZO_HAVE_CONFIG_H)
+# define ACC_CONFIG_NO_HEADER 1
+#endif
+#if defined(LZO_CFG_EXTRA_CONFIG_HEADER)
+# include LZO_CFG_EXTRA_CONFIG_HEADER
+#endif
+#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED)
+# error "include this file first"
+#endif
+#include "lzo/lzoconf.h"
+#endif
+
+#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED)
+# error "version mismatch"
+#endif
+
+#if (LZO_CC_BORLANDC && LZO_ARCH_I086)
+# pragma option -h
+#endif
+
+#if (LZO_CC_MSC && (_MSC_VER >= 1000))
+# pragma warning(disable: 4127 4701)
+#endif
+#if (LZO_CC_MSC && (_MSC_VER >= 1300))
+# pragma warning(disable: 4820)
+# pragma warning(disable: 4514 4710 4711)
+#endif
+
+#if (LZO_CC_SUNPROC)
+# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED)
+# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP)
+#endif
+
+#if defined(__LZO_MMODEL_HUGE) && (!LZO_HAVE_MM_HUGE_PTR)
+# error "this should not happen - check defines for __huge"
+#endif
+
+#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING)
+#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
+# define ACC_WANT_ACC_INCD_H 1
+# define ACC_WANT_ACC_INCE_H 1
+# define ACC_WANT_ACC_INCI_H 1
+#elif 1
+# include <string.h>
+#else
+# define ACC_WANT_ACC_INCD_H 1
+#endif
+
+#if (LZO_ARCH_I086)
+# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT
+# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0])
+# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1])
+# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o)))
+#endif
+
+#if !defined(lzo_uintptr_t)
+# if defined(__LZO_MMODEL_HUGE)
+# define lzo_uintptr_t unsigned long
+# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16)
+# define __LZO_UINTPTR_T_IS_POINTER 1
+ typedef char* lzo_uintptr_t;
+# define lzo_uintptr_t lzo_uintptr_t
+# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P)
+# define lzo_uintptr_t size_t
+# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P)
+# define lzo_uintptr_t unsigned long
+# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P)
+# define lzo_uintptr_t unsigned int
+# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P)
+# define lzo_uintptr_t unsigned long long
+# else
+# define lzo_uintptr_t size_t
+# endif
+#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
+
+#if 1 && !defined(LZO_CFG_FREESTANDING)
+#if 1 && !defined(HAVE_STRING_H)
+#define HAVE_STRING_H 1
+#endif
+#if 1 && !defined(HAVE_MEMCMP)
+#define HAVE_MEMCMP 1
+#endif
+#if 1 && !defined(HAVE_MEMCPY)
+#define HAVE_MEMCPY 1
+#endif
+#if 1 && !defined(HAVE_MEMMOVE)
+#define HAVE_MEMMOVE 1
+#endif
+#if 1 && !defined(HAVE_MEMSET)
+#define HAVE_MEMSET 1
+#endif
+#endif
+
+#if 1 && defined(HAVE_STRING_H)
+#include <string.h>
+#endif
+
+#if defined(LZO_CFG_FREESTANDING)
+# undef HAVE_MEMCMP
+# undef HAVE_MEMCPY
+# undef HAVE_MEMMOVE
+# undef HAVE_MEMSET
+#endif
+
+#if !defined(HAVE_MEMCMP)
+# undef memcmp
+# define memcmp(a,b,c) lzo_memcmp(a,b,c)
+#elif !defined(__LZO_MMODEL_HUGE)
+# define lzo_memcmp(a,b,c) memcmp(a,b,c)
+#endif
+#if !defined(HAVE_MEMCPY)
+# undef memcpy
+# define memcpy(a,b,c) lzo_memcpy(a,b,c)
+#elif !defined(__LZO_MMODEL_HUGE)
+# define lzo_memcpy(a,b,c) memcpy(a,b,c)
+#endif
+#if !defined(HAVE_MEMMOVE)
+# undef memmove
+# define memmove(a,b,c) lzo_memmove(a,b,c)
+#elif !defined(__LZO_MMODEL_HUGE)
+# define lzo_memmove(a,b,c) memmove(a,b,c)
+#endif
+#if !defined(HAVE_MEMSET)
+# undef memset
+# define memset(a,b,c) lzo_memset(a,b,c)
+#elif !defined(__LZO_MMODEL_HUGE)
+# define lzo_memset(a,b,c) memset(a,b,c)
+#endif
+
+#undef NDEBUG
+#if defined(LZO_CFG_FREESTANDING)
+# undef LZO_DEBUG
+# define NDEBUG 1
+# undef assert
+# define assert(e) ((void)0)
+#else
+# if !defined(LZO_DEBUG)
+# define NDEBUG 1
+# endif
+# include <assert.h>
+#endif
+
+#if 0 && defined(__BOUNDS_CHECKING_ON)
+# include <unchecked.h>
+#else
+# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt
+# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr)
+#endif
+
+#if !defined(__lzo_inline)
+# define __lzo_inline
+#endif
+#if !defined(__lzo_forceinline)
+# define __lzo_forceinline
+#endif
+#if !defined(__lzo_noinline)
+# define __lzo_noinline
+#endif
+
+#if 1
+# define LZO_BYTE(x) ((unsigned char) (x))
+#else
+# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff))
+#endif
+
+#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b))
+#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b))
+#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
+#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c))
+
+#define lzo_sizeof(type) ((lzo_uint) (sizeof(type)))
+
+#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array))))
+
+#define LZO_SIZE(bits) (1u << (bits))
+#define LZO_MASK(bits) (LZO_SIZE(bits) - 1)
+
+#define LZO_LSIZE(bits) (1ul << (bits))
+#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1)
+
+#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits))
+#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1)
+
+#if !defined(DMUL)
+#if 0
+
+# define DMUL(a,b) ((lzo_xint) ((lzo_uint32)(a) * (lzo_uint32)(b)))
+#else
+# define DMUL(a,b) ((lzo_xint) ((a) * (b)))
+#endif
+#endif
+
+#if 1 && !defined(LZO_CFG_NO_UNALIGNED)
+#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+# if (LZO_SIZEOF_SHORT == 2)
+# define LZO_UNALIGNED_OK_2
+# endif
+# if (LZO_SIZEOF_INT == 4)
+# define LZO_UNALIGNED_OK_4
+# endif
+#endif
+#endif
+
+#if defined(LZO_UNALIGNED_OK_2)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2)
+#endif
+#if defined(LZO_UNALIGNED_OK_4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4)
+#elif defined(LZO_ALIGNED_OK_4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4)
+#endif
+
+#define MEMCPY8_DS(dest,src,len) \
+ lzo_memcpy(dest,src,len); dest += len; src += len
+
+#define BZERO8_PTR(s,l,n) \
+ lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
+
+#define MEMCPY_DS(dest,src,len) \
+ do *dest++ = *src++; while (--len > 0)
+
+__LZO_EXTERN_C int __lzo_init_done;
+__LZO_EXTERN_C const char __lzo_copyright[];
+LZO_EXTERN(const lzo_bytep) lzo_copyright(void);
+
+#ifndef __LZO_PTR_H
+#define __LZO_PTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(lzo_uintptr_t)
+# if defined(__LZO_MMODEL_HUGE)
+# define lzo_uintptr_t unsigned long
+# else
+# define lzo_uintptr_t acc_uintptr_t
+# ifdef __ACC_INTPTR_T_IS_POINTER
+# define __LZO_UINTPTR_T_IS_POINTER 1
+# endif
+# endif
+#endif
+
+#if (LZO_ARCH_I086)
+#define PTR(a) ((lzo_bytep) (a))
+#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0)
+#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0)
+#elif (LZO_MM_PVP)
+#define PTR(a) ((lzo_bytep) (a))
+#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0)
+#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0)
+#else
+#define PTR(a) ((lzo_uintptr_t) (a))
+#define PTR_LINEAR(a) PTR(a)
+#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0)
+#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0)
+#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
+#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
+#endif
+
+#define PTR_LT(a,b) (PTR(a) < PTR(b))
+#define PTR_GE(a,b) (PTR(a) >= PTR(b))
+#define PTR_DIFF(a,b) (PTR(a) - PTR(b))
+#define pd(a,b) ((lzo_uint) ((a)-(b)))
+
+LZO_EXTERN(lzo_uintptr_t)
+__lzo_ptr_linear(const lzo_voidp ptr);
+
+typedef union
+{
+ char a_char;
+ unsigned char a_uchar;
+ short a_short;
+ unsigned short a_ushort;
+ int a_int;
+ unsigned int a_uint;
+ long a_long;
+ unsigned long a_ulong;
+ lzo_int a_lzo_int;
+ lzo_uint a_lzo_uint;
+ lzo_int32 a_lzo_int32;
+ lzo_uint32 a_lzo_uint32;
+ ptrdiff_t a_ptrdiff_t;
+ lzo_uintptr_t a_lzo_uintptr_t;
+ lzo_voidp a_lzo_voidp;
+ void * a_void_p;
+ lzo_bytep a_lzo_bytep;
+ lzo_bytepp a_lzo_bytepp;
+ lzo_uintp a_lzo_uintp;
+ lzo_uint * a_lzo_uint_p;
+ lzo_uint32p a_lzo_uint32p;
+ lzo_uint32 * a_lzo_uint32_p;
+ unsigned char * a_uchar_p;
+ char * a_char_p;
+}
+lzo_full_align_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#define LZO_DETERMINISTIC
+
+#define LZO_DICT_USE_PTR
+#if 0 && (LZO_ARCH_I086)
+# undef LZO_DICT_USE_PTR
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+# define lzo_dict_t const lzo_bytep
+# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+#else
+# define lzo_dict_t lzo_uint
+# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+#endif
+
+#endif
+
+#if !defined(MINILZO_CFG_SKIP_LZO_PTR)
+
+LZO_PUBLIC(lzo_uintptr_t)
+__lzo_ptr_linear(const lzo_voidp ptr)
+{
+ lzo_uintptr_t p;
+
+#if (LZO_ARCH_I086)
+ p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr));
+#elif (LZO_MM_PVP)
+ p = (lzo_uintptr_t) (ptr);
+ p = (p << 3) | (p >> 61);
+#else
+ p = (lzo_uintptr_t) PTR_LINEAR(ptr);
+#endif
+
+ return p;
+}
+
+LZO_PUBLIC(unsigned)
+__lzo_align_gap(const lzo_voidp ptr, lzo_uint size)
+{
+#if defined(__LZO_UINTPTR_T_IS_POINTER)
+ size_t n = (size_t) ptr;
+ n = (((n + size - 1) / size) * size) - n;
+#else
+ lzo_uintptr_t p, n;
+ p = __lzo_ptr_linear(ptr);
+ n = (((p + size - 1) / size) * size) - p;
+#endif
+
+ assert(size > 0);
+ assert((long)n >= 0);
+ assert(n <= size);
+ return (unsigned)n;
+}
+
+#endif
+
+/* If you use the LZO library in a product, I would appreciate that you
+ * keep this copyright string in the executable of your product.
+ */
+
+const char __lzo_copyright[] =
+#if !defined(__LZO_IN_MINLZO)
+ LZO_VERSION_STRING;
+#else
+ "\r\n\n"
+ "LZO data compression library.\n"
+ "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Markus Franz Xaver Johannes Oberhumer\n"
+ "<markus@oberhumer.com>\n"
+ "http://www.oberhumer.com $\n\n"
+ "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n"
+ "$Built: " __DATE__ " " __TIME__ " $\n"
+ "$Info: " LZO_INFO_STRING " $\n";
+#endif
+
+LZO_PUBLIC(const lzo_bytep)
+lzo_copyright(void)
+{
+#if (LZO_OS_DOS16 && LZO_CC_TURBOC)
+ return (lzo_voidp) __lzo_copyright;
+#else
+ return (const lzo_bytep) __lzo_copyright;
+#endif
+}
+
+LZO_PUBLIC(unsigned)
+lzo_version(void)
+{
+ return LZO_VERSION;
+}
+
+LZO_PUBLIC(const char *)
+lzo_version_string(void)
+{
+ return LZO_VERSION_STRING;
+}
+
+LZO_PUBLIC(const char *)
+lzo_version_date(void)
+{
+ return LZO_VERSION_DATE;
+}
+
+LZO_PUBLIC(const lzo_charp)
+_lzo_version_string(void)
+{
+ return LZO_VERSION_STRING;
+}
+
+LZO_PUBLIC(const lzo_charp)
+_lzo_version_date(void)
+{
+ return LZO_VERSION_DATE;
+}
+
+#define LZO_BASE 65521u
+#define LZO_NMAX 5552
+
+#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1
+#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1);
+#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2);
+#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4);
+#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8);
+
+LZO_PUBLIC(lzo_uint32)
+lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len)
+{
+ lzo_uint32 s1 = adler & 0xffff;
+ lzo_uint32 s2 = (adler >> 16) & 0xffff;
+ unsigned k;
+
+ if (buf == NULL)
+ return 1;
+
+ while (len > 0)
+ {
+ k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX;
+ len -= k;
+ if (k >= 16) do
+ {
+ LZO_DO16(buf,0);
+ buf += 16;
+ k -= 16;
+ } while (k >= 16);
+ if (k != 0) do
+ {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k > 0);
+ s1 %= LZO_BASE;
+ s2 %= LZO_BASE;
+ }
+ return (s2 << 16) | s1;
+}
+
+#undef LZO_DO1
+#undef LZO_DO2
+#undef LZO_DO4
+#undef LZO_DO8
+#undef LZO_DO16
+
+#if !defined(MINILZO_CFG_SKIP_LZO_STRING)
+#undef lzo_memcmp
+#undef lzo_memcpy
+#undef lzo_memmove
+#undef lzo_memset
+#if !defined(__LZO_MMODEL_HUGE)
+# undef LZO_HAVE_MM_HUGE_PTR
+#endif
+#define lzo_hsize_t lzo_uint
+#define lzo_hvoid_p lzo_voidp
+#define lzo_hbyte_p lzo_bytep
+#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f
+#define lzo_hmemcmp lzo_memcmp
+#define lzo_hmemcpy lzo_memcpy
+#define lzo_hmemmove lzo_memmove
+#define lzo_hmemset lzo_memset
+#define __LZOLIB_HMEMCPY_CH_INCLUDED 1
+#if !defined(LZOLIB_PUBLIC)
+# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f)
+#endif
+LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len)
+{
+#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCMP)
+ const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1;
+ const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2;
+ if __lzo_likely(len > 0) do
+ {
+ int d = *p1 - *p2;
+ if (d != 0)
+ return d;
+ p1++; p2++;
+ } while __lzo_likely(--len > 0);
+ return 0;
+#else
+ return memcmp(s1, s2, len);
+#endif
+}
+LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len)
+{
+#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCPY)
+ lzo_hbyte_p p1 = (lzo_hbyte_p) dest;
+ const lzo_hbyte_p p2 = (const lzo_hbyte_p) src;
+ if (!(len > 0) || p1 == p2)
+ return dest;
+ do
+ *p1++ = *p2++;
+ while __lzo_likely(--len > 0);
+ return dest;
+#else
+ return memcpy(dest, src, len);
+#endif
+}
+LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len)
+{
+#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMMOVE)
+ lzo_hbyte_p p1 = (lzo_hbyte_p) dest;
+ const lzo_hbyte_p p2 = (const lzo_hbyte_p) src;
+ if (!(len > 0) || p1 == p2)
+ return dest;
+ if (p1 < p2)
+ {
+ do
+ *p1++ = *p2++;
+ while __lzo_likely(--len > 0);
+ }
+ else
+ {
+ p1 += len;
+ p2 += len;
+ do
+ *--p1 = *--p2;
+ while __lzo_likely(--len > 0);
+ }
+ return dest;
+#else
+ return memmove(dest, src, len);
+#endif
+}
+LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len)
+{
+#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMSET)
+ lzo_hbyte_p p = (lzo_hbyte_p) s;
+ if __lzo_likely(len > 0) do
+ *p++ = (unsigned char) c;
+ while __lzo_likely(--len > 0);
+ return s;
+#else
+ return memset(s, c, len);
+#endif
+}
+#undef LZOLIB_PUBLIC
+#endif
+
+#if !defined(__LZO_IN_MINILZO)
+
+#define ACC_WANT_ACC_CHK_CH 1
+#undef ACCCHK_ASSERT
+
+ ACCCHK_ASSERT_IS_SIGNED_T(lzo_int)
+ ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint)
+
+ ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32)
+ ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32)
+ ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0)
+ ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4)
+
+#if !defined(__LZO_UINTPTR_T_IS_POINTER)
+ ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t)
+#endif
+ ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
+
+ ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint)
+ ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32))
+ ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint))
+ ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint))
+
+#endif
+#undef ACCCHK_ASSERT
+
+LZO_PUBLIC(int)
+_lzo_config_check(void)
+{
+ lzo_bool r = 1;
+ union { unsigned char c[2*sizeof(lzo_xint)]; lzo_xint l[2]; } u;
+ lzo_uintptr_t p;
+
+#if !defined(LZO_CFG_NO_CONFIG_CHECK)
+#if defined(LZO_ABI_BIG_ENDIAN)
+ u.l[0] = u.l[1] = 0; u.c[sizeof(lzo_xint) - 1] = 128;
+ r &= (u.l[0] == 128);
+#endif
+#if defined(LZO_ABI_LITTLE_ENDIAN)
+ u.l[0] = u.l[1] = 0; u.c[0] = 128;
+ r &= (u.l[0] == 128);
+#endif
+#if defined(LZO_UNALIGNED_OK_2)
+ p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0];
+ u.l[0] = u.l[1] = 0;
+ r &= ((* (const lzo_ushortp) (p+1)) == 0);
+#endif
+#if defined(LZO_UNALIGNED_OK_4)
+ p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0];
+ u.l[0] = u.l[1] = 0;
+ r &= ((* (const lzo_uint32p) (p+1)) == 0);
+#endif
+#endif
+
+ LZO_UNUSED(u); LZO_UNUSED(p);
+ return r == 1 ? LZO_E_OK : LZO_E_ERROR;
+}
+
+int __lzo_init_done = 0;
+
+LZO_PUBLIC(int)
+__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5,
+ int s6, int s7, int s8, int s9)
+{
+ int r;
+
+#if defined(__LZO_IN_MINILZO)
+#elif (LZO_CC_MSC && ((_MSC_VER) < 700))
+#else
+#define ACC_WANT_ACC_CHK_CH 1
+#undef ACCCHK_ASSERT
+#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr)
+#endif
+#undef ACCCHK_ASSERT
+
+ __lzo_init_done = 1;
+
+ if (v == 0)
+ return LZO_E_ERROR;
+
+ r = (s1 == -1 || s1 == (int) sizeof(short)) &&
+ (s2 == -1 || s2 == (int) sizeof(int)) &&
+ (s3 == -1 || s3 == (int) sizeof(long)) &&
+ (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) &&
+ (s5 == -1 || s5 == (int) sizeof(lzo_uint)) &&
+ (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) &&
+ (s7 == -1 || s7 == (int) sizeof(char *)) &&
+ (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) &&
+ (s9 == -1 || s9 == (int) sizeof(lzo_callback_t));
+ if (!r)
+ return LZO_E_ERROR;
+
+ r = _lzo_config_check();
+ if (r != LZO_E_OK)
+ return r;
+
+ return r;
+}
+
+#if !defined(__LZO_IN_MINILZO)
+
+#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD)
+
+#if 0
+BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment,
+ WORD wHeapSize, LPSTR lpszCmdLine )
+#else
+int __far __pascal LibMain ( int a, short b, short c, long d )
+#endif
+{
+ LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d);
+ return 1;
+}
+
+#endif
+
+#endif
+
+#define do_compress _lzo1x_1_do_compress
+
+#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS)
+
+#define LZO_NEED_DICT_H
+#define D_BITS 14
+#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5)
+#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
+
+#ifndef __LZO_CONFIG1X_H
+#define __LZO_CONFIG1X_H
+
+#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z)
+# define LZO1X
+#endif
+
+#if !defined(__LZO_IN_MINILZO)
+#include "lzo/lzo1x.h"
+#endif
+
+#define LZO_EOF_CODE
+#undef LZO_DETERMINISTIC
+
+#define M1_MAX_OFFSET 0x0400
+#ifndef M2_MAX_OFFSET
+#define M2_MAX_OFFSET 0x0800
+#endif
+#define M3_MAX_OFFSET 0x4000
+#define M4_MAX_OFFSET 0xbfff
+
+#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET)
+
+#define M1_MIN_LEN 2
+#define M1_MAX_LEN 2
+#define M2_MIN_LEN 3
+#ifndef M2_MAX_LEN
+#define M2_MAX_LEN 8
+#endif
+#define M3_MIN_LEN 3
+#define M3_MAX_LEN 33
+#define M4_MIN_LEN 3
+#define M4_MAX_LEN 9
+
+#define M1_MARKER 0
+#define M2_MARKER 64
+#define M3_MARKER 32
+#define M4_MARKER 16
+
+#ifndef MIN_LOOKAHEAD
+#define MIN_LOOKAHEAD (M2_MAX_LEN + 1)
+#endif
+
+#if defined(LZO_NEED_DICT_H)
+
+#ifndef LZO_HASH
+#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B
+#endif
+#define DL_MIN_LEN M2_MIN_LEN
+
+#ifndef __LZO_DICT_H
+#define __LZO_DICT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(D_BITS) && defined(DBITS)
+# define D_BITS DBITS
+#endif
+#if !defined(D_BITS)
+# error "D_BITS is not defined"
+#endif
+#if (D_BITS < 16)
+# define D_SIZE LZO_SIZE(D_BITS)
+# define D_MASK LZO_MASK(D_BITS)
+#else
+# define D_SIZE LZO_USIZE(D_BITS)
+# define D_MASK LZO_UMASK(D_BITS)
+#endif
+#define D_HIGH ((D_MASK >> 1) + 1)
+
+#if !defined(DD_BITS)
+# define DD_BITS 0
+#endif
+#define DD_SIZE LZO_SIZE(DD_BITS)
+#define DD_MASK LZO_MASK(DD_BITS)
+
+#if !defined(DL_BITS)
+# define DL_BITS (D_BITS - DD_BITS)
+#endif
+#if (DL_BITS < 16)
+# define DL_SIZE LZO_SIZE(DL_BITS)
+# define DL_MASK LZO_MASK(DL_BITS)
+#else
+# define DL_SIZE LZO_USIZE(DL_BITS)
+# define DL_MASK LZO_UMASK(DL_BITS)
+#endif
+
+#if (D_BITS != DL_BITS + DD_BITS)
+# error "D_BITS does not match"
+#endif
+#if (D_BITS < 8 || D_BITS > 18)
+# error "invalid D_BITS"
+#endif
+#if (DL_BITS < 8 || DL_BITS > 20)
+# error "invalid DL_BITS"
+#endif
+#if (DD_BITS < 0 || DD_BITS > 6)
+# error "invalid DD_BITS"
+#endif
+
+#if !defined(DL_MIN_LEN)
+# define DL_MIN_LEN 3
+#endif
+#if !defined(DL_SHIFT)
+# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN)
+#endif
+
+#define LZO_HASH_GZIP 1
+#define LZO_HASH_GZIP_INCREMENTAL 2
+#define LZO_HASH_LZO_INCREMENTAL_A 3
+#define LZO_HASH_LZO_INCREMENTAL_B 4
+
+#if !defined(LZO_HASH)
+# error "choose a hashing strategy"
+#endif
+
+#undef DM
+#undef DX
+
+#if (DL_MIN_LEN == 3)
+# define _DV2_A(p,shift1,shift2) \
+ (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2])
+# define _DV2_B(p,shift1,shift2) \
+ (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0])
+# define _DV3_B(p,shift1,shift2,shift3) \
+ ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0])
+#elif (DL_MIN_LEN == 2)
+# define _DV2_A(p,shift1,shift2) \
+ (( (lzo_xint)(p[0]) << shift1) ^ p[1])
+# define _DV2_B(p,shift1,shift2) \
+ (( (lzo_xint)(p[1]) << shift1) ^ p[2])
+#else
+# error "invalid DL_MIN_LEN"
+#endif
+#define _DV_A(p,shift) _DV2_A(p,shift,shift)
+#define _DV_B(p,shift) _DV2_B(p,shift,shift)
+#define DA2(p,s1,s2) \
+ (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0])
+#define DS2(p,s1,s2) \
+ (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0])
+#define DX2(p,s1,s2) \
+ (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
+#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0])
+#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0])
+#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
+#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s)))
+#define DM(v) DMS(v,0)
+
+#if (LZO_HASH == LZO_HASH_GZIP)
+# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT))
+
+#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT)
+# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2])
+# define _DINDEX(dv,p) (dv)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_A((p),5)
+# define DVAL_NEXT(dv,p) \
+ dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2])
+# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B)
+# define __LZO_HASH_INCREMENTAL
+# define DVAL_FIRST(dv,p) dv = _DV_B((p),5)
+# define DVAL_NEXT(dv,p) \
+ dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5)))
+# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5)
+# define DVAL_LOOKAHEAD DL_MIN_LEN
+
+#else
+# error "choose a hashing strategy"
+#endif
+
+#ifndef DINDEX
+#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS)
+#endif
+#if !defined(DINDEX1) && defined(D_INDEX1)
+#define DINDEX1 D_INDEX1
+#endif
+#if !defined(DINDEX2) && defined(D_INDEX2)
+#define DINDEX2 D_INDEX2
+#endif
+
+#if !defined(__LZO_HASH_INCREMENTAL)
+# define DVAL_FIRST(dv,p) ((void) 0)
+# define DVAL_NEXT(dv,p) ((void) 0)
+# define DVAL_LOOKAHEAD 0
+#endif
+
+#if !defined(DVAL_ASSERT)
+#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG)
+static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
+{
+ lzo_xint df;
+ DVAL_FIRST(df,(p));
+ assert(DINDEX(dv,p) == DINDEX(df,p));
+}
+#else
+# define DVAL_ASSERT(dv,p) ((void) 0)
+#endif
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+# define DENTRY(p,in) (p)
+# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex]
+#else
+# define DENTRY(p,in) ((lzo_uint) ((p)-(in)))
+# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex]
+#endif
+
+#if (DD_BITS == 0)
+
+# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in)
+# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in)
+# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in)
+
+#else
+
+# define UPDATE_D(dict,drun,dv,p,in) \
+ dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
+# define UPDATE_I(dict,drun,index,p,in) \
+ dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
+# define UPDATE_P(ptr,drun,p,in) \
+ (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK
+
+#endif
+
+#if defined(LZO_DICT_USE_PTR)
+
+#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
+ (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset)
+
+#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
+ (BOUNDS_CHECKING_OFF_IN_EXPR(( \
+ m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \
+ PTR_LT(m_pos,in) || \
+ (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) <= 0 || \
+ m_off > max_offset )))
+
+#else
+
+#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
+ (m_off == 0 || \
+ ((m_off = pd(ip, in) - m_off) > max_offset) || \
+ (m_pos = (ip) - (m_off), 0) )
+
+#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
+ (pd(ip, in) <= m_off || \
+ ((m_off = pd(ip, in) - m_off) > max_offset) || \
+ (m_pos = (ip) - (m_off), 0) )
+
+#endif
+
+#if defined(LZO_DETERMINISTIC)
+# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET
+#else
+# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+#endif
+
+#define DO_COMPRESS lzo1x_1_compress
+
+static __lzo_noinline lzo_uint
+do_compress ( const lzo_bytep in , lzo_uint in_len,
+ lzo_bytep out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+{
+ register const lzo_bytep ip;
+ lzo_bytep op;
+ const lzo_bytep const in_end = in + in_len;
+ const lzo_bytep const ip_end = in + in_len - M2_MAX_LEN - 5;
+ const lzo_bytep ii;
+ lzo_dict_p const dict = (lzo_dict_p) wrkmem;
+
+ op = out;
+ ip = in;
+ ii = ip;
+
+ ip += 4;
+ for (;;)
+ {
+ register const lzo_bytep m_pos;
+ lzo_uint m_off;
+ lzo_uint m_len;
+ lzo_uint dindex;
+
+ DINDEX1(dindex,ip);
+ GINDEX(m_pos,m_off,dict,dindex,in);
+ if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
+ goto literal;
+#if 1
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+ DINDEX2(dindex,ip);
+#endif
+ GINDEX(m_pos,m_off,dict,dindex,in);
+ if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
+ goto literal;
+ if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
+ goto try_match;
+ goto literal;
+
+try_match:
+#if 1 && defined(LZO_UNALIGNED_OK_2)
+ if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
+#else
+ if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
+#endif
+ {
+ }
+ else
+ {
+ if __lzo_likely(m_pos[2] == ip[2])
+ {
+#if 0
+ if (m_off <= M2_MAX_OFFSET)
+ goto match;
+ if (lit <= 3)
+ goto match;
+ if (lit == 3)
+ {
+ assert(op - 2 > out); op[-2] |= LZO_BYTE(3);
+ *op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
+ goto code_match;
+ }
+ if (m_pos[3] == ip[3])
+#endif
+ goto match;
+ }
+ else
+ {
+#if 0
+#if 0
+ if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3)
+#else
+ if (m_off <= M1_MAX_OFFSET && lit == 3)
+#endif
+ {
+ register lzo_uint t;
+
+ t = lit;
+ assert(op - 2 > out); op[-2] |= LZO_BYTE(t);
+ do *op++ = *ii++; while (--t > 0);
+ assert(ii == ip);
+ m_off -= 1;
+ *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2));
+ *op++ = LZO_BYTE(m_off >> 2);
+ ip += 2;
+ goto match_done;
+ }
+#endif
+ }
+ }
+
+literal:
+ UPDATE_I(dict,0,dindex,ip,in);
+ ++ip;
+ if __lzo_unlikely(ip >= ip_end)
+ break;
+ continue;
+
+match:
+ UPDATE_I(dict,0,dindex,ip,in);
+ if (pd(ip,ii) > 0)
+ {
+ register lzo_uint t = pd(ip,ii);
+
+ if (t <= 3)
+ {
+ assert(op - 2 > out);
+ op[-2] |= LZO_BYTE(t);
+ }
+ else if (t <= 18)
+ *op++ = LZO_BYTE(t - 3);
+ else
+ {
+ register lzo_uint tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255)
+ {
+ tt -= 255;
+ *op++ = 0;
+ }
+ assert(tt > 0);
+ *op++ = LZO_BYTE(tt);
+ }
+ do *op++ = *ii++; while (--t > 0);
+ }
+
+ assert(ii == ip);
+ ip += 3;
+ if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ ||
+ m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++
+#ifdef LZO1Y
+ || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++
+ || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++
+#endif
+ )
+ {
+ --ip;
+ m_len = pd(ip, ii);
+ assert(m_len >= 3); assert(m_len <= M2_MAX_LEN);
+
+ if (m_off <= M2_MAX_OFFSET)
+ {
+ m_off -= 1;
+#if defined(LZO1X)
+ *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
+ *op++ = LZO_BYTE(m_off >> 3);
+#elif defined(LZO1Y)
+ *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2));
+ *op++ = LZO_BYTE(m_off >> 2);
+#endif
+ }
+ else if (m_off <= M3_MAX_OFFSET)
+ {
+ m_off -= 1;
+ *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
+ goto m3_m4_offset;
+ }
+ else
+#if defined(LZO1X)
+ {
+ m_off -= 0x4000;
+ assert(m_off > 0); assert(m_off <= 0x7fff);
+ *op++ = LZO_BYTE(M4_MARKER |
+ ((m_off & 0x4000) >> 11) | (m_len - 2));
+ goto m3_m4_offset;
+ }
+#elif defined(LZO1Y)
+ goto m4_match;
+#endif
+ }
+ else
+ {
+ {
+ const lzo_bytep end = in_end;
+ const lzo_bytep m = m_pos + M2_MAX_LEN + 1;
+ while (ip < end && *m == *ip)
+ m++, ip++;
+ m_len = pd(ip, ii);
+ }
+ assert(m_len > M2_MAX_LEN);
+
+ if (m_off <= M3_MAX_OFFSET)
+ {
+ m_off -= 1;
+ if (m_len <= 33)
+ *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
+ else
+ {
+ m_len -= 33;
+ *op++ = M3_MARKER | 0;
+ goto m3_m4_len;
+ }
+ }
+ else
+ {
+#if defined(LZO1Y)
+m4_match:
+#endif
+ m_off -= 0x4000;
+ assert(m_off > 0); assert(m_off <= 0x7fff);
+ if (m_len <= M4_MAX_LEN)
+ *op++ = LZO_BYTE(M4_MARKER |
+ ((m_off & 0x4000) >> 11) | (m_len - 2));
+ else
+ {
+ m_len -= M4_MAX_LEN;
+ *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
+m3_m4_len:
+ while (m_len > 255)
+ {
+ m_len -= 255;
+ *op++ = 0;
+ }
+ assert(m_len > 0);
+ *op++ = LZO_BYTE(m_len);
+ }
+ }
+
+m3_m4_offset:
+ *op++ = LZO_BYTE((m_off & 63) << 2);
+ *op++ = LZO_BYTE(m_off >> 6);
+ }
+
+#if 0
+match_done:
+#endif
+ ii = ip;
+ if __lzo_unlikely(ip >= ip_end)
+ break;
+ }
+
+ *out_len = pd(op, out);
+ return pd(in_end,ii);
+}
+
+LZO_PUBLIC(int)
+DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
+ lzo_bytep out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+{
+ lzo_bytep op = out;
+ lzo_uint t;
+
+ if __lzo_unlikely(in_len <= M2_MAX_LEN + 5)
+ t = in_len;
+ else
+ {
+ t = do_compress(in,in_len,op,out_len,wrkmem);
+ op += *out_len;
+ }
+
+ if (t > 0)
+ {
+ const lzo_bytep ii = in + in_len - t;
+
+ if (op == out && t <= 238)
+ *op++ = LZO_BYTE(17 + t);
+ else if (t <= 3)
+ op[-2] |= LZO_BYTE(t);
+ else if (t <= 18)
+ *op++ = LZO_BYTE(t - 3);
+ else
+ {
+ lzo_uint tt = t - 18;
+
+ *op++ = 0;
+ while (tt > 255)
+ {
+ tt -= 255;
+ *op++ = 0;
+ }
+ assert(tt > 0);
+ *op++ = LZO_BYTE(tt);
+ }
+ do *op++ = *ii++; while (--t > 0);
+ }
+
+ *op++ = M4_MARKER | 1;
+ *op++ = 0;
+ *op++ = 0;
+
+ *out_len = pd(op, out);
+ return LZO_E_OK;
+}
+
+#endif
+
+#undef do_compress
+#undef DO_COMPRESS
+#undef LZO_HASH
+
+#undef LZO_TEST_OVERRUN
+#undef DO_DECOMPRESS
+#define DO_DECOMPRESS lzo1x_decompress
+
+#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS)
+
+#if defined(LZO_TEST_OVERRUN)
+# if !defined(LZO_TEST_OVERRUN_INPUT)
+# define LZO_TEST_OVERRUN_INPUT 2
+# endif
+# if !defined(LZO_TEST_OVERRUN_OUTPUT)
+# define LZO_TEST_OVERRUN_OUTPUT 2
+# endif
+# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND)
+# define LZO_TEST_OVERRUN_LOOKBEHIND
+# endif
+#endif
+
+#undef TEST_IP
+#undef TEST_OP
+#undef TEST_LB
+#undef TEST_LBO
+#undef NEED_IP
+#undef NEED_OP
+#undef HAVE_TEST_IP
+#undef HAVE_TEST_OP
+#undef HAVE_NEED_IP
+#undef HAVE_NEED_OP
+#undef HAVE_ANY_IP
+#undef HAVE_ANY_OP
+
+#if defined(LZO_TEST_OVERRUN_INPUT)
+# if (LZO_TEST_OVERRUN_INPUT >= 1)
+# define TEST_IP (ip < ip_end)
+# endif
+# if (LZO_TEST_OVERRUN_INPUT >= 2)
+# define NEED_IP(x) \
+ if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_OVERRUN_OUTPUT)
+# if (LZO_TEST_OVERRUN_OUTPUT >= 1)
+# define TEST_OP (op <= op_end)
+# endif
+# if (LZO_TEST_OVERRUN_OUTPUT >= 2)
+# undef TEST_OP
+# define NEED_OP(x) \
+ if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
+# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun
+# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun
+#else
+# define TEST_LB(m_pos) ((void) 0)
+# define TEST_LBO(m_pos,o) ((void) 0)
+#endif
+
+#if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
+# define TEST_IP (ip < ip_end)
+#endif
+
+#if defined(TEST_IP)
+# define HAVE_TEST_IP
+#else
+# define TEST_IP 1
+#endif
+#if defined(TEST_OP)
+# define HAVE_TEST_OP
+#else
+# define TEST_OP 1
+#endif
+
+#if defined(NEED_IP)
+# define HAVE_NEED_IP
+#else
+# define NEED_IP(x) ((void) 0)
+#endif
+#if defined(NEED_OP)
+# define HAVE_NEED_OP
+#else
+# define NEED_OP(x) ((void) 0)
+#endif
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
+# define HAVE_ANY_IP
+#endif
+#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
+# define HAVE_ANY_OP
+#endif
+
+#undef __COPY4
+#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
+
+#undef COPY4
+#if defined(LZO_UNALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4(dst,src)
+#elif defined(LZO_ALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src))
+#endif
+
+#if defined(DO_DECOMPRESS)
+LZO_PUBLIC(int)
+DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
+ lzo_bytep out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+#endif
+{
+ register lzo_bytep op;
+ register const lzo_bytep ip;
+ register lzo_uint t;
+#if defined(COPY_DICT)
+ lzo_uint m_off;
+ const lzo_bytep dict_end;
+#else
+ register const lzo_bytep m_pos;
+#endif
+
+ const lzo_bytep const ip_end = in + in_len;
+#if defined(HAVE_ANY_OP)
+ lzo_bytep const op_end = out + *out_len;
+#endif
+#if defined(LZO1Z)
+ lzo_uint last_m_off = 0;
+#endif
+
+ LZO_UNUSED(wrkmem);
+
+#if defined(COPY_DICT)
+ if (dict)
+ {
+ if (dict_len > M4_MAX_OFFSET)
+ {
+ dict += dict_len - M4_MAX_OFFSET;
+ dict_len = M4_MAX_OFFSET;
+ }
+ dict_end = dict + dict_len;
+ }
+ else
+ {
+ dict_len = 0;
+ dict_end = NULL;
+ }
+#endif
+
+ *out_len = 0;
+
+ op = out;
+ ip = in;
+
+ if (*ip > 17)
+ {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while (TEST_IP && TEST_OP)
+ {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 15 + *ip++;
+ }
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (PTR_ALIGNED2_4(op,ip))
+ {
+#endif
+ COPY4(op,ip);
+ op += 4; ip += 4;
+ if (--t > 0)
+ {
+ if (t >= 4)
+ {
+ do {
+ COPY4(op,ip);
+ op += 4; ip += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *ip++; while (--t > 0);
+ }
+ else
+ do *op++ = *ip++; while (--t > 0);
+ }
+#if !defined(LZO_UNALIGNED_OK_4)
+ }
+ else
+#endif
+#endif
+#if !defined(LZO_UNALIGNED_OK_4)
+ {
+ *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
+ do *op++ = *ip++; while (--t > 0);
+ }
+#endif
+
+first_literal_run:
+
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(3);
+ t = 3; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LB(m_pos); NEED_OP(3);
+ *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+
+ do {
+match:
+ if (t >= 64)
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1X)
+ m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ m_off = t & 0x1f;
+ if (m_off >= 0x1c)
+ m_off = last_m_off;
+ else
+ {
+ m_off = 1 + (m_off << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+ }
+ t = (t >> 5) - 1;
+#endif
+#else
+#if defined(LZO1X)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 3;
+ m_pos -= *ip++ << 2;
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ {
+ lzo_uint off = t & 0x1f;
+ m_pos = op;
+ if (off >= 0x1c)
+ {
+ assert(last_m_off > 0);
+ m_pos -= last_m_off;
+ }
+ else
+ {
+ off = 1 + (off << 6) + (*ip++ >> 2);
+ m_pos -= off;
+ last_m_off = off;
+ }
+ }
+ t = (t >> 5) - 1;
+#endif
+ TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
+ goto copy_match;
+#endif
+ }
+ else if (t >= 32)
+ {
+ t &= 31;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 31 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#else
+#if defined(LZO1Z)
+ {
+ lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ m_pos = op - off;
+ last_m_off = off;
+ }
+#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
+ m_pos = op - 1;
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos = op - 1;
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#endif
+ ip += 2;
+ }
+ else if (t >= 16)
+ {
+#if defined(COPY_DICT)
+ m_off = (t & 8) << 11;
+#else
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+#endif
+ t &= 7;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 7 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off += (ip[0] << 6) + (ip[1] >> 2);
+#else
+ m_off += (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_off == 0)
+ goto eof_found;
+ m_off += 0x4000;
+#if defined(LZO1Z)
+ last_m_off = m_off;
+#endif
+#else
+#if defined(LZO1Z)
+ m_pos -= (ip[0] << 6) + (ip[1] >> 2);
+#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+#if defined(LZO1Z)
+ last_m_off = pd((const lzo_bytep)op, m_pos);
+#endif
+#endif
+ }
+ else
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(2);
+ t = 2; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = 1 + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LB(m_pos); NEED_OP(2);
+ *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+ }
+
+#if defined(COPY_DICT)
+
+ NEED_OP(t+3-1);
+ t += 3-1; COPY_DICT(t,m_off)
+
+#else
+
+ TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
+ {
+ assert((op - m_pos) >= 4);
+#else
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
+ {
+#endif
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4 - (3 - 1);
+ do {
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *m_pos++; while (--t > 0);
+ }
+ else
+#endif
+ {
+copy_match:
+ *op++ = *m_pos++; *op++ = *m_pos++;
+ do *op++ = *m_pos++; while (--t > 0);
+ }
+
+#endif
+
+match_done:
+#if defined(LZO1Z)
+ t = ip[-1] & 3;
+#else
+ t = ip[-2] & 3;
+#endif
+ if (t == 0)
+ break;
+
+match_next:
+ assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1);
+#if 0
+ do *op++ = *ip++; while (--t > 0);
+#else
+ *op++ = *ip++;
+ if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
+#endif
+ t = *ip++;
+ } while (TEST_IP && TEST_OP);
+ }
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
+ *out_len = pd(op, out);
+ return LZO_E_EOF_NOT_FOUND;
+#endif
+
+eof_found:
+ assert(t == 1);
+ *out_len = pd(op, out);
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+
+#if defined(HAVE_NEED_IP)
+input_overrun:
+ *out_len = pd(op, out);
+ return LZO_E_INPUT_OVERRUN;
+#endif
+
+#if defined(HAVE_NEED_OP)
+output_overrun:
+ *out_len = pd(op, out);
+ return LZO_E_OUTPUT_OVERRUN;
+#endif
+
+#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
+lookbehind_overrun:
+ *out_len = pd(op, out);
+ return LZO_E_LOOKBEHIND_OVERRUN;
+#endif
+}
+
+#endif
+
+#define LZO_TEST_OVERRUN
+#undef DO_DECOMPRESS
+#define DO_DECOMPRESS lzo1x_decompress_safe
+
+#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE)
+
+#if defined(LZO_TEST_OVERRUN)
+# if !defined(LZO_TEST_OVERRUN_INPUT)
+# define LZO_TEST_OVERRUN_INPUT 2
+# endif
+# if !defined(LZO_TEST_OVERRUN_OUTPUT)
+# define LZO_TEST_OVERRUN_OUTPUT 2
+# endif
+# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND)
+# define LZO_TEST_OVERRUN_LOOKBEHIND
+# endif
+#endif
+
+#undef TEST_IP
+#undef TEST_OP
+#undef TEST_LB
+#undef TEST_LBO
+#undef NEED_IP
+#undef NEED_OP
+#undef HAVE_TEST_IP
+#undef HAVE_TEST_OP
+#undef HAVE_NEED_IP
+#undef HAVE_NEED_OP
+#undef HAVE_ANY_IP
+#undef HAVE_ANY_OP
+
+#if defined(LZO_TEST_OVERRUN_INPUT)
+# if (LZO_TEST_OVERRUN_INPUT >= 1)
+# define TEST_IP (ip < ip_end)
+# endif
+# if (LZO_TEST_OVERRUN_INPUT >= 2)
+# define NEED_IP(x) \
+ if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_OVERRUN_OUTPUT)
+# if (LZO_TEST_OVERRUN_OUTPUT >= 1)
+# define TEST_OP (op <= op_end)
+# endif
+# if (LZO_TEST_OVERRUN_OUTPUT >= 2)
+# undef TEST_OP
+# define NEED_OP(x) \
+ if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# endif
+#endif
+
+#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
+# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun
+# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun
+#else
+# define TEST_LB(m_pos) ((void) 0)
+# define TEST_LBO(m_pos,o) ((void) 0)
+#endif
+
+#if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
+# define TEST_IP (ip < ip_end)
+#endif
+
+#if defined(TEST_IP)
+# define HAVE_TEST_IP
+#else
+# define TEST_IP 1
+#endif
+#if defined(TEST_OP)
+# define HAVE_TEST_OP
+#else
+# define TEST_OP 1
+#endif
+
+#if defined(NEED_IP)
+# define HAVE_NEED_IP
+#else
+# define NEED_IP(x) ((void) 0)
+#endif
+#if defined(NEED_OP)
+# define HAVE_NEED_OP
+#else
+# define NEED_OP(x) ((void) 0)
+#endif
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
+# define HAVE_ANY_IP
+#endif
+#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
+# define HAVE_ANY_OP
+#endif
+
+#undef __COPY4
+#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
+
+#undef COPY4
+#if defined(LZO_UNALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4(dst,src)
+#elif defined(LZO_ALIGNED_OK_4)
+# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src))
+#endif
+
+#if defined(DO_DECOMPRESS)
+LZO_PUBLIC(int)
+DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
+ lzo_bytep out, lzo_uintp out_len,
+ lzo_voidp wrkmem )
+#endif
+{
+ register lzo_bytep op;
+ register const lzo_bytep ip;
+ register lzo_uint t;
+#if defined(COPY_DICT)
+ lzo_uint m_off;
+ const lzo_bytep dict_end;
+#else
+ register const lzo_bytep m_pos;
+#endif
+
+ const lzo_bytep const ip_end = in + in_len;
+#if defined(HAVE_ANY_OP)
+ lzo_bytep const op_end = out + *out_len;
+#endif
+#if defined(LZO1Z)
+ lzo_uint last_m_off = 0;
+#endif
+
+ LZO_UNUSED(wrkmem);
+
+#if defined(COPY_DICT)
+ if (dict)
+ {
+ if (dict_len > M4_MAX_OFFSET)
+ {
+ dict += dict_len - M4_MAX_OFFSET;
+ dict_len = M4_MAX_OFFSET;
+ }
+ dict_end = dict + dict_len;
+ }
+ else
+ {
+ dict_len = 0;
+ dict_end = NULL;
+ }
+#endif
+
+ *out_len = 0;
+
+ op = out;
+ ip = in;
+
+ if (*ip > 17)
+ {
+ t = *ip++ - 17;
+ if (t < 4)
+ goto match_next;
+ assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ do *op++ = *ip++; while (--t > 0);
+ goto first_literal_run;
+ }
+
+ while (TEST_IP && TEST_OP)
+ {
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 15 + *ip++;
+ }
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (PTR_ALIGNED2_4(op,ip))
+ {
+#endif
+ COPY4(op,ip);
+ op += 4; ip += 4;
+ if (--t > 0)
+ {
+ if (t >= 4)
+ {
+ do {
+ COPY4(op,ip);
+ op += 4; ip += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *ip++; while (--t > 0);
+ }
+ else
+ do *op++ = *ip++; while (--t > 0);
+ }
+#if !defined(LZO_UNALIGNED_OK_4)
+ }
+ else
+#endif
+#endif
+#if !defined(LZO_UNALIGNED_OK_4)
+ {
+ *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
+ do *op++ = *ip++; while (--t > 0);
+ }
+#endif
+
+first_literal_run:
+
+ t = *ip++;
+ if (t >= 16)
+ goto match;
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(3);
+ t = 3; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LB(m_pos); NEED_OP(3);
+ *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+
+ do {
+match:
+ if (t >= 64)
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1X)
+ m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ m_off = t & 0x1f;
+ if (m_off >= 0x1c)
+ m_off = last_m_off;
+ else
+ {
+ m_off = 1 + (m_off << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+ }
+ t = (t >> 5) - 1;
+#endif
+#else
+#if defined(LZO1X)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1;
+#elif defined(LZO1Y)
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 3;
+ m_pos -= *ip++ << 2;
+ t = (t >> 4) - 3;
+#elif defined(LZO1Z)
+ {
+ lzo_uint off = t & 0x1f;
+ m_pos = op;
+ if (off >= 0x1c)
+ {
+ assert(last_m_off > 0);
+ m_pos -= last_m_off;
+ }
+ else
+ {
+ off = 1 + (off << 6) + (*ip++ >> 2);
+ m_pos -= off;
+ last_m_off = off;
+ }
+ }
+ t = (t >> 5) - 1;
+#endif
+ TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
+ goto copy_match;
+#endif
+ }
+ else if (t >= 32)
+ {
+ t &= 31;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 31 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#else
+#if defined(LZO1Z)
+ {
+ lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
+ m_pos = op - off;
+ last_m_off = off;
+ }
+#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
+ m_pos = op - 1;
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos = op - 1;
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+#endif
+ ip += 2;
+ }
+ else if (t >= 16)
+ {
+#if defined(COPY_DICT)
+ m_off = (t & 8) << 11;
+#else
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+#endif
+ t &= 7;
+ if (t == 0)
+ {
+ NEED_IP(1);
+ while (*ip == 0)
+ {
+ t += 255;
+ ip++;
+ NEED_IP(1);
+ }
+ t += 7 + *ip++;
+ }
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off += (ip[0] << 6) + (ip[1] >> 2);
+#else
+ m_off += (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_off == 0)
+ goto eof_found;
+ m_off += 0x4000;
+#if defined(LZO1Z)
+ last_m_off = m_off;
+#endif
+#else
+#if defined(LZO1Z)
+ m_pos -= (ip[0] << 6) + (ip[1] >> 2);
+#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
+ m_pos -= (* (const lzo_ushortp) ip) >> 2;
+#else
+ m_pos -= (ip[0] >> 2) + (ip[1] << 6);
+#endif
+ ip += 2;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+#if defined(LZO1Z)
+ last_m_off = pd((const lzo_bytep)op, m_pos);
+#endif
+#endif
+ }
+ else
+ {
+#if defined(COPY_DICT)
+#if defined(LZO1Z)
+ m_off = 1 + (t << 6) + (*ip++ >> 2);
+ last_m_off = m_off;
+#else
+ m_off = 1 + (t >> 2) + (*ip++ << 2);
+#endif
+ NEED_OP(2);
+ t = 2; COPY_DICT(t,m_off)
+#else
+#if defined(LZO1Z)
+ t = 1 + (t << 6) + (*ip++ >> 2);
+ m_pos = op - t;
+ last_m_off = t;
+#else
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+#endif
+ TEST_LB(m_pos); NEED_OP(2);
+ *op++ = *m_pos++; *op++ = *m_pos;
+#endif
+ goto match_done;
+ }
+
+#if defined(COPY_DICT)
+
+ NEED_OP(t+3-1);
+ t += 3-1; COPY_DICT(t,m_off)
+
+#else
+
+ TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
+#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
+#if !defined(LZO_UNALIGNED_OK_4)
+ if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
+ {
+ assert((op - m_pos) >= 4);
+#else
+ if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
+ {
+#endif
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4 - (3 - 1);
+ do {
+ COPY4(op,m_pos);
+ op += 4; m_pos += 4; t -= 4;
+ } while (t >= 4);
+ if (t > 0) do *op++ = *m_pos++; while (--t > 0);
+ }
+ else
+#endif
+ {
+copy_match:
+ *op++ = *m_pos++; *op++ = *m_pos++;
+ do *op++ = *m_pos++; while (--t > 0);
+ }
+
+#endif
+
+match_done:
+#if defined(LZO1Z)
+ t = ip[-1] & 3;
+#else
+ t = ip[-2] & 3;
+#endif
+ if (t == 0)
+ break;
+
+match_next:
+ assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1);
+#if 0
+ do *op++ = *ip++; while (--t > 0);
+#else
+ *op++ = *ip++;
+ if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
+#endif
+ t = *ip++;
+ } while (TEST_IP && TEST_OP);
+ }
+
+#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
+ *out_len = pd(op, out);
+ return LZO_E_EOF_NOT_FOUND;
+#endif
+
+eof_found:
+ assert(t == 1);
+ *out_len = pd(op, out);
+ return (ip == ip_end ? LZO_E_OK :
+ (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
+
+#if defined(HAVE_NEED_IP)
+input_overrun:
+ *out_len = pd(op, out);
+ return LZO_E_INPUT_OVERRUN;
+#endif
+
+#if defined(HAVE_NEED_OP)
+output_overrun:
+ *out_len = pd(op, out);
+ return LZO_E_OUTPUT_OVERRUN;
+#endif
+
+#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
+lookbehind_overrun:
+ *out_len = pd(op, out);
+ return LZO_E_LOOKBEHIND_OVERRUN;
+#endif
+}
+
+#endif
+
+/***** End of minilzo.c *****/
+
diff --git a/extern/lzo/minilzo/minilzo.h b/extern/lzo/minilzo/minilzo.h
new file mode 100644
index 00000000000..93916bc89b2
--- /dev/null
+++ b/extern/lzo/minilzo/minilzo.h
@@ -0,0 +1,112 @@
+/* minilzo.h -- mini subset of the LZO real-time data compression library
+
+ This file is part of the LZO real-time data compression library.
+
+ Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ All Rights Reserved.
+
+ The LZO library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ The LZO library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the LZO library; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Markus F.X.J. Oberhumer
+ <markus@oberhumer.com>
+ http://www.oberhumer.com/opensource/lzo/
+ */
+
+/*
+ * NOTE:
+ * the full LZO package can be found at
+ * http://www.oberhumer.com/opensource/lzo/
+ */
+
+
+#ifndef __MINILZO_H
+#define __MINILZO_H
+
+#define MINILZO_VERSION 0x2030
+
+#ifdef __LZOCONF_H
+# error "you cannot use both LZO and miniLZO"
+#endif
+
+#undef LZO_HAVE_CONFIG_H
+#include "lzoconf.h"
+
+#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
+# error "version mismatch in header files"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***********************************************************************
+//
+************************************************************************/
+
+/* Memory required for the wrkmem parameter.
+ * When the required size is 0, you can also pass a NULL pointer.
+ */
+
+#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
+#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
+#define LZO1X_MEM_DECOMPRESS (0)
+
+
+/* compression */
+LZO_EXTERN(int)
+lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem );
+
+/* decompression */
+LZO_EXTERN(int)
+lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem /* NOT USED */ );
+
+/* safe decompression with overrun testing */
+LZO_EXTERN(int)
+lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
+ lzo_bytep dst, lzo_uintp dst_len,
+ lzo_voidp wrkmem /* NOT USED */ );
+
+
+#define LZO_OUT_LEN(size) ((size) + (size) / 16 + 64 + 3)
+
+#define LZO_HEAP_ALLOC(var,size) \
+ lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* already included */
+
diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h
index f0dba3cc7a4..b21ce473202 100644
--- a/intern/smoke/extern/smoke_API.h
+++ b/intern/smoke/extern/smoke_API.h
@@ -20,7 +20,7 @@
* The Original Code is Copyright (C) 2009 by Daniel Genrich
* All rights reserved.
*
- * Contributor(s): None
+ * Contributor(s): Daniel Genrich
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -32,6 +32,10 @@
extern "C" {
#endif
+// export
+void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles);
+
+// low res
struct FLUID_3D *smoke_init(int *res, float *p0, float dt);
void smoke_free(struct FLUID_3D *fluid);
@@ -57,11 +61,14 @@ void smoke_turbulence_free(struct WTURBULENCE *wt);
void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid);
float *smoke_turbulence_get_density(struct WTURBULENCE *wt);
-void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res);
+void smoke_turbulence_get_res(struct WTURBULENCE *wt, unsigned int *res);
void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type);
-void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength);
+void smoke_turbulence_initBlenderRNA(struct WTURBULENCE *wt, float *strength);
+
+void smoke_turbulence_dissolve(struct WTURBULENCE *wt, int speed, int log);
-void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log);
+// export
+void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw);
#ifdef __cplusplus
}
diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp
index ff66f29143c..89dd893198b 100644
--- a/intern/smoke/intern/FLUID_3D.cpp
+++ b/intern/smoke/intern/FLUID_3D.cpp
@@ -75,8 +75,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
// allocate arrays
_totalCells = _xRes * _yRes * _zRes;
_slabSize = _xRes * _yRes;
- _divergence = new float[_totalCells];
- _pressure = new float[_totalCells];
_xVelocity = new float[_totalCells];
_yVelocity = new float[_totalCells];
_zVelocity = new float[_totalCells];
@@ -86,20 +84,11 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
_xForce = new float[_totalCells];
_yForce = new float[_totalCells];
_zForce = new float[_totalCells];
- _vorticity = new float[_totalCells];
_density = new float[_totalCells];
_densityOld = new float[_totalCells];
_heat = new float[_totalCells];
_heatOld = new float[_totalCells];
- _residual = new float[_totalCells];
- _direction = new float[_totalCells];
- _q = new float[_totalCells];
- _obstacles = new unsigned char[_totalCells];
- _xVorticity = new float[_totalCells];
- _yVorticity = new float[_totalCells];
- _zVorticity = new float[_totalCells];
- _h = new float[_totalCells];
- _Precond = new float[_totalCells];
+ _obstacles = new unsigned char[_totalCells]; // set 0 at end of step
// DG TODO: check if alloc went fine
@@ -109,8 +98,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
_densityOld[x] = 0.0f;
_heat[x] = 0.0f;
_heatOld[x] = 0.0f;
- _divergence[x] = 0.0f;
- _pressure[x] = 0.0f;
_xVelocity[x] = 0.0f;
_yVelocity[x] = 0.0f;
_zVelocity[x] = 0.0f;
@@ -120,19 +107,11 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
_xForce[x] = 0.0f;
_yForce[x] = 0.0f;
_zForce[x] = 0.0f;
- _xVorticity[x] = 0.0f;
- _yVorticity[x] = 0.0f;
- _zVorticity[x] = 0.0f;
- _residual[x] = 0.0f;
- _q[x] = 0.0f;
- _direction[x] = 0.0f;
- _h[x] = 0.0f;
- _Precond[x] = 0.0f;
_obstacles[x] = false;
}
// set side obstacles
- int index;
+ size_t index;
for (int y = 0; y < _yRes; y++) // z
for (int x = 0; x < _xRes; x++)
{
@@ -177,8 +156,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
FLUID_3D::~FLUID_3D()
{
- if (_divergence) delete[] _divergence;
- if (_pressure) delete[] _pressure;
if (_xVelocity) delete[] _xVelocity;
if (_yVelocity) delete[] _yVelocity;
if (_zVelocity) delete[] _zVelocity;
@@ -188,23 +165,14 @@ FLUID_3D::~FLUID_3D()
if (_xForce) delete[] _xForce;
if (_yForce) delete[] _yForce;
if (_zForce) delete[] _zForce;
- if (_residual) delete[] _residual;
- if (_direction) delete[] _direction;
- if (_q) delete[] _q;
if (_density) delete[] _density;
if (_densityOld) delete[] _densityOld;
if (_heat) delete[] _heat;
if (_heatOld) delete[] _heatOld;
- if (_xVorticity) delete[] _xVorticity;
- if (_yVorticity) delete[] _yVorticity;
- if (_zVorticity) delete[] _zVorticity;
- if (_vorticity) delete[] _vorticity;
- if (_h) delete[] _h;
- if (_Precond) delete[] _Precond;
if (_obstacles) delete[] _obstacles;
// if (_wTurbulence) delete _wTurbulence;
- printf("deleted fluid\n");
+ // printf("deleted fluid\n");
}
// init direct access functions from blender
@@ -263,6 +231,8 @@ void FLUID_3D::step()
*/
_totalTime += _dt;
_totalSteps++;
+
+ memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes);
}
//////////////////////////////////////////////////////////////////////
@@ -300,7 +270,7 @@ void FLUID_3D::artificialDamping(float* field) {
//////////////////////////////////////////////////////////////////////
void FLUID_3D::copyBorderAll(float* field)
{
- int index;
+ size_t index;
for (int y = 0; y < _yRes; y++)
for (int x = 0; x < _xRes; x++)
{
@@ -367,9 +337,16 @@ void FLUID_3D::addForce()
//////////////////////////////////////////////////////////////////////
void FLUID_3D::project()
{
- int index, x, y, z;
+ int x, y, z;
+ size_t index;
+
+ float *_pressure = new float[_totalCells];
+ float *_divergence = new float[_totalCells];
- setObstacleBoundaries();
+ memset(_pressure, 0, sizeof(float)*_totalCells);
+ memset(_divergence, 0, sizeof(float)*_totalCells);
+
+ setObstacleBoundaries(_pressure);
// copy out the boundaries
if(DOMAIN_BC_LEFT == 0) setNeumannX(_xVelocity, _res);
@@ -414,7 +391,7 @@ void FLUID_3D::project()
// solve Poisson equation
solvePressurePre(_pressure, _divergence, _obstacles);
- setObstaclePressure();
+ setObstaclePressure(_pressure);
// project out solution
float invDx = 1.0f / _dx;
@@ -430,6 +407,9 @@ void FLUID_3D::project()
_zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx;
}
}
+
+ if (_pressure) delete[] _pressure;
+ if (_divergence) delete[] _divergence;
}
//////////////////////////////////////////////////////////////////////
@@ -465,7 +445,7 @@ void FLUID_3D::addObstacle(OBSTACLE* obstacle)
//////////////////////////////////////////////////////////////////////
// calculate the obstacle directional types
//////////////////////////////////////////////////////////////////////
-void FLUID_3D::setObstaclePressure()
+void FLUID_3D::setObstaclePressure(float *_pressure)
{
// tag remaining obstacle blocks
for (int z = 1, index = _slabSize + _xRes + 1;
@@ -539,7 +519,7 @@ void FLUID_3D::setObstaclePressure()
}
}
-void FLUID_3D::setObstacleBoundaries()
+void FLUID_3D::setObstacleBoundaries(float *_pressure)
{
// cull degenerate obstacles , move to addObstacle?
for (int z = 1, index = _slabSize + _xRes + 1;
@@ -600,6 +580,18 @@ void FLUID_3D::addVorticity()
int x,y,z,index;
if(_vorticityEps<=0.) return;
+ float *_xVorticity, *_yVorticity, *_zVorticity, *_vorticity;
+
+ _xVorticity = new float[_totalCells];
+ _yVorticity = new float[_totalCells];
+ _zVorticity = new float[_totalCells];
+ _vorticity = new float[_totalCells];
+
+ memset(_xVorticity, 0, sizeof(float)*_totalCells);
+ memset(_yVorticity, 0, sizeof(float)*_totalCells);
+ memset(_zVorticity, 0, sizeof(float)*_totalCells);
+ memset(_vorticity, 0, sizeof(float)*_totalCells);
+
// calculate vorticity
float gridSize = 0.5f / _dx;
index = _slabSize + _xRes + 1;
@@ -662,6 +654,11 @@ void FLUID_3D::addVorticity()
_zForce[index] += (N[0] * _yVorticity[index] - N[1] * _xVorticity[index]) * _dx * eps;
}
}
+
+ if (_xVorticity) delete[] _xVorticity;
+ if (_yVorticity) delete[] _yVorticity;
+ if (_zVorticity) delete[] _zVorticity;
+ if (_vorticity) delete[] _vorticity;
}
//////////////////////////////////////////////////////////////////////
diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h
index 78a4cf076e3..9d9e7318204 100644
--- a/intern/smoke/intern/FLUID_3D.h
+++ b/intern/smoke/intern/FLUID_3D.h
@@ -64,7 +64,7 @@ class FLUID_3D
// dimensions
int _xRes, _yRes, _zRes, _maxRes;
Vec3Int _res;
- int _totalCells;
+ size_t _totalCells;
int _slabSize;
float _dx;
float _p0[3];
@@ -81,7 +81,6 @@ class FLUID_3D
float* _densityOld;
float* _heat;
float* _heatOld;
- float* _pressure;
float* _xVelocity;
float* _yVelocity;
float* _zVelocity;
@@ -91,19 +90,9 @@ class FLUID_3D
float* _xForce;
float* _yForce;
float* _zForce;
- float* _divergence;
- float* _xVorticity;
- float* _yVorticity;
- float* _zVorticity;
- float* _vorticity;
- float* _h;
- float* _Precond;
unsigned char* _obstacles;
// CG fields
- float* _residual;
- float* _direction;
- float* _q;
int _iterations;
// simulation constants
@@ -134,8 +123,8 @@ class FLUID_3D
void solveHeat(float* field, float* b, unsigned char* skip);
// handle obstacle boundaries
- void setObstacleBoundaries();
- void setObstaclePressure();
+ void setObstacleBoundaries(float *_pressure);
+ void setObstaclePressure(float *_pressure);
public:
// advection, accessed e.g. by WTURBULENCE class
diff --git a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
index a35beaa05d7..7d078d86d61 100644
--- a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
+++ b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
@@ -28,10 +28,17 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
{
int x, y, z;
size_t index;
+ float *_q, *_Precond, *_h, *_residual, *_direction;
// i = 0
int i = 0;
+ _residual = new float[_totalCells]; // set 0
+ _direction = new float[_totalCells]; // set 0
+ _q = new float[_totalCells]; // set 0
+ _h = new float[_totalCells]; // set 0
+ _Precond = new float[_totalCells]; // set 0
+
memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes);
memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes);
memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes);
@@ -191,11 +198,18 @@ void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
i++;
}
// cout << i << " iterations converged to " << sqrt(maxR) << endl;
+
+ if (_h) delete[] _h;
+ if (_Precond) delete[] _Precond;
+ if (_residual) delete[] _residual;
+ if (_direction) delete[] _direction;
+ if (_q) delete[] _q;
}
//////////////////////////////////////////////////////////////////////
// solve the poisson equation with CG
//////////////////////////////////////////////////////////////////////
+#if 0
void FLUID_3D::solvePressure(float* field, float* b, unsigned char* skip)
{
int x, y, z;
@@ -344,6 +358,7 @@ void FLUID_3D::solvePressure(float* field, float* b, unsigned char* skip)
}
// cout << i << " iterations converged to " << maxR << endl;
}
+#endif
//////////////////////////////////////////////////////////////////////
// solve the heat equation with CG
@@ -353,10 +368,15 @@ void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
int x, y, z;
size_t index;
const float heatConst = _dt * _heatDiffusion / (_dx * _dx);
+ float *_q, *_residual, *_direction;
// i = 0
int i = 0;
+ _residual = new float[_totalCells]; // set 0
+ _direction = new float[_totalCells]; // set 0
+ _q = new float[_totalCells]; // set 0
+
memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes);
memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes);
memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes);
@@ -496,5 +516,9 @@ void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
i++;
}
// cout << i << " iterations converged to " << maxR << endl;
+
+ if (_residual) delete[] _residual;
+ if (_direction) delete[] _direction;
+ if (_q) delete[] _q;
}
diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp
index db7a1b55afa..dd092d4f0cc 100644
--- a/intern/smoke/intern/WTURBULENCE.cpp
+++ b/intern/smoke/intern/WTURBULENCE.cpp
@@ -81,25 +81,9 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no
_densityBig = new float[_totalCellsBig];
_densityBigOld = new float[_totalCellsBig];
- // allocate high resolution velocity field. Note that this is only
- // necessary because we use MacCormack advection. For semi-Lagrangian
- // advection, these arrays are not necessary.
- _tempBig1 = _tempBig2 =
- _bigUx = _bigUy = _bigUz = NULL;
- _tempBig1 = new float[_totalCellsBig];
- _tempBig2 = new float[_totalCellsBig];
- _bigUx = new float[_totalCellsBig];
- _bigUy = new float[_totalCellsBig];
- _bigUz = new float[_totalCellsBig];
-
for(int i = 0; i < _totalCellsBig; i++) {
_densityBig[i] =
- _densityBigOld[i] =
- _bigUx[i] =
- _bigUy[i] =
- _bigUz[i] =
- _tempBig1[i] =
- _tempBig2[i] = 0.;
+ _densityBigOld[i] = 0.;
}
// allocate & init texture coordinates
@@ -154,12 +138,6 @@ WTURBULENCE::~WTURBULENCE() {
delete[] _densityBig;
delete[] _densityBigOld;
- delete[] _bigUx;
- delete[] _bigUy;
- delete[] _bigUz;
- delete[] _tempBig1;
- delete[] _tempBig2;
-
delete[] _tcU;
delete[] _tcV;
delete[] _tcW;
@@ -315,7 +293,7 @@ static float minDz(int x, int y, int z, float* input, Vec3Int res)
// handle texture coordinates (advection, reset, eigenvalues),
// Beware -- uses big density maccormack as temporary arrays
//////////////////////////////////////////////////////////////////////
-void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel) {
+void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *_tempBig1, float *_tempBig2) {
// advection
SWAP_POINTERS(_tcTemp, _tcU);
FLUID_3D::copyBorderX(_tcTemp, _resSm);
@@ -602,12 +580,32 @@ Vec3 WTURBULENCE::WVelocityWithJacobian(Vec3 orgPos, float* xUnwarped, float* yU
//////////////////////////////////////////////////////////////////////
void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
{
+ // big velocity macCormack fields
+ float* _bigUx;
+ float* _bigUy;
+ float* _bigUz;
+
+ // temp arrays for BFECC and MacCormack - they have more convenient
+ // names in the actual implementations
+ float* _tempBig1;
+ float* _tempBig2;
+
+ // allocate high resolution velocity field. Note that this is only
+ // necessary because we use MacCormack advection. For semi-Lagrangian
+ // advection, these arrays are not necessary.
+ _tempBig1 = new float[_totalCellsBig];
+ _tempBig2 = new float[_totalCellsBig];
+
// enlarge timestep to match grid
const float dt = dtOrg * _amplify;
const float invAmp = 1.0f / _amplify;
+ _bigUx = new float[_totalCellsBig];
+ _bigUy = new float[_totalCellsBig];
+ _bigUz = new float[_totalCellsBig];
+
// prepare textures
- advectTextureCoordinates(dtOrg, xvel,yvel,zvel);
+ advectTextureCoordinates(dtOrg, xvel,yvel,zvel, _tempBig1, _tempBig2);
// compute eigenvalues of the texture coordinates
computeEigenvalues();
@@ -744,6 +742,13 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel,
IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
*/
_totalStepsBig++;
+
+ delete[] _bigUx;
+ delete[] _bigUy;
+ delete[] _bigUz;
+
+ delete[] _tempBig1;
+ delete[] _tempBig2;
}
//////////////////////////////////////////////////////////////////////
@@ -752,225 +757,257 @@ void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel,
//////////////////////////////////////////////////////////////////////
void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
{
- // enlarge timestep to match grid
- const float dt = dtOrg * _amplify;
- const float invAmp = 1.0f / _amplify;
+ // big velocity macCormack fields
+ float* _bigUx;
+ float* _bigUy;
+ float* _bigUz;
- // prepare textures
- advectTextureCoordinates(dtOrg, xvel,yvel,zvel);
+ // temp arrays for BFECC and MacCormack - they have more convenient
+ // names in the actual implementations
+ float* _tempBig1;
+ float* _tempBig2;
- // do wavelet decomposition of energy
- computeEnergy(xvel, yvel, zvel, obstacles);
- decomposeEnergy();
+ // allocate high resolution velocity field. Note that this is only
+ // necessary because we use MacCormack advection. For semi-Lagrangian
+ // advection, these arrays are not necessary.
+ _tempBig1 = new float[_totalCellsBig];
+ _tempBig2 = new float[_totalCellsBig];
- // zero out coefficients inside of the obstacle
- for (int x = 0; x < _totalCellsSm; x++)
- if (obstacles[x]) _energy[x] = 0.f;
+ // enlarge timestep to match grid
+ const float dt = dtOrg * _amplify;
+ const float invAmp = 1.0f / _amplify;
- // parallel region setup
- float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. };
-#if PARALLEL==1
-#pragma omp parallel
-#endif
- { float maxVelMag1 = 0.;
-#if PARALLEL==1
- const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */
-#endif
+ _bigUx = new float[_totalCellsBig];
+ _bigUy = new float[_totalCellsBig];
+ _bigUz = new float[_totalCellsBig];
- // vector noise main loop
-#if PARALLEL==1
-#pragma omp for schedule(static)
-#endif
- for (int zSmall = 0; zSmall < _zResSm; zSmall++)
- for (int ySmall = 0; ySmall < _yResSm; ySmall++)
- for (int xSmall = 0; xSmall < _xResSm; xSmall++)
- {
- const int indexSmall = xSmall + ySmall * _xResSm + zSmall * _slabSizeSm;
-
- // compute jacobian
- float jacobian[3][3] = {
- { minDx(xSmall, ySmall, zSmall, _tcU, _resSm), minDx(xSmall, ySmall, zSmall, _tcV, _resSm), minDx(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
- { minDy(xSmall, ySmall, zSmall, _tcU, _resSm), minDy(xSmall, ySmall, zSmall, _tcV, _resSm), minDy(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
- { minDz(xSmall, ySmall, zSmall, _tcU, _resSm), minDz(xSmall, ySmall, zSmall, _tcV, _resSm), minDz(xSmall, ySmall, zSmall, _tcW, _resSm) }
- };
-
- // get LU factorization of texture jacobian and apply
- // it to unit vectors
- JAMA::LU<float> LU = computeLU3x3(jacobian);
- float xUnwarped[] = {1.0f, 0.0f, 0.0f};
- float yUnwarped[] = {0.0f, 1.0f, 0.0f};
- float zUnwarped[] = {0.0f, 0.0f, 1.0f};
- float xWarped[] = {1.0f, 0.0f, 0.0f};
- float yWarped[] = {0.0f, 1.0f, 0.0f};
- float zWarped[] = {0.0f, 0.0f, 1.0f};
- bool nonSingular = LU.isNonsingular();
-#if 0
- // UNUSED
- float eigMax = 10.0f;
- float eigMin = 0.1f;
-#endif
- if (nonSingular)
- {
- solveLU3x3(LU, xUnwarped, xWarped);
- solveLU3x3(LU, yUnwarped, yWarped);
- solveLU3x3(LU, zUnwarped, zWarped);
-
- // compute the eigenvalues while we have the Jacobian available
- Vec3 eigenvalues = Vec3(1.);
- computeEigenvalues3x3( &eigenvalues[0], jacobian);
- _eigMax[indexSmall] = MAX3V(eigenvalues);
- _eigMin[indexSmall] = MIN3V(eigenvalues);
- }
-
- // make sure to skip one on the beginning and end
- int xStart = (xSmall == 0) ? 1 : 0;
- int xEnd = (xSmall == _xResSm - 1) ? _amplify - 1 : _amplify;
- int yStart = (ySmall == 0) ? 1 : 0;
- int yEnd = (ySmall == _yResSm - 1) ? _amplify - 1 : _amplify;
- int zStart = (zSmall == 0) ? 1 : 0;
- int zEnd = (zSmall == _zResSm - 1) ? _amplify - 1 : _amplify;
-
- for (int zBig = zStart; zBig < zEnd; zBig++)
- for (int yBig = yStart; yBig < yEnd; yBig++)
- for (int xBig = xStart; xBig < xEnd; xBig++)
- {
- const int x = xSmall * _amplify + xBig;
- const int y = ySmall * _amplify + yBig;
- const int z = zSmall * _amplify + zBig;
-
- // get unit position for both fine and coarse grid
- const Vec3 pos = Vec3(x,y,z);
- const Vec3 posSm = pos * invAmp;
-
- // get grid index for both fine and coarse grid
- const int index = x + y *_xResBig + z *_slabSizeBig;
-
- // get a linearly interpolated velocity and texcoords
- // from the coarse grid
- Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel,
- posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
- Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW,
- posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
-
- // multiply the texture coordinate by _resSm so that turbulence
- // synthesis begins at the first octave that the coarse grid
- // cannot capture
- Vec3 texCoord = Vec3(uvw[0] * _resSm[0],
- uvw[1] * _resSm[1],
- uvw[2] * _resSm[2]);
-
- // retrieve wavelet energy at highest frequency
- float energy = INTERPOLATE::lerp3d(
- _highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm);
-
- // base amplitude for octave 0
- float coefficient = sqrtf(2.0f * fabs(energy));
- const float amplitude = *_strength * fabs(0.5 * coefficient) * persistence;
-
- // add noise to velocity, but only if the turbulence is
- // sufficiently undeformed, and the energy is large enough
- // to make a difference
- const bool addNoise = _eigMax[indexSmall] < 2. &&
- _eigMin[indexSmall] > 0.5;
- if (addNoise && amplitude > _cullingThreshold) {
- // base amplitude for octave 0
- float amplitudeScaled = amplitude;
+ // prepare textures
+ advectTextureCoordinates(dtOrg, xvel,yvel,zvel, _tempBig1, _tempBig2);
+
+ // do wavelet decomposition of energy
+ computeEnergy(xvel, yvel, zvel, obstacles);
+ decomposeEnergy();
+
+ // zero out coefficients inside of the obstacle
+ for (int x = 0; x < _totalCellsSm; x++)
+ if (obstacles[x]) _energy[x] = 0.f;
+
+ // parallel region setup
+ float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. };
+
+ #if PARALLEL==1
+ #pragma omp parallel
+ #endif
+ { float maxVelMag1 = 0.;
+ #if PARALLEL==1
+ const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */
+ #endif
+
+ // vector noise main loop
+ #if PARALLEL==1
+ #pragma omp for schedule(static)
+ #endif
+ for (int zSmall = 0; zSmall < _zResSm; zSmall++)
+ for (int ySmall = 0; ySmall < _yResSm; ySmall++)
+ for (int xSmall = 0; xSmall < _xResSm; xSmall++)
+ {
+ const int indexSmall = xSmall + ySmall * _xResSm + zSmall * _slabSizeSm;
+
+ // compute jacobian
+ float jacobian[3][3] = {
+ { minDx(xSmall, ySmall, zSmall, _tcU, _resSm), minDx(xSmall, ySmall, zSmall, _tcV, _resSm), minDx(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
+ { minDy(xSmall, ySmall, zSmall, _tcU, _resSm), minDy(xSmall, ySmall, zSmall, _tcV, _resSm), minDy(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
+ { minDz(xSmall, ySmall, zSmall, _tcU, _resSm), minDz(xSmall, ySmall, zSmall, _tcV, _resSm), minDz(xSmall, ySmall, zSmall, _tcW, _resSm) }
+ };
+
+ // get LU factorization of texture jacobian and apply
+ // it to unit vectors
+ JAMA::LU<float> LU = computeLU3x3(jacobian);
+ float xUnwarped[] = {1.0f, 0.0f, 0.0f};
+ float yUnwarped[] = {0.0f, 1.0f, 0.0f};
+ float zUnwarped[] = {0.0f, 0.0f, 1.0f};
+ float xWarped[] = {1.0f, 0.0f, 0.0f};
+ float yWarped[] = {0.0f, 1.0f, 0.0f};
+ float zWarped[] = {0.0f, 0.0f, 1.0f};
+ bool nonSingular = LU.isNonsingular();
+
+ #if 0
+ // UNUSED
+ float eigMax = 10.0f;
+ float eigMin = 0.1f;
+ #endif
- for (int octave = 0; octave < _octaves; octave++)
- {
- // multiply the vector noise times the maximum allowed
- // noise amplitude at this octave, and add it to the total
- vel += WVelocityWithJacobian(texCoord, &xUnwarped[0], &yUnwarped[0], &zUnwarped[0]) * amplitudeScaled;
+ if (nonSingular)
+ {
+ solveLU3x3(LU, xUnwarped, xWarped);
+ solveLU3x3(LU, yUnwarped, yWarped);
+ solveLU3x3(LU, zUnwarped, zWarped);
+
+ // compute the eigenvalues while we have the Jacobian available
+ Vec3 eigenvalues = Vec3(1.);
+ computeEigenvalues3x3( &eigenvalues[0], jacobian);
+ _eigMax[indexSmall] = MAX3V(eigenvalues);
+ _eigMin[indexSmall] = MIN3V(eigenvalues);
+ }
- // scale coefficient for next octave
- amplitudeScaled *= persistence;
- texCoord *= 2.0f;
- }
- }
+ // make sure to skip one on the beginning and end
+ int xStart = (xSmall == 0) ? 1 : 0;
+ int xEnd = (xSmall == _xResSm - 1) ? _amplify - 1 : _amplify;
+ int yStart = (ySmall == 0) ? 1 : 0;
+ int yEnd = (ySmall == _yResSm - 1) ? _amplify - 1 : _amplify;
+ int zStart = (zSmall == 0) ? 1 : 0;
+ int zEnd = (zSmall == _zResSm - 1) ? _amplify - 1 : _amplify;
+
+ for (int zBig = zStart; zBig < zEnd; zBig++)
+ for (int yBig = yStart; yBig < yEnd; yBig++)
+ for (int xBig = xStart; xBig < xEnd; xBig++)
+ {
+ const int x = xSmall * _amplify + xBig;
+ const int y = ySmall * _amplify + yBig;
+ const int z = zSmall * _amplify + zBig;
+
+ // get unit position for both fine and coarse grid
+ const Vec3 pos = Vec3(x,y,z);
+ const Vec3 posSm = pos * invAmp;
+
+ // get grid index for both fine and coarse grid
+ const int index = x + y *_xResBig + z *_slabSizeBig;
+
+ // get a linearly interpolated velocity and texcoords
+ // from the coarse grid
+ Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel,
+ posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
+ Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW,
+ posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
+
+ // multiply the texture coordinate by _resSm so that turbulence
+ // synthesis begins at the first octave that the coarse grid
+ // cannot capture
+ Vec3 texCoord = Vec3(uvw[0] * _resSm[0],
+ uvw[1] * _resSm[1],
+ uvw[2] * _resSm[2]);
+
+ // retrieve wavelet energy at highest frequency
+ float energy = INTERPOLATE::lerp3d(
+ _highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm);
+
+ // base amplitude for octave 0
+ float coefficient = sqrtf(2.0f * fabs(energy));
+ const float amplitude = *_strength * fabs(0.5 * coefficient) * persistence;
+
+ // add noise to velocity, but only if the turbulence is
+ // sufficiently undeformed, and the energy is large enough
+ // to make a difference
+ const bool addNoise = _eigMax[indexSmall] < 2. &&
+ _eigMin[indexSmall] > 0.5;
+
+ if (addNoise && amplitude > _cullingThreshold) {
+ // base amplitude for octave 0
+ float amplitudeScaled = amplitude;
+
+ for (int octave = 0; octave < _octaves; octave++)
+ {
+ // multiply the vector noise times the maximum allowed
+ // noise amplitude at this octave, and add it to the total
+ vel += WVelocityWithJacobian(texCoord, &xUnwarped[0], &yUnwarped[0], &zUnwarped[0]) * amplitudeScaled;
+
+ // scale coefficient for next octave
+ amplitudeScaled *= persistence;
+ texCoord *= 2.0f;
+ }
+ }
+
+ // Store velocity + turbulence in big grid for maccormack step
+ //
+ // If you wanted to save memory, you would instead perform a
+ // semi-Lagrangian backtrace for the current grid cell here. Then
+ // you could just throw the velocity away.
+ _bigUx[index] = vel[0];
+ _bigUy[index] = vel[1];
+ _bigUz[index] = vel[2];
+
+ // compute the velocity magnitude for substepping later
+ const float velMag = _bigUx[index] * _bigUx[index] +
+ _bigUy[index] * _bigUy[index] +
+ _bigUz[index] * _bigUz[index];
+ if (velMag > maxVelMag1) maxVelMag1 = velMag;
+
+ // zero out velocity inside obstacles
+ float obsCheck = INTERPOLATE::lerp3dToFloat(
+ obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
+
+ if (obsCheck > 0.95)
+ _bigUx[index] = _bigUy[index] = _bigUz[index] = 0.;
+ } // xyz
+
+ #if PARALLEL==1
+ maxVelMagThreads[id] = maxVelMag1;
+ #else
+ maxVelMagThreads[0] = maxVelMag1;
+ #endif
+ }
+ } // omp
+
+ // compute maximum over threads
+ float maxVelMag = maxVelMagThreads[0];
+ #if PARALLEL==1
+ for (int i = 1; i < 8; i++)
+ if (maxVelMag < maxVelMagThreads[i])
+ maxVelMag = maxVelMagThreads[i];
+ #endif
+
+ // prepare density for an advection
+ SWAP_POINTERS(_densityBig, _densityBigOld);
+
+ // based on the maximum velocity present, see if we need to substep,
+ // but cap the maximum number of substeps to 5
+ const int maxSubSteps = 25;
+ const int maxVel = 5;
+ maxVelMag = sqrt(maxVelMag) * dt;
+ int totalSubsteps = (int)(maxVelMag / (float)maxVel);
+ totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
+ // printf("totalSubsteps: %d\n", totalSubsteps);
+ totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
+ const float dtSubdiv = dt / (float)totalSubsteps;
+
+ // set boundaries of big velocity grid
+ FLUID_3D::setZeroX(_bigUx, _resBig);
+ FLUID_3D::setZeroY(_bigUy, _resBig);
+ FLUID_3D::setZeroZ(_bigUz, _resBig);
+
+ // do the MacCormack advection, with substepping if necessary
+ for(int substep = 0; substep < totalSubsteps; substep++)
+ {
+ FLUID_3D::advectFieldMacCormack(dtSubdiv, _bigUx, _bigUy, _bigUz,
+ _densityBigOld, _densityBig, _tempBig1, _tempBig2, _resBig, NULL);
- // Store velocity + turbulence in big grid for maccormack step
- //
- // If you wanted to save memory, you would instead perform a
- // semi-Lagrangian backtrace for the current grid cell here. Then
- // you could just throw the velocity away.
- _bigUx[index] = vel[0];
- _bigUy[index] = vel[1];
- _bigUz[index] = vel[2];
-
- // compute the velocity magnitude for substepping later
- const float velMag = _bigUx[index] * _bigUx[index] +
- _bigUy[index] * _bigUy[index] +
- _bigUz[index] * _bigUz[index];
- if (velMag > maxVelMag1) maxVelMag1 = velMag;
-
- // zero out velocity inside obstacles
- float obsCheck = INTERPOLATE::lerp3dToFloat(
- obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
- if (obsCheck > 0.95)
- _bigUx[index] = _bigUy[index] = _bigUz[index] = 0.;
- } // xyz
+ if (substep < totalSubsteps - 1)
+ SWAP_POINTERS(_densityBig, _densityBigOld);
+ } // substep
-#if PARALLEL==1
- maxVelMagThreads[id] = maxVelMag1;
-#else
- maxVelMagThreads[0] = maxVelMag1;
-#endif
- }
- } // omp
-
- // compute maximum over threads
- float maxVelMag = maxVelMagThreads[0];
-#if PARALLEL==1
- for (int i = 1; i < 8; i++)
- if (maxVelMag < maxVelMagThreads[i])
- maxVelMag = maxVelMagThreads[i];
-#endif
+ // wipe the density borders
+ FLUID_3D::setZeroBorder(_densityBig, _resBig);
- // prepare density for an advection
- SWAP_POINTERS(_densityBig, _densityBigOld);
+ // reset texture coordinates now in preparation for next timestep
+ // Shouldn't do this before generating the noise because then the
+ // eigenvalues stored do not reflect the underlying texture coordinates
+ resetTextureCoordinates();
- // based on the maximum velocity present, see if we need to substep,
- // but cap the maximum number of substeps to 5
- const int maxSubSteps = 25;
- const int maxVel = 5;
- maxVelMag = sqrt(maxVelMag) * dt;
- int totalSubsteps = (int)(maxVelMag / (float)maxVel);
- totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
- // printf("totalSubsteps: %d\n", totalSubsteps);
- totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
- const float dtSubdiv = dt / (float)totalSubsteps;
+ // output files
+ // string prefix = string("./amplified.preview/density_bigxy_");
+ // FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f);
+ //string df3prefix = string("./df3/density_big_");
+ //IMAGE::dumpDF3(_totalStepsBig, df3prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
+ // string pbrtPrefix = string("./pbrt/density_big_");
+ // IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
- // set boundaries of big velocity grid
- FLUID_3D::setZeroX(_bigUx, _resBig);
- FLUID_3D::setZeroY(_bigUy, _resBig);
- FLUID_3D::setZeroZ(_bigUz, _resBig);
+ _totalStepsBig++;
- // do the MacCormack advection, with substepping if necessary
- for(int substep = 0; substep < totalSubsteps; substep++)
- {
- FLUID_3D::advectFieldMacCormack(dtSubdiv, _bigUx, _bigUy, _bigUz,
- _densityBigOld, _densityBig, _tempBig1, _tempBig2, _resBig, NULL);
+ delete[] _bigUx;
+ delete[] _bigUy;
+ delete[] _bigUz;
- if (substep < totalSubsteps - 1)
- SWAP_POINTERS(_densityBig, _densityBigOld);
- } // substep
-
- // wipe the density borders
- FLUID_3D::setZeroBorder(_densityBig, _resBig);
-
- // reset texture coordinates now in preparation for next timestep
- // Shouldn't do this before generating the noise because then the
- // eigenvalues stored do not reflect the underlying texture coordinates
- resetTextureCoordinates();
-
- // output files
- // string prefix = string("./amplified.preview/density_bigxy_");
- // FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f);
- //string df3prefix = string("./df3/density_big_");
- //IMAGE::dumpDF3(_totalStepsBig, df3prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
- // string pbrtPrefix = string("./pbrt/density_big_");
- // IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
-
- _totalStepsBig++;
+ delete[] _tempBig1;
+ delete[] _tempBig2;
}
diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h
index d4e6b0c6a17..c21e002ad48 100644
--- a/intern/smoke/intern/WTURBULENCE.h
+++ b/intern/smoke/intern/WTURBULENCE.h
@@ -49,7 +49,7 @@ class WTURBULENCE
void stepTurbulenceFull(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
// texcoord functions
- void advectTextureCoordinates(float dtOrg, float* xvel, float* yvel, float* zvel);
+ void advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *_tempBig1, float *_tempBig2);
void resetTextureCoordinates();
void computeEnergy(float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
@@ -73,7 +73,7 @@ class WTURBULENCE
// is accessed on through rna gui
float *_strength;
- protected:
+ // protected:
// enlargement factor from original velocity field / simulation
// _Big = _amplify * _Sm
int _amplify;
@@ -111,26 +111,17 @@ class WTURBULENCE
float* _densityBig;
float* _densityBigOld;
- // big velocity macCormack fields
- float* _bigUx;
- float* _bigUy;
- float* _bigUz;
- // temp arrays for BFECC and MacCormack - they have more convenient
- // names in the actual implementations
- float* _tempBig1;
- float* _tempBig2;
-
// texture coordinates for noise
float* _tcU;
float* _tcV;
float* _tcW;
float* _tcTemp;
- float* _eigMin;
- float* _eigMax;
+ float* _eigMin; // no save -dg
+ float* _eigMax; // no save -dg
// wavelet decomposition of velocity energies
- float* _energy;
+ float* _energy; // no save -dg
// noise data
float* _noiseTile;
@@ -140,7 +131,7 @@ class WTURBULENCE
int _totalStepsBig;
// highest frequency component of wavelet decomposition
- float* _highFreqEnergy;
+ float* _highFreqEnergy; // no save -dg
void computeEigenvalues();
void decomposeEnergy();
diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp
index 2e95a576eaf..5a016b51bbe 100644
--- a/intern/smoke/intern/smoke_API.cpp
+++ b/intern/smoke/intern/smoke_API.cpp
@@ -20,7 +20,7 @@
* The Original Code is Copyright (C) 2009 by Daniel Genrich
* All rights reserved.
*
- * Contributor(s): None
+ * Contributor(s): Daniel Genrich
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -137,7 +137,7 @@ extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
}
}
-extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
+extern "C" void smoke_turbulence_dissolve(WTURBULENCE *wt, int speed, int log)
{
float *density = wt->getDensityBig();
Vec3Int r = wt->getResBig();
@@ -172,7 +172,7 @@ extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
}
}
-extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
+extern "C" void smoke_turbulence_initBlenderRNA(WTURBULENCE *wt, float *strength)
{
wt->initBlenderRNA(strength);
}
@@ -181,6 +181,36 @@ template < class T > inline T ABS( T a ) {
return (0 < a) ? a : -a ;
}
+extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles)
+{
+ *dens = fluid->_density;
+ *densold = fluid->_densityOld;
+ *heat = fluid->_heat;
+ *heatold = fluid->_heatOld;
+ *vx = fluid->_xVelocity;
+ *vy = fluid->_yVelocity;
+ *vz = fluid->_zVelocity;
+ *vxold = fluid->_xVelocityOld;
+ *vyold = fluid->_yVelocityOld;
+ *vzold = fluid->_zVelocityOld;
+ *obstacles = fluid->_obstacles;
+ dt = &(fluid->_dt);
+ dx = &(fluid->_dx);
+
+}
+
+extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw)
+{
+ if(!wt)
+ return;
+
+ *dens = wt->_densityBig;
+ *densold = wt->_densityBigOld;
+ *tcu = wt->_tcU;
+ *tcv = wt->_tcV;
+ *tcw = wt->_tcW;
+}
+
extern "C" float *smoke_get_density(FLUID_3D *fluid)
{
return fluid->_density;
@@ -193,17 +223,17 @@ extern "C" float *smoke_get_heat(FLUID_3D *fluid)
extern "C" float *smoke_get_velocity_x(FLUID_3D *fluid)
{
- return fluid->_xVorticity;
+ return fluid->_xVelocity;
}
extern "C" float *smoke_get_velocity_y(FLUID_3D *fluid)
{
- return fluid->_yVorticity;
+ return fluid->_yVelocity;
}
extern "C" float *smoke_get_velocity_z(FLUID_3D *fluid)
{
- return fluid->_zVorticity;
+ return fluid->_zVelocity;
}
extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
@@ -211,14 +241,13 @@ extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
return wt ? wt->getDensityBig() : NULL;
}
-extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res)
+extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, unsigned int *res)
{
if(wt)
{
- Vec3Int r = wt->getResBig();
- res[0] = r[0];
- res[1] = r[1];
- res[2] = r[2];
+ res[0] = wt->_resBig[0];
+ res[1] = wt->_resBig[1];
+ res[2] = wt->_resBig[2];
}
}
diff --git a/release/ui/buttons_physics_smoke.py b/release/ui/buttons_physics_smoke.py
index 7e2395216c0..d187e4c5901 100644
--- a/release/ui/buttons_physics_smoke.py
+++ b/release/ui/buttons_physics_smoke.py
@@ -1,6 +1,11 @@
import bpy
+def smoke_panel_enabled_low(smd):
+ if smd.smoke_type == 'TYPE_DOMAIN':
+ return smd.domain.point_cache.baked==False
+ return True
+
class PhysicButtonsPanel(bpy.types.Panel):
__space_type__ = "PROPERTIES"
__region_type__ = "WINDOW"
@@ -38,6 +43,8 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel):
split.itemL()
if md:
+
+ # layout.enabled = smoke_panel_enabled(md)
layout.itemR(md, "smoke_type", expand=True)
if md.smoke_type == 'TYPE_DOMAIN':
@@ -49,13 +56,6 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel):
col = split.column()
col.itemL(text="Resolution:")
col.itemR(domain, "maxres", text="Divisions")
-
- col.itemL(text="Display:")
- col.itemR(domain, "visibility", text="Resolution")
- col.itemR(domain, "color", slider=True)
- sub = col.column()
- sub.active = domain.highres
- sub.itemR(domain, "viewhighres")
col = split.column()
col.itemL(text="Behavior:")
@@ -88,9 +88,9 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel):
#elif md.smoke_type == 'TYPE_COLL':
# layout.itemS()
-
-class PHYSICS_PT_smoke_highres(PhysicButtonsPanel):
- __label__ = "Smoke High Resolution"
+
+class PHYSICS_PT_smoke_groups(PhysicButtonsPanel):
+ __label__ = "Smoke Groups"
__default_closed__ = True
def poll(self, context):
@@ -100,33 +100,89 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel):
return False
- def draw_header(self, context):
- layout = self.layout
-
- high = context.smoke.domain_settings
-
- layout.itemR(high, "highres", text="")
-
def draw(self, context):
layout = self.layout
- high = context.smoke.domain_settings
-
- layout.active = high.highres
+ group = context.smoke.domain_settings
split = layout.split()
col = split.column()
- col.itemL(text="Resolution:")
- col.itemR(high, "amplify", text="Divisions")
+ col.itemL(text="Flow Group:")
+ col.itemR(group, "fluid_group", text="")
+
+ #col.itemL(text="Effector Group:")
+ #col.itemR(group, "eff_group", text="")
+
+ col = split.column()
+ col.itemL(text="Collision Group:")
+ col.itemR(group, "coll_group", text="")
+
+class PHYSICS_PT_smoke_cache(PhysicButtonsPanel):
+ __label__ = "Smoke Cache"
+ __default_closed__ = True
+
+ def poll(self, context):
+ md = context.smoke
+ if md:
+ return (md.smoke_type == 'TYPE_DOMAIN')
+
+ return False
+
+ def draw(self, context):
+ layout = self.layout
+
+ md = context.smoke
- sub = split.column()
- sub.itemL(text="Noise Method:")
- sub.row().itemR(high, "noise_type", text="")
- sub.itemR(high, "strength")
+ if md.smoke_type == 'TYPE_DOMAIN':
-class PHYSICS_PT_smoke_groups(PhysicButtonsPanel):
- __label__ = "Smoke Groups"
+ domain = md.domain_settings
+ cache = domain.point_cache
+
+ layout.set_context_pointer("PointCache", cache)
+
+ row = layout.row()
+ row.template_list(cache, "point_cache_list", cache, "active_point_cache_index")
+ col = row.column(align=True)
+ col.itemO("ptcache.add_new", icon="ICON_ZOOMIN", text="")
+ col.itemO("ptcache.remove", icon="ICON_ZOOMOUT", text="")
+
+ row = layout.row()
+ row.itemR(cache, "name")
+
+ row = layout.row()
+ row.itemR(cache, "start_frame")
+ row.itemR(cache, "end_frame")
+
+ row = layout.row()
+
+ if cache.baked == True:
+ row.itemO("ptcache.free_bake", text="Free Bake")
+ else:
+ row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
+
+ subrow = row.row()
+ subrow.enabled = cache.frames_skipped or cache.outdated
+ subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
+
+ row = layout.row()
+ #row.enabled = smoke_panel_enabled(psys)
+ row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
+
+ row = layout.row()
+ #row.enabled = smoke_panel_enabled(psys)
+
+ layout.itemL(text=cache.info)
+
+ layout.itemS()
+
+ row = layout.row()
+ row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
+ row.itemO("ptcache.free_bake_all", text="Free All Bakes")
+ layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
+
+class PHYSICS_PT_smoke_highres(PhysicButtonsPanel):
+ __label__ = "Smoke High Resolution"
__default_closed__ = True
def poll(self, context):
@@ -136,24 +192,93 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel):
return False
+ def draw_header(self, context):
+ layout = self.layout
+
+ high = context.smoke.domain_settings
+
+ layout.itemR(high, "highres", text="")
+
def draw(self, context):
layout = self.layout
- group = context.smoke.domain_settings
+ md = context.smoke_hr
- split = layout.split()
+ if md:
- col = split.column()
- col.itemL(text="Flow Group:")
- col.itemR(group, "fluid_group", text="")
-
- #col.itemL(text="Effector Group:")
- #col.itemR(group, "eff_group", text="")
+ split = layout.split()
+
+ col = split.column()
+ col.itemL(text="Resolution:")
+ col.itemR(md, "amplify", text="Divisions")
+
+ sub = split.column()
+ sub.itemL(text="Noise Method:")
+ sub.row().itemR(md, "noise_type", text="")
+ sub.itemR(md, "strength")
+ sub.itemR(md, "show_highres")
+
+class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel):
+ __label__ = "Smoke Cache"
+ __default_closed__ = True
+
+ def poll(self, context):
+ return (context.smoke_hr != None)
+
+ def draw(self, context):
+ layout = self.layout
+
+ md = context.smoke_hr
+
+ if md:
+
+ cache = md.point_cache
+
+ layout.set_context_pointer("PointCache", cache)
+
+ row = layout.row()
+ row.template_list(cache, "point_cache_list", cache, "active_point_cache_index")
+ col = row.column(align=True)
+ col.itemO("ptcache.add_new", icon="ICON_ZOOMIN", text="")
+ col.itemO("ptcache.remove", icon="ICON_ZOOMOUT", text="")
+
+ row = layout.row()
+ row.itemR(cache, "name")
+
+ row = layout.row()
+ row.itemR(cache, "start_frame")
+ row.itemR(cache, "end_frame")
+
+ row = layout.row()
+
+ if cache.baked == True:
+ row.itemO("ptcache.free_bake", text="Free Bake")
+ else:
+ row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
+
+ subrow = row.row()
+ subrow.enabled = cache.frames_skipped or cache.outdated
+ subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
- col = split.column()
- col.itemL(text="Collision Group:")
- col.itemR(group, "coll_group", text="")
+ row = layout.row()
+ #row.enabled = smoke_panel_enabled(psys)
+ row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
+
+ row = layout.row()
+ #row.enabled = smoke_panel_enabled(psys)
+
+ layout.itemL(text=cache.info)
+
+ layout.itemS()
+
+ row = layout.row()
+ row.itemO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
+ row.itemO("ptcache.free_bake_all", text="Free All Bakes")
+ layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
+
bpy.types.register(PHYSICS_PT_smoke)
-bpy.types.register(PHYSICS_PT_smoke_highres)
+bpy.types.register(PHYSICS_PT_smoke_cache)
bpy.types.register(PHYSICS_PT_smoke_groups)
+#bpy.types.register(PHYSICS_PT_smoke_highres)
+#bpy.types.register(PHYSICS_PT_smoke_cache_highres)
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 5d9dddfe30d..531487549da 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -60,8 +60,8 @@
#define PTCACHE_TYPE_SOFTBODY 0
#define PTCACHE_TYPE_PARTICLES 1
#define PTCACHE_TYPE_CLOTH 2
-#define PTCACHE_TYPE_SMOKE_DOMAIN_LOW 3
-#define PTCACHE_TYPE_SMOKE_DOMAIN_HIGH 4
+#define PTCACHE_TYPE_SMOKE_DOMAIN 3
+#define PTCACHE_TYPE_SMOKE_HIGHRES 4
/* PTCache read return code */
#define PTCACHE_READ_EXACT 1
@@ -158,7 +158,7 @@ void BKE_ptcache_make_particle_key(struct ParticleKey *key, int index, void **da
void BKE_ptcache_id_from_softbody(PTCacheID *pid, struct Object *ob, struct SoftBody *sb);
void BKE_ptcache_id_from_particles(PTCacheID *pid, struct Object *ob, struct ParticleSystem *psys);
void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd);
-void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd, int num);
+void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd);
void BKE_ptcache_ids_from_object(struct ListBase *lb, struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h
index 8dc38640e9a..bd8581112f8 100644
--- a/source/blender/blenkernel/BKE_smoke.h
+++ b/source/blender/blenkernel/BKE_smoke.h
@@ -32,24 +32,17 @@
#ifndef BKE_SMOKE_H_
#define BKE_SMOKE_H_
+typedef int (*bresenham_callback) (float *input, int res[3], int *pixel, float *tRay);
+
void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
void smokeModifier_free (struct SmokeModifierData *smd);
void smokeModifier_reset(struct SmokeModifierData *smd);
void smokeModifier_createType(struct SmokeModifierData *smd);
-void smoke_set_tray(struct SmokeModifierData *smd, size_t index, float transparency);
-float smoke_get_tray(struct SmokeModifierData *smd, size_t index);
-float smoke_get_tvox(struct SmokeModifierData *smd, size_t index);
-void smoke_set_tvox(struct SmokeModifierData *smd, size_t index, float tvox);
-
-void smoke_set_bigtray(struct SmokeModifierData *smd, size_t index, float transparency);
-float smoke_get_bigtray(struct SmokeModifierData *smd, size_t index);
-float smoke_get_bigtvox(struct SmokeModifierData *smd, size_t index);
-void smoke_set_bigtvox(struct SmokeModifierData *smd, size_t index, float tvox);
+// high res modifier
+void smokeHRModifier_do(struct SmokeHRModifierData *shrmd, struct Scene *scene, struct Object *ob, int useRenderParams, int isFinalCalc);
+void smokeHRModifier_free(struct SmokeHRModifierData *shrmd);
-long long smoke_get_mem_req(int xres, int yres, int zres, int amplify);
-void smoke_prepare_View(struct SmokeModifierData *smd, float *light);
-void smoke_prepare_bigView(struct SmokeModifierData *smd, float *light);
#endif /* BKE_SMOKE_H_ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 8d1df98c5b4..17079205423 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -34,6 +34,8 @@ SET(INC
../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern
../../../intern/bsp/extern ../blenfont
../../../intern/audaspace/intern
+ ../../../extern/lzo/minilzo
+ ../../../extern/lzma
${ZLIB_INC}
)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index fdc7782a0b1..0c7922de6ff 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -11,6 +11,8 @@ incs += ' #/extern/bullet2/src'
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
incs += ' ../gpu #/extern/glew/include'
incs += ' #/intern/smoke/extern'
+incs += ' #/extern/lzo/minilzo'
+incs += ' #/extern/lzma'
incs += ' #/intern/audaspace/intern'
incs += ' ' + env['BF_OPENGL_INC']
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 53d1baa5c9c..1e2560bf809 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -5801,26 +5801,6 @@ static void smokeModifier_initData(ModifierData *md)
smd->coll = NULL;
smd->type = 0;
smd->time = -1;
-
- /*
- smd->fluid = NULL;
- smd->maxres = 48;
- smd->amplify = 4;
- smd->omega = 0.5;
- smd->time = 0;
- smd->flags = 0;
- smd->noise = MOD_SMOKE_NOISEWAVE;
- smd->visibility = 1;
-
- // init 3dview buffer
- smd->tvox = NULL;
- smd->tray = NULL;
- smd->tvoxbig = NULL;
- smd->traybig = NULL;
- smd->viewsettings = 0;
- smd->bind = NULL;
- smd->max_textures = 0;
- */
}
static void smokeModifier_freeData(ModifierData *md)
@@ -5884,6 +5864,50 @@ static void smokeModifier_updateDepgraph(
*/
}
+
+/* Smoke High Resolution */
+
+static void smokeHRModifier_initData(ModifierData *md)
+{
+ SmokeHRModifierData *shrmd = (SmokeHRModifierData*) md;
+
+ shrmd->wt = NULL;
+ shrmd->time = -1;
+ shrmd->strength = 2.0f;
+ shrmd->amplify = 1;
+ shrmd->noise = MOD_SMOKE_NOISEWAVE;
+ shrmd->point_cache = BKE_ptcache_add(&shrmd->ptcaches);
+ shrmd->point_cache->flag |= PTCACHE_DISK_CACHE;
+ shrmd->point_cache->step = 1;
+}
+
+static void smokeHRModifier_freeData(ModifierData *md)
+{
+ SmokeHRModifierData *shrmd = (SmokeHRModifierData*) md;
+
+ smokeHRModifier_free (shrmd);
+}
+
+static void smokeHRModifier_deformVerts(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+ SmokeHRModifierData *shrmd = (SmokeHRModifierData*) md;
+ smokeHRModifier_do(shrmd, md->scene, ob, useRenderParams, isFinalCalc);
+}
+
+static int smokeHRModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+
+static void smokeHRModifier_updateDepgraph(
+ ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
+ DagNode *obNode)
+{
+ ;
+}
+
/* Cloth */
static void clothModifier_initData(ModifierData *md)
@@ -8580,10 +8604,23 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->type = eModifierTypeType_OnlyDeform;
mti->initData = smokeModifier_initData;
mti->freeData = smokeModifier_freeData;
- mti->flags = eModifierTypeFlag_AcceptsMesh;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_UsesPointCache
+ | eModifierTypeFlag_Single;
mti->deformVerts = smokeModifier_deformVerts;
mti->dependsOnTime = smokeModifier_dependsOnTime;
mti->updateDepgraph = smokeModifier_updateDepgraph;
+
+ mti = INIT_TYPE(SmokeHR);
+ mti->type = eModifierTypeType_OnlyDeform;
+ mti->initData = smokeHRModifier_initData;
+ mti->freeData = smokeHRModifier_freeData;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_UsesPointCache
+ | eModifierTypeFlag_Single;
+ mti->deformVerts = smokeHRModifier_deformVerts;
+ mti->dependsOnTime = smokeHRModifier_dependsOnTime;
+ mti->updateDepgraph = smokeHRModifier_updateDepgraph;
mti = INIT_TYPE(Cloth);
mti->type = eModifierTypeType_Nonconstructive;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 09170d92866..ca27bde039b 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -59,7 +59,12 @@
#include "BLI_blenlib.h"
+/* both in intern */
#include "smoke_API.h"
+#include "minilzo.h"
+
+#include "LzmaLib.h"
+
/* needed for directory lookup */
#ifndef WIN32
@@ -469,43 +474,116 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
pid->info_types= (1<<BPHYS_DATA_TIMES);
}
-#if 0 // XXX smoke pointcache stuff breaks compiling now
/* Smoke functions */
static int ptcache_totpoint_smoke(void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
- if(sds->fluid)
- {
+ if(sds->fluid) {
return sds->res[0]*sds->res[1]*sds->res[2];
}
else
return 0;
}
+static int ptcache_totpoint_smoke_turbulence(void *smoke_v)
+{
+ SmokeHRModifierData *shrmd= (SmokeHRModifierData *)smoke_v;
+
+ if(shrmd->wt) {
+ /*
+ unsigned int res[3];
+
+ smoke_turbulence_get_res(sds->wt, res);
+ return res[0]*res[1]*res[2];
+ */
+ return 0;
+ }
+ else
+ return 0;
+}
+
// forward decleration
static int ptcache_file_write(PTCacheFile *pf, void *f, size_t tot, int size);
+static int ptcache_compress_write(PTCacheFile *pf, unsigned char *in, unsigned int in_len, unsigned char *out, int mode)
+{
+ int r;
+ unsigned char compressed;
+ LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS);
+ unsigned int out_len = LZO_OUT_LEN(in_len);
+ unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ size_t sizeOfIt = 5;
+
+ if(mode == 1) {
+ r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem);
+ if (!(r == LZO_E_OK) || (out_len >= in_len))
+ compressed = 0;
+ else
+ compressed = 1;
+ }
+ else if(mode == 2) {
+
+ r = LzmaCompress(out, (size_t *)&out_len, in, in_len,//assume sizeof(char)==1....
+ props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
+
+ if(!(r == SZ_OK) || (out_len >= in_len))
+ compressed = 0;
+ else
+ compressed = 2;
+ }
+
+ ptcache_file_write(pf, &compressed, 1, sizeof(unsigned char));
+ if(compressed) {
+ ptcache_file_write(pf, &out_len, 1, sizeof(unsigned int));
+ ptcache_file_write(pf, out, out_len, sizeof(unsigned char));
+ }
+ else
+ ptcache_file_write(pf, in, in_len, sizeof(unsigned char));
+
+ if(compressed == 2)
+ {
+ ptcache_file_write(pf, &sizeOfIt, 1, sizeof(unsigned int));
+ ptcache_file_write(pf, props, sizeOfIt, sizeof(unsigned char));
+ }
+
+ MEM_freeN(props);
+
+ return r;
+}
+
static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
- if(sds->fluid)
- {
+ if(sds->fluid) {
size_t res = sds->res[0]*sds->res[1]*sds->res[2];
- float *dens, *densold, *heat, *heatold, *vx, *vy, *vz;
-
- smoke_export(sds->fluid, &dens, &densold, &heat, &heatold, &vx, &vy, &vz);
-
- ptcache_file_write(pf, dens, res, sizeof(float));
- ptcache_file_write(pf, densold, res, sizeof(float));
- ptcache_file_write(pf, heat, res, sizeof(float));
- ptcache_file_write(pf, heatold, res, sizeof(float));
- ptcache_file_write(pf, vx, res, sizeof(float));
- ptcache_file_write(pf, vy, res, sizeof(float));
- ptcache_file_write(pf, vz, res, sizeof(float));
+ float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold;
+ unsigned char *obstacles;
+ unsigned int in_len = sizeof(float)*(unsigned int)res;
+ unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer");
+ int mode = res >= 1000000 ? 2 : 1;
+
+ smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
+
+ ptcache_compress_write(pf, (unsigned char *)sds->view3d, in_len*4, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)dens, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)densold, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)heat, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)heatold, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)vx, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)vy, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)vz, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)vxold, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)vyold, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)vzold, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode);
+ ptcache_file_write(pf, &dt, 1, sizeof(float));
+ ptcache_file_write(pf, &dx, 1, sizeof(float));
+
+ MEM_freeN(out);
return 1;
}
@@ -513,32 +591,134 @@ static int ptcache_write_smoke(PTCacheFile *pf, void *smoke_v)
return 0;
}
+static int ptcache_write_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
+{
+ SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
+ SmokeDomainSettings *sds = smd->domain;
+ /*
+ if(sds->wt) {
+ unsigned int res_big[3];
+ size_t res = sds->res[0]*sds->res[1]*sds->res[2];
+ float *dens, *densold, *tcu, *tcv, *tcw;
+ unsigned int in_len = sizeof(float)*(unsigned int)res;
+ unsigned int in_len_big = sizeof(float) * (unsigned int)res_big;
+ unsigned char *out;
+ int mode;
+
+ smoke_turbulence_get_res(sds->wt, res_big);
+ mode = res_big[0]*res_big[1]*res_big[2] >= 1000000 ? 2 : 1;
+
+ smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
+
+ out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer");
+
+ ptcache_compress_write(pf, (unsigned char *)dens, in_len_big, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)densold, in_len_big, out, mode);
+
+ MEM_freeN(out);
+ out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer");
+ ptcache_compress_write(pf, (unsigned char *)tcu, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)tcv, in_len, out, mode);
+ ptcache_compress_write(pf, (unsigned char *)tcw, in_len, out, mode);
+ MEM_freeN(out);
+
+ return 1;
+ }
+*/
+ return 0;
+}
+
// forward decleration
static int ptcache_file_read(PTCacheFile *pf, void *f, size_t tot, int size);
+static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigned int len)
+{
+ int r;
+ unsigned char compressed = 0;
+ unsigned int in_len;
+ unsigned int out_len = len;
+ unsigned char *in;
+ unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
+ size_t sizeOfIt = 5;
+
+ ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
+ if(compressed) {
+ ptcache_file_read(pf, &in_len, 1, sizeof(unsigned int));
+ in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
+ ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
+
+ if(compressed == 1)
+ r = lzo1x_decompress(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
+ else if(compressed == 2)
+ {
+ size_t leni = in_len, leno = out_len;
+ ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
+ ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
+ r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
+ }
+
+ MEM_freeN(in);
+ }
+ else {
+ ptcache_file_read(pf, result, len, sizeof(unsigned char));
+ }
+
+ MEM_freeN(props);
+
+ return r;
+}
+
static void ptcache_read_smoke(PTCacheFile *pf, void *smoke_v)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
- if(sds->fluid)
- {
+ if(sds->fluid) {
size_t res = sds->res[0]*sds->res[1]*sds->res[2];
- float *dens, *densold, *heat, *heatold, *vx, *vy, *vz;
+ float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold;
+ unsigned char *obstacles;
+ unsigned int out_len = (unsigned int)res * sizeof(float);
- smoke_export(sds->fluid, &dens, &densold, &heat, &heatold, &vx, &vy, &vz);
-
- ptcache_file_read(pf, dens, res, sizeof(float));
- ptcache_file_read(pf, densold, res, sizeof(float));
- ptcache_file_read(pf, heat, res, sizeof(float));
- ptcache_file_read(pf, heatold, res, sizeof(float));
- ptcache_file_read(pf, vx, res, sizeof(float));
- ptcache_file_read(pf, vy, res, sizeof(float));
- ptcache_file_read(pf, vz, res, sizeof(float));
+ smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles);
+
+ ptcache_compress_read(pf, (unsigned char *)sds->view3d, out_len*4);
+ ptcache_compress_read(pf, (unsigned char*)dens, out_len);
+ ptcache_compress_read(pf, (unsigned char*)densold, out_len);
+ ptcache_compress_read(pf, (unsigned char*)heat, out_len);
+ ptcache_compress_read(pf, (unsigned char*)heatold, out_len);
+ ptcache_compress_read(pf, (unsigned char*)vx, out_len);
+ ptcache_compress_read(pf, (unsigned char*)vy, out_len);
+ ptcache_compress_read(pf, (unsigned char*)vz, out_len);
+ ptcache_compress_read(pf, (unsigned char*)vxold, out_len);
+ ptcache_compress_read(pf, (unsigned char*)vyold, out_len);
+ ptcache_compress_read(pf, (unsigned char*)vzold, out_len);
+ ptcache_compress_read(pf, (unsigned char*)obstacles, (unsigned int)res);
+ ptcache_file_read(pf, &dt, 1, sizeof(float));
+ ptcache_file_read(pf, &dx, 1, sizeof(float));
+ }
+}
+
+static void ptcache_read_smoke_turbulence(PTCacheFile *pf, void *smoke_v)
+{
+ SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
+ SmokeDomainSettings *sds = smd->domain;
+ /*
+ if(sds->fluid) {
+ unsigned int res[3];
+ float *dens, *densold, *tcu, *tcv, *tcw;
+ unsigned int out_len = sizeof(float)*(unsigned int)res;
+
+ smoke_turbulence_get_res(sds->wt, res);
+
+ smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw);
+
+ ptcache_compress_read(pf, (unsigned char*)dens, out_len);
}
+ */
}
-void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd, int num)
+
+void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeModifierData *smd)
{
SmokeDomainSettings *sds = smd->domain;
@@ -547,24 +727,21 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
pid->ob= ob;
pid->calldata= smd;
- // if(num == 0)
- pid->type= PTCACHE_TYPE_SMOKE_DOMAIN_LOW;
- // else if(num == 1)
- // pid->type= PTCACHE_TYPE_SMOKE_DOMAIN_HIGH;
-
+ pid->type= PTCACHE_TYPE_SMOKE_DOMAIN;
pid->stack_index= modifiers_indexInObject(ob, (ModifierData *)smd);
pid->cache= sds->point_cache;
pid->cache_ptr= &sds->point_cache;
pid->ptcaches= &sds->ptcaches;
-
pid->totpoint= pid->totwrite= ptcache_totpoint_smoke;
pid->write_elem= NULL;
pid->read_elem= NULL;
+
pid->read_stream = ptcache_read_smoke;
pid->write_stream = ptcache_write_smoke;
+
pid->interpolate_elem= NULL;
pid->write_header= ptcache_write_basic_header;
@@ -573,7 +750,6 @@ void BKE_ptcache_id_from_smoke(PTCacheID *pid, struct Object *ob, struct SmokeMo
pid->data_types= (1<<BPHYS_DATA_LOCATION); // bogus values tot make pointcache happy
pid->info_types= 0;
}
-#endif // XXX smoke poitcache stuff breaks compiling
void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *clmd)
{
@@ -633,18 +809,15 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md);
BLI_addtail(lb, pid);
}
- /*
- // enabled on next commit
if(md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
- BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md, 0);
+ BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md);
BLI_addtail(lb, pid);
}
}
- */
}
}
@@ -1140,13 +1313,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(use_old) {
if(pid->read_elem && ptcache_file_read(pf, (void*)old_data1, 1, old_elemsize))
pid->read_elem(i, pid->calldata, NULL, frs_sec, cfra, old_data1);
- else
+ else if(pid->read_elem)
{ error = 1; break; }
}
else {
if(pid->read_elem && (pm || ptcache_file_read_data(pf)))
pid->read_elem(*index, pid->calldata, pm ? pm->cur : pf->cur, frs_sec, cfra1 ? (float)cfra1 : (float)cfrai, NULL);
- else
+ else if(pid->read_elem)
{ error = 1; break; }
}
@@ -1185,7 +1358,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else
{ error = 1; break; }
}
- else
+ else if(pid->read_elem)
{ error = 1; break; }
}
else {
@@ -1197,7 +1370,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else
{ error = 1; break; }
}
- else
+ else if(pid->read_elem)
{ error = 1; break; }
}
@@ -1639,8 +1812,11 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
sbFreeSimulation(pid->calldata);
else if(pid->type == PTCACHE_TYPE_PARTICLES)
psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH);
- else if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN_LOW)
+ else if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
+ {
smokeModifier_reset(pid->calldata);
+ printf("reset PTCACHE_TYPE_SMOKE_DOMAIN\n");
+ }
}
if(clear)
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
@@ -1689,17 +1865,14 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
BKE_ptcache_id_from_cloth(&pid, ob, (ClothModifierData*)md);
reset |= BKE_ptcache_id_reset(scene, &pid, mode);
}
- /*
- // enabled on next commit
if(md->type == eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData *)md;
if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
- BKE_ptcache_id_from_smoke(&pid, ob, (SmokeModifierData*)md, 0);
+ BKE_ptcache_id_from_smoke(&pid, ob, (SmokeModifierData*)md);
reset |= BKE_ptcache_id_reset(scene, &pid, mode);
}
}
- */
}
return reset;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 22ea41276ff..6449ae10eee 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -54,10 +54,13 @@
#include "BKE_DerivedMesh.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
+#include "BKE_pointcache.h"
+#include "BKE_smoke.h"
#include "BKE_utildefines.h"
#include "DNA_customdata_types.h"
#include "DNA_group_types.h"
+#include "DNA_lamp_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -120,9 +123,9 @@ struct DerivedMesh;
struct SmokeModifierData;
// forward declerations
-static void get_cell(struct SmokeModifierData *smd, float *pos, int *cell, int correct);
-static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, int correct);
+void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct);
void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len);
+void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light);
#define TRI_UVOFFSET (1./4.)
@@ -205,17 +208,18 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
// TODO: put in failsafe if res<=0 - dg
// printf("res[0]: %d, res[1]: %d, res[2]: %d\n", smd->domain->res[0], smd->domain->res[1], smd->domain->res[2]);
-
// dt max is 0.1
smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, 0.1);
- smd->domain->wt = smoke_turbulence_init(smd->domain->res, (smd->domain->flags & MOD_SMOKE_HIGHRES) ? (smd->domain->amplify + 1) : 0, smd->domain->noise);
smd->time = scene->r.cfra;
smd->domain->firstframe = smd->time;
-
- smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta));
- if(smd->domain->wt)
- smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength));
+ if(!smd->domain->view3d)
+ {
+ // TVox is for transparency
+ smd->domain->view3d = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2]*4, "Smoke_tVox");
+ }
+
+ smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta));
return 1;
}
@@ -256,7 +260,8 @@ int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, Derive
SmokeCollSettings *scs = smd->coll;
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getFaceArray(dm);
- size_t i = 0, divs = 0;
+ size_t i = 0;
+ int divs = 0;
int *tridivs = NULL;
float cell_len = 1.0 / 50.0; // for res = 50
size_t newdivs = 0;
@@ -507,27 +512,14 @@ void smokeModifier_freeDomain(SmokeModifierData *smd)
if(smd->domain)
{
// free visualisation buffers
- if(smd->domain->bind)
- {
- glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
- MEM_freeN(smd->domain->bind);
- }
- smd->domain->max_textures = 0; // unnecessary but let's be sure
-
- if(smd->domain->tray)
- MEM_freeN(smd->domain->tray);
- if(smd->domain->tvox)
- MEM_freeN(smd->domain->tvox);
- if(smd->domain->traybig)
- MEM_freeN(smd->domain->traybig);
- if(smd->domain->tvoxbig)
- MEM_freeN(smd->domain->tvoxbig);
-
+ if(smd->domain->view3d)
+ MEM_freeN(smd->domain->view3d);
+
if(smd->domain->fluid)
smoke_free(smd->domain->fluid);
- if(smd->domain->wt)
- smoke_turbulence_free(smd->domain->wt);
+ BKE_ptcache_free_list(&smd->domain->ptcaches);
+ smd->domain->point_cache = NULL;
MEM_freeN(smd->domain);
smd->domain = NULL;
@@ -582,44 +574,24 @@ void smokeModifier_reset(struct SmokeModifierData *smd)
{
if(smd->domain)
{
- // free visualisation buffers
- if(smd->domain->bind)
- {
- glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
- MEM_freeN(smd->domain->bind);
- smd->domain->bind = NULL;
- }
- smd->domain->max_textures = 0;
- if(smd->domain->viewsettings < MOD_SMOKE_VIEW_USEBIG)
- smd->domain->viewsettings = 0;
- else
- smd->domain->viewsettings = MOD_SMOKE_VIEW_USEBIG;
-
- if(smd->domain->tray)
- MEM_freeN(smd->domain->tray);
- if(smd->domain->tvox)
- MEM_freeN(smd->domain->tvox);
- if(smd->domain->traybig)
- MEM_freeN(smd->domain->traybig);
- if(smd->domain->tvoxbig)
- MEM_freeN(smd->domain->tvoxbig);
-
- smd->domain->tvox = NULL;
- smd->domain->tray = NULL;
- smd->domain->tvoxbig = NULL;
- smd->domain->traybig = NULL;
+ if(smd->domain->view3d)
+ MEM_freeN(smd->domain->view3d);
+ smd->domain->view3d = NULL;
+
+ smd->domain->tex = NULL;
if(smd->domain->fluid)
{
smoke_free(smd->domain->fluid);
smd->domain->fluid = NULL;
}
-
- if(smd->domain->wt)
- {
- smoke_turbulence_free(smd->domain->wt);
- smd->domain->wt = NULL;
- }
+
+ smd->domain->point_cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ smd->domain->point_cache->flag |= PTCACHE_OUTDATED;
+ smd->domain->point_cache->simframe= 0;
+ smd->domain->point_cache->last_exact= 0;
+
+ printf("reset_domain\n");
}
else if(smd->flow)
{
@@ -677,31 +649,24 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
smd->domain->smd = smd;
+ smd->domain->point_cache = BKE_ptcache_add(&smd->domain->ptcaches);
+ smd->domain->point_cache->flag |= PTCACHE_DISK_CACHE;
+ smd->domain->point_cache->step = 1;
+
/* set some standard values */
smd->domain->fluid = NULL;
- smd->domain->wt = NULL;
smd->domain->eff_group = NULL;
smd->domain->fluid_group = NULL;
smd->domain->coll_group = NULL;
smd->domain->maxres = 32;
- smd->domain->amplify = 1;
- smd->domain->omega = 1.0;
smd->domain->alpha = -0.001;
smd->domain->beta = 0.1;
smd->domain->flags = MOD_SMOKE_DISSOLVE_LOG;
- smd->domain->strength = 2.0;
- smd->domain->noise = MOD_SMOKE_NOISEWAVE;
- smd->domain->visibility = 1;
smd->domain->diss_speed = 5;
// init 3dview buffer
- smd->domain->tvox = NULL;
- smd->domain->tray = NULL;
- smd->domain->tvoxbig = NULL;
- smd->domain->traybig = NULL;
- smd->domain->viewsettings = 0;
- smd->domain->bind = NULL;
- smd->domain->max_textures = 0;
+ smd->domain->view3d = NULL;
+ smd->domain->tex = NULL;
}
else if(smd->type & MOD_SMOKE_TYPE_FLOW)
{
@@ -736,15 +701,15 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
}
// forward declaration
-void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big);
+void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm);
void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{
- if(scene->r.cfra >= smd->time)
- smokeModifier_init(smd, ob, scene, dm);
-
if((smd->type & MOD_SMOKE_TYPE_FLOW))
{
+ if(scene->r.cfra >= smd->time)
+ smokeModifier_init(smd, ob, scene, dm);
+
if(scene->r.cfra > smd->time)
{
// XXX TODO
@@ -764,6 +729,9 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
else if(smd->type & MOD_SMOKE_TYPE_COLL)
{
+ if(scene->r.cfra >= smd->time)
+ smokeModifier_init(smd, ob, scene, dm);
+
if(scene->r.cfra > smd->time)
{
// XXX TODO
@@ -786,459 +754,484 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
}
else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
{
+ PointCache *cache;
+ PTCacheID pid;
+ float timescale;
+ int cache_result = 0;
+ int startframe, endframe, framenr;
SmokeDomainSettings *sds = smd->domain;
+ float light[3] = {0.0,0.0,0.0};
+ int have_lamp = 0;
+
+ printf("smd->type & MOD_SMOKE_TYPE_DOMAIN\n");
+
+ framenr = scene->r.cfra;
+
+ cache = sds->point_cache;
+
+ BKE_ptcache_id_from_smoke(&pid, ob, smd);
+ BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
+
+ /* handle continuous simulation with the play button */
+ if(BKE_ptcache_get_continue_physics())
+ {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ cache->last_exact= 0;
+
+ smokeModifier_init(smd, ob, scene, dm);
+
+ smoke_simulate_domain(smd, scene, ob, dm);
+
+ return;
+ }
- if(scene->r.cfra > smd->time)
+ if(framenr < startframe)
{
- GroupObject *go = NULL;
- Base *base = NULL;
-
- tstart();
-
- if(sds->flags & MOD_SMOKE_DISSOLVE)
- {
- smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
-
- if(sds->wt)
- smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
- }
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ cache->last_exact= 0;
- /* reset view for new frame */
- if(sds->viewsettings < MOD_SMOKE_VIEW_USEBIG)
- sds->viewsettings = 0;
- else
- sds->viewsettings = MOD_SMOKE_VIEW_USEBIG;
+ // we got back in time, reset smoke in this case (TODO: use cache later)
+ // smd->time = scene->r.cfra;
+ // smokeModifier_reset(smd);
- // do flows and fluids
- if(1)
- {
- Object *otherobj = NULL;
- ModifierData *md = NULL;
+ return;
+ }
+ else if(framenr > endframe)
+ {
+ framenr = endframe;
+ }
- if(sds->fluid_group) // we use groups since we have 2 domains
- go = sds->fluid_group->gobject.first;
- else
- base = scene->base.first;
+ if(!(cache->flag & PTCACHE_SIMULATION_VALID))
+ {
+ // printf("reseting\n");
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ }
+
+ smokeModifier_init(smd, ob, scene, dm);
- while(base || go)
- {
- otherobj = NULL;
+ /* try to read from cache */
+ cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
+ printf("cache_result: %d\n", cache_result);
+
+ if(cache_result == PTCACHE_READ_EXACT)
+ {
+ SmokeDomainSettings *sds = smd->domain;
+
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
+ sds->v3dnum = framenr;
+
+ // printf("PTCACHE_READ_EXACT\n");
+ return;
+ }
+ else if(cache_result==PTCACHE_READ_OLD)
+ {
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
+
+ // printf("PTCACHE_READ_OLD\n");
+
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ }
+ else if(ob->id.lib || (cache->flag & PTCACHE_BAKED))
+ {
+ /* if baked and nothing in cache, do nothing */
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ cache->last_exact= 0;
+
+ // printf("PTCACHE_BAKED\n");
+ return;
+ }
+ else if((cache_result==0) && (startframe!=framenr) && !(cache->flag & PTCACHE_SIMULATION_VALID))
+ {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ cache->last_exact= 0;
+
+ return;
+ }
+
+ /* do simulation */
+
+ // low res
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
+
+ smoke_simulate_domain(smd, scene, ob, dm);
+
+ {
+ // float light[3] = {0.0,0.0,0.0}; // TODO: take real LAMP coordinates - dg
+ Base *base_tmp = NULL;
- if(sds->fluid_group)
+ for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
+ {
+ if(base_tmp->object->type == OB_LAMP)
+ {
+ Lamp *la = (Lamp *)base_tmp->object->data;
+
+ if(la->type == LA_LOCAL)
{
- if(go->ob)
- otherobj = go->ob;
+ VECCOPY(light, base_tmp->object->obmat[3]);
+ have_lamp = 1;
+ break;
}
- else
- otherobj = base->object;
+ }
+ }
+ }
- if(!otherobj)
- {
- if(sds->fluid_group)
- go = go->next;
- else
- base= base->next;
+ smoke_prepare_View(smd, (float)framenr, light, have_lamp);
- continue;
- }
+ BKE_ptcache_write_cache(&pid, framenr);
+
+ printf("Writing cache_low\n");
+
- md = modifiers_findByType(otherobj, eModifierType_Smoke);
+ tend();
+ printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
+ }
+}
+
+void smoke_simulate_domain(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm)
+{
+ GroupObject *go = NULL;
+ Base *base = NULL;
+ SmokeDomainSettings *sds = smd->domain;
+
+ tstart();
+
+ if(sds->flags & MOD_SMOKE_DISSOLVE)
+ smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
+
+ // do flows and fluids
+ if(1)
+ {
+ Object *otherobj = NULL;
+ ModifierData *md = NULL;
+
+ if(sds->fluid_group) // we use groups since we have 2 domains
+ go = sds->fluid_group->gobject.first;
+ else
+ base = scene->base.first;
+
+ while(base || go)
+ {
+ otherobj = NULL;
+
+ if(sds->fluid_group)
+ {
+ if(go->ob)
+ otherobj = go->ob;
+ }
+ else
+ otherobj = base->object;
+
+ if(!otherobj)
+ {
+ if(sds->fluid_group)
+ go = go->next;
+ else
+ base= base->next;
+
+ continue;
+ }
+
+ md = modifiers_findByType(otherobj, eModifierType_Smoke);
+
+ // check for active smoke modifier
+ if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+ {
+ SmokeModifierData *smd2 = (SmokeModifierData *)md;
+
+ // check for initialized smoke object
+ if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
+ {
+ // we got nice flow object
+ SmokeFlowSettings *sfs = smd2->flow;
- // check for active smoke modifier
- if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+ if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
{
- SmokeModifierData *smd2 = (SmokeModifierData *)md;
+ ParticleSystem *psys = sfs->psys;
+ ParticleSettings *part=psys->part;
+ ParticleData *pa = NULL;
+ int p = 0;
+ float *density = smoke_get_density(sds->fluid);
+ // float *bigdensity = smoke_turbulence_get_density(sds->wt);
+ float *heat = smoke_get_heat(sds->fluid);
+ float *velocity_x = smoke_get_velocity_x(sds->fluid);
+ float *velocity_y = smoke_get_velocity_y(sds->fluid);
+ float *velocity_z = smoke_get_velocity_z(sds->fluid);
+ unsigned char *obstacle = smoke_get_obstacle(sds->fluid);
+
+ // debug printf("found flow psys\n");
- // check for initialized smoke object
- if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
+ // mostly copied from particle code
+ for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
{
- // we got nice flow object
- SmokeFlowSettings *sfs = smd2->flow;
+ int cell[3];
+ size_t i = 0;
+ size_t index = 0;
+ int badcell = 0;
- if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
+ if(pa->alive == PARS_KILLED) continue;
+ else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
+ else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
+ else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
+
+ // VECCOPY(pos, pa->state.co);
+ // Mat4MulVecfl (ob->imat, pos);
+
+ // 1. get corresponding cell
+ get_cell(sds->p0, sds->res, sds->dx, pa->state.co, cell, 0);
+
+ // check if cell is valid (in the domain boundary)
+ for(i = 0; i < 3; i++)
{
- ParticleSystem *psys = sfs->psys;
- ParticleSettings *part=psys->part;
- ParticleData *pa = NULL;
- int p = 0;
- float *density = smoke_get_density(sds->fluid);
- float *bigdensity = smoke_turbulence_get_density(sds->wt);
- float *heat = smoke_get_heat(sds->fluid);
- float *velocity_x = smoke_get_velocity_x(sds->fluid);
- float *velocity_y = smoke_get_velocity_y(sds->fluid);
- float *velocity_z = smoke_get_velocity_z(sds->fluid);
- unsigned char *obstacle = smoke_get_obstacle(sds->fluid);
- int bigres[3];
-
- printf("found flow psys\n");
-
- // mostly copied from particle code
- for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
+ if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
{
- int cell[3];
- size_t i = 0;
- size_t index = 0;
- int badcell = 0;
-
- if(pa->alive == PARS_KILLED) continue;
- else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
- else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
- else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
-
- // VECCOPY(pos, pa->state.co);
- // Mat4MulVecfl (ob->imat, pos);
-
- // 1. get corresponding cell
- get_cell(smd, pa->state.co, cell, 0);
-
- // check if cell is valid (in the domain boundary)
- for(i = 0; i < 3; i++)
- {
- if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))
- {
- badcell = 1;
- break;
- }
- }
-
- if(badcell)
- continue;
-
- // 2. set cell values (heat, density and velocity)
- index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
-
- if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow
- {
- // heat[index] += sfs->temp * 0.1;
- // density[index] += sfs->density * 0.1;
-
- heat[index] = sfs->temp;
- density[index] = sfs->density;
-
- /*
- velocity_x[index] = pa->state.vel[0];
- velocity_y[index] = pa->state.vel[1];
- velocity_z[index] = pa->state.vel[2];
- */
- obstacle[index] |= 2;
-
- // we need different handling for the high-res feature
- if(bigdensity)
- {
- // init all surrounding cells according to amplification, too
- int i, j, k;
-
- smoke_turbulence_get_res(smd->domain->wt, bigres);
-
- for(i = 0; i < smd->domain->amplify + 1; i++)
- for(j = 0; j < smd->domain->amplify + 1; j++)
- for(k = 0; k < smd->domain->amplify + 1; k++)
- {
- index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
- bigdensity[index] = sfs->density;
- }
- }
- }
- else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow
- {
- heat[index] = 0.f;
- density[index] = 0.f;
- velocity_x[index] = 0.f;
- velocity_y[index] = 0.f;
- velocity_z[index] = 0.f;
-
- // we need different handling for the high-res feature
- if(bigdensity)
- {
- // init all surrounding cells according to amplification, too
- int i, j, k;
-
- smoke_turbulence_get_res(smd->domain->wt, bigres);
-
- for(i = 0; i < smd->domain->amplify + 1; i++)
- for(j = 0; j < smd->domain->amplify + 1; j++)
- for(k = 0; k < smd->domain->amplify + 1; k++)
- {
- index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
- bigdensity[index] = 0.f;
- }
- }
- }
+ badcell = 1;
+ break;
}
}
- else
+
+ if(badcell)
+ continue;
+
+ // 2. set cell values (heat, density and velocity)
+ index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+
+ if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow
{
- /*
- for()
- {
- // no psys
- BVHTreeNearest nearest;
+ // heat[index] += sfs->temp * 0.1;
+ // density[index] += sfs->density * 0.1;
- nearest.index = -1;
- nearest.dist = FLT_MAX;
+ heat[index] = sfs->temp;
+ density[index] = sfs->density;
- BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
- }*/
+ /*
+ velocity_x[index] = pa->state.vel[0];
+ velocity_y[index] = pa->state.vel[1];
+ velocity_z[index] = pa->state.vel[2];
+ */
+ obstacle[index] |= 2;
+ }
+ else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow
+ {
+ heat[index] = 0.f;
+ density[index] = 0.f;
+ velocity_x[index] = 0.f;
+ velocity_y[index] = 0.f;
+ velocity_z[index] = 0.f;
}
- }
+ }
}
-
- if(sds->fluid_group)
- go = go->next;
else
- base= base->next;
- }
+ {
+ /*
+ for()
+ {
+ // no psys
+ BVHTreeNearest nearest;
+
+ nearest.index = -1;
+ nearest.dist = FLT_MAX;
+
+ BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
+ }*/
+ }
+ }
}
- // do effectors
- /*
- if(sds->eff_group)
+ if(sds->fluid_group)
+ go = go->next;
+ else
+ base= base->next;
+ }
+ }
+
+ // do effectors
+ /*
+ if(sds->eff_group)
+ {
+ for(go = sds->eff_group->gobject.first; go; go = go->next)
+ {
+ if(go->ob)
{
- for(go = sds->eff_group->gobject.first; go; go = go->next)
+ if(ob->pd)
{
- if(go->ob)
- {
- if(ob->pd)
- {
-
- }
- }
+
}
}
- */
+ }
+ }
+ */
+
+ // do collisions
+ if(1)
+ {
+ Object *otherobj = NULL;
+ ModifierData *md = NULL;
+
+ if(sds->coll_group) // we use groups since we have 2 domains
+ go = sds->coll_group->gobject.first;
+ else
+ base = scene->base.first;
+
+ while(base || go)
+ {
+ otherobj = NULL;
- // do collisions
- if(1)
+ if(sds->coll_group)
{
- Object *otherobj = NULL;
- ModifierData *md = NULL;
+ if(go->ob)
+ otherobj = go->ob;
+ }
+ else
+ otherobj = base->object;
- if(sds->coll_group) // we use groups since we have 2 domains
- go = sds->coll_group->gobject.first;
+ if(!otherobj)
+ {
+ if(sds->coll_group)
+ go = go->next;
else
- base = scene->base.first;
+ base= base->next;
- while(base || go)
- {
- otherobj = NULL;
+ continue;
+ }
+
+ md = modifiers_findByType(otherobj, eModifierType_Smoke);
+
+ // check for active smoke modifier
+ if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
+ {
+ SmokeModifierData *smd2 = (SmokeModifierData *)md;
- if(sds->coll_group)
- {
- if(go->ob)
- otherobj = go->ob;
- }
- else
- otherobj = base->object;
+ if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
+ {
+ // we got nice collision object
+ SmokeCollSettings *scs = smd2->coll;
+ size_t i, j;
+ unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
- if(!otherobj)
+ for(i = 0; i < scs->numpoints; i++)
{
- if(sds->coll_group)
- go = go->next;
- else
- base= base->next;
+ int badcell = 0;
+ size_t index = 0;
+ int cell[3];
- continue;
- }
-
- md = modifiers_findByType(otherobj, eModifierType_Smoke);
+ // 1. get corresponding cell
+ get_cell(sds->p0, sds->res, sds->dx, &scs->points[3 * i], cell, 0);
- // check for active smoke modifier
- if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
- {
- SmokeModifierData *smd2 = (SmokeModifierData *)md;
-
- if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
- {
- // we got nice collision object
- SmokeCollSettings *scs = smd2->coll;
- size_t i, j;
- unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);
-
- for(i = 0; i < scs->numpoints; i++)
+ // check if cell is valid (in the domain boundary)
+ for(j = 0; j < 3; j++)
+ if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
{
- int badcell = 0;
- size_t index = 0;
- int cell[3];
-
- // 1. get corresponding cell
- get_cell(smd, &scs->points[3 * i], cell, 0);
-
- // check if cell is valid (in the domain boundary)
- for(j = 0; j < 3; j++)
- if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
- {
- badcell = 1;
- break;
- }
-
- if(badcell)
- continue;
-
- // 2. set cell values (heat, density and velocity)
- index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+ badcell = 1;
+ break;
+ }
- // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
- // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
-
- obstacles[index] = 1;
+ if(badcell)
+ continue;
- // for moving gobstacles
- /*
- const LbmFloat maxVelVal = 0.1666;
- const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
-
- LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); {
- const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5;
- USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);
- if(usqr>maxusqr) {
- // cutoff at maxVelVal
- for(int jj=0; jj<3; jj++) {
- if(objvel[jj]>0.) objvel[jj] = maxVelVal;
- if(objvel[jj]<0.) objvel[jj] = -maxVelVal;
- }
- } }
-
- const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) );
- const LbmVec oldov=objvel; // debug
- objvel = vec2L((*pNormals)[n]) *dp;
- */
- }
- }
+ // 2. set cell values (heat, density and velocity)
+ index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
+
+ // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);
+ // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);
+
+ obstacles[index] = 1;
+
+ // for moving gobstacles
+ /*
+ const LbmFloat maxVelVal = 0.1666;
+ const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;
+
+ LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); {
+ const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5;
+ USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);
+ if(usqr>maxusqr) {
+ // cutoff at maxVelVal
+ for(int jj=0; jj<3; jj++) {
+ if(objvel[jj]>0.) objvel[jj] = maxVelVal;
+ if(objvel[jj]<0.) objvel[jj] = -maxVelVal;
+ }
+ } }
+
+ const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) );
+ const LbmVec oldov=objvel; // debug
+ objvel = vec2L((*pNormals)[n]) *dp;
+ */
}
-
- if(sds->coll_group)
- go = go->next;
- else
- base= base->next;
}
}
-
- // set new time
- smd->time = scene->r.cfra;
-
- // simulate the actual smoke (c++ code in intern/smoke)
- smoke_step(sds->fluid, smd->time);
- if(sds->wt)
- smoke_turbulence_step(sds->wt, sds->fluid);
- tend();
- printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
- }
- else if(scene->r.cfra < smd->time)
- {
- // we got back in time, reset smoke in this case (TODO: use cache later)
- smd->time = scene->r.cfra;
- smokeModifier_reset(smd);
+ if(sds->coll_group)
+ go = go->next;
+ else
+ base= base->next;
}
}
+
+ // set new time
+ smd->time = scene->r.cfra;
+
+ // simulate the actual smoke (c++ code in intern/smoke)
+ smoke_step(sds->fluid, smd->time);
}
+static int calc_voxel_transp(float *input, int res[3], int *pixel, float *tRay)
+{
+ const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]);
+
+ // T_ray *= T_vox
+ *tRay *= input[index*4];
+
+ return *tRay;
+}
+
+// forward decleration
+void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb);
+
// update necessary information for 3dview
-void smoke_prepare_View(SmokeModifierData *smd, float *light)
+void smoke_prepare_View(SmokeModifierData *smd, float framenr, float *light, int have_light)
{
float *density = NULL;
int x, y, z;
-
- if(!smd->domain->tray)
- {
- // TRay is for self shadowing
- smd->domain->tray = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2], "Smoke_tRay");
- }
- if(!smd->domain->tvox)
- {
- // TVox is for tranaparency
- smd->domain->tvox = MEM_callocN(sizeof(float)*smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2], "Smoke_tVox");
- }
+ size_t cells, i;
+ SmokeDomainSettings *sds = smd->domain;
// update 3dview
density = smoke_get_density(smd->domain->fluid);
for(x = 0; x < smd->domain->res[0]; x++)
- for(y = 0; y < smd->domain->res[1]; y++)
- for(z = 0; z < smd->domain->res[2]; z++)
- {
- size_t index;
-
- index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
- // Transparency computation
- // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
- // T_vox = exp(-C_ext * h)
- // C_ext/sigma_t = density * C_ext
- smoke_set_tvox(smd, index, exp(-density[index] * 7.0 * smd->domain->dx));
- }
- smoke_calc_transparency(smd, light, 0);
-}
-
-// update necessary information for 3dview ("high res" option)
-void smoke_prepare_bigView(SmokeModifierData *smd, float *light)
-{
- float *density = NULL;
- size_t i = 0;
- int bigres[3];
+ for(y = 0; y < smd->domain->res[1]; y++)
+ for(z = 0; z < smd->domain->res[2]; z++)
+ {
+ size_t index;
- smoke_turbulence_get_res(smd->domain->wt, bigres);
+ index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
+ // Transparency computation
+ // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
+ // T_vox = exp(-C_ext * h)
+ // C_ext/sigma_t = density * C_ext
+ smd->domain->view3d[index * 4] = smd->domain->view3d[index * 4 + 1] =
+ smd->domain->view3d[index * 4 + 2] = exp(-density[index] * 7.0 * smd->domain->dx);
+ smd->domain->view3d[index * 4 + 3] = 1.0 - smd->domain->view3d[index * 4];
+
+ }
- if(!smd->domain->traybig)
+ if(have_light)
{
- // TRay is for self shadowing
- smd->domain->traybig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tRayBig");
- }
- if(!smd->domain->tvoxbig)
- {
- // TVox is for tranaparency
- smd->domain->tvoxbig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tVoxBig");
- }
+ smoke_calc_transparency(sds->view3d, sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp);
- density = smoke_turbulence_get_density(smd->domain->wt);
- for (i = 0; i < bigres[0] * bigres[1] * bigres[2]; i++)
- {
- // Transparency computation
- // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
- // T_vox = exp(-C_ext * h)
- // C_ext/sigma_t = density * C_ext
- smoke_set_bigtvox(smd, i, exp(-density[i] * 7.0 * smd->domain->dx / (smd->domain->amplify + 1)) );
+ cells = smd->domain->res[0]*smd->domain->res[1]*smd->domain->res[2];
+ for(i = 0; i < cells; i++)
+ {
+ smd->domain->view3d[i * 4] = smd->domain->view3d[i * 4 + 1] =
+ smd->domain->view3d[i * 4 + 2] = smd->domain->view3d[i * 4 + 1] * smd->domain->view3d[i * 4 + 0];
+ }
}
- smoke_calc_transparency(smd, light, 1);
-}
-
-
-float smoke_get_tvox(SmokeModifierData *smd, size_t index)
-{
- return smd->domain->tvox[index];
-}
-
-void smoke_set_tvox(SmokeModifierData *smd, size_t index, float tvox)
-{
- smd->domain->tvox[index] = tvox;
-}
-
-float smoke_get_tray(SmokeModifierData *smd, size_t index)
-{
- return smd->domain->tray[index];
-}
-
-void smoke_set_tray(SmokeModifierData *smd, size_t index, float transparency)
-{
- smd->domain->tray[index] = transparency;
-}
-
-float smoke_get_bigtvox(SmokeModifierData *smd, size_t index)
-{
- return smd->domain->tvoxbig[index];
-}
-
-void smoke_set_bigtvox(SmokeModifierData *smd, size_t index, float tvox)
-{
- smd->domain->tvoxbig[index] = tvox;
-}
-
-float smoke_get_bigtray(SmokeModifierData *smd, size_t index)
-{
- return smd->domain->traybig[index];
-}
-
-void smoke_set_bigtray(SmokeModifierData *smd, size_t index, float transparency)
-{
- smd->domain->traybig[index] = transparency;
+ smd->domain->v3dnum = framenr;
}
long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
@@ -1259,34 +1252,7 @@ long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
return totalMB;
}
-
-static void calc_voxel_transp(SmokeModifierData *smd, int *pixel, float *tRay)
-{
- // printf("Pixel(%d, %d, %d)\n", pixel[0], pixel[1], pixel[2]);
- const size_t index = smoke_get_index(pixel[0], smd->domain->res[0], pixel[1], smd->domain->res[1], pixel[2]);
-
- // T_ray *= T_vox
- *tRay *= smoke_get_tvox(smd, index);
-}
-
-static void calc_voxel_transp_big(SmokeModifierData *smd, int *pixel, float *tRay)
-{
- int bigres[3];
- size_t index;
-
- smoke_turbulence_get_res(smd->domain->wt, bigres);
- index = smoke_get_index(pixel[0], bigres[0], pixel[1], bigres[1], pixel[2]);
-
- /*
- if(index > bigres[0]*bigres[1]*bigres[2])
- printf("pixel[0]: %d, [1]: %d, [2]: %d\n", pixel[0], pixel[1], pixel[2]);
- */
-
- // T_ray *= T_vox
- *tRay *= smoke_get_bigtvox(smd, index);
-}
-
-static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, int big)
+static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *input, int res[3])
{
int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
int pixel[3];
@@ -1313,11 +1279,7 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
err_1 = dy2 - l;
err_2 = dz2 - l;
for (i = 0; i < l; i++) {
- if(!big)
- calc_voxel_transp(smd, pixel, tRay);
- else
- calc_voxel_transp_big(smd, pixel, tRay);
- if(*tRay < 0.0f)
+ if(cb(input, res, pixel, tRay) < 0.0)
return;
if (err_1 > 0) {
pixel[1] += y_inc;
@@ -1335,11 +1297,7 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
err_1 = dx2 - m;
err_2 = dz2 - m;
for (i = 0; i < m; i++) {
- if(!big)
- calc_voxel_transp(smd, pixel, tRay);
- else
- calc_voxel_transp_big(smd, pixel, tRay);
- if(*tRay < 0.0f)
+ if(cb(input, res, pixel, tRay) < 0.0f)
return;
if (err_1 > 0) {
pixel[0] += x_inc;
@@ -1357,11 +1315,7 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
err_1 = dy2 - n;
err_2 = dx2 - n;
for (i = 0; i < n; i++) {
- if(!big)
- calc_voxel_transp(smd, pixel, tRay);
- else
- calc_voxel_transp_big(smd, pixel, tRay);
- if(*tRay < 0.0f)
+ if(cb(input, res, pixel, tRay) < 0.0f)
return;
if (err_1 > 0) {
pixel[1] += y_inc;
@@ -1376,41 +1330,15 @@ static void bresenham_linie_3D(SmokeModifierData *smd, int x1, int y1, int z1, i
pixel[2] += z_inc;
}
}
- if(!big)
- calc_voxel_transp(smd, pixel, tRay);
- else
- calc_voxel_transp_big(smd, pixel, tRay);
+ cb(input, res, pixel, tRay);
}
-static void get_cell(struct SmokeModifierData *smd, float *pos, int *cell, int correct)
-{
- float tmp[3];
-
- VECSUB(tmp, pos, smd->domain->p0);
- VecMulf(tmp, 1.0 / smd->domain->dx);
-
- if(correct)
- {
- cell[0] = MIN2(smd->domain->res[0] - 1, MAX2(0, (int)floor(tmp[0])));
- cell[1] = MIN2(smd->domain->res[1] - 1, MAX2(0, (int)floor(tmp[1])));
- cell[2] = MIN2(smd->domain->res[2] - 1, MAX2(0, (int)floor(tmp[2])));
- }
- else
- {
- cell[0] = (int)floor(tmp[0]);
- cell[1] = (int)floor(tmp[1]);
- cell[2] = (int)floor(tmp[2]);
- }
-}
-static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, int correct)
+static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct)
{
float tmp[3];
- int res[3];
- smoke_turbulence_get_res(smd->domain->wt, res);
-
- VECSUB(tmp, pos, smd->domain->p0);
- VecMulf(tmp, (smd->domain->amplify + 1)/ smd->domain->dx );
+ VECSUB(tmp, pos, p0);
+ VecMulf(tmp, 1.0 / dx);
if(correct)
{
@@ -1426,43 +1354,23 @@ static void get_bigcell(struct SmokeModifierData *smd, float *pos, int *cell, in
}
}
-
-void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int big)
+void smoke_calc_transparency(float *result, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb)
{
int x, y, z;
float bv[6];
- int res[3];
float bigfactor = 1.0;
// x
- bv[0] = smd->domain->p0[0];
- bv[1] = smd->domain->p1[0];
+ bv[0] = p0[0];
+ bv[1] = p1[0];
// y
- bv[2] = smd->domain->p0[1];
- bv[3] = smd->domain->p1[1];
+ bv[2] = p0[1];
+ bv[3] = p1[1];
// z
- bv[4] = smd->domain->p0[2];
- bv[5] = smd->domain->p1[2];
-/*
- printf("bv[0]: %f, [1]: %f, [2]: %f, [3]: %f, [4]: %f, [5]: %f\n", bv[0], bv[1], bv[2], bv[3], bv[4], bv[5]);
-
- printf("p0[0]: %f, p0[1]: %f, p0[2]: %f\n", smd->domain->p0[0], smd->domain->p0[1], smd->domain->p0[2]);
- printf("p1[0]: %f, p1[1]: %f, p1[2]: %f\n", smd->domain->p1[0], smd->domain->p1[1], smd->domain->p1[2]);
- printf("dx: %f, amp: %d\n", smd->domain->dx, smd->domain->amplify);
-*/
- if(!big)
- {
- res[0] = smd->domain->res[0];
- res[1] = smd->domain->res[1];
- res[2] = smd->domain->res[2];
- }
- else
- {
- smoke_turbulence_get_res(smd->domain->wt, res);
- bigfactor = 1.0 / (smd->domain->amplify + 1);
- }
+ bv[4] = p0[2];
+ bv[5] = p1[2];
-#pragma omp parallel for schedule(static) private(y, z) shared(big, smd, light, res, bigfactor)
+// #pragma omp parallel for schedule(static) private(y, z)
for(x = 0; x < res[0]; x++)
for(y = 0; y < res[1]; y++)
for(z = 0; z < res[2]; z++)
@@ -1475,41 +1383,26 @@ void smoke_calc_transparency(struct SmokeModifierData *smd, float *light, int bi
index = smoke_get_index(x, res[0], y, res[1], z);
- // voxelCenter = m_voxelarray[i].GetCenter();
- voxelCenter[0] = smd->domain->p0[0] + smd->domain->dx * bigfactor * x + smd->domain->dx * bigfactor * 0.5;
- voxelCenter[1] = smd->domain->p0[1] + smd->domain->dx * bigfactor * y + smd->domain->dx * bigfactor * 0.5;
- voxelCenter[2] = smd->domain->p0[2] + smd->domain->dx * bigfactor * z + smd->domain->dx * bigfactor * 0.5;
-
- // printf("vc[0]: %f, vc[1]: %f, vc[2]: %f\n", voxelCenter[0], voxelCenter[1], voxelCenter[2]);
- // printf("light[0]: %f, light[1]: %f, light[2]: %f\n", light[0], light[1], light[2]);
+ voxelCenter[0] = p0[0] + dx * x + dx * 0.5;
+ voxelCenter[1] = p0[1] + dx * y + dx * 0.5;
+ voxelCenter[2] = p0[2] + dx * z + dx * 0.5;
// get starting position (in voxel coords)
if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON)
{
// we're ouside
- // printf("out: pos[0]: %f, pos[1]: %f, pos[2]: %f\n", pos[0], pos[1], pos[2]);
- if(!big)
- get_cell(smd, pos, cell, 1);
- else
- get_bigcell(smd, pos, cell, 1);
+ get_cell(p0, res, dx, pos, cell, 1);
}
else
{
- // printf("in: pos[0]: %f, pos[1]: %f, pos[2]: %f\n", light[0], light[1], light[2]);
// we're inside
- if(!big)
- get_cell(smd, light, cell, 1);
- else
- get_bigcell(smd, light, cell, 1);
+ get_cell(p0, res, dx, light, cell, 1);
}
- // printf("cell - [0]: %d, [1]: %d, [2]: %d\n", cell[0], cell[1], cell[2]);
- bresenham_linie_3D(smd, cell[0], cell[1], cell[2], x, y, z, &tRay, big);
+ bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, res);
- if(!big)
- smoke_set_tray(smd, index, tRay);
- else
- smoke_set_bigtray(smd, index, tRay);
+ // convention -> from a RGBA float array, use G value for tRay
+ result[index*4 + 1] = tRay;
}
}
diff --git a/source/blender/blenkernel/intern/smokehighres.c b/source/blender/blenkernel/intern/smokehighres.c
new file mode 100644
index 00000000000..6a2e0549158
--- /dev/null
+++ b/source/blender/blenkernel/intern/smokehighres.c
@@ -0,0 +1,137 @@
+/**
+ * smokehighres.c
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Daniel Genrich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* Part of the code copied from elbeem fluid library, copyright by Nils Thuerey */
+
+#include "DNA_scene_types.h"
+#include "DNA_listBase.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_smoke_types.h"
+
+#include "BKE_modifier.h"
+#include "BKE_smoke.h"
+#include "BKE_pointcache.h"
+
+#include "smoke_API.h"
+
+// we need different handling for the high-res feature
+/*
+if(bigdensity)
+{
+ // init all surrounding cells according to amplification, too
+ int i, j, k;
+
+ smoke_turbulence_get_res(smd->domain->wt, bigres);
+
+ for(i = 0; i < smd->domain->amplify + 1; i++)
+ for(j = 0; j < smd->domain->amplify + 1; j++)
+ for(k = 0; k < smd->domain->amplify + 1; k++)
+ {
+ index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);
+ bigdensity[index] = sfs->density;
+ }
+}
+*/
+
+static void smokeHRinit(SmokeHRModifierData *shrmd, SmokeDomainSettings *sds)
+{
+ if(!shrmd->wt)
+ {
+ shrmd->wt = smoke_turbulence_init(sds->res, shrmd->amplify + 1, shrmd->noise);
+ smoke_turbulence_initBlenderRNA(shrmd->wt, &shrmd->strength);
+ }
+}
+
+void smokeHRModifier_free(SmokeHRModifierData *shrmd)
+{
+ if(shrmd->wt)
+ smoke_turbulence_free(shrmd->wt);
+
+ BKE_ptcache_free_list(&shrmd->ptcaches);
+ shrmd->point_cache = NULL;
+}
+
+void smokeHRModifier_do(SmokeHRModifierData *shrmd, Scene *scene, Object *ob, int useRenderParams, int isFinalCalc)
+{
+ ModifierData *md = NULL;
+ SmokeModifierData *smd = NULL;
+ SmokeDomainSettings *sds = NULL;
+
+ // find underlaying smoke domain
+ smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke);
+ if(!(smd && smd->type == MOD_SMOKE_TYPE_DOMAIN))
+ return;
+
+ sds = smd->domain;
+
+ smokeHRinit(shrmd, sds);
+
+ // smoke_turbulence_dissolve(shrmd->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
+
+ // smoke_turbulence_step(shrmd->wt, sds->fluid);
+}
+
+
+// update necessary information for 3dview ("high res" option)
+void smoke_prepare_bigView(SmokeHRModifierData *shrmd, float *light)
+{
+ float *density = NULL;
+ size_t i = 0;
+ int bigres[3];
+/*
+ smoke_turbulence_get_res(shrmd->wt, bigres);
+
+ if(!smd->domain->traybig)
+ {
+ // TRay is for self shadowing
+ smd->domain->traybig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tRayBig");
+ }
+ if(!smd->domain->tvoxbig)
+ {
+ // TVox is for tranaparency
+ smd->domain->tvoxbig = MEM_callocN(sizeof(float)*bigres[0]*bigres[1]*bigres[2], "Smoke_tVoxBig");
+ }
+
+ density = smoke_turbulence_get_density(smd->domain->wt);
+ for (i = 0; i < bigres[0] * bigres[1] * bigres[2]; i++)
+ {
+ // Transparency computation
+ // formula taken from "Visual Simulation of Smoke" / Fedkiw et al. pg. 4
+ // T_vox = exp(-C_ext * h)
+ // C_ext/sigma_t = density * C_ext
+ smoke_set_bigtvox(smd, i, exp(-density[i] * 7.0 * smd->domain->dx / (smd->domain->amplify + 1)) );
+ }
+ smoke_calc_transparency(smd, light, 1);
+ */
+}
+
+
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 3e1b73e51be..fad45f1b6c3 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -65,20 +65,22 @@
extern "C" {
#endif
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-#ifndef M_PI_2
-#define M_PI_2 1.57079632679489661923
-#endif
-#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880
-#endif
-#ifndef M_SQRT1_2
-#define M_SQRT1_2 0.70710678118654752440
-#endif
-#ifndef M_1_PI
-#define M_1_PI 0.318309886183790671538
+# ifndef _WIN64
+ #ifndef M_PI
+ #define M_PI 3.14159265358979323846
+ #endif
+ #ifndef M_PI_2
+ #define M_PI_2 1.57079632679489661923
+ #endif
+ #ifndef M_SQRT2
+ #define M_SQRT2 1.41421356237309504880
+ #endif
+ #ifndef M_SQRT1_2
+ #define M_SQRT1_2 0.70710678118654752440
+ #endif
+ #ifndef M_1_PI
+ #define M_1_PI 0.318309886183790671538
+ #endif
#endif
#define MAXPATHLEN MAX_PATH
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index db811b22460..71994b97521 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3669,8 +3669,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
else if (md->type==eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData*) md;
- smd->point_cache = NULL;
-
if(smd->type==MOD_SMOKE_TYPE_DOMAIN)
{
smd->flow = NULL;
@@ -3679,23 +3677,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
smd->domain->smd = smd;
smd->domain->fluid = NULL;
- smd->domain->wt = NULL;
- smd->domain->tvox = NULL;
- smd->domain->tray = NULL;
- smd->domain->tvoxbig = NULL;
- smd->domain->traybig = NULL;
- smd->domain->bind = NULL;
- smd->domain->max_textures= 0;
-
- // do_versions trick
- if(smd->domain->strength < 1.0)
- smd->domain->strength = 2.0;
-
- // reset 3dview
- if(smd->domain->viewsettings < MOD_SMOKE_VIEW_USEBIG)
- smd->domain->viewsettings = 0;
- else
- smd->domain->viewsettings = MOD_SMOKE_VIEW_USEBIG;
+ smd->domain->view3d = NULL;
+ smd->domain->tex = NULL;
+
+ direct_link_pointcache_list(fd, &smd->domain->ptcaches, &smd->domain->point_cache);
}
else if(smd->type==MOD_SMOKE_TYPE_FLOW)
{
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index ede7aacfea8..31fe0c01900 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1126,14 +1126,17 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
else if(md->type==eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData*) md;
- if(smd->type==MOD_SMOKE_TYPE_DOMAIN)
+ if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
writestruct(wd, DATA, "SmokeDomainSettings", 1, smd->domain);
- else if(smd->type==MOD_SMOKE_TYPE_FLOW)
+ else if(smd->type & MOD_SMOKE_TYPE_FLOW)
writestruct(wd, DATA, "SmokeFlowSettings", 1, smd->flow);
/*
- else if(smd->type==MOD_SMOKE_TYPE_COLL)
+ else if(smd->type & MOD_SMOKE_TYPE_COLL)
writestruct(wd, DATA, "SmokeCollSettings", 1, smd->coll);
*/
+
+ if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+ write_pointcaches(wd, &smd->domain->ptcaches);
}
else if(md->type==eModifierType_Fluidsim) {
FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 9983e24f2c9..16900d6d894 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -161,6 +161,13 @@ int ED_object_modifier_remove(ReportList *reports, Scene *scene, Object *ob, Mod
DAG_scene_sort(scene);
}
+ else if(md->type == eModifierType_Smoke) {
+ ModifierData *tmd = modifiers_findByType(ob, eModifierType_SmokeHR);
+ if(tmd) {
+ BLI_remlink(&ob->modifiers, tmd);
+ modifier_free(tmd);
+ }
+ }
BLI_remlink(&ob->modifiers, md);
modifier_free(md);
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 530500cfafa..994bb0010d8 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -553,7 +553,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
"world", "object", "mesh", "armature", "lattice", "curve",
"meta_ball", "lamp", "camera", "material", "material_slot",
"texture", "texture_slot", "bone", "edit_bone", "particle_system",
- "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL};
+ "cloth", "soft_body", "fluid", "smoke", "smoke_hr", "collision", "brush", NULL};
CTX_data_dir_set(result, dir);
return 1;
@@ -697,6 +697,16 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
return 1;
}
}
+ else if(CTX_data_equals(member, "smoke_hr")) {
+ PointerRNA *ptr= get_pointer_type(path, &RNA_Object);
+
+ if(ptr && ptr->data) {
+ Object *ob= ptr->data;
+ ModifierData *md= modifiers_findByType(ob, eModifierType_SmokeHR);
+ CTX_data_pointer_set(result, &ob->id, &RNA_SmokeHRModifier, md);
+ return 1;
+ }
+ }
else if(CTX_data_equals(member, "collision")) {
PointerRNA *ptr= get_pointer_type(path, &RNA_Object);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 466b55ba862..55565c83f5e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -5309,356 +5309,20 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
}
/* draw code for smoke */
- if((md = modifiers_findByType(ob, eModifierType_Smoke)))
- {
- SmokeModifierData *smd = (SmokeModifierData *)md;
-
- // draw collision objects
- if((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll)
- {
- /*SmokeCollSettings *scs = smd->coll;
- if(scs->points)
- {
- size_t i;
-
- wmLoadMatrix(rv3d->viewmat);
-
- if(col || (ob->flag & SELECT)) cpack(0xFFFFFF);
- glDepthMask(GL_FALSE);
- glEnable(GL_BLEND);
-
-
- // glPointSize(3.0);
- bglBegin(GL_POINTS);
-
- for(i = 0; i < scs->numpoints; i++)
- {
- bglVertex3fv(&scs->points[3*i]);
- }
-
- bglEnd();
- glPointSize(1.0);
-
- wmMultMatrix(ob->obmat);
- glDisable(GL_BLEND);
- glDepthMask(GL_TRUE);
- if(col) cpack(col);
-
- }
- */
- }
-
- // only draw domains
- if(smd->domain && smd->domain->fluid)
- {
- int x, y, z, i;
- float viewnormal[3];
- int mainaxis[3] = {0,0,0};
- float align = 0, signed_align = 0;
- int max_textures = 0, counter_textures = 0;
- float *buffer = NULL;
- int res[3];
- float bigfactor = 1.0;
- int big = (smd->domain->flags & MOD_SMOKE_HIGHRES) && (smd->domain->viewsettings & MOD_SMOKE_VIEW_USEBIG);
- int new = 0;
- int have_lamp = 0;
-
- // GUI sent redraw event
- if(smd->domain->flags & MOD_SMOKE_VIEW_REDRAWNICE)
- {
- new = 1;
- smd->domain->flags &= ~MOD_SMOKE_VIEW_REDRAWNICE;
- }
-
- if(!big)
- {
- res[0] = smd->domain->res[0];
- res[1] = smd->domain->res[1];
- res[2] = smd->domain->res[2];
- }
- else
- {
- smoke_turbulence_get_res(smd->domain->wt, res);
- bigfactor = 1.0 / (smd->domain->amplify + 1);
- }
-
- wmLoadMatrix(rv3d->viewmat);
-
- if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visibility, also while wpaint */
- glDepthMask(GL_FALSE);
- glEnable(GL_BLEND);
-
- // get view vector
- VECCOPY(viewnormal, rv3d->viewinv[2]);
- Normalize(viewnormal);
- for(i = 0; i < 3; i++)
- {
- if(ABS(viewnormal[i]) > align)
- {
- mainaxis[0] = i;
- align = ABS(viewnormal[i]);
- signed_align = viewnormal[i];
- }
- }
- mainaxis[1] = (mainaxis[0] + 1) % 3;
- mainaxis[2] = (mainaxis[0] + 2) % 3;
-
- if(!smd->domain->bind)
- {
- smd->domain->bind = MEM_callocN(sizeof(GLuint)*256, "Smoke_bind");
- if(big)
- smd->domain->viewsettings |= MOD_SMOKE_VIEW_CHANGETOBIG;
- new = 3;
- }
-
- // check if view axis / mode has been changed
- if(smd->domain->viewsettings)
- {
- if(big)
- {
- if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_BIG))
- new = 2;
- else if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_CHANGETOBIG))
- new = 1;
-
- smd->domain->viewsettings |= MOD_SMOKE_VIEW_CHANGETOBIG;
- }
- else
- {
- if(!(smd->domain->viewsettings & MOD_SMOKE_VIEW_SMALL))
- new = 2;
- else if(smd->domain->viewsettings & MOD_SMOKE_VIEW_CHANGETOBIG)
- new = 1;
-
- smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_CHANGETOBIG;
- }
-
- if(!new)
- {
- if((mainaxis[0] == 0) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_X))
- new = 1;
- else if((mainaxis[0] == 1) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_Y))
- new = 1;
- else if((mainaxis[0] == 2) && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_Z))
- new = 1;
-
- // printf("check axis\n");
- }
- }
- else
- new = 3;
-
- if(new > 1)
- {
- float light[3] = {0.0,0.0,0.0}; // TODO: take real LAMP coordinates - dg
- Base *base_tmp = NULL;
-
- for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
- {
- if(base_tmp->object->type == OB_LAMP)
- {
- Lamp *la = (Lamp *)base_tmp->object->data;
-
- if(la->type == LA_LOCAL)
- {
- VECCOPY(light, base_tmp->object->obmat[3]);
- have_lamp = 1;
- break;
- }
- }
- }
-
- if(!big && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SMALL))
- {
- smoke_prepare_View(smd, light);
- // printf("prepared View!\n");
- }
- else if(big && !(smd->domain->viewsettings & MOD_SMOKE_VIEW_BIG))
- {
- smoke_prepare_bigView(smd, light);
- // printf("prepared bigView!\n");
- }
- }
-
- // printf("big: %d, new: %d\n", big, new);
-
- // only create buffer if we need to create new textures
- if(new)
- buffer = MEM_mallocN(sizeof(float)*res[mainaxis[1]]*res[mainaxis[2]]*4, "SmokeDrawBuffer");
-
- if(buffer || smd->domain->viewsettings)
- {
- int mod_texture = 0;
-
- // printf("if(buffer || smd->domain->viewsettings)\n");
-
- max_textures = (res[mainaxis[0]] > 256) ? 256 : res[mainaxis[0]];
-
- if(!smd->domain->viewsettings) // new frame or new start
- {
- smd->domain->max_textures = max_textures;
- glGenTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
- new = 1;
- // printf("glGenTextures\n");
- }
- else
- {
- if(new)
- {
- // printf("glDeleteTextures\n");
- glDeleteTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
- smd->domain->max_textures = max_textures;
- glGenTextures(smd->domain->max_textures, (GLuint *)smd->domain->bind);
- }
- }
-
- mod_texture = MAX3(1, smd->domain->visibility, (int)(res[mainaxis[0]] / smd->domain->max_textures ));
-
- // align order of billboards to be front or backview (e.g. +x or -x axis)
- if(signed_align < 0)
- {
- z = res[mainaxis[0]] - 1;
- }
- else
- {
- z = 0;
- }
-
- for (; signed_align > 0 ? (z < res[mainaxis[0]]) : (z >= 0); signed_align > 0 ? z++ : z--) // 2
- {
- float quad[4][3];
-
- if(new)
- {
- for (y = 0; y < res[mainaxis[1]]; y++) // 1
- {
- for (x = 0; x < res[mainaxis[2]]; x++) // 0
- {
- size_t index;
- size_t image_index;
- float tray, tvox;
-
- image_index = smoke_get_index2d(y, res[mainaxis[1]], x);
-
- if(mainaxis[0] == 0)
- {
- // mainaxis[1] == 1, mainaxis[2] == 2
- index = smoke_get_index(z, res[mainaxis[0]], y, res[mainaxis[1]], x);
- }
- else if(mainaxis[0] == 1)
- {
- // mainaxis[1] == 2, mainaxis[2] == 0
- index = smoke_get_index(x, res[mainaxis[2]], z, res[mainaxis[0]], y);
- }
- else // mainaxis[0] == 2
- {
- // mainaxis[1] == 0, mainaxis[2] == 1
- index = smoke_get_index(y, res[mainaxis[1]], x, res[mainaxis[2]], z);
- }
-
- if(!big)
- {
- tvox = smoke_get_tvox(smd, index);
- tray = smoke_get_tray(smd, index);
- }
- else
- {
- tvox = smoke_get_bigtvox(smd, index);
- tray = smoke_get_bigtray(smd, index);
- }
-
- if(!have_lamp)
- tray = 1.0;
-
- // fill buffer with luminance and alpha
- // 1 - T_vox
- buffer[image_index*4 + 3] = 1.0 - tvox; // 0 = transparent => d.h. tvox = 1
-
- // L_vox = Omega * L_light * (1 - T_vox) * T_ray
- buffer[image_index*4] = buffer[image_index*4 + 1] = buffer[image_index*4 + 2] = smd->domain->omega * 1.0 * tvox * tray;
- }
- }
- }
- glBindTexture(GL_TEXTURE_2D, smd->domain->bind[counter_textures]);
- glEnable(GL_TEXTURE_2D);
-
- if(new)
- {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res[mainaxis[1]], res[mainaxis[2]], 0, GL_RGBA, GL_FLOAT, buffer);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
- }
-
- if((z % mod_texture) == 0 )
- {
- // botttom left
- quad[3][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
- quad[3][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + smd->domain->dx * bigfactor * 0.5;
- quad[3][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + smd->domain->dx * bigfactor * 0.5;
-
- // top right
- quad[1][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
- quad[1][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + (res[mainaxis[1]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
- quad[1][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + (res[mainaxis[2]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
-
- // top left
- quad[2][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
- quad[2][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + smd->domain->dx * bigfactor * 0.5;
- quad[2][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + (res[mainaxis[2]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
-
- // bottom right
- quad[0][mainaxis[0]] = smd->domain->p0[mainaxis[0]] + z * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
- quad[0][mainaxis[1]] = smd->domain->p0[mainaxis[1]] + (res[mainaxis[1]] - 1) * smd->domain->dx * bigfactor + smd->domain->dx * bigfactor * 0.5;
- quad[0][mainaxis[2]] = smd->domain->p0[mainaxis[2]] + smd->domain->dx * bigfactor * 0.5;
-
- glBegin(GL_QUADS); // Start Drawing Quads
-
- glTexCoord2f(1.0f, 0.0f);
- glVertex3fv(quad[0]); // Left And Up 1 Unit (Top Left)
- glTexCoord2f(1.0f, 1.0f);
- glVertex3fv(quad[1]); // Right And Up 1 Unit (Top Right)
- glTexCoord2f(0.0f, 1.0f);
- glVertex3fv(quad[2]); // Right And Down One Unit (Bottom Right)
- glTexCoord2f(0.0f, 0.0f);
- glVertex3fv(quad[3]); // Left And Down One Unit (Bottom Left)
-
- glEnd();
- }
- counter_textures++;
- }
- }
- if(buffer)
- {
- MEM_freeN(buffer);
- buffer = NULL;
- }
-
- // set correct flag for viewsettings
- if(1)
- {
- // do not clear BIG/SMALL flag
- smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_X;
- smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_Y;
- smd->domain->viewsettings &= ~MOD_SMOKE_VIEW_Z;
-
- // set what caches we have
- if(big)
- smd->domain->viewsettings |= MOD_SMOKE_VIEW_BIG;
- else
- smd->domain->viewsettings |= MOD_SMOKE_VIEW_SMALL;
-
- if(mainaxis[0] == 0)
- smd->domain->viewsettings |= MOD_SMOKE_VIEW_X;
- else if(mainaxis[0] == 1)
- smd->domain->viewsettings |= MOD_SMOKE_VIEW_Y;
- else if(mainaxis[0] == 2)
- smd->domain->viewsettings |= MOD_SMOKE_VIEW_Z;
+ if(((SmokeHRModifierData *)(md = modifiers_findByType(ob, eModifierType_SmokeHR)) && (((SmokeHRModifierData *)md)->flags & MOD_SMOKE_SHOWHIGHRES))) {
+ // GPU_create_smoke(smd);
+ // draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res);
+ // GPU_free_smoke(smd);
+ }
+ else {
+ md = modifiers_findByType(ob, eModifierType_Smoke);
+ if (md) {
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+ if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain) {
+ GPU_create_smoke(smd);
+ draw_volume(scene, ar, v3d, base, smd->domain->tex, smd->domain->res);
+ GPU_free_smoke(smd);
}
-
- wmMultMatrix(ob->obmat);
- glDisable(GL_BLEND);
- glDepthMask(GL_TRUE);
- if(col) cpack(col);
}
}
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
new file mode 100644
index 00000000000..221003360f4
--- /dev/null
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -0,0 +1,304 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): Daniel Genrich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+
+#include <string.h>
+#include <math.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf.h"
+
+
+#include "MTC_matrixops.h"
+
+#include "DNA_armature_types.h"
+#include "DNA_boid_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_constraint_types.h" // for drawing constraint
+#include "DNA_effect_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_object_fluidsim.h"
+#include "DNA_particle_types.h"
+#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_smoke_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
+#include "BLI_rand.h"
+
+#include "BKE_anim.h" //for the where_on_path function
+#include "BKE_curve.h"
+#include "BKE_constraint.h" // for the get_constraint_target function
+#include "BKE_DerivedMesh.h"
+#include "BKE_deform.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_font.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_key.h"
+#include "BKE_lattice.h"
+#include "BKE_mesh.h"
+#include "BKE_material.h"
+#include "BKE_mball.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_particle.h"
+#include "BKE_property.h"
+#include "BKE_smoke.h"
+#include "BKE_unit.h"
+#include "BKE_utildefines.h"
+#include "smoke_API.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "GPU_draw.h"
+#include "GPU_material.h"
+#include "GPU_extensions.h"
+
+#include "ED_mesh.h"
+#include "ED_particle.h"
+#include "ED_screen.h"
+#include "ED_types.h"
+#include "ED_util.h"
+
+#include "UI_resources.h"
+#include "UI_interface_icons.h"
+
+#include "WM_api.h"
+#include "BLF_api.h"
+
+#include "GPU_extensions.h"
+
+#include "view3d_intern.h" // own include
+
+struct GPUTexture;
+
+/* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */
+static float cv[][3] = {
+ {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
+ {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
+};
+
+// edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
+static float edges[12][2][3] = {
+ {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
+ {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
+ {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
+ {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
+
+ {{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
+ {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
+ {{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
+ {{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
+
+ {{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
+ {{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
+ {{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
+ {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}
+};
+
+int intersect_edges(float *points, float a, float b, float c, float d)
+{
+ int i;
+ float t;
+ int numpoints = 0;
+
+ for (i=0; i<12; i++) {
+ t = -(a*edges[i][0][0] + b*edges[i][0][1] + c*edges[i][0][2] + d)
+ / (a*edges[i][1][0] + b*edges[i][1][1] + c*edges[i][1][2]);
+ if ((t>0)&&(t<2)) {
+ points[numpoints * 3 + 0] = edges[i][0][0] + edges[i][1][0]*t;
+ points[numpoints * 3 + 1] = edges[i][0][1] + edges[i][1][1]*t;
+ points[numpoints * 3 + 2] = edges[i][0][2] + edges[i][1][2]*t;
+ numpoints++;
+ }
+ }
+ return numpoints;
+}
+
+static int convex(float *p0, float *up, float *a, float *b)
+{
+ // Vec3 va = a-p0, vb = b-p0;
+ float va[3], vb[3], tmp[3];
+ VECSUB(va, a, p0);
+ VECSUB(vb, b, p0);
+ Crossf(tmp, va, vb);
+ return INPR(up, tmp) >= 0;
+}
+
+// copied from gpu_extension.c
+static int is_pow2(int n)
+{
+ return ((n)&(n-1))==0;
+}
+
+static int larger_pow2(int n)
+{
+ if (is_pow2(n))
+ return n;
+
+ while(!is_pow2(n))
+ n= n&(n-1);
+
+ return n*2;
+}
+
+void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, int res[3])
+{
+ Object *ob = base->object;
+ RegionView3D *rv3d= ar->regiondata;
+
+ float viewnormal[3];
+ // int res[3];
+ int i, j, n;
+ float d, d0, dd;
+ float *points = NULL;
+ int numpoints = 0;
+ float cor[3] = {1.,1.,1.};
+
+ /*
+ res[0] = smd->domain->res[0];
+ res[1] = smd->domain->res[1];
+ res[2] = smd->domain->res[2];
+ */
+
+ wmLoadMatrix(rv3d->viewmat);
+
+ glDepthMask(GL_FALSE);
+ glEnable(GL_TEXTURE_3D);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // get view vector
+ VECCOPY(viewnormal, rv3d->viewinv[2]);
+ Normalize(viewnormal);
+
+ // find cube vertex that is closest to the viewer
+ for (i=0; i<8; i++) {
+ float x,y,z;
+
+ x = cv[i][0] + viewnormal[0];
+ y = cv[i][1] + viewnormal[1];
+ z = cv[i][2] + viewnormal[2];
+
+ if ((x>=-1.0f)&&(x<=1.0f)
+ &&(y>=-1.0f)&&(y<=1.0f)
+ &&(z>=-1.0f)&&(z<=1.0f)) {
+ break;
+ }
+ }
+
+ GPU_texture_bind(tex, 0);
+
+ cor[0] = (float)res[0]/(float)larger_pow2(res[0]);
+ cor[1] = (float)res[1]/(float)larger_pow2(res[1]);
+ cor[2] = (float)res[2]/(float)larger_pow2(res[2]);
+
+ // our slices are defined by the plane equation a*x + b*y +c*z + d = 0
+ // (a,b,c), the plane normal, are given by viewdir
+ // d is the parameter along the view direction. the first d is given by
+ // inserting previously found vertex into the plane equation
+ d0 = -(viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]);
+ dd = 2.0*d0/64.0f;
+ n = 0;
+
+ // printf("d0: %f, dd: %f\n", d0, dd);
+
+ points = MEM_callocN(sizeof(float)*12*3, "smoke_points_preview");
+
+ for (d = d0; d > -d0; d -= dd) {
+ float p0[3];
+ // intersect_edges returns the intersection points of all cube edges with
+ // the given plane that lie within the cube
+ numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], d);
+
+ if (numpoints > 2) {
+ VECCOPY(p0, points);
+
+ // sort points to get a convex polygon
+ for(i = 1; i < numpoints - 1; i++)
+ {
+ for(j = i + 1; j < numpoints; j++)
+ {
+ if(convex(p0, viewnormal, &points[j * 3], &points[i * 3]))
+ {
+ float tmp2[3];
+ VECCOPY(tmp2, &points[i * 3]);
+ VECCOPY(&points[i * 3], &points[j * 3]);
+ VECCOPY(&points[j * 3], tmp2);
+ }
+ }
+ }
+
+ glBegin(GL_POLYGON);
+ for (i = 0; i < numpoints; i++) {
+ glColor3f(1.0, 1.0, 1.0);
+ glTexCoord3d((points[i * 3 + 0] + 1.0)*cor[0]/2.0, (points[i * 3 + 1] + 1)*cor[1]/2.0, (points[i * 3 + 2] + 1.0)*cor[2]/2.0);
+ glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
+ }
+ glEnd();
+ }
+ n++;
+ }
+
+ GPU_texture_unbind(tex);
+
+ MEM_freeN(points);
+
+ wmMultMatrix(ob->obmat);
+
+ glDisable(GL_TEXTURE_3D);
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+}
+
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index acd1c62bc17..e5e85cf9d16 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -156,6 +156,9 @@ void VIEW3D_OT_snap_menu(struct wmOperatorType *ot);
ARegion *view3d_has_buttons_region(ScrArea *sa);
ARegion *view3d_has_tools_region(ScrArea *sa);
+/* draw_volume.c */
+void draw_volume(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct Base *base, struct GPUTexture *tex, int res[3]);
+
#endif /* ED_VIEW3D_INTERN_H */
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index 82ff51dc5ce..1c6b8399422 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -112,6 +112,10 @@ int GPU_verify_image(struct Image *ima, int tftile, int tfmode, int compare, int
void GPU_free_image(struct Image *ima);
void GPU_free_images(void);
+/* smoke drawing functions */
+void GPU_free_smoke(struct SmokeModifierData *smd);
+void GPU_create_smoke(struct SmokeModifierData *smd);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index eba585e8838..e00cab79ce0 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -73,6 +73,7 @@ int GPU_print_error(char *str);
GPUTexture *GPU_texture_create_1D(int w, float *pixels);
GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels);
+GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels);
GPUTexture *GPU_texture_create_depth(int w, int h);
GPUTexture *GPU_texture_from_blender(struct Image *ima,
struct ImageUser *iuser, double time, int mipmap);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index e7846a23905..a81c7e03455 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -38,9 +38,11 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_smoke_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
@@ -744,6 +746,23 @@ int GPU_update_image_time(Image *ima, double time)
return inc;
}
+
+void GPU_free_smoke(SmokeModifierData *smd)
+{
+ if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain)
+ {
+ if(smd->domain->tex)
+ GPU_texture_free(smd->domain->tex);
+ smd->domain->tex = NULL;
+ }
+}
+
+void GPU_create_smoke(SmokeModifierData *smd)
+{
+ if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && !smd->domain->tex)
+ smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->view3d);
+}
+
void GPU_free_image(Image *ima)
{
/* free regular image binding */
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 467b2c4a7f4..0b6640b9e27 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -312,6 +312,78 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
return tex;
}
+
+GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels)
+{
+ GPUTexture *tex;
+ GLenum type, format, internalformat;
+ void *pixels = NULL;
+
+ tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ tex->w = w;
+ tex->h = h;
+ tex->depth = depth;
+ tex->number = -1;
+ tex->refcount = 1;
+ tex->target = GL_TEXTURE_3D;
+
+ glGenTextures(1, &tex->bindcode);
+
+ if (!tex->bindcode) {
+ fprintf(stderr, "GPUTexture: texture create failed: %d\n",
+ (int)glGetError());
+ GPU_texture_free(tex);
+ return NULL;
+ }
+
+ // if (!GLEW_ARB_texture_non_power_of_two)
+ {
+ tex->w = larger_pow2(tex->w);
+ tex->h = larger_pow2(tex->h);
+ tex->depth = larger_pow2(tex->depth);
+ }
+
+ tex->number = 0;
+ glBindTexture(tex->target, tex->bindcode);
+
+ type = GL_UNSIGNED_BYTE;
+ format = GL_RGBA;
+ internalformat = GL_RGBA8;
+
+ if (fpixels)
+ pixels = GPU_texture_convert_pixels(w*h*depth, fpixels);
+
+ glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, 0);
+
+ if (fpixels) {
+ glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, pixels);
+
+ /*
+ if (tex->w > w)
+ GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h);
+ if (tex->h > h)
+ GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h);
+ */
+ }
+
+ // glTexImage3D(tex->target, 0, GL_RGBA, w, h, depth, 0, GL_RGBA, GL_FLOAT, fpixels);
+
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,GL_CLAMP_TO_BORDER);
+
+
+ if (pixels)
+ MEM_freeN(pixels);
+
+ if (tex)
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, double time, int mipmap)
{
GPUTexture *tex;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 9d1707599b9..33499574012 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -42,6 +42,7 @@ typedef enum ModifierType {
eModifierType_Multires,
eModifierType_Surface,
eModifierType_Smoke,
+ eModifierType_SmokeHR,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -252,9 +253,36 @@ typedef struct SmokeModifierData {
struct SmokeCollSettings *coll; /* collision objects */
float time;
int type; /* domain, inflow, outflow, ... */
- struct PointCache *point_cache; /* definition is in DNA_object_force.h */
} SmokeModifierData;
+
+/* noise */
+#define MOD_SMOKE_NOISEWAVE (1<<0)
+#define MOD_SMOKE_NOISEFFT (1<<1)
+#define MOD_SMOKE_NOISECURL (1<<2)
+
+/* flags */
+#define MOD_SMOKE_SHOWHIGHRES (1<<0) /* show high resolution */
+
+typedef struct SmokeHRModifierData {
+ ModifierData modifier;
+
+ struct WTURBULENCE *wt; // WTURBULENCE object, if active
+ struct PointCache *point_cache; /* definition is in DNA_object_force.h */
+ struct ListBase ptcaches;
+ struct GPUTexture *tex;
+ float *view3d; /* voxel data for display */
+ unsigned int v3dnum; /* number of frame in view3d buffer */
+ float time;
+ float strength;
+ int res[3];
+ int maxres;
+ short noise; /* noise type: wave, curl, anisotropic */
+ short pad;
+ int amplify;
+ int flags;
+} SmokeHRModifierData;
+
typedef struct DisplaceModifierData {
ModifierData modifier;
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index c7f49d3ddd2..2d8b21b86de 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -30,24 +30,12 @@
#define DNA_SMOKE_TYPES_H
/* flags */
-#define MOD_SMOKE_HIGHRES (1<<1) /* compute high resolution */
+#define MOD_SMOKE_HIGHRES (1<<1) /* enable high resolution */
#define MOD_SMOKE_DISSOLVE (1<<2) /* let smoke dissolve */
#define MOD_SMOKE_DISSOLVE_LOG (1<<3) /* using 1/x for dissolve */
-/* noise */
-#define MOD_SMOKE_NOISEWAVE (1<<0)
-#define MOD_SMOKE_NOISEFFT (1<<1)
-#define MOD_SMOKE_NOISECURL (1<<2)
/* viewsettings */
-#define MOD_SMOKE_VIEW_X (1<<0)
-#define MOD_SMOKE_VIEW_Y (1<<1)
-#define MOD_SMOKE_VIEW_Z (1<<2)
-#define MOD_SMOKE_VIEW_SMALL (1<<3)
-#define MOD_SMOKE_VIEW_BIG (1<<4)
-#define MOD_SMOKE_VIEW_CHANGETOBIG (1<<5)
-#define MOD_SMOKE_VIEW_REDRAWNICE (1<<6)
-#define MOD_SMOKE_VIEW_REDRAWALL (1<<7)
-#define MOD_SMOKE_VIEW_USEBIG (1<<8)
+/* nothing so far */
typedef struct SmokeDomainSettings {
struct SmokeModifierData *smd; /* for fast RNA access */
@@ -55,33 +43,27 @@ typedef struct SmokeDomainSettings {
struct Group *fluid_group;
struct Group *eff_group; // effector group for e.g. wind force
struct Group *coll_group; // collision objects group
- unsigned int *bind;
- float *tvox;
- float *tray;
- float *tvoxbig;
- float *traybig;
+ struct GPUTexture *tex;
+ float *view3d; /* voxel data for display */
+ unsigned int v3dnum; /* number of frame in view3d buffer */
float p0[3]; /* start point of BB */
float p1[3]; /* end point of BB */
float dx; /* edge length of one cell */
float firstframe;
float lastframe;
- float omega; /* smoke color - from 0 to 1 */
float temp; /* fluid temperature */
float tempAmb; /* ambient temperature */
float alpha;
float beta;
int res[3]; /* domain resolution */
- int amplify; /* wavelet amplification */
int maxres; /* longest axis on the BB gets this resolution assigned */
int flags; /* show up-res or low res, etc */
- int visibility; /* how many billboards to show (every 2nd, 3rd, 4th,..) */
int viewsettings;
- int max_textures;
- short noise; /* noise type: wave, curl, anisotropic */
short diss_percent;
+ short pad;
int diss_speed;/* in frames */
- float strength;
- struct WTURBULENCE *wt; // WTURBULENCE object, if active
+ struct PointCache *point_cache; /* definition is in DNA_object_force.h */
+ struct ListBase ptcaches;
} SmokeDomainSettings;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index e08bc734242..e4fe92317d4 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -387,6 +387,7 @@ extern StructRNA RNA_SmokeCollSettings;
extern StructRNA RNA_SmokeDomainSettings;
extern StructRNA RNA_SmokeFlowSettings;
extern StructRNA RNA_SmokeModifier;
+extern StructRNA RNA_SmokeHRModifier;
extern StructRNA RNA_SmoothModifier;
extern StructRNA RNA_SoftBodyModifier;
extern StructRNA RNA_SoftBodySettings;
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 837158b9ec8..f2c8e404a52 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -68,6 +68,7 @@ EnumPropertyItem modifier_type_items[] ={
{eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""},
{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
{eModifierType_Smoke, "SMOKE", 0, "Smoke", ""},
+ {eModifierType_SmokeHR, "SMOKE_HR", 0, "SmokeHR", ""},
{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
@@ -156,6 +157,8 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_SurfaceModifier;
case eModifierType_Smoke:
return &RNA_SmokeModifier;
+ case eModifierType_SmokeHR:
+ return &RNA_SmokeHRModifier;
default:
return &RNA_Modifier;
}
@@ -181,19 +184,30 @@ static void rna_Smoke_set_type(bContext *C, PointerRNA *ptr)
{
SmokeModifierData *smd= (SmokeModifierData *)ptr->data;
Object *ob= (Object*)ptr->id.data;
+
+ // nothing changed
+ if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+ return;
smokeModifier_free(smd); // XXX TODO: completely free all 3 pointers
smokeModifier_createType(smd); // create regarding of selected type
- // particle_system_slot_add_exec(C, NULL);
- // particle_system_slot_remove_exec(C, NULL);
- if(smd->type == MOD_SMOKE_TYPE_DOMAIN)
+ if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
ob->dt = OB_WIRE;
// update dependancy since a domain - other type switch could have happened
rna_Modifier_dependency_update(C, ptr);
}
+static void rna_SmokeHR_reset(bContext *C, PointerRNA *ptr)
+{
+ // SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data;
+
+ // smokeModifier_reset(settings->smd);
+
+ // rna_Smoke_update(C, ptr);
+}
+
static void rna_ExplodeModifier_vgroup_get(PointerRNA *ptr, char *value)
{
ExplodeModifierData *emd= (ExplodeModifierData*)ptr->data;
@@ -1499,6 +1513,55 @@ static void rna_def_modifier_cloth(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Point Cache", "");
}
+static void rna_def_modifier_smoke_highresolution(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_noise_type_items[] = {
+ {MOD_SMOKE_NOISEWAVE, "NOISEWAVE", 0, "Wavelet", ""},
+#if FFTW3 == 1
+ {MOD_SMOKE_NOISEFFT, "NOISEFFT", 0, "FFT", ""},
+#endif
+ /* {MOD_SMOKE_NOISECURL, "NOISECURL", 0, "Curl", ""}, */
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "SmokeHRModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Smoke High Resolution Modifier", "Smoke high resolution simulation modifier.");
+ RNA_def_struct_sdna(srna, "SmokeHRModifierData");
+
+ prop= RNA_def_property(srna, "show_highres", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_SHOWHIGHRES);
+ RNA_def_property_ui_text(prop, "High res", "Show high resolution (using amplification).");
+ RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
+
+ prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noise");
+ RNA_def_property_enum_items(prop, prop_noise_type_items);
+ RNA_def_property_ui_text(prop, "Noise Method", "Noise method which is used for creating the high resolution");
+ RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_SmokeHR_reset");
+
+ prop= RNA_def_property(srna, "amplify", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "amplify");
+ RNA_def_property_range(prop, 1, 10);
+ RNA_def_property_ui_range(prop, 1, 10, 1, 0);
+ RNA_def_property_ui_text(prop, "Amplification", "Enhance the resolution of smoke by this factor using noise.");
+ RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_SmokeHR_reset");
+
+ prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "strength");
+ RNA_def_property_range(prop, 1.0, 10.0);
+ RNA_def_property_ui_range(prop, 1.0, 10.0, 1, 2);
+ RNA_def_property_ui_text(prop, "Strength", "Strength of wavelet noise");
+ RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_SmokeHR_reset");
+
+ prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "point_cache");
+ RNA_def_property_struct_type(prop, "PointCache");
+ RNA_def_property_ui_text(prop, "Point Cache", "");
+
+}
+
static void rna_def_modifier_smoke(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1915,6 +1978,7 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_multires(brna);
rna_def_modifier_surface(brna);
rna_def_modifier_smoke(brna);
+ rna_def_modifier_smoke_highresolution(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 6f1babb495a..a119eefa62c 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -78,11 +78,28 @@ static void rna_Smoke_reset_dependancy(bContext *C, PointerRNA *ptr)
rna_Smoke_dependency_update(C, ptr);
}
+static void rna_Smoke_enable_HR(bContext *C, PointerRNA *ptr)
+{
+ SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data;
+ Object *ob = (Object*)ptr->id.data;
+
+ if(settings->flags & MOD_SMOKE_HIGHRES)
+ BLI_addtail(&ob->modifiers, modifier_new(eModifierType_SmokeHR));
+ else
+ {
+ ModifierData *tmd = modifiers_findByType(ob, eModifierType_SmokeHR);
+ if(tmd) {
+ BLI_remlink(&ob->modifiers, tmd);
+ modifier_free(tmd);
+ }
+ }
+}
+
static void rna_Smoke_redraw(bContext *C, PointerRNA *ptr)
{
SmokeDomainSettings *settings = (SmokeDomainSettings*)ptr->data;
- settings->flags |= MOD_SMOKE_VIEW_REDRAWNICE;
+ // settings->flags |= MOD_SMOKE_VIEW_REDRAWNICE;
}
static char *rna_SmokeDomainSettings_path(PointerRNA *ptr)
@@ -116,14 +133,6 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem prop_noise_type_items[] = {
- {MOD_SMOKE_NOISEWAVE, "NOISEWAVE", 0, "Wavelet", ""},
-#if FFTW3 == 1
- {MOD_SMOKE_NOISEFFT, "NOISEFFT", 0, "FFT", ""},
-#endif
- /* {MOD_SMOKE_NOISECURL, "NOISECURL", 0, "Curl", ""}, */
- {0, NULL, 0, NULL, NULL}};
-
srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL);
RNA_def_struct_ui_text(srna, "Domain Settings", "Smoke domain settings.");
RNA_def_struct_sdna(srna, "SmokeDomainSettings");
@@ -136,56 +145,19 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Max Res", "Maximal resolution used in the fluid domain.");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
- prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "omega");
- RNA_def_property_range(prop, 0.02, 1.0);
- RNA_def_property_ui_range(prop, 0.02, 1.0, 0.02, 2);
- RNA_def_property_ui_text(prop, "Color", "Smoke color (0 = black, 1 = white).");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Smoke_redraw");
-
- prop= RNA_def_property(srna, "amplify", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "amplify");
- RNA_def_property_range(prop, 1, 10);
- RNA_def_property_ui_range(prop, 1, 10, 1, 0);
- RNA_def_property_ui_text(prop, "Amplification", "Enhance the resolution of smoke by this factor using noise.");
- RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
-
- prop= RNA_def_property(srna, "highres", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGHRES);
- RNA_def_property_ui_text(prop, "High res", "Enable high resolution (using amplification).");
- RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
-
- prop= RNA_def_property(srna, "viewhighres", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "viewsettings", MOD_SMOKE_VIEW_USEBIG);
- RNA_def_property_ui_text(prop, "Show High Resolution", "Show high resolution (using amplification).");
- RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_redraw");
-
- prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "noise");
- RNA_def_property_enum_items(prop, prop_noise_type_items);
- RNA_def_property_ui_text(prop, "Noise Method", "Noise method which is used for creating the high resolution");
- RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
-
- prop= RNA_def_property(srna, "visibility", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "visibility");
- RNA_def_property_range(prop, 1, 15);
- RNA_def_property_ui_range(prop, 1, 15, 1, 0);
- RNA_def_property_ui_text(prop, "Display", "How much of the resolution should be shown during preview (every 2nd, 3rd, etc).");
- RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Smoke_redraw");
-
prop= RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "alpha");
RNA_def_property_range(prop, -5.0, 5.0);
RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5);
RNA_def_property_ui_text(prop, "Gravity", "Higher value results in sinking smoke");
- RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
+ RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
prop= RNA_def_property(srna, "beta", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "beta");
RNA_def_property_range(prop, -5.0, 5.0);
RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5);
RNA_def_property_ui_text(prop, "Heat", "Higher value results in faster rising smoke.");
- RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
+ RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
prop= RNA_def_property(srna, "coll_group", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "coll_group");
@@ -208,13 +180,6 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Effector Group", "Limit effectors to this group.");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset_dependancy");
- prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "strength");
- RNA_def_property_range(prop, 1.0, 10.0);
- RNA_def_property_ui_range(prop, 1.0, 10.0, 1, 2);
- RNA_def_property_ui_text(prop, "Strength", "Strength of wavelet noise");
- RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_reset");
-
prop= RNA_def_property(srna, "dissolve_speed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "diss_speed");
RNA_def_property_range(prop, 1.0, 100.0);
@@ -222,6 +187,11 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
+ prop= RNA_def_property(srna, "highres", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGHRES);
+ RNA_def_property_ui_text(prop, "High Resolution Smoke", "Enable high resolution smoke");
+ RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, "rna_Smoke_enable_HR");
+
prop= RNA_def_property(srna, "dissolve_smoke", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE);
RNA_def_property_ui_text(prop, "Dissolve Smoke", "Enable smoke to disappear over time.");
@@ -231,6 +201,11 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE_LOG);
RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x ");
RNA_def_property_update(prop, NC_OBJECT|ND_MODIFIER, NULL);
+
+ prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "point_cache");
+ RNA_def_property_struct_type(prop, "PointCache");
+ RNA_def_property_ui_text(prop, "Point Cache", "");
}
static void rna_def_smoke_flow_settings(BlenderRNA *brna)
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 3a2cef2d038..3b95c409b30 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -319,6 +319,8 @@ IF(UNIX)
bf_dummy
bf_bullet
bf_smoke
+ bf_minilzo
+ bf_lzma
bf_common
bf_ketsji
bf_logic