diff options
Diffstat (limited to 'dep/StormLib/src')
271 files changed, 0 insertions, 64801 deletions
diff --git a/dep/StormLib/src/FileStream.cpp b/dep/StormLib/src/FileStream.cpp deleted file mode 100644 index 413f2acb3a2..00000000000 --- a/dep/StormLib/src/FileStream.cpp +++ /dev/null @@ -1,2294 +0,0 @@ -/*****************************************************************************/ -/* FileStream.cpp Copyright (c) Ladislav Zezula 2010 */ -/*---------------------------------------------------------------------------*/ -/* File stream support for StormLib */ -/* */ -/* Windows support: Written by Ladislav Zezula */ -/* Mac support: Written by Sam Wilkins */ -/* Linux support: Written by Sam Wilkins and Ivan Komissarov */ -/* Big-endian: Written & debugged by Sam Wilkins */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 11.06.10 1.00 Lad Derived from StormPortMac.cpp and StormPortLinux.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" -#include "FileStream.h" - -#ifdef _MSC_VER -#pragma comment(lib, "wininet.lib") -#endif - -//----------------------------------------------------------------------------- -// Local defines - -#ifndef INVALID_HANDLE_VALUE -#define INVALID_HANDLE_VALUE ((HANDLE)-1) -#endif - -#ifdef _MSC_VER -#pragma warning(disable: 4800) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) -#endif - -//----------------------------------------------------------------------------- -// Local functions - platform-specific functions - -#ifndef PLATFORM_WINDOWS -static int nLastError = ERROR_SUCCESS; - -int GetLastError() -{ - return nLastError; -} - -void SetLastError(int nError) -{ - nLastError = nError; -} -#endif - -#ifndef PLATFORM_LITTLE_ENDIAN -void ConvertPartHeader(void * partHeader) -{ - PPART_FILE_HEADER theHeader = (PPART_FILE_HEADER)partHeader; - - theHeader->PartialVersion = SwapUInt32(theHeader->PartialVersion); - theHeader->Flags = SwapUInt32(theHeader->Flags); - theHeader->FileSizeLo = SwapUInt32(theHeader->FileSizeLo); - theHeader->FileSizeHi = SwapUInt32(theHeader->FileSizeHi); - theHeader->BlockSize = SwapUInt32(theHeader->BlockSize); -} -#endif - -//----------------------------------------------------------------------------- -// Preparing file bitmap for a complete file of a given size - -#define DEFAULT_BLOCK_SIZE 0x4000 - -static bool Dummy_GetBitmap( - TFileStream * pStream, - TFileBitmap * pBitmap, - DWORD Length, - LPDWORD LengthNeeded) -{ - ULONGLONG FileSize = 0; - DWORD TotalLength; - DWORD BlockCount; - DWORD BitmapSize; - DWORD LastByte; - bool bResult = false; - - // Get file size and calculate bitmap length - FileStream_GetSize(pStream, FileSize); - BlockCount = (DWORD)(((FileSize - 1) / DEFAULT_BLOCK_SIZE) + 1); - BitmapSize = (DWORD)(((BlockCount - 1) / 8) + 1); - - // Calculate and give the total length - TotalLength = sizeof(TFileBitmap) + BitmapSize; - if(LengthNeeded != NULL) - *LengthNeeded = TotalLength; - - // Has the caller given enough space for storing the structure? - if(Length >= sizeof(TFileBitmap)) - { - memset(pBitmap, 0, sizeof(TFileBitmap)); - pBitmap->EndOffset = FileSize; - pBitmap->IsComplete = 1; - pBitmap->BitmapSize = BitmapSize; - pBitmap->BlockSize = DEFAULT_BLOCK_SIZE; - bResult = true; - } - - // Do we have enough space to fill the bitmap as well? - if(Length >= TotalLength) - { - LPBYTE pbBitmap = (LPBYTE)(pBitmap + 1); - - // Fill the full blocks - memset(pbBitmap, 0xFF, (BlockCount / 8)); - pbBitmap += (BlockCount / 8); - bResult = true; - - // Supply the last block - if(BlockCount & 7) - { - LastByte = (1 << (BlockCount & 7)) - 1; - pbBitmap[0] = (BYTE)LastByte; - } - } - - return bResult; -} - -//----------------------------------------------------------------------------- -// Local functions - base file support - -static bool BaseFile_Read( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position - void * pvBuffer, // Pointer to data to be read - DWORD dwBytesToRead) // Number of bytes to read from the file -{ - ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; - DWORD dwBytesRead = 0; // Must be set by platform-specific code - -#ifdef PLATFORM_WINDOWS - { - // Note: StormLib no longer supports Windows 9x. - // Thus, we can use the OVERLAPPED structure to specify - // file offset to read from file. This allows us to skip - // one system call to SetFilePointer - - // Update the byte offset - pStream->Base.File.FilePos = ByteOffset; - - // Read the data - if(dwBytesToRead != 0) - { - OVERLAPPED Overlapped; - - Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); - Overlapped.Offset = (DWORD)ByteOffset; - Overlapped.hEvent = NULL; - if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped)) - return false; - } -/* - // If the byte offset is different from the current file position, - // we have to update the file position - if(ByteOffset != pStream->Base.File.FilePos) - { - LONG ByteOffsetHi = (LONG)(ByteOffset >> 32); - - SetFilePointer(pStream->Base.File.hFile, (LONG)ByteOffset, &ByteOffsetHi, FILE_BEGIN); - pStream->Base.File.FilePos = ByteOffset; - } - - // Read the data - if(dwBytesToRead != 0) - { - if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, NULL)) - return false; - } -*/ - } -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - { - ssize_t bytes_read; - - // If the byte offset is different from the current file position, - // we have to update the file position - if(ByteOffset != pStream->Base.File.FilePos) - { - lseek((intptr_t)pStream->Base.File.hFile, (off_t)(ByteOffset), SEEK_SET); - pStream->Base.File.FilePos = ByteOffset; - } - - // Perform the read operation - if(dwBytesToRead != 0) - { - bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead); - if(bytes_read == -1) - { - nLastError = errno; - return false; - } - - dwBytesRead = (DWORD)(size_t)bytes_read; - } - } -#endif - - // Increment the current file position by number of bytes read - // If the number of bytes read doesn't match to required amount, return false - pStream->Base.File.FilePos = ByteOffset + dwBytesRead; - if(dwBytesRead != dwBytesToRead) - SetLastError(ERROR_HANDLE_EOF); - return (dwBytesRead == dwBytesToRead); -} - -/** - * \a pStream Pointer to an open stream - * \a pByteOffset Pointer to file byte offset. If NULL, writes to current position - * \a pvBuffer Pointer to data to be written - * \a dwBytesToWrite Number of bytes to write to the file - */ - -static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite) -{ - ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; - DWORD dwBytesWritten = 0; // Must be set by platform-specific code - -#ifdef PLATFORM_WINDOWS - { - // Note: StormLib no longer supports Windows 9x. - // Thus, we can use the OVERLAPPED structure to specify - // file offset to read from file. This allows us to skip - // one system call to SetFilePointer - - // Update the byte offset - pStream->Base.File.FilePos = ByteOffset; - - // Read the data - if(dwBytesToWrite != 0) - { - OVERLAPPED Overlapped; - - Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); - Overlapped.Offset = (DWORD)ByteOffset; - Overlapped.hEvent = NULL; - if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped)) - return false; - } -/* - // If the byte offset is different from the current file position, - // we have to update the file position - if(ByteOffset != pStream->Base.File.FilePos) - { - LONG ByteOffsetHi = (LONG)(ByteOffset >> 32); - - SetFilePointer(pStream->Base.File.hFile, (LONG)ByteOffset, &ByteOffsetHi, FILE_BEGIN); - pStream->Base.File.FilePos = ByteOffset; - } - - // Read the data - if(dwBytesToWrite != 0) - { - if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, NULL)) - return false; - } -*/ - } -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - { - ssize_t bytes_written; - - // If the byte offset is different from the current file position, - // we have to update the file position - if(ByteOffset != pStream->Base.File.FilePos) - { - lseek((intptr_t)pStream->Base.File.hFile, (off_t)(ByteOffset), SEEK_SET); - pStream->Base.File.FilePos = ByteOffset; - } - - // Perform the read operation - bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite); - if(bytes_written == -1) - { - nLastError = errno; - return false; - } - - dwBytesWritten = (DWORD)(size_t)bytes_written; - } -#endif - - // Increment the current file position by number of bytes read - pStream->Base.File.FilePos = ByteOffset + dwBytesWritten; - - // Also modify the file size, if needed - if(pStream->Base.File.FilePos > pStream->Base.File.FileSize) - pStream->Base.File.FileSize = pStream->Base.File.FilePos; - - if(dwBytesWritten != dwBytesToWrite) - SetLastError(ERROR_DISK_FULL); - return (dwBytesWritten == dwBytesToWrite); -} - -static bool BaseFile_GetPos( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG & ByteOffset) // Pointer to file byte offset -{ - ByteOffset = pStream->Base.File.FilePos; - return true; -} - -static bool BaseFile_GetSize( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG & FileSize) // Pointer where to store file size -{ - FileSize = pStream->Base.File.FileSize; - return true; -} - -/** - * \a pStream Pointer to an open stream - * \a NewFileSize New size of the file - */ -static bool BaseFile_SetSize(TFileStream * pStream, ULONGLONG NewFileSize) -{ -#ifdef PLATFORM_WINDOWS - { - LONG FileSizeHi = (LONG)(NewFileSize >> 32); - LONG FileSizeLo; - DWORD dwNewPos; - bool bResult; - - // Set the position at the new file size - dwNewPos = SetFilePointer(pStream->Base.File.hFile, (LONG)NewFileSize, &FileSizeHi, FILE_BEGIN); - if(dwNewPos == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS) - return false; - - // Set the current file pointer as the end of the file - bResult = (bool)SetEndOfFile(pStream->Base.File.hFile); - - // Restore the file position - FileSizeHi = (LONG)(pStream->Base.File.FilePos >> 32); - FileSizeLo = (LONG)(pStream->Base.File.FilePos); - SetFilePointer(pStream->Base.File.hFile, FileSizeLo, &FileSizeHi, FILE_BEGIN); - return bResult; - } -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - { - if(ftruncate((intptr_t)pStream->Base.File.hFile, (off_t)NewFileSize) == -1) - { - nLastError = errno; - return false; - } - - return true; - } -#endif -} - -static bool BaseFile_GetTime(TFileStream * pStream, ULONGLONG * pFileTime) -{ - *pFileTime = pStream->Base.File.FileTime; - return true; -} - -// Renames the file pointed by pStream so that it contains data from pNewStream -static bool BaseFile_Switch(TFileStream * pStream, TFileStream * pNewStream) -{ -#ifdef PLATFORM_WINDOWS - // Delete the original stream file. Don't check the result value, - // because if the file doesn't exist, it would fail - DeleteFile(pStream->szFileName); - - // Rename the new file to the old stream's file - return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName); -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - // "rename" on Linux also works if the target file exists - if(rename(pNewStream->szFileName, pStream->szFileName) == -1) - { - nLastError = errno; - return false; - } - - return true; -#endif -} - -static void BaseFile_Close(TFileStream * pStream) -{ - if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE) - { -#ifdef PLATFORM_WINDOWS - CloseHandle(pStream->Base.File.hFile); -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - close((intptr_t)pStream->Base.File.hFile); -#endif - } - - // Also invalidate the handle - pStream->Base.File.hFile = INVALID_HANDLE_VALUE; -} - -static bool BaseFile_Create( - TFileStream * pStream, - const TCHAR * szFileName, - DWORD dwStreamFlags) -{ -#ifdef PLATFORM_WINDOWS - { - DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0; - - pStream->Base.File.hFile = CreateFile(szFileName, - GENERIC_READ | GENERIC_WRITE, - dwWriteShare | FILE_SHARE_READ, - NULL, - CREATE_ALWAYS, - 0, - NULL); - if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE) - return false; - } -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - { - intptr_t handle; - - handle = open(szFileName, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if(handle == -1) - { - nLastError = errno; - return false; - } - - pStream->Base.File.hFile = (HANDLE)handle; - } -#endif - - // Fill-in the entry points - pStream->BaseRead = BaseFile_Read; - pStream->BaseWrite = BaseFile_Write; - pStream->BaseGetPos = BaseFile_GetPos; - pStream->BaseGetSize = BaseFile_GetSize; - pStream->BaseSetSize = BaseFile_SetSize; - pStream->BaseSetSize = BaseFile_SetSize; - pStream->BaseGetTime = BaseFile_GetTime; - pStream->BaseClose = BaseFile_Close; - - // Reset the file position - pStream->Base.File.FileSize = 0; - pStream->Base.File.FilePos = 0; - pStream->dwFlags = dwStreamFlags; - return true; -} - -static bool BaseFile_Open( - TFileStream * pStream, - const TCHAR * szFileName, - DWORD dwStreamFlags) -{ -#ifdef PLATFORM_WINDOWS - { - ULARGE_INTEGER FileSize; - DWORD dwDesiredAccess = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? GENERIC_READ : GENERIC_ALL; - DWORD dwWriteShare = (dwStreamFlags & STREAM_FLAG_WRITE_SHARE) ? FILE_SHARE_WRITE : 0; - - // Open the file - pStream->Base.File.hFile = CreateFile(szFileName, - dwDesiredAccess, - dwWriteShare | FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - 0, - NULL); - if(pStream->Base.File.hFile == INVALID_HANDLE_VALUE) - return false; - - // Query the file size - FileSize.LowPart = GetFileSize(pStream->Base.File.hFile, &FileSize.HighPart); - pStream->Base.File.FileSize = FileSize.QuadPart; - - // Query last write time - GetFileTime(pStream->Base.File.hFile, NULL, NULL, (LPFILETIME)&pStream->Base.File.FileTime); - } -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - { - struct stat fileinfo; - int oflag = (dwStreamFlags & STREAM_FLAG_READ_ONLY) ? O_RDONLY : O_RDWR; - intptr_t handle; - - // Open the file - handle = open(szFileName, oflag); - if(handle == -1) - { - nLastError = errno; - return false; - } - - // Get the file size - if(fstat(handle, &fileinfo) == -1) - { - nLastError = errno; - return false; - } - - // time_t is number of seconds since 1.1.1970, UTC. - // 1 second = 10000000 (decimal) in FILETIME - // Set the start to 1.1.1970 00:00:00 - pStream->Base.File.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime); - pStream->Base.File.FileSize = (ULONGLONG)fileinfo.st_size; - pStream->Base.File.hFile = (HANDLE)handle; - } -#endif - - // Fill-in the entry points - pStream->BaseRead = BaseFile_Read; - pStream->BaseWrite = BaseFile_Write; - pStream->BaseGetPos = BaseFile_GetPos; - pStream->BaseGetSize = BaseFile_GetSize; - pStream->BaseSetSize = BaseFile_SetSize; - pStream->BaseGetTime = BaseFile_GetTime; - pStream->BaseClose = BaseFile_Close; - - // Reset the file position - pStream->Base.File.FilePos = 0; - pStream->dwFlags = dwStreamFlags; - return true; -} - -//----------------------------------------------------------------------------- -// Local functions - base memory-mapped file support - -static bool BaseMap_Read( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position - void * pvBuffer, // Pointer to data to be read - DWORD dwBytesToRead) // Number of bytes to read from the file -{ - ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Map.FilePos; - - // Do we have to read anything at all? - if(dwBytesToRead != 0) - { - // Don't allow reading past file size - if((ByteOffset + dwBytesToRead) > pStream->Base.Map.FileSize) - return false; - - // Copy the required data - memcpy(pvBuffer, pStream->Base.Map.pbFile + (size_t)ByteOffset, dwBytesToRead); - } - - // Move the current file position - pStream->Base.Map.FilePos += dwBytesToRead; - return true; -} - -static bool BaseMap_GetPos( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG & ByteOffset) // Pointer to file byte offset -{ - ByteOffset = pStream->Base.Map.FilePos; - return true; -} - -static bool BaseMap_GetSize( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG & FileSize) // Pointer where to store file size -{ - FileSize = pStream->Base.Map.FileSize; - return true; -} - -static bool BaseMap_GetTime(TFileStream * pStream, ULONGLONG * pFileTime) -{ - *pFileTime = pStream->Base.Map.FileTime; - return true; -} - -static void BaseMap_Close(TFileStream * pStream) -{ -#ifdef PLATFORM_WINDOWS - if(pStream->Base.Map.pbFile != NULL) - UnmapViewOfFile(pStream->Base.Map.pbFile); -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - if(pStream->Base.Map.pbFile != NULL) - munmap(pStream->Base.Map.pbFile, (size_t )pStream->Base.Map.FileSize); -#endif - - pStream->Base.Map.pbFile = NULL; -} - -static bool BaseMap_Open( - TFileStream * pStream, - const TCHAR * szFileName, - DWORD dwStreamFlags) -{ -#ifdef PLATFORM_WINDOWS - - ULARGE_INTEGER FileSize; - HANDLE hFile; - HANDLE hMap; - bool bResult = false; - - // Open the file for read access - hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(hFile != NULL) - { - // Retrieve file size. Don't allow mapping file of a zero size. - FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart); - if(FileSize.QuadPart != 0) - { - // Retrieve file time - GetFileTime(hFile, NULL, NULL, (LPFILETIME)&pStream->Base.Map.FileTime); - - // Now create mapping object - hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); - if(hMap != NULL) - { - // Map the entire view into memory - // Note that this operation will fail if the file can't fit - // into usermode address space - pStream->Base.Map.pbFile = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); - if(pStream->Base.Map.pbFile != NULL) - { - pStream->Base.Map.FileSize = FileSize.QuadPart; - pStream->Base.Map.FilePos = 0; - bResult = true; - } - - // Close the map handle - CloseHandle(hMap); - } - } - - // Close the file handle - CloseHandle(hFile); - } - - // If the file is not there and is not available for random access, - // report error - if(bResult == false) - return false; -#endif - -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - struct stat fileinfo; - intptr_t handle; - bool bResult = false; - - // Open the file - handle = open(szFileName, O_RDONLY); - if(handle != -1) - { - // Get the file size - if(fstat(handle, &fileinfo) != -1) - { - pStream->Base.Map.pbFile = (LPBYTE)mmap(NULL, (size_t)fileinfo.st_size, PROT_READ, MAP_PRIVATE, handle, 0); - if(pStream->Base.Map.pbFile != NULL) - { - // time_t is number of seconds since 1.1.1970, UTC. - // 1 second = 10000000 (decimal) in FILETIME - // Set the start to 1.1.1970 00:00:00 - pStream->Base.Map.FileTime = 0x019DB1DED53E8000ULL + (10000000 * fileinfo.st_mtime); - pStream->Base.Map.FileSize = (ULONGLONG)fileinfo.st_size; - pStream->Base.Map.FilePos = 0; - bResult = true; - } - } - close(handle); - } - - // Did the mapping fail? - if(bResult == false) - { - nLastError = errno; - return false; - } -#endif - - // Fill-in entry points - pStream->BaseRead = BaseMap_Read; - pStream->BaseGetPos = BaseMap_GetPos; - pStream->BaseGetSize = BaseMap_GetSize; - pStream->BaseGetTime = BaseMap_GetTime; - pStream->BaseClose = BaseMap_Close; - pStream->dwFlags = dwStreamFlags; - return true; -} - -//----------------------------------------------------------------------------- -// Local functions - base HTTP file support - -static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR * szServerName) -{ - // Check for HTTP - if(!_tcsnicmp(szFileName, _T("http://"), 7)) - szFileName += 7; - - // Cut off the server name - if(szServerName != NULL) - { - while(szFileName[0] != 0 && szFileName[0] != _T('/')) - *szServerName++ = *szFileName++; - *szServerName = 0; - } - else - { - while(szFileName[0] != 0 && szFileName[0] != _T('/')) - *szFileName++; - } - - // Return the remainder - return szFileName; -} - -static bool BaseHttp_Read( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position - void * pvBuffer, // Pointer to data to be read - DWORD dwBytesToRead) // Number of bytes to read from the file -{ -#ifdef PLATFORM_WINDOWS - ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.Http.FilePos; - DWORD dwTotalBytesRead = 0; - - // Do we have to read anything at all? - if(dwBytesToRead != 0) - { - HINTERNET hRequest; - LPCTSTR szFileName; - LPBYTE pbBuffer = (LPBYTE)pvBuffer; - TCHAR szRangeRequest[0x80]; - DWORD dwStartOffset = (DWORD)ByteOffset; - DWORD dwEndOffset = dwStartOffset + dwBytesToRead; - BYTE Buffer[0x200]; - - // Open HTTP request to the file - szFileName = BaseHttp_ExtractServerName(pStream->szFileName, NULL); - hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0); - if(hRequest != NULL) - { - // Add range request to the HTTP headers - // http://www.clevercomponents.com/articles/article015/resuming.asp - _stprintf(szRangeRequest, _T("Range: bytes=%d-%d"), dwStartOffset, dwEndOffset); - HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW); - - // Send the request to the server - if(HttpSendRequest(hRequest, NULL, 0, NULL, 0)) - { - while(dwTotalBytesRead < dwBytesToRead) - { - DWORD dwBlockBytesToRead = dwBytesToRead - dwTotalBytesRead; - DWORD dwBlockBytesRead = 0; - - // Read the block from the file - if(dwBlockBytesToRead > sizeof(Buffer)) - dwBlockBytesToRead = sizeof(Buffer); - InternetReadFile(hRequest, pbBuffer, dwBlockBytesToRead, &dwBlockBytesRead); - - // Check for end - if(dwBlockBytesRead == 0) - break; - - // Move buffers - dwTotalBytesRead += dwBlockBytesRead; - pbBuffer += dwBlockBytesRead; - } - } - InternetCloseHandle(hRequest); - } - } - - // Increment the current file position by number of bytes read - pStream->Base.Http.FilePos = ByteOffset + dwTotalBytesRead; - - // If the number of bytes read doesn't match the required amount, return false - if(dwTotalBytesRead != dwBytesToRead) - SetLastError(ERROR_HANDLE_EOF); - return (dwTotalBytesRead == dwBytesToRead); - -#else - - // Not supported - pStream = pStream; - pByteOffset = pByteOffset; - pvBuffer = pvBuffer; - dwBytesToRead = dwBytesToRead; - SetLastError(ERROR_NOT_SUPPORTED); - return false; - -#endif -} - -static bool BaseHttp_GetPos( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG & ByteOffset) // Pointer to file byte offset -{ - ByteOffset = pStream->Base.Http.FilePos; - return true; -} - -static bool BaseHttp_GetSize( - TFileStream * pStream, // Pointer to an open stream - ULONGLONG & FileSize) // Pointer where to store file size -{ - FileSize = pStream->Base.Http.FileSize; - return true; -} - -static bool BaseHttp_GetTime(TFileStream * pStream, ULONGLONG * pFileTime) -{ - *pFileTime = pStream->Base.Http.FileTime; - return true; -} - -static void BaseHttp_Close(TFileStream * pStream) -{ -#ifdef PLATFORM_WINDOWS - if(pStream->Base.Http.hConnect != NULL) - InternetCloseHandle(pStream->Base.Http.hConnect); - pStream->Base.Http.hConnect = NULL; - - if(pStream->Base.Http.hInternet != NULL) - InternetCloseHandle(pStream->Base.Http.hInternet); - pStream->Base.Http.hInternet = NULL; -#else - pStream = pStream; -#endif -} - -static bool BaseHttp_Open( - TFileStream * pStream, - const TCHAR * szFileName, - DWORD dwStreamFlags) -{ -#ifdef PLATFORM_WINDOWS - - HINTERNET hRequest; - DWORD dwTemp = 0; - bool bFileAvailable = false; - int nError = ERROR_SUCCESS; - - // Don't connect to the internet - if(!InternetGetConnectedState(&dwTemp, 0)) - nError = GetLastError(); - - // Initiate the connection to the internet - if(nError == ERROR_SUCCESS) - { - pStream->Base.Http.hInternet = InternetOpen(_T("StormLib HTTP MPQ reader"), - INTERNET_OPEN_TYPE_PRECONFIG, - NULL, - NULL, - 0); - if(pStream->Base.Http.hInternet == NULL) - nError = GetLastError(); - } - - // Connect to the server - if(nError == ERROR_SUCCESS) - { - TCHAR szServerName[MAX_PATH]; - DWORD dwFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE; - - // Initiate connection with the server - szFileName = BaseHttp_ExtractServerName(szFileName, szServerName); - pStream->Base.Http.hConnect = InternetConnect(pStream->Base.Http.hInternet, - szServerName, - INTERNET_DEFAULT_HTTP_PORT, - NULL, - NULL, - INTERNET_SERVICE_HTTP, - dwFlags, - 0); - if(pStream->Base.Http.hConnect == NULL) - nError = GetLastError(); - } - - // Now try to query the file size - if(nError == ERROR_SUCCESS) - { - // Open HTTP request to the file - hRequest = HttpOpenRequest(pStream->Base.Http.hConnect, _T("GET"), szFileName, NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0); - if(hRequest != NULL) - { - if(HttpSendRequest(hRequest, NULL, 0, NULL, 0)) - { - ULONGLONG FileTime = 0; - DWORD dwFileSize = 0; - DWORD dwDataSize; - DWORD dwIndex = 0; - - // Check if the MPQ has Last Modified field - dwDataSize = sizeof(ULONGLONG); - if(HttpQueryInfo(hRequest, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &FileTime, &dwDataSize, &dwIndex)) - pStream->Base.Http.FileTime = FileTime; - - // Verify if the server supports random access - dwDataSize = sizeof(DWORD); - if(HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwFileSize, &dwDataSize, &dwIndex)) - { - if(dwFileSize != 0) - { - pStream->Base.Http.FileSize = dwFileSize; - pStream->Base.Http.FilePos = 0; - bFileAvailable = true; - } - } - } - InternetCloseHandle(hRequest); - } - } - - // If the file is not there and is not available for random access, - // report error - if(bFileAvailable == false) - { - BaseHttp_Close(pStream); - return false; - } - - // Fill-in entry points - pStream->BaseRead = BaseHttp_Read; - pStream->BaseGetPos = BaseHttp_GetPos; - pStream->BaseGetSize = BaseHttp_GetSize; - pStream->BaseGetTime = BaseHttp_GetTime; - pStream->BaseClose = BaseHttp_Close; - pStream->dwFlags = dwStreamFlags; - return true; - -#else - - // Not supported - pStream = pStream; - szFileName = szFileName; - SetLastError(ERROR_NOT_SUPPORTED); - return false; - -#endif -} - -//----------------------------------------------------------------------------- -// Local functions - linear stream support - -static bool LinearStream_Read( - TLinearStream * pStream, // Pointer to an open stream - ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position - void * pvBuffer, // Pointer to data to be read - DWORD dwBytesToRead) // Number of bytes to read from the file -{ - ULONGLONG ByteOffset; - ULONGLONG EndOffset; - LPBYTE pbBitmap; - DWORD BlockIndex; - DWORD ByteIndex; - DWORD BitMask; - - // At this point, we must have a bitmap set - assert(pStream->pBitmap != NULL); - - // If we have data map, we must check if the data block is present in the MPQ - if(dwBytesToRead != 0) - { - DWORD BlockSize = pStream->pBitmap->BlockSize; - - // Get the offset where we read it from - if(pByteOffset == NULL) - pStream->BaseGetPos(pStream, ByteOffset); - else - ByteOffset = *pByteOffset; - EndOffset = ByteOffset + dwBytesToRead; - - // If the start of the area is within the region - // protected by data map, check each block - if(ByteOffset < pStream->pBitmap->EndOffset) - { - // Cut the end of the stream protected by the data map - EndOffset = STORMLIB_MIN(EndOffset, pStream->pBitmap->EndOffset); - - // Calculate the initial block index - BlockIndex = (DWORD)(ByteOffset / BlockSize); - pbBitmap = (LPBYTE)(pStream->pBitmap + 1); - - // Parse each block - while(ByteOffset < EndOffset) - { - // Prepare byte index and bit mask - ByteIndex = BlockIndex / 8; - BitMask = 1 << (BlockIndex & 0x07); - - // If that bit is not set, it means that the block is not present - if((pbBitmap[ByteIndex] & BitMask) == 0) - { - SetLastError(ERROR_FILE_CORRUPT); - return false; - } - - // Move to tne next block - ByteOffset += BlockSize; - BlockIndex++; - } - } - } - - // Now if all tests passed, we can call the base read function - return pStream->BaseRead(pStream, pByteOffset, pvBuffer, dwBytesToRead); -} - -static bool LinearStream_Switch(TLinearStream * pStream, TLinearStream * pNewStream) -{ - // Sanity checks - assert((pNewStream->dwFlags & STREAM_PROVIDER_MASK) == STREAM_PROVIDER_LINEAR); - assert((pNewStream->dwFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_FILE); - assert((pStream->dwFlags & STREAM_PROVIDER_MASK) == STREAM_PROVIDER_LINEAR); - assert((pStream->dwFlags & BASE_PROVIDER_MASK) == BASE_PROVIDER_FILE); - - // Close the new stream - pNewStream->BaseClose(pNewStream); - - // Close the source stream - pStream->BaseClose(pStream); - - // Rename the new data source file to the existing file - if(!BaseFile_Switch(pStream, pNewStream)) - return false; - - // Now we have to open the "pStream" again - if(!BaseFile_Open(pStream, pStream->szFileName, pNewStream->dwFlags)) - return false; - - // We need to cleanup the new data stream - FileStream_Close(pNewStream); - return true; -} - -static bool LinearStream_GetBitmap( - TLinearStream * pStream, - TFileBitmap * pBitmap, - DWORD Length, - LPDWORD LengthNeeded) -{ - DWORD TotalLength; - bool bResult = false; - - // Assumed that we have bitmap now - assert(pStream->pBitmap != NULL); - - // Give the bitmap length - TotalLength = sizeof(TFileBitmap) + pStream->pBitmap->BitmapSize; - if(LengthNeeded != NULL) - *LengthNeeded = TotalLength; - - // Do we have enough space to fill at least the bitmap structure? - if(Length >= sizeof(TFileBitmap)) - { - // Enough space for complete bitmap? - if(Length >= TotalLength) - { - memcpy(pBitmap, pStream->pBitmap, TotalLength); - bResult = true; - } - else - { - memcpy(pBitmap, pStream->pBitmap, sizeof(TFileBitmap)); - bResult = true; - } - } - - return bResult; -} - -static void LinearStream_Close(TLinearStream * pStream) -{ - // Free the data map, if any - if(pStream->pBitmap != NULL) - STORM_FREE(pStream->pBitmap); - pStream->pBitmap = NULL; - - // Call the base class for closing the stream - return pStream->BaseClose(pStream); -} - -static bool LinearStream_Open(TLinearStream * pStream) -{ - // No extra work here really; just set entry points - pStream->StreamRead = pStream->BaseRead; - pStream->StreamWrite = pStream->BaseWrite; - pStream->StreamGetPos = pStream->BaseGetPos; - pStream->StreamGetSize = pStream->BaseGetSize; - pStream->StreamSetSize = pStream->BaseSetSize; - pStream->StreamGetTime = pStream->BaseGetTime; - pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap; - pStream->StreamSwitch = (STREAM_SWITCH)LinearStream_Switch; - pStream->StreamClose = (STREAM_CLOSE)LinearStream_Close; - return true; -} - -//----------------------------------------------------------------------------- -// Local functions - partial stream support - -static bool IsPartHeader(PPART_FILE_HEADER pPartHdr) -{ - // Version number must be 2 - if(pPartHdr->PartialVersion == 2) - { - // GameBuildNumber must be an ASCII number - if(isdigit(pPartHdr->GameBuildNumber[0]) && isdigit(pPartHdr->GameBuildNumber[1]) && isdigit(pPartHdr->GameBuildNumber[2])) - { - // Block size must be power of 2 - if((pPartHdr->BlockSize & (pPartHdr->BlockSize - 1)) == 0) - return true; - } - } - - return false; -} - -static bool PartialStream_Read( - TPartialStream * pStream, - ULONGLONG * pByteOffset, - void * pvBuffer, - DWORD dwBytesToRead) -{ - ULONGLONG RawByteOffset; - LPBYTE pbBuffer = (LPBYTE)pvBuffer; - DWORD dwBytesRemaining = dwBytesToRead; - DWORD dwPartOffset; - DWORD dwPartIndex; - DWORD dwBytesRead = 0; - DWORD dwBlockSize = pStream->BlockSize; - bool bResult = false; - int nFailReason = ERROR_HANDLE_EOF; // Why it failed if not enough bytes was read - - // If the byte offset is not entered, use the current position - if(pByteOffset == NULL) - pByteOffset = &pStream->VirtualPos; - - // Check if the file position is not at or beyond end of the file - if(*pByteOffset >= pStream->VirtualSize) - { - SetLastError(ERROR_HANDLE_EOF); - return false; - } - - // Get the part index where the read offset is - // Note that the part index should now be within the range, - // as read requests beyond-EOF are handled by the previous test - dwPartIndex = (DWORD)(*pByteOffset / pStream->BlockSize); - assert(dwPartIndex < pStream->BlockCount); - - // If the number of bytes remaining goes past - // the end of the file, cut them - if((*pByteOffset + dwBytesRemaining) > pStream->VirtualSize) - dwBytesRemaining = (DWORD)(pStream->VirtualSize - *pByteOffset); - - // Calculate the offset in the current part - dwPartOffset = (DWORD)(*pByteOffset) & (pStream->BlockSize - 1); - - // Read all data, one part at a time - while(dwBytesRemaining != 0) - { - PPART_FILE_MAP_ENTRY PartMap = pStream->PartMap + dwPartIndex; - DWORD dwBytesInPart; - - // If the part is not present in the file, we fail the read - if((PartMap->Flags & 3) == 0) - { - nFailReason = ERROR_FILE_CORRUPT; - bResult = false; - break; - } - - // If we are in the last part, we have to cut the number of bytes in the last part - if(dwPartIndex == pStream->BlockCount - 1) - dwBlockSize = (DWORD)pStream->VirtualSize & (pStream->BlockSize - 1); - - // Get the number of bytes reamining in the current part - dwBytesInPart = dwBlockSize - dwPartOffset; - - // Compute the raw file offset of the file part - RawByteOffset = MAKE_OFFSET64(PartMap->BlockOffsHi, PartMap->BlockOffsLo); - if(RawByteOffset == 0) - { - nFailReason = ERROR_FILE_CORRUPT; - bResult = false; - break; - } - - // If the number of bytes in part is too big, cut it - if(dwBytesInPart > dwBytesRemaining) - dwBytesInPart = dwBytesRemaining; - - // Append the offset within the part - RawByteOffset += dwPartOffset; - if(!pStream->BaseRead(pStream, &RawByteOffset, pbBuffer, dwBytesInPart)) - { - nFailReason = ERROR_FILE_CORRUPT; - bResult = false; - break; - } - - // Increment the file position - dwBytesRemaining -= dwBytesInPart; - dwBytesRead += dwBytesInPart; - pbBuffer += dwBytesInPart; - - // Move to the next file part - dwPartOffset = 0; - dwPartIndex++; - } - - // Move the file position by the number of bytes read - pStream->VirtualPos = *pByteOffset + dwBytesRead; - if(dwBytesRead != dwBytesToRead) - SetLastError(nFailReason); - return (dwBytesRead == dwBytesToRead); -} - -static bool PartialStream_GetPos( - TPartialStream * pStream, - ULONGLONG & ByteOffset) -{ - ByteOffset = pStream->VirtualPos; - return true; -} - -static bool PartialStream_GetSize( - TPartialStream * pStream, // Pointer to an open stream - ULONGLONG & FileSize) // Pointer where to store file size -{ - FileSize = pStream->VirtualSize; - return true; -} - -static bool PartialStream_GetBitmap( - TPartialStream * pStream, - TFileBitmap * pBitmap, - DWORD Length, - LPDWORD LengthNeeded) -{ - LPBYTE pbBitmap; - DWORD TotalLength; - DWORD BitmapSize = 0; - DWORD ByteOffset; - DWORD BitMask; - bool bResult = false; - - // Do we have stream bitmap? - BitmapSize = ((pStream->BlockCount - 1) / 8) + 1; - - // Give the bitmap length - TotalLength = sizeof(TFileBitmap) + BitmapSize; - if(LengthNeeded != NULL) - *LengthNeeded = TotalLength; - - // Do we have enough to fill at least the header? - if(Length >= sizeof(TFileBitmap)) - { - // Fill the bitmap header - pBitmap->StartOffset = 0; - pBitmap->EndOffset = pStream->VirtualSize; - pBitmap->IsComplete = 1; - pBitmap->BitmapSize = BitmapSize; - pBitmap->BlockSize = pStream->BlockSize; - pBitmap->Reserved = 0; - - // Is there at least one incomplete block? - for(DWORD i = 0; i < pStream->BlockCount; i++) - { - if(pStream->PartMap[i].Flags != 3) - { - pBitmap->IsComplete = 0; - break; - } - } - - bResult = true; - } - - // Do we have enough space for supplying the bitmap? - if(Length >= TotalLength) - { - // Fill the file bitmap - pbBitmap = (LPBYTE)(pBitmap + 1); - for(DWORD i = 0; i < pStream->BlockCount; i++) - { - // Is the block there? - if(pStream->PartMap[i].Flags == 3) - { - ByteOffset = i / 8; - BitMask = 1 << (i & 7); - pbBitmap[ByteOffset] |= BitMask; - } - } - bResult = true; - } - - return bResult; -} - -static void PartialStream_Close(TPartialStream * pStream) -{ - // Free the part map - if(pStream->PartMap != NULL) - STORM_FREE(pStream->PartMap); - pStream->PartMap = NULL; - - // Clear variables - pStream->VirtualSize = 0; - pStream->VirtualPos = 0; - - // Close the base stream - assert(pStream->BaseClose != NULL); - pStream->BaseClose(pStream); -} - -static bool PartialStream_Open(TPartialStream * pStream) -{ - PART_FILE_HEADER PartHdr; - ULONGLONG VirtualSize; // Size of the file stored in part file - ULONGLONG ByteOffset = {0}; - DWORD BlockCount; - - // Sanity check - assert(pStream->BaseRead != NULL); - - // Attempt to read PART file header - if(pStream->BaseRead(pStream, &ByteOffset, &PartHdr, sizeof(PART_FILE_HEADER))) - { - // We need to swap PART file header on big-endian platforms - BSWAP_PART_HEADER(&PartHdr); - - // Verify the PART file header - if(IsPartHeader(&PartHdr)) - { - // Calculate the number of parts in the file - VirtualSize = MAKE_OFFSET64(PartHdr.FileSizeHi, PartHdr.FileSizeLo); - assert(VirtualSize != 0); - BlockCount = (DWORD)((VirtualSize + PartHdr.BlockSize - 1) / PartHdr.BlockSize); - - // Allocate the map entry array - pStream->PartMap = STORM_ALLOC(PART_FILE_MAP_ENTRY, BlockCount); - if(pStream->PartMap != NULL) - { - // Load the block map - if(pStream->BaseRead(pStream, NULL, pStream->PartMap, BlockCount * sizeof(PART_FILE_MAP_ENTRY))) - { - // Swap the array of file map entries - BSWAP_ARRAY32_UNSIGNED(pStream->PartMap, BlockCount * sizeof(PART_FILE_MAP_ENTRY)); - - // Fill the members of PART file stream - pStream->VirtualSize = ((ULONGLONG)PartHdr.FileSizeHi) + PartHdr.FileSizeLo; - pStream->VirtualPos = 0; - pStream->BlockCount = BlockCount; - pStream->BlockSize = PartHdr.BlockSize; - - // Set new function pointers - pStream->StreamRead = (STREAM_READ)PartialStream_Read; - pStream->StreamGetPos = (STREAM_GETPOS)PartialStream_GetPos; - pStream->StreamGetSize = (STREAM_GETSIZE)PartialStream_GetSize; - pStream->StreamGetTime = pStream->BaseGetTime; - pStream->StreamGetTime = pStream->BaseGetTime; - pStream->StreamGetBmp = (STREAM_GETBMP)PartialStream_GetBitmap; - pStream->StreamClose = (STREAM_CLOSE)PartialStream_Close; - return true; - } - - // Free the part map - STORM_FREE(pStream->PartMap); - pStream->PartMap = NULL; - } - } - } - - SetLastError(ERROR_BAD_FORMAT); - return false; -} - -//----------------------------------------------------------------------------- -// Local functions - encrypted stream support - -// Note: Starcraft II - Installer.exe (4.1.1.4219): Suffix derived from battle.net auth. code -// Address of decryption routine: 0053A3D0 http://us.battle.net/static/mediakey/sc2-authenticationcode-enUS.txt -// Pointer to decryptor object: ECX Numbers mean offset of 4-char group of auth code (follows in comment) -// Pointer to key: ECX+0x5C -0C- -1C--08- -18--04- -14--00- -10- -static const char * MpqeKey_Starcraft2_Install_deDE = "expand 32-byte kSSXH00004XFXK4KX00008EKJD3CA0000Y64ZY45M0000YD9V"; // Y45MD3CAK4KXSSXHYD9VY64Z8EKJ4XFX -static const char * MpqeKey_Starcraft2_Install_enGB = "expand 32-byte kANGY000029ZH6NA20000HRGF8UDG0000NY82G8MN00006A3D"; // G8MN8UDG6NA2ANGY6A3DNY82HRGF29ZH -static const char * MpqeKey_Starcraft2_Install_enSG = "expand 32-byte kWW5B0000F7HWFDU90000FWZSHLB20000BLRSW9RR00003ECE"; // W9RRHLB2FDU9WW5B3ECEBLRSFWZSF7HW -static const char * MpqeKey_Starcraft2_Install_enUS = "expand 32-byte kTFD80000ETR5VM5G0000K859RE5N0000WT6F3DH500005LXG"; // 3DH5RE5NVM5GTFD85LXGWT6FK859ETR5 -static const char * MpqeKey_Starcraft2_Install_esES = "expand 32-byte kQU4Y0000XKTQ94PF0000N4R4UAXE0000AZ248WLK0000249P"; // 8WLKUAXE94PFQU4Y249PAZ24N4R4XKTQ -static const char * MpqeKey_Starcraft2_Install_esMX = "expand 32-byte kSQBR00004G54HGGX0000MF9GXX3V0000FFDXA34D0000FE5U"; // A34DXX3VHGGXSQBRFE5UFFDXMF9G4G54 -static const char * MpqeKey_Starcraft2_Install_frFR = "expand 32-byte kFWPQ00006EAJ8HJE0000PFER9K9300008MA2ZG7J0000UA76"; // ZG7J9K938HJEFWPQUA768MA2PFER6EAJ -static const char * MpqeKey_Starcraft2_Install_itIT = "expand 32-byte kXV7E00008BL2TVAP0000GVMWUNNN0000SVBWNE7C00003G2B"; // NE7CUNNNTVAPXV7E3G2BSVBWGVMW8BL2 -static const char * MpqeKey_Starcraft2_Install_koKR = "expand 32-byte kQWK70000838FBM9Q0000WQDB2FTM0000MWAZ3V9E0000U6MA"; // 3V9E2FTMBM9QQWK7U6MAMWAZWQDB838F -static const char * MpqeKey_Starcraft2_Install_plPL = "expand 32-byte k83U6000048L6LULJ00004MQDB8ME0000UP6K2NSF0000YHA3"; // 2NSFB8MELULJ83U6YHA3UP6K4MQD48L6 -static const char * MpqeKey_Starcraft2_Install_ptBR = "expand 32-byte kU8BM0000SW4EZ4CU00005F9CZ9EW0000CTY6QA2T0000B5WX"; // QA2TZ9EWZ4CUU8BMB5WXCTY65F9CSW4E -static const char * MpqeKey_Starcraft2_Install_ruRU = "expand 32-byte k9SH70000YEGT4BAT0000QDK978W60000V9NLVHB30000D68V"; // VHB378W64BAT9SH7D68VV9NLQDK9YEGT -static const char * MpqeKey_Starcraft2_Install_zhTW = "expand 32-byte k7KBN0000D9NEM6GC0000N3PLQJV400003BRDU3NF00009XQJ"; // U3NFQJV4M6GC7KBN9XQJ3BRDN3PLD9NE - -// Note: Diablo III: Agent.exe (1.0.0.954): Suffix derived from battle.net auth. code -// Address of decryption routine: 00502b00 http://dist.blizzard.com/mediakey/d3-authenticationcode-enGB.txt -// Pointer to decryptor object: ECX Numbers mean offset of 4-char group of auth code (follows in comment) -// Pointer to key: ECX+0x5C -0C- -1C--08- -18--04- -14--00- -10- -static const char * MpqeKey_Diablo3_Install_deDE = "expand 32-byte kEFH40000QRZKY3520000XC9MF6EJ0000CFH2UCMX0000XFRX"; // UCMXF6EJY352EFH4XFRXCFH2XC9MQRZK -static const char * MpqeKey_Diablo3_Install_enGB = "expand 32-byte kXP4G0000PHBPRP7W0000J9UNHY4800007SL9MMKV0000HYBQ"; // MMKVHY48RP7WXP4GHYBQ7SL9J9UNPHBP -static const char * MpqeKey_Diablo3_Install_enSG = "expand 32-byte kTZ9M00003CPPVGGL0000JYETWHQ70000FDCL8MXL0000QZQS"; // 8MXLWHQ7VGGLTZ9MQZQSFDCLJYET3CPP -static const char * MpqeKey_Diablo3_Install_enUS = "expand 32-byte kGUNG0000WZSZXFE20000UAKP5TM60000HKQ9EJ2R00005QDG"; // EJ2R5TM6XFE2GUNG5QDGHKQ9UAKPWZSZ -static const char * MpqeKey_Diablo3_Install_esES = "expand 32-byte kK65U0000HQQTZ6LN0000CLP4BE420000WZVMPBGF0000GJQ3"; // PBGFBE42Z6LNK65UGJQ3WZVMCLP4HQQT -static const char * MpqeKey_Diablo3_Install_esMX = "expand 32-byte kW5P200008VU2TSGC0000JPEYJJS90000C47AX7SE00008EBS"; // X7SEJJS9TSGCW5P28EBSC47AJPEY8VU2 -static const char * MpqeKey_Diablo3_Install_frFR = "expand 32-byte kRY3D00007YA2YE6X0000XS4PQA8V0000ZDE45KVB0000LGC5"; // 5KVBQA8VYE6XRY3DLGC5ZDE4XS4P7YA2 -static const char * MpqeKey_Diablo3_Install_itIT = "expand 32-byte kVVY40000B2546EVN00005B8KD2K50000DWYT478J0000XX8T"; // 478JD2K56EVNVVY4XX8TDWYT5B8KB254 -static const char * MpqeKey_Diablo3_Install_koKR = "expand 32-byte k6YWH0000474ARZTN0000NVWDVNFQ0000VDH98TS40000E9CH"; // 8TS4VNFQRZTN6YWHE9CHVDH9NVWD474A -static const char * MpqeKey_Diablo3_Install_plPL = "expand 32-byte k4ZJJ0000BLJBF4LZ0000A6GAZ32D00003AZQLJ520000XVKK"; // LJ52Z32DF4LZ4ZJJXVKK3AZQA6GABLJB -static const char * MpqeKey_Diablo3_Install_ptBR = "expand 32-byte k545Y0000XYAGCUE20000WHE7HY2E0000JPVYK6BD0000KNLB"; // K6BDHY2ECUE2545YKNLBJPVYWHE7XYAG -static const char * MpqeKey_Diablo3_Install_ruRU = "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // -static const char * MpqeKey_Diablo3_Install_zhTW = "expand 32-byte kMRUC0000AA8HV3ZZ0000UX2TQTN80000A8CG6VWC0000ZXV8"; // 6VWCQTN8V3ZZMRUCZXV8A8CGUX2TAA8H -static const char * MpqeKey_Diablo3_Install_zhCN = "expand 32-byte kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // - -static const char * MpqKeyArray[] = -{ - MpqeKey_Starcraft2_Install_deDE, - MpqeKey_Starcraft2_Install_enGB, - MpqeKey_Starcraft2_Install_enSG, - MpqeKey_Starcraft2_Install_enUS, - MpqeKey_Starcraft2_Install_esES, - MpqeKey_Starcraft2_Install_esMX, - MpqeKey_Starcraft2_Install_frFR, - MpqeKey_Starcraft2_Install_itIT, - MpqeKey_Starcraft2_Install_koKR, - MpqeKey_Starcraft2_Install_plPL, - MpqeKey_Starcraft2_Install_ptBR, - MpqeKey_Starcraft2_Install_ruRU, - MpqeKey_Starcraft2_Install_zhTW, - - MpqeKey_Diablo3_Install_deDE, - MpqeKey_Diablo3_Install_enGB, - MpqeKey_Diablo3_Install_enSG, - MpqeKey_Diablo3_Install_enUS, - MpqeKey_Diablo3_Install_esES, - MpqeKey_Diablo3_Install_esMX, - MpqeKey_Diablo3_Install_frFR, - MpqeKey_Diablo3_Install_itIT, - MpqeKey_Diablo3_Install_koKR, - MpqeKey_Diablo3_Install_plPL, - MpqeKey_Diablo3_Install_ptBR, -// MpqeKey_Diablo3_Install_ruRU, - MpqeKey_Diablo3_Install_zhTW, -// MpqeKey_Diablo3_Install_zhCN, - - NULL -}; - -static DWORD Rol32(DWORD dwValue, DWORD dwRolCount) -{ - DWORD dwShiftRight = 32 - dwRolCount; - - return (dwValue << dwRolCount) | (dwValue >> dwShiftRight); -} - -static void DecryptFileChunk( - DWORD * MpqData, - LPBYTE pbKey, - ULONGLONG ByteOffset, - DWORD dwLength) -{ - ULONGLONG ChunkOffset; - DWORD KeyShuffled[0x10]; - DWORD KeyMirror[0x10]; - DWORD RoundCount = 0x14; - - // Prepare the key - ChunkOffset = ByteOffset / MPQE_CHUNK_SIZE; - memcpy(KeyMirror, pbKey, MPQE_CHUNK_SIZE); - BSWAP_ARRAY32_UNSIGNED(KeyMirror, MPQE_CHUNK_SIZE); - KeyMirror[0x05] = (DWORD)(ChunkOffset >> 32); - KeyMirror[0x08] = (DWORD)(ChunkOffset); - - while(dwLength >= MPQE_CHUNK_SIZE) - { - // Shuffle the key - part 1 - KeyShuffled[0x0E] = KeyMirror[0x00]; - KeyShuffled[0x0C] = KeyMirror[0x01]; - KeyShuffled[0x05] = KeyMirror[0x02]; - KeyShuffled[0x0F] = KeyMirror[0x03]; - KeyShuffled[0x0A] = KeyMirror[0x04]; - KeyShuffled[0x07] = KeyMirror[0x05]; - KeyShuffled[0x0B] = KeyMirror[0x06]; - KeyShuffled[0x09] = KeyMirror[0x07]; - KeyShuffled[0x03] = KeyMirror[0x08]; - KeyShuffled[0x06] = KeyMirror[0x09]; - KeyShuffled[0x08] = KeyMirror[0x0A]; - KeyShuffled[0x0D] = KeyMirror[0x0B]; - KeyShuffled[0x02] = KeyMirror[0x0C]; - KeyShuffled[0x04] = KeyMirror[0x0D]; - KeyShuffled[0x01] = KeyMirror[0x0E]; - KeyShuffled[0x00] = KeyMirror[0x0F]; - - // Shuffle the key - part 2 - for(DWORD i = 0; i < RoundCount; i += 2) - { - KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x02]), 0x07); - KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0E]), 0x09); - KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x0A]), 0x0D); - KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x03]), 0x12); - - KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x04]), 0x07); - KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x0C]), 0x09); - KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x07]), 0x0D); - KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x06]), 0x12); - - KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x01]), 0x07); - KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x05]), 0x09); - KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x0B]), 0x0D); - KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x08]), 0x12); - - KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x00]), 0x07); - KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x0F]), 0x09); - KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x09]), 0x0D); - KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x0D]), 0x12); - - KeyShuffled[0x04] = KeyShuffled[0x04] ^ Rol32((KeyShuffled[0x0E] + KeyShuffled[0x09]), 0x07); - KeyShuffled[0x08] = KeyShuffled[0x08] ^ Rol32((KeyShuffled[0x04] + KeyShuffled[0x0E]), 0x09); - KeyShuffled[0x09] = KeyShuffled[0x09] ^ Rol32((KeyShuffled[0x08] + KeyShuffled[0x04]), 0x0D); - KeyShuffled[0x0E] = KeyShuffled[0x0E] ^ Rol32((KeyShuffled[0x09] + KeyShuffled[0x08]), 0x12); - - KeyShuffled[0x01] = KeyShuffled[0x01] ^ Rol32((KeyShuffled[0x0C] + KeyShuffled[0x0A]), 0x07); - KeyShuffled[0x0D] = KeyShuffled[0x0D] ^ Rol32((KeyShuffled[0x01] + KeyShuffled[0x0C]), 0x09); - KeyShuffled[0x0A] = KeyShuffled[0x0A] ^ Rol32((KeyShuffled[0x0D] + KeyShuffled[0x01]), 0x0D); - KeyShuffled[0x0C] = KeyShuffled[0x0C] ^ Rol32((KeyShuffled[0x0A] + KeyShuffled[0x0D]), 0x12); - - KeyShuffled[0x00] = KeyShuffled[0x00] ^ Rol32((KeyShuffled[0x05] + KeyShuffled[0x07]), 0x07); - KeyShuffled[0x03] = KeyShuffled[0x03] ^ Rol32((KeyShuffled[0x00] + KeyShuffled[0x05]), 0x09); - KeyShuffled[0x07] = KeyShuffled[0x07] ^ Rol32((KeyShuffled[0x03] + KeyShuffled[0x00]), 0x0D); - KeyShuffled[0x05] = KeyShuffled[0x05] ^ Rol32((KeyShuffled[0x07] + KeyShuffled[0x03]), 0x12); - - KeyShuffled[0x02] = KeyShuffled[0x02] ^ Rol32((KeyShuffled[0x0F] + KeyShuffled[0x0B]), 0x07); - KeyShuffled[0x06] = KeyShuffled[0x06] ^ Rol32((KeyShuffled[0x02] + KeyShuffled[0x0F]), 0x09); - KeyShuffled[0x0B] = KeyShuffled[0x0B] ^ Rol32((KeyShuffled[0x06] + KeyShuffled[0x02]), 0x0D); - KeyShuffled[0x0F] = KeyShuffled[0x0F] ^ Rol32((KeyShuffled[0x0B] + KeyShuffled[0x06]), 0x12); - } - - // Decrypt one data chunk - BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE); - MpqData[0x00] = MpqData[0x00] ^ (KeyShuffled[0x0E] + KeyMirror[0x00]); - MpqData[0x01] = MpqData[0x01] ^ (KeyShuffled[0x04] + KeyMirror[0x0D]); - MpqData[0x02] = MpqData[0x02] ^ (KeyShuffled[0x08] + KeyMirror[0x0A]); - MpqData[0x03] = MpqData[0x03] ^ (KeyShuffled[0x09] + KeyMirror[0x07]); - MpqData[0x04] = MpqData[0x04] ^ (KeyShuffled[0x0A] + KeyMirror[0x04]); - MpqData[0x05] = MpqData[0x05] ^ (KeyShuffled[0x0C] + KeyMirror[0x01]); - MpqData[0x06] = MpqData[0x06] ^ (KeyShuffled[0x01] + KeyMirror[0x0E]); - MpqData[0x07] = MpqData[0x07] ^ (KeyShuffled[0x0D] + KeyMirror[0x0B]); - MpqData[0x08] = MpqData[0x08] ^ (KeyShuffled[0x03] + KeyMirror[0x08]); - MpqData[0x09] = MpqData[0x09] ^ (KeyShuffled[0x07] + KeyMirror[0x05]); - MpqData[0x0A] = MpqData[0x0A] ^ (KeyShuffled[0x05] + KeyMirror[0x02]); - MpqData[0x0B] = MpqData[0x0B] ^ (KeyShuffled[0x00] + KeyMirror[0x0F]); - MpqData[0x0C] = MpqData[0x0C] ^ (KeyShuffled[0x02] + KeyMirror[0x0C]); - MpqData[0x0D] = MpqData[0x0D] ^ (KeyShuffled[0x06] + KeyMirror[0x09]); - MpqData[0x0E] = MpqData[0x0E] ^ (KeyShuffled[0x0B] + KeyMirror[0x06]); - MpqData[0x0F] = MpqData[0x0F] ^ (KeyShuffled[0x0F] + KeyMirror[0x03]); - BSWAP_ARRAY32_UNSIGNED(MpqData, MPQE_CHUNK_SIZE); - - // Update byte offset in the key - KeyMirror[0x08]++; - if(KeyMirror[0x08] == 0) - KeyMirror[0x05]++; - - // Move pointers and decrease number of bytes to decrypt - MpqData += (MPQE_CHUNK_SIZE / sizeof(DWORD)); - dwLength -= MPQE_CHUNK_SIZE; - } -} - -static const char * DetectFileKey(LPBYTE pbEncryptedHeader) -{ - ULONGLONG ByteOffset = 0; - BYTE FileHeader[MPQE_CHUNK_SIZE]; - BYTE Key[MPQE_CHUNK_SIZE]; - - // We just try all known keys one by one - for(int i = 0; MpqKeyArray[i] != NULL; i++) - { - // Copy the key there - memcpy(Key, MpqKeyArray[i], MPQE_CHUNK_SIZE); - BSWAP_ARRAY32_UNSIGNED(Key, MPQE_CHUNK_SIZE); - - // Try to decrypt with the given key - memcpy(FileHeader, pbEncryptedHeader, MPQE_CHUNK_SIZE); - DecryptFileChunk((LPDWORD)FileHeader, Key, ByteOffset, MPQE_CHUNK_SIZE); - - // We check the decrypted data - // All known encrypted MPQs have header at the begin of the file, - // so we check for MPQ signature there. - if(FileHeader[0] == 'M' && FileHeader[1] == 'P' && FileHeader[2] == 'Q') - return MpqKeyArray[i]; - } - - // Key not found, sorry - return NULL; -} - -static bool EncryptedStream_Read( - TEncryptedStream * pStream, // Pointer to an open stream - ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position - void * pvBuffer, // Pointer to data to be read - DWORD dwBytesToRead) // Number of bytes to read from the file -{ - ULONGLONG StartOffset; // Offset of the first byte to be read from the file - ULONGLONG ByteOffset; // Offset that the caller wants - ULONGLONG EndOffset; // End offset that is to be read from the file - DWORD dwBytesToAllocate; - DWORD dwBytesToDecrypt; - DWORD dwOffsetInCache; - LPBYTE pbMpqData = NULL; - bool bResult = false; - - // Get the byte offset - if(pByteOffset == NULL) - pStream->BaseGetPos(pStream, ByteOffset); - else - ByteOffset = *pByteOffset; - - // Cut it down to MPQE chunk size - StartOffset = ByteOffset; - StartOffset = StartOffset & ~(MPQE_CHUNK_SIZE - 1); - EndOffset = ByteOffset + dwBytesToRead; - - // Calculate number of bytes to decrypt - dwBytesToDecrypt = (DWORD)(EndOffset - StartOffset); - dwBytesToAllocate = (dwBytesToDecrypt + (MPQE_CHUNK_SIZE - 1)) & ~(MPQE_CHUNK_SIZE - 1); - - // Allocate buffers for encrypted and decrypted data - pbMpqData = STORM_ALLOC(BYTE, dwBytesToAllocate); - if(pbMpqData) - { - // Get the offset of the desired data in the cache - dwOffsetInCache = (DWORD)(ByteOffset - StartOffset); - - // Read the file from the stream as-is - if(pStream->BaseRead(pStream, &StartOffset, pbMpqData, dwBytesToDecrypt)) - { - // Decrypt the data - DecryptFileChunk((LPDWORD)pbMpqData, pStream->Key, StartOffset, dwBytesToAllocate); - - // Copy the decrypted data - memcpy(pvBuffer, pbMpqData + dwOffsetInCache, dwBytesToRead); - bResult = true; - } - else - { - assert(false); - } - - // Free decryption buffer - STORM_FREE(pbMpqData); - } - - // Free buffers and exit - return bResult; -} - -static bool EncryptedStream_Open(TEncryptedStream * pStream) -{ - ULONGLONG ByteOffset = 0; - BYTE EncryptedHeader[MPQE_CHUNK_SIZE]; - const char * szKey; - - // Sanity check - assert(pStream->BaseRead != NULL); - - // Load one MPQE chunk and try to detect the file key - if(pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, sizeof(EncryptedHeader))) - { - // Attempt to decrypt the MPQ header with all known keys - szKey = DetectFileKey(EncryptedHeader); - if(szKey != NULL) - { - // Copy the key for the file - memcpy(pStream->Key, szKey, MPQE_CHUNK_SIZE); - BSWAP_ARRAY32_UNSIGNED(pStream->Key, MPQE_CHUNK_SIZE); - - // Assign functions - pStream->StreamRead = (STREAM_READ)EncryptedStream_Read; - pStream->StreamGetPos = pStream->BaseGetPos; - pStream->StreamGetSize = pStream->BaseGetSize; - pStream->StreamGetTime = pStream->BaseGetTime; - pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap; - pStream->StreamClose = pStream->BaseClose; - - // We need to reset the position back to the begin of the file - pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, 0); - return true; - } - - // An unknown key - SetLastError(ERROR_UNKNOWN_FILE_KEY); - } - return false; -} - -//----------------------------------------------------------------------------- -// Public functions - -/** - * This function creates a new file for read-write access - * - * - If the current platform supports file sharing, - * the file must be created for read sharing (i.e. another application - * can open the file for read, but not for write) - * - If the file does not exist, the function must create new one - * - If the file exists, the function must rewrite it and set to zero size - * - The parameters of the function must be validate by the caller - * - The function must initialize all stream function pointers in TFileStream - * - If the function fails from any reason, it must close all handles - * and free all memory that has been allocated in the process of stream creation, - * including the TFileStream structure itself - * - * \a szFileName Name of the file to create - */ - -TFileStream * FileStream_CreateFile( - const TCHAR * szFileName, - DWORD dwStreamFlags) -{ - TFileStream * pStream; - - // We only support creation of linear, local file - if((dwStreamFlags & (STREAM_PROVIDER_MASK | BASE_PROVIDER_MASK)) != (STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE)) - { - SetLastError(ERROR_NOT_SUPPORTED); - return NULL; - } - - // Allocate file stream structure for linear stream - pStream = STORM_ALLOC(TFileStream, 1); - if(pStream != NULL) - { - // Reset entire structure to zero - memset(pStream, 0, sizeof(TFileStream)); - _tcscpy(pStream->szFileName, szFileName); - - // Attempt to create the disk file - if(BaseFile_Create(pStream, szFileName, dwStreamFlags)) - { - // Fill the stream provider functions - pStream->StreamRead = pStream->BaseRead; - pStream->StreamWrite = pStream->BaseWrite; - pStream->StreamGetPos = pStream->BaseGetPos; - pStream->StreamGetSize = pStream->BaseGetSize; - pStream->StreamSetSize = pStream->BaseSetSize; - pStream->StreamGetTime = pStream->BaseGetTime; - pStream->StreamGetBmp = (STREAM_GETBMP)Dummy_GetBitmap;; - pStream->StreamSwitch = (STREAM_SWITCH)LinearStream_Switch; - pStream->StreamClose = pStream->BaseClose; - return pStream; - } - - // File create failed, delete the stream - STORM_FREE(pStream); - pStream = NULL; - } - - // Return the stream - return pStream; -} - -/** - * This function opens an existing file for read or read-write access - * - If the current platform supports file sharing, - * the file must be open for read sharing (i.e. another application - * can open the file for read, but not for write) - * - If the file does not exist, the function must return NULL - * - If the file exists but cannot be open, then function must return NULL - * - The parameters of the function must be validate by the caller - * - The function must check if the file is a PART file, - * and create TPartialStream object if so. - * - The function must initialize all stream function pointers in TFileStream - * - If the function fails from any reason, it must close all handles - * and free all memory that has been allocated in the process of stream creation, - * including the TFileStream structure itself - * - * \a szFileName Name of the file to open - * \a dwStreamFlags specifies the provider and base storage type - */ - -TFileStream * FileStream_OpenFile( - const TCHAR * szFileName, - DWORD dwStreamFlags) -{ - TFileStream * pStream = NULL; - size_t StreamSize = 0; - bool bStreamResult = false; - bool bBaseResult = false; - - // Allocate file stream for each stream provider - switch(dwStreamFlags & STREAM_PROVIDER_MASK) - { - case STREAM_PROVIDER_LINEAR: // Allocate structure for linear stream - StreamSize = sizeof(TLinearStream); - break; - - case STREAM_PROVIDER_PARTIAL: - dwStreamFlags |= STREAM_FLAG_READ_ONLY; - StreamSize = sizeof(TPartialStream); - break; - - case STREAM_PROVIDER_ENCRYPTED: - dwStreamFlags |= STREAM_FLAG_READ_ONLY; - StreamSize = sizeof(TEncryptedStream); - break; - - default: - return NULL; - } - - // Allocate the stream for each type - pStream = (TFileStream *)STORM_ALLOC(BYTE, StreamSize); - if(pStream == NULL) - return NULL; - - // Fill the stream structure with zeros - memset(pStream, 0, StreamSize); - _tcscpy(pStream->szFileName, szFileName); - - // Now initialize the respective base provider - switch(dwStreamFlags & BASE_PROVIDER_MASK) - { - case BASE_PROVIDER_FILE: - bBaseResult = BaseFile_Open(pStream, szFileName, dwStreamFlags); - break; - - case BASE_PROVIDER_MAP: - dwStreamFlags |= STREAM_FLAG_READ_ONLY; - bBaseResult = BaseMap_Open(pStream, szFileName, dwStreamFlags); - break; - - case BASE_PROVIDER_HTTP: - dwStreamFlags |= STREAM_FLAG_READ_ONLY; - bBaseResult = BaseHttp_Open(pStream, szFileName, dwStreamFlags); - break; - } - - // If we failed to open the base storage, fail the operation - if(bBaseResult == false) - { - STORM_FREE(pStream); - return NULL; - } - - // Now initialize the stream provider - switch(dwStreamFlags & STREAM_PROVIDER_MASK) - { - case STREAM_PROVIDER_LINEAR: - bStreamResult = LinearStream_Open((TLinearStream *)pStream); - break; - - case STREAM_PROVIDER_PARTIAL: - bStreamResult = PartialStream_Open((TPartialStream *)pStream); - break; - - case STREAM_PROVIDER_ENCRYPTED: - bStreamResult = EncryptedStream_Open((TEncryptedStream *)pStream); - break; - } - - // If the operation failed, free the stream and set it to NULL - if(bStreamResult == false) - { - // Only close the base stream - pStream->BaseClose(pStream); - STORM_FREE(pStream); - pStream = NULL; - } - - return pStream; -} - -/** - * Reads data from the stream - * - * - Returns true if the read operation succeeded and all bytes have been read - * - Returns false if either read failed or not all bytes have been read - * - If the pByteOffset is NULL, the function must read the data from the current file position - * - The function can be called with dwBytesToRead = 0. In that case, pvBuffer is ignored - * and the function just adjusts file pointer. - * - * \a pStream Pointer to an open stream - * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position - * \a pvBuffer Pointer to data to be read - * \a dwBytesToRead Number of bytes to read from the file - * - * \returns - * - If the function reads the required amount of bytes, it returns true. - * - If the function reads less than required bytes, it returns false and GetLastError() returns ERROR_HANDLE_EOF - * - If the function fails, it reads false and GetLastError() returns an error code different from ERROR_HANDLE_EOF - */ -bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead) -{ - assert(pStream->StreamRead != NULL); - return pStream->StreamRead(pStream, pByteOffset, pvBuffer, dwBytesToRead); -} - -/** - * This function writes data to the stream - * - * - Returns true if the write operation succeeded and all bytes have been written - * - Returns false if either write failed or not all bytes have been written - * - If the pByteOffset is NULL, the function must write the data to the current file position - * - * \a pStream Pointer to an open stream - * \a pByteOffset Pointer to file byte offset. If NULL, it reads from the current position - * \a pvBuffer Pointer to data to be written - * \a dwBytesToWrite Number of bytes to write to the file - */ -bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite) -{ - if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) - return false; - - assert(pStream->StreamWrite != NULL); - return pStream->StreamWrite(pStream, pByteOffset, pvBuffer, dwBytesToWrite); -} - -/** - * This function returns the current file position - * \a pStream - * \a ByteOffset - */ -bool FileStream_GetPos(TFileStream * pStream, ULONGLONG & ByteOffset) -{ - assert(pStream->StreamGetPos != NULL); - return pStream->StreamGetPos(pStream, ByteOffset); -} - -/** - * Returns the size of a file - * - * \a pStream Pointer to an open stream - * \a FileSize Pointer where to store the file size - */ -bool FileStream_GetSize(TFileStream * pStream, ULONGLONG & FileSize) -{ - assert(pStream->StreamGetSize != NULL); - return pStream->StreamGetSize(pStream, FileSize); -} - -/** - * Sets the size of a file - * - * \a pStream Pointer to an open stream - * \a NewFileSize File size to set - */ -bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize) -{ - if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) - return false; - - assert(pStream->StreamSetSize != NULL); - return pStream->StreamSetSize(pStream, NewFileSize); -} - -/** - * Returns the last write time of a file - * - * \a pStream Pointer to an open stream - * \a pFileType Pointer where to store the file last write time - */ -bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFileTime) -{ - assert(pStream->StreamGetTime != NULL); - return pStream->StreamGetTime(pStream, pFileTime); -} - -/** - * Switches a stream with another. Used for final phase of archive compacting. - * Performs these steps: - * - * 1) Closes the handle to the existing MPQ - * 2) Renames the temporary MPQ to the original MPQ, overwrites existing one - * 3) Opens the MPQ stores the handle and stream position to the new stream structure - * - * \a pStream Pointer to an open stream - * \a pTempStream Temporary ("working") stream (created during archive compacting) - */ -bool FileStream_Switch(TFileStream * pStream, TFileStream * pNewStream) -{ - if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) - return false; - - assert(pStream->StreamSwitch != NULL); - return pStream->StreamSwitch(pStream, pNewStream); -} - -/** - * Returns the file name of the stream - * - * \a pStream Pointer to an open stream - */ -TCHAR * FileStream_GetFileName(TFileStream * pStream) -{ - assert(pStream != NULL); - return pStream->szFileName; -} - -/** - * Returns true if the stream is read-only - * - * \a pStream Pointer to an open stream - */ -bool FileStream_IsReadOnly(TFileStream * pStream) -{ - return (pStream->dwFlags & STREAM_FLAG_READ_ONLY) ? true : false; -} - -/** - * This function enabled a linear stream to include data bitmap. - * Used by MPQs v 4.0 from WoW. Each file block is represented by - * a bit in the bitmap. 1 means the block is present, 0 means it's not. - * - * \a pStream Pointer to an open stream - * \a pBitmap Pointer to file bitmap - */ - -bool FileStream_SetBitmap(TFileStream * pStream, TFileBitmap * pBitmap) -{ - TLinearStream * pLinearStream; - - // It must be a linear stream. - if((pStream->dwFlags & STREAM_PROVIDER_MASK) != STREAM_PROVIDER_LINEAR) - return false; - pLinearStream = (TLinearStream *)pStream; - - // Two bitmaps are not allowed - if(pLinearStream->pBitmap != NULL) - return false; - - // We need to change some entry points - pLinearStream->StreamRead = (STREAM_READ)LinearStream_Read; - pLinearStream->StreamGetBmp = (STREAM_GETBMP)LinearStream_GetBitmap; - - // Using data bitmap renders the stream to be read only. - pLinearStream->dwFlags |= STREAM_FLAG_READ_ONLY; - pLinearStream->pBitmap = pBitmap; - return true; -} - -/** - * This function retrieves the file bitmap. A file bitmap is an array - * of bits, each bit representing one file block. A value of 1 means - * that the block is present in the file, a value of 0 means that the - * block is not present. - * - * \a pStream Pointer to an open stream - * \a pBitmap Pointer to buffer where to store the file bitmap - * \a Length Size of buffer pointed by pBitmap, in bytes - * \a LengthNeeded If non-NULL, the function supplies the necessary byte size of the buffer - */ -bool FileStream_GetBitmap(TFileStream * pStream, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded) -{ - assert(pStream->StreamGetBmp != NULL); - return pStream->StreamGetBmp(pStream, pBitmap, Length, LengthNeeded); -} - -/** - * This function closes an archive file and frees any data buffers - * that have been allocated for stream management. The function must also - * support partially allocated structure, i.e. one or more buffers - * can be NULL, if there was an allocation failure during the process - * - * \a pStream Pointer to an open stream - */ -void FileStream_Close(TFileStream * pStream) -{ - // Check if the stream structure is allocated at all - if(pStream != NULL) - { - // Close the stream provider. - // This will also close the base stream - assert(pStream->StreamClose != NULL); - pStream->StreamClose(pStream); - - // Free the stream itself - STORM_FREE(pStream); - } -} - -//----------------------------------------------------------------------------- -// main - for testing purposes - -#ifdef __STORMLIB_TEST__ -int FileStream_Test(const TCHAR * szFileName, DWORD dwStreamFlags) -{ - TFileStream * pStream; - TMPQHeader MpqHeader; - ULONGLONG FilePos; - TMPQBlock * pBlock; - TMPQHash * pHash; - - InitializeMpqCryptography(); - - pStream = FileStream_OpenFile(szFileName, dwStreamFlags); - if(pStream == NULL) - return GetLastError(); - - // Read the MPQ header - FileStream_Read(pStream, NULL, &MpqHeader, MPQ_HEADER_SIZE_V2); - if(MpqHeader.dwID != ID_MPQ) - return ERROR_FILE_CORRUPT; - - // Read the hash table - pHash = STORM_ALLOC(TMPQHash, MpqHeader.dwHashTableSize); - if(pHash != NULL) - { - FilePos = MpqHeader.dwHashTablePos; - FileStream_Read(pStream, &FilePos, pHash, MpqHeader.dwHashTableSize * sizeof(TMPQHash)); - DecryptMpqBlock(pHash, MpqHeader.dwHashTableSize * sizeof(TMPQHash), MPQ_KEY_HASH_TABLE); - STORM_FREE(pHash); - } - - // Read the block table - pBlock = STORM_ALLOC(TMPQBlock, MpqHeader.dwBlockTableSize); - if(pBlock != NULL) - { - FilePos = MpqHeader.dwBlockTablePos; - FileStream_Read(pStream, &FilePos, pBlock, MpqHeader.dwBlockTableSize * sizeof(TMPQBlock)); - DecryptMpqBlock(pBlock, MpqHeader.dwBlockTableSize * sizeof(TMPQBlock), MPQ_KEY_BLOCK_TABLE); - STORM_FREE(pBlock); - } - - FileStream_Close(pStream); - return ERROR_SUCCESS; -} -#endif - -/* -int FileStream_Test() -{ - TFileStream * pStream; - - InitializeMpqCryptography(); - - // - // Test 1: Write to a stream - // - - pStream = FileStream_CreateFile("E:\\Stream.bin", 0); - if(pStream != NULL) - { - char szString1[100] = "This is a single line\n\r"; - DWORD dwLength = strlen(szString1); - - for(int i = 0; i < 10; i++) - { - if(!FileStream_Write(pStream, NULL, szString1, dwLength)) - { - printf("Failed to write to the stream\n"); - return ERROR_CAN_NOT_COMPLETE; - } - } - FileStream_Close(pStream); - } - - // - // Test2: Read from the stream - // - - pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); - if(pStream != NULL) - { - char szString1[100] = "This is a single line\n\r"; - char szString2[100]; - DWORD dwLength = strlen(szString1); - - // This call must end with an error - if(FileStream_Write(pStream, NULL, "aaa", 3)) - { - printf("Write succeeded while it should fail\n"); - return -1; - } - - for(int i = 0; i < 10; i++) - { - if(!FileStream_Read(pStream, NULL, szString2, dwLength)) - { - printf("Failed to read from the stream\n"); - return -1; - } - - szString2[dwLength] = 0; - if(strcmp(szString1, szString2)) - { - printf("Data read from file are different from data written\n"); - return -1; - } - } - FileStream_Close(pStream); - } - - // - // Test3: Open the temp stream, write some data and switch it to the original stream - // - - pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); - if(pStream != NULL) - { - TFileStream * pTempStream; - ULONGLONG FileSize; - - pTempStream = FileStream_CreateFile("E:\\TempStream.bin", 0); - if(pTempStream == NULL) - { - printf("Failed to create temp stream\n"); - return -1; - } - - // Copy the original stream to the temp - if(!FileStream_GetSize(pStream, FileSize)) - { - printf("Failed to get the file size\n"); - return -1; - } - - while(FileSize != 0) - { - DWORD dwBytesToRead = (DWORD)FileSize; - char Buffer[0x80]; - - if(dwBytesToRead > sizeof(Buffer)) - dwBytesToRead = sizeof(Buffer); - - if(!FileStream_Read(pStream, NULL, Buffer, dwBytesToRead)) - { - printf("CopyStream: Read source file failed\n"); - return -1; - } - - if(!FileStream_Write(pTempStream, NULL, Buffer, dwBytesToRead)) - { - printf("CopyStream: Write target file failed\n"); - return -1; - } - - FileSize -= dwBytesToRead; - } - - // Switch the streams - // Note that the pTempStream is closed by the operation - FileStream_Switch(pStream, pTempStream); - FileStream_Close(pStream); - } - - // - // Test4: Read from the stream again - // - - pStream = FileStream_OpenFile("E:\\Stream.bin", STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); - if(pStream != NULL) - { - char szString1[100] = "This is a single line\n\r"; - char szString2[100]; - DWORD dwLength = strlen(szString1); - - for(int i = 0; i < 10; i++) - { - if(!FileStream_Read(pStream, NULL, szString2, dwLength)) - { - printf("Failed to read from the stream\n"); - return -1; - } - - szString2[dwLength] = 0; - if(strcmp(szString1, szString2)) - { - printf("Data read from file are different from data written\n"); - return -1; - } - } - FileStream_Close(pStream); - } - - return 0; -} -*/ - diff --git a/dep/StormLib/src/FileStream.h b/dep/StormLib/src/FileStream.h deleted file mode 100644 index 31fe757514d..00000000000 --- a/dep/StormLib/src/FileStream.h +++ /dev/null @@ -1,189 +0,0 @@ -/*****************************************************************************/ -/* FileStream.h Copyright (c) Ladislav Zezula 2012 */ -/*---------------------------------------------------------------------------*/ -/* Description: Definitions for FileStream object */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 14.04.12 1.00 Lad The first version of FileStream.h */ -/*****************************************************************************/ - -#ifndef __FILESTREAM_H__ -#define __FILESTREAM_H__ - -//----------------------------------------------------------------------------- -// Function prototypes - -typedef bool (*STREAM_READ)( - struct TFileStream * pStream, // Pointer to an open stream - ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position - void * pvBuffer, // Pointer to data to be read - DWORD dwBytesToRead // Number of bytes to read from the file - ); - -typedef bool (*STREAM_WRITE)( - struct TFileStream * pStream, // Pointer to an open stream - ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it writes to the current position - const void * pvBuffer, // Pointer to data to be written - DWORD dwBytesToWrite // Number of bytes to read from the file - ); - -typedef bool (*STREAM_GETPOS)( - struct TFileStream * pStream, // Pointer to an open stream - ULONGLONG & ByteOffset // Pointer to store current file position - ); - -typedef bool (*STREAM_GETSIZE)( - struct TFileStream * pStream, // Pointer to an open stream - ULONGLONG & FileSize // Receives the file size, in bytes - ); - -typedef bool (*STREAM_SETSIZE)( - struct TFileStream * pStream, // Pointer to an open stream - ULONGLONG FileSize // New size for the file, in bytes - ); - -typedef bool (*STREAM_GETTIME)( - struct TFileStream * pStream, - ULONGLONG * pFT - ); - -typedef bool (*STREAM_SWITCH)( - struct TFileStream * pStream, - struct TFileStream * pNewStream - ); - -typedef bool (*STREAM_GETBMP)( - TFileStream * pStream, - TFileBitmap * pBitmap, - DWORD Length, - LPDWORD LengthNeeded - ); - -typedef void (*STREAM_CLOSE)( - struct TFileStream * pStream - ); - -//----------------------------------------------------------------------------- -// Local structures - part file structure - -typedef struct _PART_FILE_HEADER -{ - DWORD PartialVersion; // Always set to 2 - char GameBuildNumber[0x20]; // Minimum build number of the game that can use this MPQ - DWORD Flags; // Flags (details unknown) - DWORD FileSizeLo; // Low 32 bits of the contained file size - DWORD FileSizeHi; // High 32 bits of the contained file size - DWORD BlockSize; // Size of one file block, in bytes - -} PART_FILE_HEADER, *PPART_FILE_HEADER; - -// Structure describing the block-to-file map entry -typedef struct _PART_FILE_MAP_ENTRY -{ - DWORD Flags; // 3 = the block is present in the file - DWORD BlockOffsLo; // Low 32 bits of the block position in the file - DWORD BlockOffsHi; // High 32 bits of the block position in the file - DWORD LargeValueLo; // 64-bit value, meaning is unknown - DWORD LargeValueHi; - -} PART_FILE_MAP_ENTRY, *PPART_FILE_MAP_ENTRY; - -//----------------------------------------------------------------------------- -// Local structures - -union TBaseData -{ - struct - { - ULONGLONG FileSize; // Size of the file - ULONGLONG FilePos; // Current file position - ULONGLONG FileTime; // Date/time of last modification of the file - HANDLE hFile; // File handle - } File; - - struct - { - ULONGLONG FileSize; // Mapped file size - ULONGLONG FilePos; // Current stream position - ULONGLONG FileTime; // Date/time of last modification of the file - LPBYTE pbFile; // Pointer to mapped view - } Map; - - struct - { - ULONGLONG FileSize; // Size of the internet file - ULONGLONG FilePos; // Current position in the file - ULONGLONG FileTime; // Date/time of last modification of the file - HANDLE hInternet; // Internet handle - HANDLE hConnect; // Connection to the internet server - } Http; -}; - -//----------------------------------------------------------------------------- -// Structure for linear stream - -struct TFileStream -{ - // Stream provider functions - STREAM_READ StreamRead; // Pointer to stream read function for this archive. Do not use directly. - STREAM_WRITE StreamWrite; // Pointer to stream write function for this archive. Do not use directly. - STREAM_GETPOS StreamGetPos; // Pointer to function that returns current file position - STREAM_GETSIZE StreamGetSize; // Pointer to function returning file size - STREAM_SETSIZE StreamSetSize; // Pointer to function changing file size - STREAM_GETTIME StreamGetTime; // Pointer to function retrieving the file time - STREAM_GETBMP StreamGetBmp; // Pointer to function that retrieves the file bitmap - STREAM_SWITCH StreamSwitch; // Pointer to function changing the stream to another file - STREAM_CLOSE StreamClose; // Pointer to function closing the stream - - // Stream provider data members - TCHAR szFileName[MAX_PATH]; // File name - DWORD dwFlags; // Stream flags - - // Base provider functions - STREAM_READ BaseRead; - STREAM_WRITE BaseWrite; - STREAM_GETPOS BaseGetPos; // Pointer to function that returns current file position - STREAM_GETSIZE BaseGetSize; // Pointer to function returning file size - STREAM_SETSIZE BaseSetSize; // Pointer to function changing file size - STREAM_GETTIME BaseGetTime; // Pointer to function retrieving the file time - STREAM_CLOSE BaseClose; // Pointer to function closing the stream - - // Base provider data members - TBaseData Base; // Base provider data - - // Followed by stream provider data, with variable length -}; - -//----------------------------------------------------------------------------- -// Structure for linear stream - -struct TLinearStream : public TFileStream -{ - TFileBitmap * pBitmap; // Pointer to the stream bitmap -}; - -//----------------------------------------------------------------------------- -// Structure for partial stream - -struct TPartialStream : public TFileStream -{ - ULONGLONG VirtualSize; // Virtual size of the file - ULONGLONG VirtualPos; // Virtual position in the file - DWORD BlockCount; // Number of file blocks. Used by partial file stream - DWORD BlockSize; // Size of one block. Used by partial file stream - - PPART_FILE_MAP_ENTRY PartMap; // File map, variable length -}; - -//----------------------------------------------------------------------------- -// Structure for encrypted stream - -#define MPQE_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted - -struct TEncryptedStream : public TFileStream -{ - BYTE Key[MPQE_CHUNK_SIZE]; // File key -}; - -#endif // __FILESTREAM_H__ diff --git a/dep/StormLib/src/SBaseCommon.cpp b/dep/StormLib/src/SBaseCommon.cpp deleted file mode 100644 index 65818784521..00000000000 --- a/dep/StormLib/src/SBaseCommon.cpp +++ /dev/null @@ -1,1700 +0,0 @@ -/*****************************************************************************/ -/* SBaseCommon.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Common functions for StormLib, used by all SFile*** modules */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 24.03.03 1.00 Lad The first version of SFileCommon.cpp */ -/* 19.11.03 1.01 Dan Big endian handling */ -/* 12.06.04 1.01 Lad Renamed to SCommon.cpp */ -/* 06.09.10 1.01 Lad Renamed to SBaseCommon.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Ladislav Zezula 1998-2012"; - -//----------------------------------------------------------------------------- -// The buffer for decryption engine. - -LCID lcFileLocale = LANG_NEUTRAL; // File locale -USHORT wPlatform = 0; // File platform - -//----------------------------------------------------------------------------- -// Storm buffer functions - -#define STORM_BUFFER_SIZE 0x500 - -static DWORD StormBuffer[STORM_BUFFER_SIZE]; // Buffer for the decryption engine -static bool bMpqCryptographyInitialized = false; - -DWORD HashString(const char * szFileName, DWORD dwHashType) -{ - LPBYTE pbKey = (BYTE *)szFileName; - DWORD dwSeed1 = 0x7FED7FED; - DWORD dwSeed2 = 0xEEEEEEEE; - DWORD ch; - - while(*pbKey != 0) - { - ch = toupper(*pbKey++); - - dwSeed1 = StormBuffer[dwHashType + ch] ^ (dwSeed1 + dwSeed2); - dwSeed2 = ch + dwSeed1 + dwSeed2 + (dwSeed2 << 5) + 3; - } - - return dwSeed1; -} - -void InitializeMpqCryptography() -{ - DWORD dwSeed = 0x00100001; - DWORD index1 = 0; - DWORD index2 = 0; - int i; - - // Initialize the decryption buffer. - // Do nothing if already done. - if(bMpqCryptographyInitialized == false) - { - for(index1 = 0; index1 < 0x100; index1++) - { - for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100) - { - DWORD temp1, temp2; - - dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB; - temp1 = (dwSeed & 0xFFFF) << 0x10; - - dwSeed = (dwSeed * 125 + 3) % 0x2AAAAB; - temp2 = (dwSeed & 0xFFFF); - - StormBuffer[index2] = (temp1 | temp2); - } - } - - // Also register both MD5 and SHA1 hash algorithms - register_hash(&md5_desc); - register_hash(&sha1_desc); - - // Use LibTomMath as support math library for LibTomCrypt - ltc_mp = ltm_desc; - - // Don't do that again - bMpqCryptographyInitialized = true; - } -} - -//----------------------------------------------------------------------------- -// Calculates the hash table size for a given amount of files - -DWORD GetHashTableSizeForFileCount(DWORD dwFileCount) -{ - DWORD dwPowerOfTwo; - - // Round the hash table size up to the nearest power of two - for(dwPowerOfTwo = HASH_TABLE_SIZE_MIN; dwPowerOfTwo < HASH_TABLE_SIZE_MAX; dwPowerOfTwo <<= 1) - { - if(dwPowerOfTwo >= dwFileCount) - { - return dwPowerOfTwo; - } - } - - // Don't allow the hash table size go over allowed maximum - return HASH_TABLE_SIZE_MAX; -} - -//----------------------------------------------------------------------------- -// Calculates a Jenkin's Encrypting and decrypting MPQ file data - -ULONGLONG HashStringJenkins(const char * szFileName) -{ - char * szTemp; - char szLocFileName[0x108]; - char chOneChar; - size_t nLength = 0; - unsigned int primary_hash = 1; - unsigned int secondary_hash = 2; - - // This is required to produce defined results - assert(szFileName != NULL); - - // Normalize the file name - convert to uppercase, and convert "/" to "\\". - if(szFileName != NULL) - { - szTemp = szLocFileName; - while(*szFileName != 0) - { - chOneChar = (char)tolower(*szFileName++); - if(chOneChar == '/') - chOneChar = '\\'; - - *szTemp++ = chOneChar; - } - - nLength = szTemp - szLocFileName; - *szTemp = 0; - } - - // Thanks Quantam for finding out what the algorithm is. - // I am really getting old for reversing large chunks of assembly - // that does hashing :-) - hashlittle2(szLocFileName, nLength, &secondary_hash, &primary_hash); - - // Combine those 2 together - return (ULONGLONG)primary_hash * (ULONGLONG)0x100000000ULL + (ULONGLONG)secondary_hash; -} - -//----------------------------------------------------------------------------- -// This function converts the MPQ header so it always looks like version 4 - -int ConvertMpqHeaderToFormat4( - TMPQArchive * ha, - ULONGLONG FileSize, - DWORD dwFlags) -{ - ULONGLONG ByteOffset; - TMPQHeader * pHeader = ha->pHeader; - DWORD dwExpectedArchiveSize; - USHORT wFormatVersion = pHeader->wFormatVersion; - int nError = ERROR_SUCCESS; - - // If version 1.0 is forced, then the format version is forced to be 1.0 - // Reason: Storm.dll in Warcraft III ignores format version value - if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) - wFormatVersion = MPQ_FORMAT_VERSION_1; - - // Format-specific fixes - switch(wFormatVersion) - { - case MPQ_FORMAT_VERSION_1: - - // Check for malformed MPQ header version 1.0 - if(pHeader->dwHeaderSize != MPQ_HEADER_SIZE_V1) - { - pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; - ha->dwFlags |= MPQ_FLAG_PROTECTED; - } - - // - // The value of "dwArchiveSize" member in the MPQ header - // is ignored by Storm.dll and can contain garbage value - // ("w3xmaster" protector). - // - - dwExpectedArchiveSize = (DWORD)(FileSize - ha->MpqPos); - if(pHeader->dwArchiveSize != dwExpectedArchiveSize) - { - // Note: dwExpectedArchiveSize might be incorrect at this point. - // MPQs version 1.0 can have strong digital signature appended at the end, - // or they might just have arbitrary data there. - // In either case, we recalculate the archive size later when - // block table is loaded and positions of all files is known. - pHeader->dwArchiveSize = dwExpectedArchiveSize; - ha->dwFlags |= MPQ_FLAG_NEED_FIX_SIZE; - } - - // Zero the fields in 2.0 part of the MPQ header - pHeader->HiBlockTablePos64 = 0; - pHeader->wHashTablePosHi = 0; - pHeader->wBlockTablePosHi = 0; - // No break here !!! - - case MPQ_FORMAT_VERSION_2: - case MPQ_FORMAT_VERSION_3: - - // In MPQ format 3.0, the entire header is optional - // and the size of the header can actually be identical - // to size of header 2.0 - if(pHeader->dwHeaderSize < MPQ_HEADER_SIZE_V3) - { - ULONGLONG ArchiveSize64 = pHeader->dwArchiveSize; - - // In format 2.0, the archive size is obsolete and is calculated - // as the highest offset of hash table, block table or hi-block table. - // However, we can still rely on it, if the size of the archive is under 4 GB - if((FileSize - ha->MpqPos) >> 32) - { - ByteOffset = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos) + (pHeader->dwHashTableSize * sizeof(TMPQHash)); - if(ByteOffset > ArchiveSize64) - ArchiveSize64 = ByteOffset; - - ByteOffset = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) + (pHeader->dwBlockTableSize * sizeof(TMPQBlock)); - if(ByteOffset > ArchiveSize64) - ArchiveSize64 = ByteOffset; - - // Only if we actually have a hi-block table - if(pHeader->HiBlockTablePos64) - { - ByteOffset = pHeader->HiBlockTablePos64 + (pHeader->dwBlockTableSize * sizeof(USHORT)); - if(ByteOffset > ArchiveSize64) - ArchiveSize64 = ByteOffset; - } - - // We need to recalculate archive size later, - // when block table is loaded and the position of files is known - ha->dwFlags |= MPQ_FLAG_NEED_FIX_SIZE; - } - - // Initialize the rest of the 3.0 header - pHeader->ArchiveSize64 = ArchiveSize64; - pHeader->HetTablePos64 = 0; - pHeader->BetTablePos64 = 0; - } - - // - // Calculate compressed size of each table. We assume the following order: - // 1) HET table - // 2) BET table - // 3) Classic hash table - // 4) Classic block table - // 5) Hi-block table - // - - // Set all sizes to zero - pHeader->HetTableSize64 = 0; - pHeader->BetTableSize64 = 0; - - // Either both HET and BET table exist or none of them does. - if(pHeader->HetTablePos64) - { - // Compressed size of the HET and BET tables - pHeader->HetTableSize64 = pHeader->BetTablePos64 - pHeader->HetTablePos64; - pHeader->BetTableSize64 = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos) - pHeader->HetTablePos64; - } - - // Compressed size of hash and block table - if(wFormatVersion >= MPQ_FORMAT_VERSION_2) - { - // Compressed size of the hash table - pHeader->HashTableSize64 = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos) - MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos); - - // Block and hi-block table - if(pHeader->HiBlockTablePos64) - { - pHeader->BlockTableSize64 = pHeader->HiBlockTablePos64 - MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); - pHeader->HiBlockTableSize64 = pHeader->ArchiveSize64 - pHeader->HiBlockTablePos64; - } - else - { - pHeader->BlockTableSize64 = pHeader->ArchiveSize64 - MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); - pHeader->HiBlockTableSize64 = 0; - } - } - else - { - // No known MPQ in format 1.0 has any of the tables compressed - pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash); - pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock); - pHeader->HiBlockTableSize64 = 0; - } - - // Set the data chunk size for MD5 to zero - pHeader->dwRawChunkSize = 0; - - // Fill the MD5's - memset(pHeader->MD5_BlockTable, 0, MD5_DIGEST_SIZE); - memset(pHeader->MD5_HashTable, 0, MD5_DIGEST_SIZE); - memset(pHeader->MD5_HiBlockTable, 0, MD5_DIGEST_SIZE); - memset(pHeader->MD5_BetTable, 0, MD5_DIGEST_SIZE); - memset(pHeader->MD5_HetTable, 0, MD5_DIGEST_SIZE); - memset(pHeader->MD5_MpqHeader, 0, MD5_DIGEST_SIZE); - // No break here !!!! - - case MPQ_FORMAT_VERSION_4: - - // Verify header MD5. Header MD5 is calculated from the MPQ header since the 'MPQ\x1A' - // signature until the position of header MD5 at offset 0xC0 - if(!VerifyDataBlockHash(ha->pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, ha->pHeader->MD5_MpqHeader)) - nError = ERROR_FILE_CORRUPT; - break; - } - - return nError; -} - -//----------------------------------------------------------------------------- -// Default flags for (attributes) and (listfile) - -DWORD GetDefaultSpecialFileFlags(TMPQArchive * ha, DWORD dwFileSize) -{ - // Fixed for format 1.0 - if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) - return MPQ_FILE_COMPRESS | MPQ_FILE_ENCRYPTED | MPQ_FILE_FIX_KEY; - - // Size-dependent for formats 2.0-4.0 - return (dwFileSize > 0x4000) ? (MPQ_FILE_COMPRESS | MPQ_FILE_SECTOR_CRC) : (MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT); -} - - -//----------------------------------------------------------------------------- -// Encrypting and decrypting MPQ file data - -void EncryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwSeed1) -{ - LPDWORD block = (LPDWORD)pvFileBlock; - DWORD dwSeed2 = 0xEEEEEEEE; - DWORD ch; - - // Round to DWORDs - dwLength >>= 2; - - while(dwLength-- > 0) - { - dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; - ch = *block; - *block++ = ch ^ (dwSeed1 + dwSeed2); - - dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); - dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; - } -} - -void DecryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwSeed1) -{ - LPDWORD block = (LPDWORD)pvFileBlock; - DWORD dwSeed2 = 0xEEEEEEEE; - DWORD ch; - - // Round to DWORDs - dwLength >>= 2; - - while(dwLength-- > 0) - { - dwSeed2 += StormBuffer[0x400 + (dwSeed1 & 0xFF)]; - ch = *block ^ (dwSeed1 + dwSeed2); - - dwSeed1 = ((~dwSeed1 << 0x15) + 0x11111111) | (dwSeed1 >> 0x0B); - dwSeed2 = ch + dwSeed2 + (dwSeed2 << 5) + 3; - *block++ = ch; - } -} - -/* -void EncryptMpqTable(void * pvMpqTable, DWORD dwLength, const char * szKey) -{ - EncryptMpqBlock(pvMpqTable, dwLength, HashString(szKey, MPQ_HASH_FILE_KEY)); -} - -void DecryptMpqTable(void * pvMpqTable, DWORD dwLength, const char * szKey) -{ - DecryptMpqBlock(pvMpqTable, dwLength, HashString(szKey, MPQ_HASH_FILE_KEY)); -} -*/ - -/** - * Functions tries to get file decryption key. The trick comes from sector - * positions which are stored at the begin of each compressed file. We know the - * file size, that means we know number of sectors that means we know the first - * DWORD value in sector position. And if we know encrypted and decrypted value, - * we can find the decryption key !!! - * - * hf - MPQ file handle - * SectorOffsets - DWORD array of sector positions - * ch - Decrypted value of the first sector pos - */ - -DWORD DetectFileKeyBySectorSize(LPDWORD SectorOffsets, DWORD decrypted) -{ - DWORD saveKey1; - DWORD temp = *SectorOffsets ^ decrypted; // temp = seed1 + seed2 - temp -= 0xEEEEEEEE; // temp = seed1 + StormBuffer[0x400 + (seed1 & 0xFF)] - - for(int i = 0; i < 0x100; i++) // Try all 255 possibilities - { - DWORD seed1; - DWORD seed2 = 0xEEEEEEEE; - DWORD ch; - - // Try the first DWORD (We exactly know the value) - seed1 = temp - StormBuffer[0x400 + i]; - seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; - ch = SectorOffsets[0] ^ (seed1 + seed2); - - if(ch != decrypted) - continue; - - // Add 1 because we are decrypting sector positions - saveKey1 = seed1 + 1; - - // If OK, continue and test the second value. We don't know exactly the value, - // but we know that the second one has lower 16 bits set to zero - // (no compressed sector is larger than 0xFFFF bytes) - seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); - seed2 = ch + seed2 + (seed2 << 5) + 3; - - seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; - ch = SectorOffsets[1] ^ (seed1 + seed2); - - if((ch & 0xFFFF0000) == 0) - return saveKey1; - } - return 0; -} - -// Function tries to detect file encryption key. It expectes at least two uncompressed bytes -DWORD DetectFileKeyByKnownContent(void * pvFileContent, DWORD nDwords, ...) -{ - LPDWORD pdwContent = (LPDWORD)pvFileContent; - va_list argList; - DWORD dwDecrypted[0x10]; - DWORD saveKey1; - DWORD dwTemp; - DWORD i, j; - - // We need at least two DWORDS to detect the file key - if(nDwords < 0x02 || nDwords > 0x10) - return 0; - - va_start(argList, nDwords); - for(i = 0; i < nDwords; i++) - dwDecrypted[i] = va_arg(argList, DWORD); - va_end(argList); - - dwTemp = (*pdwContent ^ dwDecrypted[0]) - 0xEEEEEEEE; - for(i = 0; i < 0x100; i++) // Try all 256 possibilities - { - DWORD seed1; - DWORD seed2 = 0xEEEEEEEE; - DWORD ch; - - // Try the first DWORD - seed1 = dwTemp - StormBuffer[0x400 + i]; - seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; - ch = pdwContent[0] ^ (seed1 + seed2); - - if(ch != dwDecrypted[0]) - continue; - - saveKey1 = seed1; - - // If OK, continue and test all bytes. - for(j = 1; j < nDwords; j++) - { - seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); - seed2 = ch + seed2 + (seed2 << 5) + 3; - - seed2 += StormBuffer[0x400 + (seed1 & 0xFF)]; - ch = pdwContent[j] ^ (seed1 + seed2); - - if(ch == dwDecrypted[j] && j == nDwords - 1) - return saveKey1; - } - } - return 0; -} - -DWORD DetectFileKeyByContent(void * pvFileContent, DWORD dwFileSize) -{ - DWORD dwFileKey; - - // Try to break the file encryption key as if it was a WAVE file - if(dwFileSize >= 0x0C) - { - dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 3, 0x46464952, dwFileSize - 8, 0x45564157); - if(dwFileKey != 0) - return dwFileKey; - } - - // Try to break the encryption key as if it was an EXE file - if(dwFileSize > 0x40) - { - dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 2, 0x00905A4D, 0x00000003); - if(dwFileKey != 0) - return dwFileKey; - } - - // Try to break the encryption key as if it was a XML file - if(dwFileSize > 0x04) - { - dwFileKey = DetectFileKeyByKnownContent(pvFileContent, 2, 0x6D783F3C, 0x6576206C); - if(dwFileKey != 0) - return dwFileKey; - } - - // Not detected, sorry - return 0; -} - -DWORD DecryptFileKey( - const char * szFileName, - ULONGLONG MpqPos, - DWORD dwFileSize, - DWORD dwFlags) -{ - DWORD dwFileKey; - DWORD dwMpqPos = (DWORD)MpqPos; - - // File key is calculated from plain name - szFileName = GetPlainFileNameA(szFileName); - dwFileKey = HashString(szFileName, MPQ_HASH_FILE_KEY); - - // Fix the key, if needed - if(dwFlags & MPQ_FILE_FIX_KEY) - dwFileKey = (dwFileKey + dwMpqPos) ^ dwFileSize; - - // Return the key - return dwFileKey; -} - -//----------------------------------------------------------------------------- -// Handle validation functions - -bool IsValidMpqHandle(TMPQArchive * ha) -{ - if(ha == NULL) - return false; - if(ha->pHeader == NULL || ha->pHeader->dwID != ID_MPQ) - return false; - - return (bool)(ha->pHeader->dwID == ID_MPQ); -} - -bool IsValidFileHandle(TMPQFile * hf) -{ - if(hf == NULL) - return false; - - if(hf->dwMagic != ID_MPQ_FILE) - return false; - - if(hf->pStream != NULL) - return true; - - return IsValidMpqHandle(hf->ha); -} - -//----------------------------------------------------------------------------- -// Hash table and block table manipulation - -// Retrieves the first hash entry for the given file. -// Every locale version of a file has its own hash entry -TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName) -{ - TMPQHash * pStartHash; // File hash entry (start) - TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; - TMPQHash * pHash; // File hash entry (current) - DWORD dwHashTableSizeMask; - DWORD dwIndex = HashString(szFileName, MPQ_HASH_TABLE_INDEX); - DWORD dwName1 = HashString(szFileName, MPQ_HASH_NAME_A); - DWORD dwName2 = HashString(szFileName, MPQ_HASH_NAME_B); - - // Get the first possible has entry that might be the one - dwHashTableSizeMask = ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0; - pStartHash = pHash = ha->pHashTable + (dwIndex & dwHashTableSizeMask); - - // There might be deleted entries in the hash table prior to our desired entry. - while(pHash->dwBlockIndex != HASH_ENTRY_FREE) - { - // If the entry agrees, we found it. - if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex < ha->dwFileTableSize) - return pHash; - - // Move to the next hash entry. Stop searching - // if we got reached the original hash entry - if(++pHash >= pHashEnd) - pHash = ha->pHashTable; - if(pHash == pStartHash) - break; - } - - // The apropriate hash entry was not found - return NULL; -} - -TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash) -{ - TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; - TMPQHash * pHash = pPrevHash; - DWORD dwName1 = pPrevHash->dwName1; - DWORD dwName2 = pPrevHash->dwName2; - - // Now go for any next entry that follows the pPrevHash, - // until either free hash entry was found, or the start entry was reached - for(;;) - { - // Move to the next hash entry. Stop searching - // if we got reached the original hash entry - if(++pHash >= pHashEnd) - pHash = ha->pHashTable; - if(pHash == pFirstHash) - break; - - // If the entry is a free entry, stop search - if(pHash->dwBlockIndex == HASH_ENTRY_FREE) - break; - - // If the entry is not free and the name agrees, we found it - if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->dwBlockIndex < ha->pHeader->dwBlockTableSize) - return pHash; - } - - // No next entry - return NULL; -} - -// Allocates an entry in the hash table -DWORD AllocateHashEntry( - TMPQArchive * ha, - TFileEntry * pFileEntry) -{ - TMPQHash * pStartHash; // File hash entry (start) - TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; - TMPQHash * pHash; // File hash entry (current) - DWORD dwHashTableSizeMask; - DWORD dwIndex = HashString(pFileEntry->szFileName, MPQ_HASH_TABLE_INDEX); - DWORD dwName1 = HashString(pFileEntry->szFileName, MPQ_HASH_NAME_A); - DWORD dwName2 = HashString(pFileEntry->szFileName, MPQ_HASH_NAME_B); - - // Get the first possible has entry that might be the one - dwHashTableSizeMask = ha->pHeader->dwHashTableSize ? (ha->pHeader->dwHashTableSize - 1) : 0; - pStartHash = pHash = ha->pHashTable + (dwIndex & dwHashTableSizeMask); - - // There might be deleted entries in the hash table prior to our desired entry. - while(pHash->dwBlockIndex < HASH_ENTRY_DELETED) - { - // If there already is an existing entry, reuse it. - if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->lcLocale == pFileEntry->lcLocale) - break; - - // Move to the next hash entry. - // If we reached the starting entry, it's failure. - if(++pHash >= pHashEnd) - pHash = ha->pHashTable; - if(pHash == pStartHash) - return HASH_ENTRY_FREE; - } - - // Fill the free hash entry - pHash->dwName1 = dwName1; - pHash->dwName2 = dwName2; - pHash->lcLocale = pFileEntry->lcLocale; - pHash->wPlatform = pFileEntry->wPlatform; - pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable); - - // Fill the hash index in the file entry - pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable); - return pFileEntry->dwHashIndex; -} - -// Finds a free space in the MPQ where to store next data -// The free space begins beyond the file that is stored at the fuhrtest -// position in the MPQ. -void FindFreeMpqSpace(TMPQArchive * ha, ULONGLONG * pFreeSpacePos) -{ - TMPQHeader * pHeader = ha->pHeader; - TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pFileEntry = ha->pFileTable; - ULONGLONG FreeSpacePos = ha->pHeader->dwHeaderSize; - DWORD dwChunkCount; - - // Parse the entire block table - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) - { - // Only take existing files - if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) - { - // If the end of the file is bigger than current MPQ table pos, update it - if((pFileEntry->ByteOffset + pFileEntry->dwCmpSize) > FreeSpacePos) - { - // Get the end of the file data - FreeSpacePos = pFileEntry->ByteOffset + pFileEntry->dwCmpSize; - - // Add the MD5 chunks, if present - if(pHeader->dwRawChunkSize != 0 && pFileEntry->dwCmpSize != 0) - { - dwChunkCount = ((pFileEntry->dwCmpSize - 1) / pHeader->dwRawChunkSize) + 1; - FreeSpacePos += dwChunkCount * MD5_DIGEST_SIZE; - } - } - } - } - - // Give the free space position to the caller - if(pFreeSpacePos != NULL) - *pFreeSpacePos = FreeSpacePos; -} - -//----------------------------------------------------------------------------- -// Common functions - MPQ File - -TMPQFile * CreateMpqFile(TMPQArchive * ha) -{ - TMPQFile * hf; - - // Allocate space for TMPQFile - hf = STORM_ALLOC(TMPQFile, 1); - if(hf != NULL) - { - // Fill the file structure - memset(hf, 0, sizeof(TMPQFile)); - hf->ha = ha; - hf->pStream = NULL; - hf->dwMagic = ID_MPQ_FILE; - } - - return hf; -} - -// Loads a table from MPQ. -// Can be used for hash table, block table, sector offset table or sector checksum table -int LoadMpqTable( - TMPQArchive * ha, - ULONGLONG ByteOffset, - void * pvTable, - DWORD dwCompressedSize, - DWORD dwRealSize, - DWORD dwKey) -{ - LPBYTE pbCompressed = NULL; - LPBYTE pbToRead = (LPBYTE)pvTable; - int nError = ERROR_SUCCESS; - - // "interface.MPQ.part" in trial version of World of Warcraft - // has block table and hash table compressed. - if(dwCompressedSize < dwRealSize) - { - // Allocate temporary buffer for holding compressed data - pbCompressed = STORM_ALLOC(BYTE, dwCompressedSize); - if(pbCompressed == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Assign the temporary buffer as target for read operation - pbToRead = pbCompressed; - } - - // Read the table - if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwCompressedSize)) - { - // First of all, decrypt the table - if(dwKey != 0) - { - BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize); - DecryptMpqBlock(pbToRead, dwCompressedSize, dwKey); - BSWAP_ARRAY32_UNSIGNED(pbToRead, dwCompressedSize); - } - - // If the table is compressed, decompress it - if(dwCompressedSize < dwRealSize) - { - int cbOutBuffer = (int)dwRealSize; - int cbInBuffer = (int)dwCompressedSize; - - if(!SCompDecompress2((char *)pvTable, &cbOutBuffer, (char *)pbCompressed, cbInBuffer)) - nError = GetLastError(); - - // Free the temporary buffer - STORM_FREE(pbCompressed); - } - } - else - { - nError = GetLastError(); - } - - BSWAP_ARRAY32_UNSIGNED(pvTable, dwRealSize); - return nError; -} - -void CalculateRawSectorOffset( - ULONGLONG & RawFilePos, - TMPQFile * hf, - DWORD dwSectorOffset) -{ - // - // Some MPQ protectors place the sector offset table after the actual file data. - // Sector offsets in the sector offset table are negative. When added - // to MPQ file offset from the block table entry, the result is a correct - // position of the file data in the MPQ. - // - // The position of sector table must be always within the MPQ, however. - // When a negative sector offset is found, we make sure that we make the addition - // just in 32-bits, and then add the MPQ offset. - // - - if(dwSectorOffset & 0x80000000) - { - RawFilePos = hf->ha->MpqPos + ((DWORD)hf->pFileEntry->ByteOffset + dwSectorOffset); - } - else - { - RawFilePos = hf->RawFilePos + dwSectorOffset; - } - - // We also have to add patch header size, if patch header is present - if(hf->pPatchInfo != NULL) - RawFilePos += hf->pPatchInfo->dwLength; -} - -unsigned char * AllocateMd5Buffer( - DWORD dwRawDataSize, - DWORD dwChunkSize, - LPDWORD pcbMd5Size) -{ - unsigned char * md5_array; - DWORD cbMd5Size; - - // Sanity check - assert(dwRawDataSize != 0); - assert(dwChunkSize != 0); - - // Calculate how many MD5's we will calculate - cbMd5Size = (((dwRawDataSize - 1) / dwChunkSize) + 1) * MD5_DIGEST_SIZE; - - // Allocate space for array or MD5s - md5_array = STORM_ALLOC(BYTE, cbMd5Size); - - // Give the size of the MD5 array - if(pcbMd5Size != NULL) - *pcbMd5Size = cbMd5Size; - return md5_array; -} - -// Allocates sector buffer and sector offset table -int AllocateSectorBuffer(TMPQFile * hf) -{ - TMPQArchive * ha = hf->ha; - - // Caller of AllocateSectorBuffer must ensure these - assert(hf->pbFileSector == NULL); - assert(hf->pFileEntry != NULL); - assert(hf->ha != NULL); - - // Don't allocate anything if the file has zero size - if(hf->pFileEntry->dwFileSize == 0 || hf->dwDataSize == 0) - return ERROR_SUCCESS; - - // Determine the file sector size and allocate buffer for it - hf->dwSectorSize = (hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) ? hf->dwDataSize : ha->dwSectorSize; - hf->pbFileSector = STORM_ALLOC(BYTE, hf->dwSectorSize); - hf->dwSectorOffs = SFILE_INVALID_POS; - - // Return result - return (hf->pbFileSector != NULL) ? (int)ERROR_SUCCESS : (int)ERROR_NOT_ENOUGH_MEMORY; -} - -// Allocates sector offset table -int AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile) -{ - TMPQArchive * ha = hf->ha; - DWORD dwLength = sizeof(TPatchInfo); - - // The following conditions must be true - assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE); - assert(hf->pPatchInfo == NULL); - -__AllocateAndLoadPatchInfo: - - // Allocate space for patch header. Start with default size, - // and if its size if bigger, then we reload them - hf->pPatchInfo = (TPatchInfo *)STORM_ALLOC(BYTE, dwLength); - if(hf->pPatchInfo == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Do we have to load the patch header from the file ? - if(bLoadFromFile) - { - // Load the patch header - if(!FileStream_Read(ha->pStream, &hf->RawFilePos, hf->pPatchInfo, dwLength)) - { - // Free the patch info - STORM_FREE(hf->pPatchInfo); - hf->pPatchInfo = NULL; - return GetLastError(); - } - - // Perform necessary swapping - hf->pPatchInfo->dwLength = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwLength); - hf->pPatchInfo->dwFlags = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwFlags); - hf->pPatchInfo->dwDataSize = BSWAP_INT32_UNSIGNED(hf->pPatchInfo->dwDataSize); - - // Verify the size of the patch header - // If it's not default size, we have to reload them - if(hf->pPatchInfo->dwLength > dwLength) - { - // Free the patch info - dwLength = hf->pPatchInfo->dwLength; - STORM_FREE(hf->pPatchInfo); - hf->pPatchInfo = NULL; - - // If the length is out of all possible ranges, fail the operation - if(dwLength > 0x400) - return ERROR_FILE_CORRUPT; - goto __AllocateAndLoadPatchInfo; - } - - // Patch file data size according to the patch header - hf->dwDataSize = hf->pPatchInfo->dwDataSize; - } - else - { - memset(hf->pPatchInfo, 0, dwLength); - } - - // Save the final length to the patch header - hf->pPatchInfo->dwLength = dwLength; - hf->pPatchInfo->dwFlags = 0x80000000; - return ERROR_SUCCESS; -} - -// Allocates sector offset table -int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile) -{ - TMPQArchive * ha = hf->ha; - TFileEntry * pFileEntry = hf->pFileEntry; - DWORD dwSectorOffsLen; - bool bSectorOffsetTableCorrupt = false; - - // Caller of AllocateSectorOffsets must ensure these - assert(hf->SectorOffsets == NULL); - assert(hf->pFileEntry != NULL); - assert(hf->dwDataSize != 0); - assert(hf->ha != NULL); - - // If the file is stored as single unit, just set number of sectors to 1 - if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) - { - hf->dwSectorCount = 1; - return ERROR_SUCCESS; - } - - // Calculate the number of data sectors - // Note that this doesn't work if the file size is zero - hf->dwSectorCount = ((hf->dwDataSize - 1) / hf->dwSectorSize) + 1; - - // Calculate the number of file sectors - dwSectorOffsLen = (hf->dwSectorCount + 1) * sizeof(DWORD); - - // If MPQ_FILE_SECTOR_CRC flag is set, there will either be extra DWORD - // or an array of MD5's. Either way, we read at least 4 bytes more - // in order to save additional read from the file. - if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) - dwSectorOffsLen += sizeof(DWORD); - - // Only allocate and load the table if the file is compressed - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED) - { - __LoadSectorOffsets: - - // Allocate the sector offset table - hf->SectorOffsets = (DWORD *)STORM_ALLOC(BYTE, dwSectorOffsLen); - if(hf->SectorOffsets == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Only read from the file if we are supposed to do so - if(bLoadFromFile) - { - ULONGLONG RawFilePos = hf->RawFilePos; - - if(hf->pPatchInfo != NULL) - RawFilePos += hf->pPatchInfo->dwLength; - - // Load the sector offsets from the file - if(!FileStream_Read(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen)) - { - // Free the sector offsets - STORM_FREE(hf->SectorOffsets); - hf->SectorOffsets = NULL; - return GetLastError(); - } - - // Swap the sector positions - BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen); - - // Decrypt loaded sector positions if necessary - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - { - // If we don't know the file key, try to find it. - if(hf->dwFileKey == 0) - { - hf->dwFileKey = DetectFileKeyBySectorSize(hf->SectorOffsets, dwSectorOffsLen); - if(hf->dwFileKey == 0) - { - STORM_FREE(hf->SectorOffsets); - hf->SectorOffsets = NULL; - return ERROR_UNKNOWN_FILE_KEY; - } - } - - // Decrypt sector positions - DecryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1); - } - - // - // Validate the sector offset table - // - // Note: Some MPQ protectors put the actual file data before the sector offset table. - // In this case, the sector offsets are negative (> 0x80000000). - // - - for(DWORD i = 0; i < hf->dwSectorCount; i++) - { - DWORD dwSectorOffset1 = hf->SectorOffsets[i+1]; - DWORD dwSectorOffset0 = hf->SectorOffsets[i]; - - // Every following sector offset must be bigger than the previous one - if(dwSectorOffset1 <= dwSectorOffset0) - { - bSectorOffsetTableCorrupt = true; - break; - } - - // The sector size must not be bigger than compressed file size - if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize) - { - bSectorOffsetTableCorrupt = true; - break; - } - } - - // If data corruption detected, free the sector offset table - if(bSectorOffsetTableCorrupt) - { - STORM_FREE(hf->SectorOffsets); - hf->SectorOffsets = NULL; - return ERROR_FILE_CORRUPT; - } - - // - // There may be various extra DWORDs loaded after the sector offset table. - // They are mostly empty on WoW release MPQs, but on MPQs from PTR, - // they contain random non-zero data. Their meaning is unknown. - // - // These extra values are, however, include in the dwCmpSize in the file - // table. We cannot ignore them, because compacting archive would fail - // - - if(hf->SectorOffsets[0] > dwSectorOffsLen) - { - dwSectorOffsLen = hf->SectorOffsets[0]; - STORM_FREE(hf->SectorOffsets); - hf->SectorOffsets = NULL; - goto __LoadSectorOffsets; - } - } - else - { - memset(hf->SectorOffsets, 0, dwSectorOffsLen); - hf->SectorOffsets[0] = dwSectorOffsLen; - } - } - - return ERROR_SUCCESS; -} - -int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile) -{ - TMPQArchive * ha = hf->ha; - TFileEntry * pFileEntry = hf->pFileEntry; - ULONGLONG RawFilePos; - DWORD dwCompressedSize = 0; - DWORD dwExpectedSize; - DWORD dwCrcOffset; // Offset of the CRC table, relative to file offset in the MPQ - DWORD dwCrcSize; - - // Caller of AllocateSectorChecksums must ensure these - assert(hf->SectorChksums == NULL); - assert(hf->SectorOffsets != NULL); - assert(hf->pFileEntry != NULL); - assert(hf->ha != NULL); - - // Single unit files don't have sector checksums - if(pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) - return ERROR_SUCCESS; - - // Caller must ensure that we are only called when we have sector checksums - assert(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC); - - // - // Older MPQs store an array of CRC32's after - // the raw file data in the MPQ. - // - // In newer MPQs, the (since Cataclysm BETA) the (attributes) file - // contains additional 32-bit values beyond the sector table. - // Their number depends on size of the (attributes), but their - // meaning is unknown. They are usually zeroed in retail game files, - // but contain some sort of checksum in BETA MPQs - // - - // Does the size of the file table match with the CRC32-based checksums? - dwExpectedSize = (hf->dwSectorCount + 2) * sizeof(DWORD); - if(hf->SectorOffsets[0] == dwExpectedSize) - { - // Is there valid size of the sector checksums? - if(hf->SectorOffsets[hf->dwSectorCount + 1] >= hf->SectorOffsets[hf->dwSectorCount]) - dwCompressedSize = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount]; - - // Ignore cases when the length is too small or too big. - if(dwCompressedSize < sizeof(DWORD) || dwCompressedSize > hf->dwSectorSize) - return ERROR_SUCCESS; - - // Allocate the array for the sector checksums - hf->SectorChksums = STORM_ALLOC(DWORD, hf->dwSectorCount); - if(hf->SectorChksums == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // If we are not supposed to load it from the file, allocate empty buffer - if(bLoadFromFile == false) - { - memset(hf->SectorChksums, 0, hf->dwSectorCount * sizeof(DWORD)); - return ERROR_SUCCESS; - } - - // Calculate offset of the CRC table - dwCrcSize = hf->dwSectorCount * sizeof(DWORD); - dwCrcOffset = hf->SectorOffsets[hf->dwSectorCount]; - CalculateRawSectorOffset(RawFilePos, hf, dwCrcOffset); - - // Now read the table from the MPQ - return LoadMpqTable(ha, RawFilePos, hf->SectorChksums, dwCompressedSize, dwCrcSize, 0); - } - - // If the size doesn't match, we ignore sector checksums -// assert(false); - return ERROR_SUCCESS; -} - -int WritePatchInfo(TMPQFile * hf) -{ - TMPQArchive * ha = hf->ha; - TPatchInfo * pPatchInfo = hf->pPatchInfo; - - // The caller must make sure that this function is only called - // when the following is true. - assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE); - assert(pPatchInfo != NULL); - - BSWAP_ARRAY32_UNSIGNED(pPatchInfo, 3 * sizeof(DWORD)); - if(!FileStream_Write(ha->pStream, &hf->RawFilePos, pPatchInfo, sizeof(TPatchInfo))) - return GetLastError(); - - return ERROR_SUCCESS; -} - -int WriteSectorOffsets(TMPQFile * hf) -{ - TMPQArchive * ha = hf->ha; - TFileEntry * pFileEntry = hf->pFileEntry; - ULONGLONG RawFilePos = hf->RawFilePos; - DWORD dwSectorOffsLen; - - // The caller must make sure that this function is only called - // when the following is true. - assert(hf->pFileEntry->dwFlags & MPQ_FILE_COMPRESSED); - assert(hf->SectorOffsets != NULL); - dwSectorOffsLen = hf->SectorOffsets[0]; - - // If file is encrypted, sector positions are also encrypted - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - EncryptMpqBlock(hf->SectorOffsets, dwSectorOffsLen, hf->dwFileKey - 1); - BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen); - - // Adjust sector offset table position, if we also have patch info - if(hf->pPatchInfo != NULL) - RawFilePos += hf->pPatchInfo->dwLength; - - // Write sector offsets to the archive - if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen)) - return GetLastError(); - - // Not necessary, as the sector checksums - // are going to be freed when this is done. -// BSWAP_ARRAY32_UNSIGNED(hf->SectorOffsets, dwSectorOffsLen); - return ERROR_SUCCESS; -} - - -int WriteSectorChecksums(TMPQFile * hf) -{ - TMPQArchive * ha = hf->ha; - ULONGLONG RawFilePos; - TFileEntry * pFileEntry = hf->pFileEntry; - LPBYTE pbCompressed; - DWORD dwCompressedSize = 0; - DWORD dwCrcSize; - int nOutSize; - int nError = ERROR_SUCCESS; - - // The caller must make sure that this function is only called - // when the following is true. - assert(hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC); - assert(hf->SectorOffsets != NULL); - assert(hf->SectorChksums != NULL); - - // If the MPQ has MD5 of each raw data chunk, - // we leave sector offsets empty - if(ha->pHeader->dwRawChunkSize != 0) - { - hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount]; - return ERROR_SUCCESS; - } - - // Calculate size of the checksum array - dwCrcSize = hf->dwSectorCount * sizeof(DWORD); - - // Allocate buffer for compressed sector CRCs. - pbCompressed = STORM_ALLOC(BYTE, dwCrcSize); - if(pbCompressed == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Perform the compression - BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize); - - nOutSize = (int)dwCrcSize; - SCompCompress((char *)pbCompressed, &nOutSize, (char *)hf->SectorChksums, (int)dwCrcSize, MPQ_COMPRESSION_ZLIB, 0, 0); - dwCompressedSize = (DWORD)nOutSize; - - // Write the sector CRCs to the archive - RawFilePos = hf->RawFilePos + hf->SectorOffsets[hf->dwSectorCount]; - if(hf->pPatchInfo != NULL) - RawFilePos += hf->pPatchInfo->dwLength; - if(!FileStream_Write(ha->pStream, &RawFilePos, pbCompressed, dwCompressedSize)) - nError = GetLastError(); - - // Not necessary, as the sector checksums - // are going to be freed when this is done. -// BSWAP_ARRAY32_UNSIGNED(hf->SectorChksums, dwCrcSize); - - // Store the sector CRCs - hf->SectorOffsets[hf->dwSectorCount + 1] = hf->SectorOffsets[hf->dwSectorCount] + dwCompressedSize; - pFileEntry->dwCmpSize += dwCompressedSize; - STORM_FREE(pbCompressed); - return nError; -} - -int WriteMemDataMD5( - TFileStream * pStream, - ULONGLONG RawDataOffs, - void * pvRawData, - DWORD dwRawDataSize, - DWORD dwChunkSize, - LPDWORD pcbTotalSize) -{ - unsigned char * md5_array; - unsigned char * md5; - LPBYTE pbRawData = (LPBYTE)pvRawData; - DWORD dwBytesRemaining = dwRawDataSize; - DWORD dwMd5ArraySize = 0; - int nError = ERROR_SUCCESS; - - // Allocate buffer for array of MD5 - md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize); - if(md5_array == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // For every file chunk, calculate MD5 - while(dwBytesRemaining != 0) - { - // Get the remaining number of bytes to read - dwChunkSize = STORMLIB_MIN(dwBytesRemaining, dwChunkSize); - - // Calculate MD5 - CalculateDataBlockHash(pbRawData, dwChunkSize, md5); - md5 += MD5_DIGEST_SIZE; - - // Move offset and size - dwBytesRemaining -= dwChunkSize; - pbRawData += dwChunkSize; - } - - // Write the array od MD5's to the file - RawDataOffs += dwRawDataSize; - if(!FileStream_Write(pStream, &RawDataOffs, md5_array, dwMd5ArraySize)) - nError = GetLastError(); - - // Give the caller the size of the MD5 array - if(pcbTotalSize != NULL) - *pcbTotalSize = dwRawDataSize + dwMd5ArraySize; - - // Free buffers and exit - STORM_FREE(md5_array); - return nError; -} - - -// Writes the MD5 for each chunk of the raw file data -int WriteMpqDataMD5( - TFileStream * pStream, - ULONGLONG RawDataOffs, - DWORD dwRawDataSize, - DWORD dwChunkSize) -{ - unsigned char * md5_array; - unsigned char * md5; - LPBYTE pbFileChunk; - DWORD dwMd5ArraySize = 0; - DWORD dwToRead = dwRawDataSize; - int nError = ERROR_SUCCESS; - - // Allocate buffer for array of MD5 - md5_array = md5 = AllocateMd5Buffer(dwRawDataSize, dwChunkSize, &dwMd5ArraySize); - if(md5_array == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Allocate space for file chunk - pbFileChunk = STORM_ALLOC(BYTE, dwChunkSize); - if(pbFileChunk == NULL) - { - STORM_FREE(md5_array); - return ERROR_NOT_ENOUGH_MEMORY; - } - - // For every file chunk, calculate MD5 - while(dwRawDataSize != 0) - { - // Get the remaining number of bytes to read - dwToRead = STORMLIB_MIN(dwRawDataSize, dwChunkSize); - - // Read the chunk - if(!FileStream_Read(pStream, &RawDataOffs, pbFileChunk, dwToRead)) - { - nError = GetLastError(); - break; - } - - // Calculate MD5 - CalculateDataBlockHash(pbFileChunk, dwToRead, md5); - md5 += MD5_DIGEST_SIZE; - - // Move offset and size - RawDataOffs += dwToRead; - dwRawDataSize -= dwToRead; - } - - // Write the array od MD5's to the file - if(nError == ERROR_SUCCESS) - { - if(!FileStream_Write(pStream, NULL, md5_array, dwMd5ArraySize)) - nError = GetLastError(); - } - - // Free buffers and exit - STORM_FREE(pbFileChunk); - STORM_FREE(md5_array); - return nError; -} - -// Frees the structure for MPQ file -void FreeMPQFile(TMPQFile *& hf) -{ - if(hf != NULL) - { - // If we have patch file attached to this one, free it first - if(hf->hfPatchFile != NULL) - FreeMPQFile(hf->hfPatchFile); - - // Then free all buffers allocated in the file structure - if(hf->pPatchHeader != NULL) - STORM_FREE(hf->pPatchHeader); - if(hf->pbFileData != NULL) - STORM_FREE(hf->pbFileData); - if(hf->pPatchInfo != NULL) - STORM_FREE(hf->pPatchInfo); - if(hf->SectorOffsets != NULL) - STORM_FREE(hf->SectorOffsets); - if(hf->SectorChksums != NULL) - STORM_FREE(hf->SectorChksums); - if(hf->pbFileSector != NULL) - STORM_FREE(hf->pbFileSector); - FileStream_Close(hf->pStream); - STORM_FREE(hf); - hf = NULL; - } -} - -// Frees the MPQ archive -void FreeMPQArchive(TMPQArchive *& ha) -{ - if(ha != NULL) - { - // First of all, free the patch archive, if any - if(ha->haPatch != NULL) - FreeMPQArchive(ha->haPatch); - - // Close the file stream - FileStream_Close(ha->pStream); - ha->pStream = NULL; - - // Free the file names from the file table - if(ha->pFileTable != NULL) - { - for(DWORD i = 0; i < ha->dwFileTableSize; i++) - { - if(ha->pFileTable[i].szFileName != NULL) - STORM_FREE(ha->pFileTable[i].szFileName); - ha->pFileTable[i].szFileName = NULL; - } - - // Then free all buffers allocated in the archive structure - STORM_FREE(ha->pFileTable); - } - - if(ha->pBitmap != NULL) - STORM_FREE(ha->pBitmap); - if(ha->pHashTable != NULL) - STORM_FREE(ha->pHashTable); - if(ha->pHetTable != NULL) - FreeHetTable(ha->pHetTable); - STORM_FREE(ha); - ha = NULL; - } -} - -const char * GetPlainFileNameA(const char * szFileName) -{ - const char * szPlainName = szFileName; - - while(*szFileName != 0) - { - if(*szFileName == '\\' || *szFileName == '/') - szPlainName = szFileName + 1; - szFileName++; - } - - return szPlainName; -} - -const TCHAR * GetPlainFileNameT(const TCHAR * szFileName) -{ - const TCHAR * szPlainName = szFileName; - - while(*szFileName != 0) - { - if(*szFileName == '\\' || *szFileName == '/') - szPlainName = szFileName + 1; - szFileName++; - } - - return szPlainName; -} - -bool IsInternalMpqFileName(const char * szFileName) -{ - if(szFileName != NULL && szFileName[0] == '(') - { - if(!_stricmp(szFileName, LISTFILE_NAME) || - !_stricmp(szFileName, ATTRIBUTES_NAME) || - !_stricmp(szFileName, SIGNATURE_NAME)) - { - return true; - } - } - - return false; -} - -// Verifies if the file name is a pseudo-name -bool IsPseudoFileName(const char * szFileName, DWORD * pdwFileIndex) -{ - DWORD dwFileIndex = 0; - - if(szFileName != NULL) - { - // Must be "File########.ext" - if(!_strnicmp(szFileName, "File", 4)) - { - // Check 8 digits - for(int i = 4; i < 4+8; i++) - { - if(szFileName[i] < '0' || szFileName[i] > '9') - return false; - dwFileIndex = (dwFileIndex * 10) + (szFileName[i] - '0'); - } - - // An extension must follow - if(szFileName[12] == '.') - { - if(pdwFileIndex != NULL) - *pdwFileIndex = dwFileIndex; - return true; - } - } - } - - // Not a pseudo-name - return false; -} - -//----------------------------------------------------------------------------- -// Functions calculating and verifying the MD5 signature - -bool IsValidMD5(LPBYTE pbMd5) -{ - BYTE BitSummary = 0; - - // The MD5 is considered invalid of it is zeroed - BitSummary |= pbMd5[0x00] | pbMd5[0x01] | pbMd5[0x02] | pbMd5[0x03] | pbMd5[0x04] | pbMd5[0x05] | pbMd5[0x06] | pbMd5[0x07]; - BitSummary |= pbMd5[0x08] | pbMd5[0x09] | pbMd5[0x0A] | pbMd5[0x0B] | pbMd5[0x0C] | pbMd5[0x0D] | pbMd5[0x0E] | pbMd5[0x0F]; - return (BitSummary != 0); -} - -bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5) -{ - hash_state md5_state; - BYTE md5_digest[MD5_DIGEST_SIZE]; - - // Don't verify the block if the MD5 is not valid. - if(!IsValidMD5(expected_md5)) - return true; - - // Calculate the MD5 of the data block - md5_init(&md5_state); - md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock); - md5_done(&md5_state, md5_digest); - - // Does the MD5's match? - return (memcmp(md5_digest, expected_md5, MD5_DIGEST_SIZE) == 0); -} - -void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash) -{ - hash_state md5_state; - - md5_init(&md5_state); - md5_process(&md5_state, (unsigned char *)pvDataBlock, cbDataBlock); - md5_done(&md5_state, md5_hash); -} - - -//----------------------------------------------------------------------------- -// Swapping functions - -#ifndef PLATFORM_LITTLE_ENDIAN - -// -// Note that those functions are implemented for Mac operating system, -// as this is the only supported platform that uses big endian. -// - -// Swaps a signed 16-bit integer -int16_t SwapInt16(uint16_t data) -{ - return (int16_t)CFSwapInt16(data); -} - -// Swaps an unsigned 16-bit integer -uint16_t SwapUInt16(uint16_t data) -{ - return CFSwapInt16(data); -} - -// Swaps signed 32-bit integer -int32_t SwapInt32(uint32_t data) -{ - return (int32_t)CFSwapInt32(data); -} - -// Swaps an unsigned 32-bit integer -uint32_t SwapUInt32(uint32_t data) -{ - return CFSwapInt32(data); -} - -// Swaps signed 64-bit integer -int64_t SwapInt64(int64_t data) -{ - return (int64_t)CFSwapInt64(data); -} - -// Swaps an unsigned 64-bit integer -uint64_t SwapUInt64(uint64_t data) -{ - return CFSwapInt64(data); -} - -// Swaps array of unsigned 16-bit integers -void ConvertUInt16Buffer(void * ptr, size_t length) -{ - uint16_t * buffer = (uint16_t *)ptr; - uint32_t nElements = (uint32_t)(length / sizeof(uint16_t)); - - while(nElements-- > 0) - { - *buffer = SwapUInt16(*buffer); - buffer++; - } -} - -// Swaps array of unsigned 32-bit integers -void ConvertUInt32Buffer(void * ptr, size_t length) -{ - uint32_t * buffer = (uint32_t *)ptr; - uint32_t nElements = (uint32_t)(length / sizeof(uint32_t)); - - while(nElements-- > 0) - { - *buffer = SwapUInt32(*buffer); - buffer++; - } -} - -// Swaps array of unsigned 64-bit integers -void ConvertUInt64Buffer(void * ptr, size_t length) -{ - uint64_t * buffer = (uint64_t *)ptr; - uint32_t nElements = (uint32_t)(length / sizeof(uint64_t)); - - while(nElements-- > 0) - { - *buffer = SwapUInt64(*buffer); - buffer++; - } -} - -// Swaps the TMPQUserData structure -void ConvertTMPQUserData(void *userData) -{ - TMPQUserData * theData = (TMPQUserData *)userData; - - theData->dwID = SwapUInt32(theData->dwID); - theData->cbUserDataSize = SwapUInt32(theData->cbUserDataSize); - theData->dwHeaderOffs = SwapUInt32(theData->dwHeaderOffs); - theData->cbUserDataHeader = SwapUInt32(theData->cbUserDataHeader); -} - -// Swaps the TMPQHeader structure -void ConvertTMPQHeader(void *header) -{ - TMPQHeader * theHeader = (TMPQHeader *)header; - - theHeader->dwID = SwapUInt32(theHeader->dwID); - theHeader->dwHeaderSize = SwapUInt32(theHeader->dwHeaderSize); - theHeader->dwArchiveSize = SwapUInt32(theHeader->dwArchiveSize); - theHeader->wFormatVersion = SwapUInt16(theHeader->wFormatVersion); - theHeader->wSectorSize = SwapUInt16(theHeader->wSectorSize); - theHeader->dwHashTablePos = SwapUInt32(theHeader->dwHashTablePos); - theHeader->dwBlockTablePos = SwapUInt32(theHeader->dwBlockTablePos); - theHeader->dwHashTableSize = SwapUInt32(theHeader->dwHashTableSize); - theHeader->dwBlockTableSize = SwapUInt32(theHeader->dwBlockTableSize); - - if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) - { - // Swap the hi-block table position - theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64); - - theHeader->wHashTablePosHi = SwapUInt16(theHeader->wHashTablePosHi); - theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi); - - if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3) - { - theHeader->ArchiveSize64 = SwapUInt64(theHeader->ArchiveSize64); - theHeader->BetTablePos64 = SwapUInt64(theHeader->BetTablePos64); - theHeader->HetTablePos64 = SwapUInt64(theHeader->HetTablePos64); - - if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4) - { - theHeader->HashTableSize64 = SwapUInt64(theHeader->HashTableSize64); - theHeader->BlockTableSize64 = SwapUInt64(theHeader->BlockTableSize64); - theHeader->HiBlockTableSize64 = SwapUInt64(theHeader->HiBlockTableSize64); - theHeader->HetTableSize64 = SwapUInt64(theHeader->HetTableSize64); - theHeader->BetTableSize64 = SwapUInt64(theHeader->BetTableSize64); - } - } - } -} - -#endif // PLATFORM_LITTLE_ENDIAN diff --git a/dep/StormLib/src/SBaseDumpData.cpp b/dep/StormLib/src/SBaseDumpData.cpp deleted file mode 100644 index c9dcf0a3366..00000000000 --- a/dep/StormLib/src/SBaseDumpData.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/*****************************************************************************/ -/* SBaseDumpData.cpp Copyright (c) Ladislav Zezula 2011 */ -/*---------------------------------------------------------------------------*/ -/* Description : */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 26.01.11 1.00 Lad The first version of SBaseDumpData.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -#ifdef __STORMLIB_DUMP_DATA__ - -void DumpMpqHeader(TMPQHeader * pHeader) -{ - printf("== MPQ Header =================================\n"); - printf("DWORD dwID = %08X\n", pHeader->dwID); - printf("DWORD dwHeaderSize = %08X\n", pHeader->dwHeaderSize); - printf("DWORD dwArchiveSize = %08X\n", pHeader->dwArchiveSize); - printf("USHORT wFormatVersion = %04X\n", pHeader->wFormatVersion); - printf("USHORT wSectorSize = %04X\n", pHeader->wSectorSize); - printf("DWORD dwHashTablePos = %08X\n", pHeader->dwHashTablePos); - printf("DWORD dwBlockTablePos = %08X\n", pHeader->dwBlockTablePos); - printf("DWORD dwHashTableSize = %08X\n", pHeader->dwHashTableSize); - printf("DWORD dwBlockTableSize = %08X\n", pHeader->dwBlockTableSize); - printf("ULONGLONG HiBlockTablePos64 = %016llX\n", pHeader->HiBlockTablePos64); - printf("USHORT wHashTablePosHi = %04X\n", pHeader->wHashTablePosHi); - printf("USHORT wBlockTablePosHi = %04X\n", pHeader->wBlockTablePosHi); - printf("ULONGLONG ArchiveSize64 = %016llX\n", pHeader->ArchiveSize64); - printf("ULONGLONG BetTablePos64 = %016llX\n", pHeader->BetTablePos64); - printf("ULONGLONG HetTablePos64 = %016llX\n", pHeader->HetTablePos64); - printf("ULONGLONG HashTableSize64 = %016llX\n", pHeader->HashTableSize64); - printf("ULONGLONG BlockTableSize64 = %016llX\n", pHeader->BlockTableSize64); - printf("ULONGLONG HiBlockTableSize64 = %016llX\n", pHeader->HiBlockTableSize64); - printf("ULONGLONG HetTableSize64 = %016llX\n", pHeader->HetTableSize64); - printf("ULONGLONG BetTableSize64 = %016llX\n", pHeader->BetTableSize64); - printf("DWORD dwRawChunkSize = %08X\n", pHeader->dwRawChunkSize); - printf("-----------------------------------------------\n\n"); -} - -void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable) -{ - DWORD i; - - if(pHetTable == NULL || pBetTable == NULL) - return; - - printf("== HET Header =================================\n"); - printf("ULONGLONG AndMask64 = %016llX\n", pHetTable->AndMask64); - printf("ULONGLONG OrMask64 = %016llX\n", pHetTable->OrMask64); - printf("DWORD dwIndexSizeTotal = %08X\n", pHetTable->dwIndexSizeTotal); - printf("DWORD dwIndexSizeExtra = %08X\n", pHetTable->dwIndexSizeExtra); - printf("DWORD dwIndexSize = %08X\n", pHetTable->dwIndexSize); - printf("DWORD dwMaxFileCount = %08X\n", pHetTable->dwMaxFileCount); - printf("DWORD dwHashTableSize = %08X\n", pHetTable->dwHashTableSize); - printf("DWORD dwHashBitSize = %08X\n", pHetTable->dwHashBitSize); - printf("-----------------------------------------------\n\n"); - - printf("== BET Header =================================\n"); - printf("DWORD dwTableEntrySize = %08X\n", pBetTable->dwTableEntrySize); - printf("DWORD dwBitIndex_FilePos = %08X\n", pBetTable->dwBitIndex_FilePos); - printf("DWORD dwBitIndex_FileSize = %08X\n", pBetTable->dwBitIndex_FileSize); - printf("DWORD dwBitIndex_CmpSize = %08X\n", pBetTable->dwBitIndex_CmpSize); - printf("DWORD dwBitIndex_FlagIndex = %08X\n", pBetTable->dwBitIndex_FlagIndex); - printf("DWORD dwBitIndex_Unknown = %08X\n", pBetTable->dwBitIndex_Unknown); - printf("DWORD dwBitCount_FilePos = %08X\n", pBetTable->dwBitCount_FilePos); - printf("DWORD dwBitCount_FileSize = %08X\n", pBetTable->dwBitCount_FileSize); - printf("DWORD dwBitCount_CmpSize = %08X\n", pBetTable->dwBitCount_CmpSize); - printf("DWORD dwBitCount_FlagIndex = %08X\n", pBetTable->dwBitCount_FlagIndex); - printf("DWORD dwBitCount_Unknown = %08X\n", pBetTable->dwBitCount_Unknown); - printf("DWORD dwBetHashSizeTotal = %08X\n", pBetTable->dwBetHashSizeTotal); - printf("DWORD dwBetHashSizeExtra = %08X\n", pBetTable->dwBetHashSizeExtra); - printf("DWORD dwBetHashSize = %08X\n", pBetTable->dwBetHashSize); - printf("DWORD dwMaxFileCount = %08X\n", pBetTable->dwMaxFileCount); - printf("DWORD dwFlagCount = %08X\n", pBetTable->dwFlagCount); - printf("-----------------------------------------------\n\n"); - - printf("== HET & Bet Table ======================================================================\n\n"); - printf("HetIdx HetHash BetIdx BetHash ByteOffset FileSize CmpSize FlgIdx Flags \n"); - printf("------ ------- ------ ---------------- ---------------- -------- -------- ------ --------\n"); - for(i = 0; i < pHetTable->dwHashTableSize; i++) - { - ULONGLONG ByteOffset = 0; - ULONGLONG BetHash = 0; - DWORD dwFileSize = 0; - DWORD dwCmpSize = 0; - DWORD dwFlagIndex = 0; - DWORD dwFlags = 0; - DWORD dwBetIndex = 0; - - pHetTable->pBetIndexes->GetBits(i * pHetTable->dwIndexSizeTotal, - pHetTable->dwIndexSize, - &dwBetIndex, - 4); - - if(dwBetIndex < pHetTable->dwMaxFileCount) - { - DWORD dwEntryIndex = pBetTable->dwTableEntrySize * dwBetIndex; - - pBetTable->pBetHashes->GetBits(dwBetIndex * pBetTable->dwBetHashSizeTotal, - pBetTable->dwBetHashSize, - &BetHash, - 8); - - pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_FilePos, - pBetTable->dwBitCount_FilePos, - &ByteOffset, - 8); - - pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_FileSize, - pBetTable->dwBitCount_FileSize, - &dwFileSize, - 4); - - pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_CmpSize, - pBetTable->dwBitCount_CmpSize, - &dwCmpSize, - 4); - - pBetTable->pFileTable->GetBits(dwEntryIndex + pBetTable->dwBitIndex_FlagIndex, - pBetTable->dwBitCount_FlagIndex, - &dwFlagIndex, - 4); - - dwFlags = pBetTable->pFileFlags[dwFlagIndex]; - } - - printf(" %04X %02lX %04X %016llX %016llX %08X %08X %04X %08X\n", i, - pHetTable->pHetHashes[i], - dwBetIndex, - BetHash, - ByteOffset, - dwFileSize, - dwCmpSize, - dwFlagIndex, - dwFlags); - } - printf("-----------------------------------------------------------------------------------------\n"); -} - -#endif // __STORMLIB_DUMP_DATA__ diff --git a/dep/StormLib/src/SBaseFileTable.cpp b/dep/StormLib/src/SBaseFileTable.cpp deleted file mode 100644 index 09379ca5da7..00000000000 --- a/dep/StormLib/src/SBaseFileTable.cpp +++ /dev/null @@ -1,2550 +0,0 @@ -/*****************************************************************************/ -/* SBaseFileTable.cpp Copyright (c) Ladislav Zezula 2010 */ -/*---------------------------------------------------------------------------*/ -/* Description: Common handler for classic and new hash&block tables */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 06.09.10 1.00 Lad The first version of SBaseFileTable.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local defines - -#define INVALID_FLAG_VALUE 0xCCCCCCCC -#define MAX_FLAG_INDEX 512 - -//----------------------------------------------------------------------------- -// Local structures - -// Structure for HET table header -typedef struct _HET_TABLE_HEADER -{ - DWORD dwTableSize; // Size of the entire HET table, including HET_TABLE_HEADER (in bytes) - DWORD dwMaxFileCount; // Maximum number of files in the MPQ - DWORD dwHashTableSize; // Size of the hash table (in bytes) - DWORD dwHashEntrySize; // Effective size of the hash entry (in bits) - DWORD dwIndexSizeTotal; // Total size of file index (in bits) - DWORD dwIndexSizeExtra; // Extra bits in the file index - DWORD dwIndexSize; // Effective size of the file index (in bits) - DWORD dwIndexTableSize; // Size of the block index subtable (in bytes) - -} HET_TABLE_HEADER, *PHET_TABLE_HEADER; - -// Structure for BET table header -typedef struct _BET_TABLE_HEADER -{ - DWORD dwTableSize; // Size of the entire BET table, including the header (in bytes) - DWORD dwFileCount; // Number of files in the BET table - DWORD dwUnknown08; - DWORD dwTableEntrySize; // Size of one table entry (in bits) - DWORD dwBitIndex_FilePos; // Bit index of the file position (within the entry record) - DWORD dwBitIndex_FileSize; // Bit index of the file size (within the entry record) - DWORD dwBitIndex_CmpSize; // Bit index of the compressed size (within the entry record) - DWORD dwBitIndex_FlagIndex; // Bit index of the flag index (within the entry record) - DWORD dwBitIndex_Unknown; // Bit index of the ??? (within the entry record) - DWORD dwBitCount_FilePos; // Bit size of file position (in the entry record) - DWORD dwBitCount_FileSize; // Bit size of file size (in the entry record) - DWORD dwBitCount_CmpSize; // Bit size of compressed file size (in the entry record) - DWORD dwBitCount_FlagIndex; // Bit size of flags index (in the entry record) - DWORD dwBitCount_Unknown; // Bit size of ??? (in the entry record) - DWORD dwBetHashSizeTotal; // Total size of the BET hash - DWORD dwBetHashSizeExtra; // Extra bits in the BET hash - DWORD dwBetHashSize; // Effective size of BET hash (in bits) - DWORD dwBetHashArraySize; // Size of BET hashes array, in bytes - DWORD dwFlagCount; // Number of flags in the following array - -} BET_TABLE_HEADER, *PBET_TABLE_HEADER; - -//----------------------------------------------------------------------------- -// Support for calculating bit sizes - -static void InitFileFlagArray(LPDWORD FlagArray) -{ - for(DWORD dwFlagIndex = 0; dwFlagIndex < MAX_FLAG_INDEX; dwFlagIndex++) - FlagArray[dwFlagIndex] = INVALID_FLAG_VALUE; -} - -static DWORD GetFileFlagIndex(LPDWORD FlagArray, DWORD dwFlags) -{ - // Find free or equal entry in the flag array - for(DWORD dwFlagIndex = 0; dwFlagIndex < MAX_FLAG_INDEX; dwFlagIndex++) - { - if(FlagArray[dwFlagIndex] == INVALID_FLAG_VALUE || FlagArray[dwFlagIndex] == dwFlags) - { - FlagArray[dwFlagIndex] = dwFlags; - return dwFlagIndex; - } - } - - // This should never happen - assert(false); - return 0xFFFFFFFF; -} - -static DWORD GetNecessaryBitCount(ULONGLONG MaxValue) -{ - DWORD dwBitCount = 0; - - while(MaxValue > 0) - { - MaxValue >>= 1; - dwBitCount++; - } - - return dwBitCount; -} - -//----------------------------------------------------------------------------- -// Support functions for BIT_ARRAY - -static USHORT SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF}; - -static TBitArray * CreateBitArray( - DWORD NumberOfBits, - BYTE FillValue) -{ - TBitArray * pBitArray; - size_t nSize = sizeof(TBitArray) + (NumberOfBits + 7) / 8; - - // Allocate the bit array - pBitArray = (TBitArray *)STORM_ALLOC(BYTE, nSize); - if(pBitArray != NULL) - { - memset(pBitArray, FillValue, nSize); - pBitArray->NumberOfBits = NumberOfBits; - } - - return pBitArray; -} - -void TBitArray::GetBits( - unsigned int nBitPosition, - unsigned int nBitLength, - void * pvBuffer, - int nResultByteSize) -{ - unsigned char * pbBuffer = (unsigned char *)pvBuffer; - unsigned int nBytePosition0 = (nBitPosition / 8); - unsigned int nBytePosition1 = nBytePosition0 + 1; - unsigned int nByteLength = (nBitLength / 8); - unsigned int nBitOffset = (nBitPosition & 0x07); - unsigned char BitBuffer; - - // Keep compiler happy for platforms where nResultByteSize is not used - nResultByteSize = nResultByteSize; - -#ifdef _DEBUG - // Check if the target is properly zeroed - for(int i = 0; i < nResultByteSize; i++) - assert(pbBuffer[i] == 0); -#endif - -#ifndef PLATFORM_LITTLE_ENDIAN - // Adjust the buffer pointer for big endian platforms - pbBuffer += (nResultByteSize - 1); -#endif - - // Copy whole bytes, if any - while(nByteLength > 0) - { - // Is the current position in the Elements byte-aligned? - if(nBitOffset != 0) - { - BitBuffer = (unsigned char)((Elements[nBytePosition0] >> nBitOffset) | (Elements[nBytePosition1] << (0x08 - nBitOffset))); - } - else - { - BitBuffer = Elements[nBytePosition0]; - } - -#ifdef PLATFORM_LITTLE_ENDIAN - *pbBuffer++ = BitBuffer; -#else - *pbBuffer-- = BitBuffer; -#endif - - // Move byte positions and lengths - nBytePosition1++; - nBytePosition0++; - nByteLength--; - } - - // Get the rest of the bits - nBitLength = (nBitLength & 0x07); - if(nBitLength != 0) - { - *pbBuffer = (unsigned char)(Elements[nBytePosition0] >> nBitOffset); - - if(nBitLength > (8 - nBitOffset)) - *pbBuffer = (unsigned char)((Elements[nBytePosition1] << (8 - nBitOffset)) | (Elements[nBytePosition0] >> nBitOffset)); - - *pbBuffer &= (0x01 << nBitLength) - 1; - } -} - -void TBitArray::SetBits( - unsigned int nBitPosition, - unsigned int nBitLength, - void * pvBuffer, - int nResultByteSize) -{ - unsigned char * pbBuffer = (unsigned char *)pvBuffer; - unsigned int nBytePosition = (nBitPosition / 8); - unsigned int nBitOffset = (nBitPosition & 0x07); - unsigned short BitBuffer = 0; - unsigned short AndMask = 0; - unsigned short OneByte = 0; - - // Keep compiler happy for platforms where nResultByteSize is not used - nResultByteSize = nResultByteSize; - -#ifndef PLATFORM_LITTLE_ENDIAN - // Adjust the buffer pointer for big endian platforms - pbBuffer += (nResultByteSize - 1); -#endif - - // Copy whole bytes, if any - while(nBitLength > 8) - { - // Reload the bit buffer -#ifdef PLATFORM_LITTLE_ENDIAN - OneByte = *pbBuffer++; -#else - OneByte = *pbBuffer--; -#endif - // Update the BitBuffer and AndMask for the bit array - BitBuffer = (BitBuffer >> 0x08) | (OneByte << nBitOffset); - AndMask = (AndMask >> 0x08) | (0x00FF << nBitOffset); - - // Update the byte in the array - Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer); - - // Move byte positions and lengths - nBytePosition++; - nBitLength -= 0x08; - } - - if(nBitLength != 0) - { - // Reload the bit buffer - OneByte = *pbBuffer; - - // Update the AND mask for the last bit - BitBuffer = (BitBuffer >> 0x08) | (OneByte << nBitOffset); - AndMask = (AndMask >> 0x08) | (SetBitsMask[nBitLength] << nBitOffset); - - // Update the byte in the array - Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer); - - // Update the next byte, if needed - if(AndMask & 0xFF00) - { - nBytePosition++; - BitBuffer >>= 0x08; - AndMask >>= 0x08; - - Elements[nBytePosition] = (BYTE)((Elements[nBytePosition] & ~AndMask) | BitBuffer); - } - } -} - - -//----------------------------------------------------------------------------- -// Support for hash table - -// Returns a hash table entry in the following order: -// 1) A hash table entry with the neutral locale -// 2) A hash table entry with any other locale -// 3) NULL -static TMPQHash * GetHashEntryAny(TMPQArchive * ha, const char * szFileName) -{ - TMPQHash * pHashNeutral = NULL; - TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName); - TMPQHash * pHashAny = NULL; - TMPQHash * pHash = pFirstHash; - - // Parse the found hashes - while(pHash != NULL) - { - // If we found neutral hash, remember it - if(pHash->lcLocale == 0) - pHashNeutral = pHash; - if(pHashAny == NULL) - pHashAny = pHash; - - // Get the next hash entry for that file - pHash = GetNextHashEntry(ha, pFirstHash, pHash); - } - - // At the end, return neutral hash (if found), otherwise NULL - return (pHashNeutral != NULL) ? pHashNeutral : pHashAny; -} - -// Returns a hash table entry in the following order: -// 1) A hash table entry with the preferred locale -// 2) A hash table entry with the neutral locale -// 3) NULL -static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale) -{ - TMPQHash * pHashNeutral = NULL; - TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName); - TMPQHash * pHash = pFirstHash; - - // Parse the found hashes - while(pHash != NULL) - { - // If the locales match, return it - if(pHash->lcLocale == lcLocale) - return pHash; - - // If we found neutral hash, remember it - if(pHash->lcLocale == 0) - pHashNeutral = pHash; - - // Get the next hash entry for that file - pHash = GetNextHashEntry(ha, pFirstHash, pHash); - } - - // At the end, return neutral hash (if found), otherwise NULL - return pHashNeutral; -} - -// Returns a hash table entry in the following order: -// 1) A hash table entry with the preferred locale -// 2) NULL -static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale) -{ - TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName); - TMPQHash * pHash = pFirstHash; - - // Parse the found hashes - while(pHash != NULL) - { - // If the locales match, return it - if(pHash->lcLocale == lcLocale) - return pHash; - - // Get the next hash entry for that file - pHash = GetNextHashEntry(ha, pFirstHash, pHash); - } - - // Not found - return NULL; -} - -static TMPQHash * TranslateHashTable( - TMPQArchive * ha, - ULONGLONG * pcbTableSize) -{ - TMPQHash * pHashTable; - size_t HashTableSize; - - // Allocate copy of the hash table - pHashTable = STORM_ALLOC(TMPQHash, ha->pHeader->dwHashTableSize); - if(pHashTable != NULL) - { - // Copy the hash table - HashTableSize = sizeof(TMPQHash) * ha->pHeader->dwHashTableSize; - memcpy(pHashTable, ha->pHashTable, HashTableSize); - - // Give the size to the caller - if(pcbTableSize != NULL) - { - *pcbTableSize = (ULONGLONG)HashTableSize; - } - } - - return pHashTable; -} - -static TMPQBlock * TranslateBlockTable( - TMPQArchive * ha, - ULONGLONG * pcbTableSize, - bool * pbNeedHiBlockTable) -{ - TFileEntry * pFileEntry = ha->pFileTable; - TMPQBlock * pBlockTable; - TMPQBlock * pBlock; - size_t BlockTableSize; - bool bNeedHiBlockTable = false; - - // Allocate copy of the hash table - pBlockTable = pBlock = STORM_ALLOC(TMPQBlock, ha->dwFileTableSize); - if(pBlockTable != NULL) - { - // Copy the block table - BlockTableSize = sizeof(TMPQBlock) * ha->dwFileTableSize; - for(DWORD i = 0; i < ha->dwFileTableSize; i++) - { - bNeedHiBlockTable = (pFileEntry->ByteOffset >> 32) ? true : false; - pBlock->dwFilePos = (DWORD)pFileEntry->ByteOffset; - pBlock->dwFSize = pFileEntry->dwFileSize; - pBlock->dwCSize = pFileEntry->dwCmpSize; - pBlock->dwFlags = pFileEntry->dwFlags; - - pFileEntry++; - pBlock++; - } - - // Give the size to the caller - if(pcbTableSize != NULL) - *pcbTableSize = (ULONGLONG)BlockTableSize; - - if(pbNeedHiBlockTable != NULL) - *pbNeedHiBlockTable = bNeedHiBlockTable; - } - - return pBlockTable; -} - -static USHORT * TranslateHiBlockTable( - TMPQArchive * ha, - ULONGLONG * pcbTableSize) -{ - TFileEntry * pFileEntry = ha->pFileTable; - USHORT * pHiBlockTable; - USHORT * pHiBlock; - size_t HiBlockTableSize; - - // Allocate copy of the hash table - pHiBlockTable = pHiBlock = STORM_ALLOC(USHORT, ha->dwFileTableSize); - if(pHiBlockTable != NULL) - { - // Copy the block table - HiBlockTableSize = sizeof(USHORT) * ha->dwFileTableSize; - for(DWORD i = 0; i < ha->dwFileTableSize; i++) - pHiBlock[i] = (USHORT)(pFileEntry[i].ByteOffset >> 0x20); - - // Give the size to the caller - if(pcbTableSize != NULL) - *pcbTableSize = (ULONGLONG)HiBlockTableSize; - } - - return pHiBlockTable; -} - -//----------------------------------------------------------------------------- -// General EXT table functions - -TMPQExtTable * LoadExtTable( - TMPQArchive * ha, - ULONGLONG ByteOffset, - size_t Size, - DWORD dwSignature, - DWORD dwKey) -{ - TMPQExtTable * pCompressed = NULL; // Compressed table - TMPQExtTable * pExtTable = NULL; // Uncompressed table - - // Do nothing if the size is zero - if(ByteOffset != 0 && Size != 0) - { - // Allocate size for the compressed table - pExtTable = (TMPQExtTable *)STORM_ALLOC(BYTE, Size); - if(pExtTable != NULL) - { - // Load the table from the MPQ - ByteOffset += ha->MpqPos; - if(!FileStream_Read(ha->pStream, &ByteOffset, pExtTable, (DWORD)Size)) - { - STORM_FREE(pExtTable); - return NULL; - } - - // Swap the ext table header - BSWAP_ARRAY32_UNSIGNED(pExtTable, sizeof(TMPQExtTable)); - if(pExtTable->dwSignature != dwSignature) - { - STORM_FREE(pExtTable); - return NULL; - } - - // Decrypt the block - BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); - DecryptMpqBlock(pExtTable + 1, (DWORD)(Size - sizeof(TMPQExtTable)), dwKey); - BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); - - // If the table is compressed, decompress it - if((pExtTable->dwDataSize + sizeof(TMPQExtTable)) > Size) - { - pCompressed = pExtTable; - pExtTable = (TMPQExtTable *)STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + pCompressed->dwDataSize); - if(pExtTable != NULL) - { - int cbOutBuffer = (int)pCompressed->dwDataSize; - int cbInBuffer = (int)Size; - - // Decompress the extended table - pExtTable->dwSignature = pCompressed->dwSignature; - pExtTable->dwVersion = pCompressed->dwVersion; - pExtTable->dwDataSize = pCompressed->dwDataSize; - if(!SCompDecompress2((char *)(pExtTable + 1), &cbOutBuffer, (char *)(pCompressed + 1), cbInBuffer)) - { - STORM_FREE(pExtTable); - pExtTable = NULL; - } - } - - // Free the compressed block - STORM_FREE(pCompressed); - } - } - } - - // Return the decompressed table to the caller - return pExtTable; -} - -// Used in MPQ Editor -void FreeMpqBuffer(void * pvBuffer) -{ - STORM_FREE(pvBuffer); -} - -static int SaveMpqTable( - TMPQArchive * ha, - void * pMpqTable, - ULONGLONG ByteOffset, - size_t Size, - unsigned char * md5, - DWORD dwKey, - bool bCompress) -{ - ULONGLONG FileOffset; - void * pCompressed = NULL; - int nError = ERROR_SUCCESS; - - // Do we have to compress the table? - if(bCompress) - { - int cbOutBuffer = (int)Size; - int cbInBuffer = (int)Size; - - // Allocate extra space for compressed table - pCompressed = STORM_ALLOC(BYTE, Size); - if(pCompressed == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Compress the table - SCompCompress((char *)pCompressed, &cbOutBuffer, (char *)pMpqTable, cbInBuffer, MPQ_COMPRESSION_ZLIB, 0, 0); - - // If the compression failed, revert it. Otherwise, swap the tables - if(cbOutBuffer >= cbInBuffer) - { - STORM_FREE(pCompressed); - pCompressed = NULL; - } - else - { - pMpqTable = pCompressed; - } - } - - // Encrypt the table - if(dwKey != 0) - { - BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size); - EncryptMpqBlock(pMpqTable, (DWORD)Size, dwKey); - BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size); - } - - // Calculate the MD5 - if(md5 != NULL) - { - CalculateDataBlockHash(pMpqTable, (DWORD)Size, md5); - } - - // Save the table to the MPQ - BSWAP_ARRAY32_UNSIGNED(pMpqTable, Size); - FileOffset = ha->MpqPos + ByteOffset; - if(!FileStream_Write(ha->pStream, &FileOffset, pMpqTable, (DWORD)Size)) - nError = GetLastError(); - - // Free the compressed table, if any - if(pCompressed != NULL) - STORM_FREE(pCompressed); - return nError; -} - -static int SaveExtTable( - TMPQArchive * ha, - TMPQExtTable * pExtTable, - ULONGLONG ByteOffset, - DWORD dwTableSize, - unsigned char * md5, - DWORD dwKey, - bool bCompress, - LPDWORD pcbTotalSize) -{ - ULONGLONG FileOffset; - TMPQExtTable * pCompressed = NULL; - DWORD cbTotalSize = 0; - int nError = ERROR_SUCCESS; - - // Do we have to compress the table? - if(bCompress) - { - int cbOutBuffer = (int)dwTableSize; - int cbInBuffer = (int)dwTableSize; - - // Allocate extra space for compressed table - pCompressed = (TMPQExtTable *)STORM_ALLOC(BYTE, dwTableSize); - if(pCompressed == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Compress the table - pCompressed->dwSignature = pExtTable->dwSignature; - pCompressed->dwVersion = pExtTable->dwVersion; - pCompressed->dwDataSize = pExtTable->dwDataSize; - SCompCompress((char *)(pCompressed + 1), &cbOutBuffer, (char *)(pExtTable + 1), cbInBuffer, MPQ_COMPRESSION_ZLIB, 0, 0); - - // If the compression failed, revert it. Otherwise, swap the tables - if(cbOutBuffer >= cbInBuffer) - { - STORM_FREE(pCompressed); - pCompressed = NULL; - } - else - { - pExtTable = pCompressed; - } - } - - // Encrypt the table - if(dwKey != 0) - { - BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); - EncryptMpqBlock(pExtTable + 1, (DWORD)(dwTableSize - sizeof(TMPQExtTable)), dwKey); - BSWAP_ARRAY32_UNSIGNED(pExtTable + 1, pExtTable->dwDataSize); - } - - // Calculate the MD5 of the table after - if(md5 != NULL) - { - CalculateDataBlockHash(pExtTable, dwTableSize, md5); - } - - // Save the table to the MPQ - FileOffset = ha->MpqPos + ByteOffset; - if(FileStream_Write(ha->pStream, &FileOffset, pExtTable, dwTableSize)) - cbTotalSize += dwTableSize; - else - nError = GetLastError(); - - // We have to write raw data MD5 - if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0) - { - nError = WriteMemDataMD5(ha->pStream, - FileOffset, - pExtTable, - dwTableSize, - ha->pHeader->dwRawChunkSize, - &cbTotalSize); - } - - // Give the total written size, if needed - if(pcbTotalSize != NULL) - *pcbTotalSize = cbTotalSize; - - // Free the compressed table, if any - if(pCompressed != NULL) - STORM_FREE(pCompressed); - return nError; -} - -//----------------------------------------------------------------------------- -// Support for HET table - -static void CreateHetHeader( - TMPQHetTable * pHetTable, - PHET_TABLE_HEADER pHetHeader) -{ - // Fill the BET header - pHetHeader->dwMaxFileCount = pHetTable->dwMaxFileCount; - pHetHeader->dwHashTableSize = pHetTable->dwHashTableSize; - pHetHeader->dwHashEntrySize = pHetTable->dwHashBitSize; - pHetHeader->dwIndexSizeTotal = GetNecessaryBitCount(pHetTable->dwMaxFileCount); - pHetHeader->dwIndexSizeExtra = 0; - pHetHeader->dwIndexSize = pHetHeader->dwIndexSizeTotal; - pHetHeader->dwIndexTableSize = ((pHetHeader->dwIndexSizeTotal * pHetTable->dwHashTableSize) + 7) / 8; - - // Calculate the total size needed for holding HET table - pHetHeader->dwTableSize = sizeof(HET_TABLE_HEADER) + - pHetHeader->dwHashTableSize + - pHetHeader->dwIndexTableSize; -} - -TMPQHetTable * CreateHetTable(DWORD dwMaxFileCount, DWORD dwHashBitSize, bool bCreateEmpty) -{ - TMPQHetTable * pHetTable; - - pHetTable = STORM_ALLOC(TMPQHetTable, 1); - if(pHetTable != NULL) - { - pHetTable->dwIndexSizeTotal = 0; - pHetTable->dwIndexSizeExtra = 0; - pHetTable->dwIndexSize = pHetTable->dwIndexSizeTotal; - pHetTable->dwMaxFileCount = dwMaxFileCount; - pHetTable->dwHashTableSize = (dwMaxFileCount * 4 / 3); - pHetTable->dwHashBitSize = dwHashBitSize; - - // Size of one index is calculated from max file count - pHetTable->dwIndexSizeTotal = GetNecessaryBitCount(dwMaxFileCount); - pHetTable->dwIndexSizeExtra = 0; - pHetTable->dwIndexSize = pHetTable->dwIndexSizeTotal; - - // Allocate hash table - pHetTable->pHetHashes = STORM_ALLOC(BYTE, pHetTable->dwHashTableSize); - memset(pHetTable->pHetHashes, 0, pHetTable->dwHashTableSize); - - // If we shall create empty HET table, we have to allocate empty block index table as well - if(bCreateEmpty) - pHetTable->pBetIndexes = CreateBitArray(pHetTable->dwHashTableSize * pHetTable->dwIndexSizeTotal, 0xFF); - - // Calculate masks - pHetTable->AndMask64 = 0; - if(dwHashBitSize != 0x40) - pHetTable->AndMask64 = (ULONGLONG)1 << dwHashBitSize; - pHetTable->AndMask64--; - - pHetTable->OrMask64 = (ULONGLONG)1 << (dwHashBitSize - 1); - } - - return pHetTable; -} - -static TMPQHetTable * TranslateHetTable(TMPQExtTable * pExtTable) -{ - HET_TABLE_HEADER HetHeader; - TMPQHetTable * pHetTable = NULL; - LPBYTE pbSrcData = (LPBYTE)(pExtTable + 1); - - // Sanity check - assert(pExtTable->dwSignature == HET_TABLE_SIGNATURE); - assert(pExtTable->dwVersion == 1); - - // Verify size of the HET table - if(pExtTable != NULL && pExtTable->dwDataSize >= sizeof(HET_TABLE_HEADER)) - { - // Copy the table header in order to have it aligned and swapped - memcpy(&HetHeader, pbSrcData, sizeof(HET_TABLE_HEADER)); - BSWAP_ARRAY32_UNSIGNED(&HetHeader, sizeof(HET_TABLE_HEADER)); - pbSrcData += sizeof(HET_TABLE_HEADER); - - // Verify the size of the table in the header - if(HetHeader.dwTableSize == pExtTable->dwDataSize) - { - // Create translated table - pHetTable = CreateHetTable(HetHeader.dwMaxFileCount, HetHeader.dwHashEntrySize, false); - if(pHetTable != NULL) - { - // Copy the hash table size, index size and extra bits from the HET header - pHetTable->dwHashTableSize = HetHeader.dwHashTableSize; - pHetTable->dwIndexSizeTotal = HetHeader.dwIndexSizeTotal; - pHetTable->dwIndexSizeExtra = HetHeader.dwIndexSizeExtra; - - // Fill the hash table - if(pHetTable->pHetHashes != NULL) - memcpy(pHetTable->pHetHashes, pbSrcData, pHetTable->dwHashTableSize); - pbSrcData += pHetTable->dwHashTableSize; - - // Copy the block index table - pHetTable->pBetIndexes = CreateBitArray(HetHeader.dwIndexTableSize * 8, 0xFF); - if(pHetTable->pBetIndexes != NULL) - memcpy(pHetTable->pBetIndexes->Elements, pbSrcData, HetHeader.dwIndexTableSize); - pbSrcData += HetHeader.dwIndexTableSize; - } - } - } - - return pHetTable; -} - -static TMPQExtTable * TranslateHetTable(TMPQHetTable * pHetTable, ULONGLONG * pcbHetTable) -{ - TMPQExtTable * pExtTable = NULL; - HET_TABLE_HEADER HetHeader; - LPBYTE pbLinearTable = NULL; - LPBYTE pbTrgData; - size_t HetTableSize; - - // Prepare header of the HET table - CreateHetHeader(pHetTable, &HetHeader); - - // Calculate the total size needed for holding the encrypted HET table - HetTableSize = HetHeader.dwTableSize; - - // Allocate space for the linear table - pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + HetTableSize); - if(pbLinearTable != NULL) - { - // Create the common ext table header - pExtTable = (TMPQExtTable *)pbLinearTable; - pExtTable->dwSignature = HET_TABLE_SIGNATURE; - pExtTable->dwVersion = 1; - pExtTable->dwDataSize = (DWORD)HetTableSize; - pbTrgData = (LPBYTE)(pExtTable + 1); - - // Copy the HET table header - memcpy(pbTrgData, &HetHeader, sizeof(HET_TABLE_HEADER)); - BSWAP_ARRAY32_UNSIGNED(pbTrgData, sizeof(HET_TABLE_HEADER)); - pbTrgData += sizeof(HET_TABLE_HEADER); - - // Copy the array of HET hashes - memcpy(pbTrgData, pHetTable->pHetHashes, pHetTable->dwHashTableSize); - pbTrgData += pHetTable->dwHashTableSize; - - // Copy the bit array of BET indexes - memcpy(pbTrgData, pHetTable->pBetIndexes->Elements, HetHeader.dwIndexTableSize); - - // Calculate the total size of the table, including the TMPQExtTable - if(pcbHetTable != NULL) - { - *pcbHetTable = (ULONGLONG)(sizeof(TMPQExtTable) + HetTableSize); - } - } - - return pExtTable; -} - -DWORD GetFileIndex_Het(TMPQArchive * ha, const char * szFileName) -{ - TMPQHetTable * pHetTable = ha->pHetTable; - ULONGLONG FileNameHash; - ULONGLONG AndMask64; - ULONGLONG OrMask64; - ULONGLONG BetHash; - DWORD StartIndex; - DWORD Index; - BYTE HetHash; // Upper 8 bits of the masked file name hash - - // Do nothing if the MPQ has no HET table - assert(ha->pHetTable != NULL); - - // Calculate 64-bit hash of the file name - AndMask64 = pHetTable->AndMask64; - OrMask64 = pHetTable->OrMask64; - FileNameHash = (HashStringJenkins(szFileName) & AndMask64) | OrMask64; - - // Split the file name hash into two parts: - // Part 1: The highest 8 bits of the name hash - // Part 2: The rest of the name hash (without the highest 8 bits) - HetHash = (BYTE)(FileNameHash >> (pHetTable->dwHashBitSize - 8)); - BetHash = FileNameHash & (AndMask64 >> 0x08); - - // Calculate the starting index to the hash table - StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwHashTableSize); - - // Go through HET table until we find a terminator - while(pHetTable->pHetHashes[Index] != HET_ENTRY_FREE) - { - // Did we find match ? - if(pHetTable->pHetHashes[Index] == HetHash) - { - DWORD dwFileIndex = 0; - - // Get the index of the BetHash - pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * Index, - pHetTable->dwIndexSize, - &dwFileIndex, - 4); - - // - // TODO: This condition only happens when we are opening a MPQ - // where some files were deleted by StormLib. Perhaps - // we should not allow shrinking of the file table in MPQs v 4.0? - // assert(dwFileIndex <= ha->dwFileTableSize); - // - - // Verify the BetHash against the entry in the table of BET hashes - if(dwFileIndex <= ha->dwFileTableSize && ha->pFileTable[dwFileIndex].BetHash == BetHash) - return dwFileIndex; - } - - // Move to the next entry in the primary search table - // If we came to the start index again, we are done - Index = (Index + 1) % pHetTable->dwHashTableSize; - if(Index == StartIndex) - break; - } - - // File not found - return HASH_ENTRY_FREE; -} - -DWORD AllocateHetEntry( - TMPQArchive * ha, - TFileEntry * pFileEntry) -{ - TMPQHetTable * pHetTable = ha->pHetTable; - ULONGLONG FileNameHash; - ULONGLONG AndMask64; - ULONGLONG OrMask64; - ULONGLONG BetHash; - DWORD FreeHetIndex = HASH_ENTRY_FREE; - DWORD dwFileIndex; - DWORD StartIndex; - DWORD Index; - BYTE HetHash; // Upper 8 bits of the masked file name hash - - // Do nothing if the MPQ has no HET table - assert(ha->pHetTable != NULL); - - // Calculate 64-bit hash of the file name - AndMask64 = pHetTable->AndMask64; - OrMask64 = pHetTable->OrMask64; - FileNameHash = (HashStringJenkins(pFileEntry->szFileName) & AndMask64) | OrMask64; - - // Calculate the starting index to the hash table - StartIndex = Index = (DWORD)(FileNameHash % pHetTable->dwHashTableSize); - - // Split the file name hash into two parts: - // Part 1: The highest 8 bits of the name hash - // Part 2: The rest of the name hash (without the highest 8 bits) - HetHash = (BYTE)(FileNameHash >> (pHetTable->dwHashBitSize - 8)); - BetHash = FileNameHash & (AndMask64 >> 0x08); - - // Go through HET table until we find a terminator - for(;;) - { - // Check for entries that might have been deleted - if(pHetTable->pHetHashes[Index] == HET_ENTRY_DELETED) - { - DWORD dwInvalidBetIndex = (1 << pHetTable->dwIndexSizeTotal) - 1; - DWORD dwBetIndex = 0; - - // Verify the BET index. If it's really free, we can use it - dwFileIndex = (DWORD)(pFileEntry - ha->pFileTable); - pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * Index, - pHetTable->dwIndexSize, - &dwBetIndex, - 4); - - if(dwBetIndex == dwInvalidBetIndex) - { - FreeHetIndex = Index; - break; - } - } - - // Is that entry free ? - if(pHetTable->pHetHashes[Index] == HET_ENTRY_FREE) - { - FreeHetIndex = Index; - break; - } - - // Move to the next entry in the primary search table - // If we came to the start index again, we are done - Index = (Index + 1) % pHetTable->dwHashTableSize; - if(Index == StartIndex) - return HASH_ENTRY_FREE; - } - - // Fill the HET table entry - dwFileIndex = (DWORD)(pFileEntry - ha->pFileTable); - pHetTable->pHetHashes[FreeHetIndex] = HetHash; - pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * FreeHetIndex, - pHetTable->dwIndexSize, - &dwFileIndex, - 4); - // Fill the file entry - pFileEntry->BetHash = BetHash; - pFileEntry->dwHetIndex = FreeHetIndex; - return FreeHetIndex; -} - -void FreeHetTable(TMPQHetTable * pHetTable) -{ - if(pHetTable != NULL) - { - if(pHetTable->pHetHashes != NULL) - STORM_FREE(pHetTable->pHetHashes); - if(pHetTable->pBetIndexes != NULL) - STORM_FREE(pHetTable->pBetIndexes); - - STORM_FREE(pHetTable); - } -} - -//----------------------------------------------------------------------------- -// Support for BET table - -static void CreateBetHeader( - TMPQArchive * ha, - PBET_TABLE_HEADER pBetHeader) -{ - TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pFileEntry; - ULONGLONG MaxByteOffset = 0; - DWORD FlagArray[MAX_FLAG_INDEX]; - DWORD dwMaxFlagIndex = 0; - DWORD dwMaxFileSize = 0; - DWORD dwMaxCmpSize = 0; - DWORD dwFlagIndex; - - // Initialize array of flag combinations - InitFileFlagArray(FlagArray); - - // Get the maximum values for the BET table - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) - { - // Highest file position in the MPQ - if(pFileEntry->ByteOffset > MaxByteOffset) - MaxByteOffset = pFileEntry->ByteOffset; - - // Biggest file size - if(pFileEntry->dwFileSize > dwMaxFileSize) - dwMaxFileSize = pFileEntry->dwFileSize; - - // Biggest compressed size - if(pFileEntry->dwCmpSize > dwMaxCmpSize) - dwMaxCmpSize = pFileEntry->dwCmpSize; - - // Check if this flag was there before - dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags); - if(dwFlagIndex > dwMaxFlagIndex) - dwMaxFlagIndex = dwFlagIndex; - } - - // Now save bit count for every piece of file information - pBetHeader->dwBitIndex_FilePos = 0; - pBetHeader->dwBitCount_FilePos = GetNecessaryBitCount(MaxByteOffset); - - pBetHeader->dwBitIndex_FileSize = pBetHeader->dwBitIndex_FilePos + pBetHeader->dwBitCount_FilePos; - pBetHeader->dwBitCount_FileSize = GetNecessaryBitCount(dwMaxFileSize); - - pBetHeader->dwBitIndex_CmpSize = pBetHeader->dwBitIndex_FileSize + pBetHeader->dwBitCount_FileSize; - pBetHeader->dwBitCount_CmpSize = GetNecessaryBitCount(dwMaxCmpSize); - - pBetHeader->dwBitIndex_FlagIndex = pBetHeader->dwBitIndex_CmpSize + pBetHeader->dwBitCount_CmpSize; - pBetHeader->dwBitCount_FlagIndex = GetNecessaryBitCount(dwMaxFlagIndex + 1); - - pBetHeader->dwBitIndex_Unknown = pBetHeader->dwBitIndex_FlagIndex + pBetHeader->dwBitCount_FlagIndex; - pBetHeader->dwBitCount_Unknown = 0; - - // Calculate the total size of one entry - pBetHeader->dwTableEntrySize = pBetHeader->dwBitCount_FilePos + - pBetHeader->dwBitCount_FileSize + - pBetHeader->dwBitCount_CmpSize + - pBetHeader->dwBitCount_FlagIndex + - pBetHeader->dwBitCount_Unknown; - - // Save the file count and flag count - pBetHeader->dwFileCount = ha->dwFileTableSize; - pBetHeader->dwFlagCount = dwMaxFlagIndex + 1; - pBetHeader->dwUnknown08 = 0x10; - - // Save the total size of the BET hash - pBetHeader->dwBetHashSizeTotal = ha->pHetTable->dwHashBitSize - 0x08; - pBetHeader->dwBetHashSizeExtra = 0; - pBetHeader->dwBetHashSize = pBetHeader->dwBetHashSizeTotal; - pBetHeader->dwBetHashArraySize = ((pBetHeader->dwBetHashSizeTotal * pBetHeader->dwFileCount) + 7) / 8; - - // Save the total table size - pBetHeader->dwTableSize = sizeof(BET_TABLE_HEADER) + - pBetHeader->dwFlagCount * sizeof(DWORD) + - ((pBetHeader->dwTableEntrySize * pBetHeader->dwFileCount) + 7) / 8 + - pBetHeader->dwBetHashArraySize; -} - -TMPQBetTable * CreateBetTable(DWORD dwFileCount) -{ - TMPQBetTable * pBetTable; - - // Allocate BET table - pBetTable = STORM_ALLOC(TMPQBetTable, 1); - if(pBetTable != NULL) - { - memset(pBetTable, 0, sizeof(TMPQBetTable)); - pBetTable->dwFileCount = dwFileCount; - } - - return pBetTable; -} - -static TMPQBetTable * TranslateBetTable( - TMPQArchive * ha, - TMPQExtTable * pExtTable) -{ - BET_TABLE_HEADER BetHeader; - TMPQBetTable * pBetTable = NULL; - LPBYTE pbSrcData = (LPBYTE)(pExtTable + 1); - DWORD LengthInBytes; - - // Sanity check - assert(pExtTable->dwSignature == BET_TABLE_SIGNATURE); - assert(pExtTable->dwVersion == 1); - assert(ha->pHetTable != NULL); - ha = ha; - - // Verify size of the HET table - if(pExtTable != NULL && pExtTable->dwDataSize >= sizeof(BET_TABLE_HEADER)) - { - // Copy the table header in order to have it aligned and swapped - memcpy(&BetHeader, pbSrcData, sizeof(BET_TABLE_HEADER)); - BSWAP_ARRAY32_UNSIGNED(&BetHeader, sizeof(BET_TABLE_HEADER)); - pbSrcData += sizeof(BET_TABLE_HEADER); - - // Some MPQs affected by a bug in StormLib have pBetTable->dwFileCount - // greater than ha->dwMaxFileCount - if(BetHeader.dwFileCount > ha->dwMaxFileCount) - return NULL; - - // Verify the size of the table in the header - if(BetHeader.dwTableSize == pExtTable->dwDataSize) - { - // Create translated table - pBetTable = CreateBetTable(BetHeader.dwFileCount); - if(pBetTable != NULL) - { - // Copy the variables from the header to the BetTable - pBetTable->dwTableEntrySize = BetHeader.dwTableEntrySize; - pBetTable->dwBitIndex_FilePos = BetHeader.dwBitIndex_FilePos; - pBetTable->dwBitIndex_FileSize = BetHeader.dwBitIndex_FileSize; - pBetTable->dwBitIndex_CmpSize = BetHeader.dwBitIndex_CmpSize; - pBetTable->dwBitIndex_FlagIndex = BetHeader.dwBitIndex_FlagIndex; - pBetTable->dwBitIndex_Unknown = BetHeader.dwBitIndex_Unknown; - pBetTable->dwBitCount_FilePos = BetHeader.dwBitCount_FilePos; - pBetTable->dwBitCount_FileSize = BetHeader.dwBitCount_FileSize; - pBetTable->dwBitCount_CmpSize = BetHeader.dwBitCount_CmpSize; - pBetTable->dwBitCount_FlagIndex = BetHeader.dwBitCount_FlagIndex; - pBetTable->dwBitCount_Unknown = BetHeader.dwBitCount_Unknown; - - // Since we don't know what the "unknown" is, we'll assert when it's nonzero - assert(pBetTable->dwBitCount_Unknown == 0); - - // Allocate array for flags - if(BetHeader.dwFlagCount != 0) - { - // Allocate array for file flags and load it - pBetTable->pFileFlags = STORM_ALLOC(DWORD, BetHeader.dwFlagCount); - if(pBetTable->pFileFlags != NULL) - { - LengthInBytes = BetHeader.dwFlagCount * sizeof(DWORD); - memcpy(pBetTable->pFileFlags, pbSrcData, LengthInBytes); - BSWAP_ARRAY32_UNSIGNED(pBetTable->pFileFlags, LengthInBytes); - pbSrcData += LengthInBytes; - } - - // Save the number of flags - pBetTable->dwFlagCount = BetHeader.dwFlagCount; - } - - // Load the bit-based file table - pBetTable->pFileTable = CreateBitArray(pBetTable->dwTableEntrySize * BetHeader.dwFileCount, 0); - LengthInBytes = (pBetTable->pFileTable->NumberOfBits + 7) / 8; - if(pBetTable->pFileTable != NULL) - memcpy(pBetTable->pFileTable->Elements, pbSrcData, LengthInBytes); - pbSrcData += LengthInBytes; - - // Fill the sizes of BET hash - pBetTable->dwBetHashSizeTotal = BetHeader.dwBetHashSizeTotal; - pBetTable->dwBetHashSizeExtra = BetHeader.dwBetHashSizeExtra; - pBetTable->dwBetHashSize = BetHeader.dwBetHashSize; - - // Create and load the array of BET hashes - pBetTable->pBetHashes = CreateBitArray(pBetTable->dwBetHashSizeTotal * BetHeader.dwFileCount, 0); - LengthInBytes = (pBetTable->pBetHashes->NumberOfBits + 7) / 8; - if(pBetTable->pBetHashes != NULL) - memcpy(pBetTable->pBetHashes->Elements, pbSrcData, LengthInBytes); - pbSrcData += BetHeader.dwBetHashArraySize; - - // Dump both tables -// DumpHetAndBetTable(ha->pHetTable, pBetTable); - } - } - } - - return pBetTable; -} - -TMPQExtTable * TranslateBetTable( - TMPQArchive * ha, - ULONGLONG * pcbBetTable) -{ - TMPQExtTable * pExtTable = NULL; - BET_TABLE_HEADER BetHeader; - TBitArray * pBitArray = NULL; - LPBYTE pbLinearTable = NULL; - LPBYTE pbTrgData; - size_t BetTableSize; - DWORD LengthInBytes; - DWORD FlagArray[MAX_FLAG_INDEX]; - DWORD i; - - // Calculate the bit sizes of various entries - InitFileFlagArray(FlagArray); - CreateBetHeader(ha, &BetHeader); - - // Calculate the size of the BET table - BetTableSize = sizeof(BET_TABLE_HEADER) + - BetHeader.dwFlagCount * sizeof(DWORD) + - ((BetHeader.dwTableEntrySize * BetHeader.dwFileCount) + 7) / 8 + - BetHeader.dwBetHashArraySize; - - // Allocate space - pbLinearTable = STORM_ALLOC(BYTE, sizeof(TMPQExtTable) + BetTableSize); - if(pbLinearTable != NULL) - { - // Create the common ext table header - pExtTable = (TMPQExtTable *)pbLinearTable; - pExtTable->dwSignature = BET_TABLE_SIGNATURE; - pExtTable->dwVersion = 1; - pExtTable->dwDataSize = (DWORD)BetTableSize; - pbTrgData = (LPBYTE)(pExtTable + 1); - - // Copy the BET table header - memcpy(pbTrgData, &BetHeader, sizeof(BET_TABLE_HEADER)); - BSWAP_ARRAY32_UNSIGNED(pbTrgData, sizeof(BET_TABLE_HEADER)); - pbTrgData += sizeof(BET_TABLE_HEADER); - - // Save the bit-based block table - pBitArray = CreateBitArray(BetHeader.dwFileCount * BetHeader.dwTableEntrySize, 0); - if(pBitArray != NULL) - { - TFileEntry * pFileEntry = ha->pFileTable; - DWORD dwFlagIndex = 0; - DWORD nBitOffset = 0; - - // Construct the array of flag values and bit-based file table - for(i = 0; i < BetHeader.dwFileCount; i++, pFileEntry++) - { - // - // Note: Blizzard MPQs contain valid values even for non-existant files - // (FilePos, FileSize, CmpSize and FlagIndex) - // Note: If flags is zero, it must be in the flag table too !!! - // - - // Save the byte offset - pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FilePos, - BetHeader.dwBitCount_FilePos, - &pFileEntry->ByteOffset, - 8); - pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FileSize, - BetHeader.dwBitCount_FileSize, - &pFileEntry->dwFileSize, - 4); - pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_CmpSize, - BetHeader.dwBitCount_CmpSize, - &pFileEntry->dwCmpSize, - 4); - - // Save the flag index - dwFlagIndex = GetFileFlagIndex(FlagArray, pFileEntry->dwFlags); - pBitArray->SetBits(nBitOffset + BetHeader.dwBitIndex_FlagIndex, - BetHeader.dwBitCount_FlagIndex, - &dwFlagIndex, - 4); - - // Move the bit offset - nBitOffset += BetHeader.dwTableEntrySize; - } - - // Write the array of flags - LengthInBytes = BetHeader.dwFlagCount * sizeof(DWORD); - memcpy(pbTrgData, FlagArray, LengthInBytes); - BSWAP_ARRAY32_UNSIGNED(pbTrgData, LengthInBytes); - pbTrgData += LengthInBytes; - - // Write the bit-based block table - LengthInBytes = (pBitArray->NumberOfBits + 7) / 8; - memcpy(pbTrgData, pBitArray->Elements, LengthInBytes); - pbTrgData += LengthInBytes; - - // Free the bit array - STORM_FREE(pBitArray); - } - - // Create bit array for BET hashes - pBitArray = CreateBitArray(BetHeader.dwBetHashSizeTotal * BetHeader.dwFileCount, 0); - if(pBitArray != NULL) - { - TFileEntry * pFileEntry = ha->pFileTable; - ULONGLONG AndMask64 = ha->pHetTable->AndMask64; - ULONGLONG OrMask64 = ha->pHetTable->OrMask64; - - for(i = 0; i < BetHeader.dwFileCount; i++) - { - ULONGLONG FileNameHash = 0; - - // Calculate 64-bit hash of the file name - if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL) - { - FileNameHash = (HashStringJenkins(pFileEntry->szFileName) & AndMask64) | OrMask64; - FileNameHash = FileNameHash & (AndMask64 >> 0x08); - } - - // Insert the name hash to the bit array - pBitArray->SetBits(BetHeader.dwBetHashSizeTotal * i, - BetHeader.dwBetHashSize, - &FileNameHash, - 8); - - // Move to the next file entry - pFileEntry++; - } - - // Write the array of BET hashes - LengthInBytes = (pBitArray->NumberOfBits + 7) / 8; - memcpy(pbTrgData, pBitArray->Elements, LengthInBytes); - pbTrgData += LengthInBytes; - - // Free the bit array - STORM_FREE(pBitArray); - } - - // Write the size of the BET table in the MPQ - if(pcbBetTable != NULL) - { - *pcbBetTable = (ULONGLONG)(sizeof(TMPQExtTable) + BetTableSize); - } - } - - return pExtTable; -} - -void FreeBetTable(TMPQBetTable * pBetTable) -{ - if(pBetTable != NULL) - { - if(pBetTable->pFileTable != NULL) - STORM_FREE(pBetTable->pFileTable); - if(pBetTable->pFileFlags != NULL) - STORM_FREE(pBetTable->pFileFlags); - if(pBetTable->pBetHashes != NULL) - STORM_FREE(pBetTable->pBetHashes); - - STORM_FREE(pBetTable); - } -} - -//----------------------------------------------------------------------------- -// Support for file table - -TFileEntry * GetFileEntryAny(TMPQArchive * ha, const char * szFileName) -{ - TMPQHash * pHash; - DWORD dwFileIndex; - - // If we have HET table in the MPQ, try to find the file in HET table - if(ha->pHetTable != NULL) - { - dwFileIndex = GetFileIndex_Het(ha, szFileName); - if(dwFileIndex != HASH_ENTRY_FREE) - return ha->pFileTable + dwFileIndex; - } - - // Otherwise, perform the file search in the classic hash table - if(ha->pHashTable != NULL) - { - pHash = GetHashEntryAny(ha, szFileName); - if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize) - return ha->pFileTable + pHash->dwBlockIndex; - } - - // Not found - return NULL; -} - -TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale) -{ - TMPQHash * pHash; - DWORD dwFileIndex; - - // If we have HET table in the MPQ, try to find the file in HET table - if(ha->pHetTable != NULL) - { - dwFileIndex = GetFileIndex_Het(ha, szFileName); - if(dwFileIndex != HASH_ENTRY_FREE) - return ha->pFileTable + dwFileIndex; - } - - // Otherwise, perform the file search in the classic hash table - if(ha->pHashTable != NULL) - { - pHash = GetHashEntryLocale(ha, szFileName, lcLocale); - if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize) - return ha->pFileTable + pHash->dwBlockIndex; - } - - // Not found - return NULL; -} - -TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale) -{ - TMPQHash * pHash; - DWORD dwFileIndex; - - // If we have HET table in the MPQ, try to find the file in HET table - if(ha->pHetTable != NULL) - { - dwFileIndex = GetFileIndex_Het(ha, szFileName); - if(dwFileIndex != HASH_ENTRY_FREE) - return ha->pFileTable + dwFileIndex; - } - - // Otherwise, perform the file search in the classic hash table - if(ha->pHashTable != NULL) - { - pHash = GetHashEntryExact(ha, szFileName, lcLocale); - if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize) - return ha->pFileTable + pHash->dwBlockIndex; - } - - // Not found - return NULL; -} - -TFileEntry * GetFileEntryByIndex(TMPQArchive * ha, DWORD dwIndex) -{ - // For MPQs with classic hash table - if(dwIndex < ha->dwFileTableSize) - return ha->pFileTable + dwIndex; - return NULL; -} - -void AllocateFileName(TFileEntry * pFileEntry, const char * szFileName) -{ - // Sanity check - assert(pFileEntry != NULL); - - // If the file name is pseudo file name, free it at this point - if(IsPseudoFileName(pFileEntry->szFileName, NULL)) - { - if(pFileEntry->szFileName != NULL) - STORM_FREE(pFileEntry->szFileName); - pFileEntry->szFileName = NULL; - } - - // Only allocate new file name if it's not there yet - if(pFileEntry->szFileName == NULL) - { - pFileEntry->szFileName = STORM_ALLOC(char, strlen(szFileName) + 1); - if(pFileEntry->szFileName != NULL) - strcpy(pFileEntry->szFileName, szFileName); - } -} - - -// Finds a free file entry. Does NOT increment table size. -TFileEntry * FindFreeFileEntry(TMPQArchive * ha) -{ - TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pFreeEntry = NULL; - TFileEntry * pFileEntry; - - // Try to find a free entry - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) - { - // If that entry is free, we reuse it - if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) - { - pFreeEntry = pFileEntry; - break; - } - - // - // Note: Files with "delete marker" are not deleted. - // Don't consider them free entries - // - } - - // Do we have a deleted entry? - if(pFreeEntry != NULL) - { - ClearFileEntry(ha, pFreeEntry); - return pFreeEntry; - } - - // If no file entry within the existing file table is free, - // we try the reserve space after current file table - if(ha->dwFileTableSize < ha->dwMaxFileCount) - return ha->pFileTable + ha->dwFileTableSize; - - // If we reached maximum file count, we cannot add more files to the MPQ - assert(ha->dwFileTableSize == ha->dwMaxFileCount); - return NULL; -} - - -TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale) -{ - TFileEntry * pFileEntry = NULL; - TMPQHash * pHash; - DWORD dwHashIndex; - DWORD dwFileIndex; - bool bHashEntryExists = false; - bool bHetEntryExists = false; - - // If the archive has classic hash table, we try to - // find the file in the hash table - if(ha->pHashTable != NULL) - { - // If the hash entry is already there, we reuse the file entry - pHash = GetHashEntryExact(ha, szFileName, lcLocale); - if(pHash != NULL) - { - pFileEntry = ha->pFileTable + pHash->dwBlockIndex; - bHashEntryExists = true; - } - } - - // If the archive has HET table, try to use it for - // finding the file - if(ha->pHetTable != NULL) - { - dwFileIndex = GetFileIndex_Het(ha, szFileName); - if(dwFileIndex != HASH_ENTRY_FREE) - { - pFileEntry = ha->pFileTable + dwFileIndex; - bHetEntryExists = true; - } - } - - // If still haven't found the file entry, we allocate new one - if(pFileEntry == NULL) - { - pFileEntry = FindFreeFileEntry(ha); - if(pFileEntry == NULL) - return NULL; - } - - // Fill the rest of the file entry - pFileEntry->ByteOffset = 0; - pFileEntry->FileTime = 0; - pFileEntry->dwFileSize = 0; - pFileEntry->dwCmpSize = 0; - pFileEntry->dwFlags = 0; - pFileEntry->lcLocale = 0; - pFileEntry->wPlatform = 0; - pFileEntry->dwCrc32 = 0; - memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE); - - // Allocate space for file name, if it's not there yet - AllocateFileName(pFileEntry, szFileName); - - // If the free file entry is at the end of the file table, - // we have to increment file table size - if(pFileEntry == ha->pFileTable + ha->dwFileTableSize) - { - assert(ha->dwFileTableSize < ha->dwMaxFileCount); - ha->pHeader->dwBlockTableSize++; - ha->dwFileTableSize++; - } - - // If the MPQ has hash table, we have to insert the new entry into the hash table - if(ha->pHashTable != NULL && bHashEntryExists == false) - { - dwHashIndex = AllocateHashEntry(ha, pFileEntry); - assert(dwHashIndex != HASH_ENTRY_FREE); - } - - // If the MPQ has HET table, we have to insert it to the HET table as well - if(ha->pHetTable != NULL && bHetEntryExists == false) - { - // TODO: Does HET table even support locales? - // Most probably, Blizzard gave up that silly idea long ago. - dwHashIndex = AllocateHetEntry(ha, pFileEntry); - assert(dwHashIndex != HASH_ENTRY_FREE); - } - - // Return the file entry - return pFileEntry; -} - -int RenameFileEntry( - TMPQArchive * ha, - TFileEntry * pFileEntry, - const char * szNewFileName) -{ - TMPQHash * pHash; - DWORD dwFileIndex; - int nError = ERROR_SUCCESS; - - // If the MPQ has classic hash table, clear the entry there - if(ha->pHashTable != NULL) - { - assert(pFileEntry->dwHashIndex < ha->pHeader->dwHashTableSize); - - pHash = ha->pHashTable + pFileEntry->dwHashIndex; - memset(pHash, 0xFF, sizeof(TMPQHash)); - pHash->dwBlockIndex = HASH_ENTRY_DELETED; - } - - // If the MPQ has HET table, clear the entry there as well - if(ha->pHetTable != NULL) - { - TMPQHetTable * pHetTable = ha->pHetTable; - DWORD dwInvalidFileIndex = (1 << pHetTable->dwIndexSizeTotal) - 1; - - assert(pFileEntry->dwHetIndex < pHetTable->dwHashTableSize); - - // Clear the entry in the HET hash array - pHetTable->pHetHashes[pFileEntry->dwHetIndex] = HET_ENTRY_DELETED; - - // Set the BET index to invalid index - pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * pFileEntry->dwHetIndex, - pHetTable->dwIndexSize, - &dwInvalidFileIndex, - 4); - } - - // Free the old file name - if(pFileEntry->szFileName != NULL) - STORM_FREE(pFileEntry->szFileName); - pFileEntry->szFileName = NULL; - - // Allocate new file name - AllocateFileName(pFileEntry, szNewFileName); - - // Now find a hash entry for the new file name - if(ha->pHashTable != NULL) - { - // Try to find the hash table entry for the new file name - // Note: If this fails, we leave the MPQ in a corrupt state - dwFileIndex = AllocateHashEntry(ha, pFileEntry); - if(dwFileIndex == HASH_ENTRY_FREE) - nError = ERROR_FILE_CORRUPT; - } - - // If the archive has HET table, we have to allocate HET table for the file as well - // finding the file - if(ha->pHetTable != NULL) - { - dwFileIndex = AllocateHetEntry(ha, pFileEntry); - if(dwFileIndex == HASH_ENTRY_FREE) - nError = ERROR_FILE_CORRUPT; - } - - // Invalidate the entries for (listfile) and (attributes) - // After we are done with MPQ changes, we need to re-create them - InvalidateInternalFiles(ha); - return nError; -} - -void ClearFileEntry( - TMPQArchive * ha, - TFileEntry * pFileEntry) -{ - TMPQHash * pHash = NULL; - - // If the MPQ has classic hash table, clear the entry there - if(ha->pHashTable != NULL) - { - assert(pFileEntry->dwHashIndex < ha->pHeader->dwHashTableSize); - - pHash = ha->pHashTable + pFileEntry->dwHashIndex; - memset(pHash, 0xFF, sizeof(TMPQHash)); - pHash->dwBlockIndex = HASH_ENTRY_DELETED; - } - - // If the MPQ has HET table, clear the entry there as well - if(ha->pHetTable != NULL) - { - TMPQHetTable * pHetTable = ha->pHetTable; - DWORD dwInvalidFileIndex = (1 << pHetTable->dwIndexSizeTotal) - 1; - - assert(pFileEntry->dwHetIndex < pHetTable->dwHashTableSize); - - // Clear the entry in the HET hash array - pHetTable->pHetHashes[pFileEntry->dwHetIndex] = HET_ENTRY_DELETED; - - // Set the BET index to invalid index - pHetTable->pBetIndexes->SetBits(pHetTable->dwIndexSizeTotal * pFileEntry->dwHetIndex, - pHetTable->dwIndexSize, - &dwInvalidFileIndex, - 4); - } - - // Free the file name, and set the file entry as deleted - if(pFileEntry->szFileName != NULL) - STORM_FREE(pFileEntry->szFileName); - - // Invalidate the file entry - memset(pFileEntry, 0, sizeof(TFileEntry)); -} - -int FreeFileEntry( - TMPQArchive * ha, - TFileEntry * pFileEntry) -{ - TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pTempEntry; - int nError = ERROR_SUCCESS; - - // - // If we have HET table, we cannot just get rid of the file - // Doing so would lead to empty gaps in the HET table - // We have to keep BET hash, hash index, HET index, locale, platform and file name - // - - if(ha->pHetTable == NULL) - { - TFileEntry * pLastFileEntry = ha->pFileTable + ha->dwFileTableSize - 1; - TFileEntry * pLastUsedEntry = pLastFileEntry; - - // Zero the file entry - ClearFileEntry(ha, pFileEntry); - - // Now there is a chance that we created a chunk of free - // file entries at the end of the file table. We check this - // and eventually free all deleted file entries at the end - for(pTempEntry = ha->pFileTable; pTempEntry < pFileTableEnd; pTempEntry++) - { - // Is that an occupied file entry? - if(pTempEntry->dwFlags & MPQ_FILE_EXISTS) - pLastUsedEntry = pTempEntry; - } - - // Can we free some entries at the end? - if(pLastUsedEntry < pLastFileEntry) - { - // Fix the size of the file table entry - ha->dwFileTableSize = (DWORD)(pLastUsedEntry - ha->pFileTable) + 1; - ha->pHeader->dwBlockTableSize = ha->dwFileTableSize; - } - } - else - { - // Note: Deleted entries in Blizzard MPQs version 4.0 - // normally contain valid byte offset and length - pFileEntry->dwFlags &= ~MPQ_FILE_EXISTS; - nError = ERROR_SUCCESS; - } - - return nError; -} - -void InvalidateInternalFiles(TMPQArchive * ha) -{ - TFileEntry * pFileEntry; - - // Invalidate the (listfile), if not done yet - if(!(ha->dwFlags & MPQ_FLAG_INV_LISTFILE)) - { - pFileEntry = GetFileEntryExact(ha, LISTFILE_NAME, LANG_NEUTRAL); - if(pFileEntry != NULL) - FreeFileEntry(ha, pFileEntry); - ha->dwFlags |= MPQ_FLAG_INV_LISTFILE; - } - - // Invalidate the (attributes), if not done yet - if(!(ha->dwFlags & MPQ_FLAG_INV_ATTRIBUTES)) - { - pFileEntry = GetFileEntryExact(ha, ATTRIBUTES_NAME, LANG_NEUTRAL); - if(pFileEntry != NULL) - FreeFileEntry(ha, pFileEntry); - ha->dwFlags |= MPQ_FLAG_INV_ATTRIBUTES; - } - - // Remember that the MPQ has been changed and it will be necessary - // to update the tables - ha->dwFlags |= MPQ_FLAG_CHANGED; -} - -//----------------------------------------------------------------------------- -// Functions that loads and verify MPQ data bitmap - -int LoadMpqDataBitmap(TMPQArchive * ha, ULONGLONG FileSize, bool * pbFileIsComplete) -{ - TMPQBitmap * pBitmap = NULL; - TMPQBitmap DataBitmap; - ULONGLONG BitmapOffset; - ULONGLONG EndOfMpq; - DWORD DataBlockCount = 0; - DWORD BitmapByteSize; - DWORD WholeByteCount; - DWORD ExtraBitsCount; - - // Is there enough space for a MPQ bitmap? - EndOfMpq = ha->MpqPos + ha->pHeader->ArchiveSize64; - FileSize = FileSize - sizeof(TMPQBitmap); - if(FileSize > EndOfMpq) - { - // Try to load the data bitmap from the end of the file - if(FileStream_Read(ha->pStream, &FileSize, &DataBitmap, sizeof(TMPQBitmap))) - { - // Is it a valid data bitmap? - BSWAP_ARRAY32_UNSIGNED((LPDWORD)(&DataBitmap), sizeof(TMPQBitmap)); - if(DataBitmap.dwSignature == MPQ_DATA_BITMAP_SIGNATURE) - { - // We assume that MPQs with data bitmap begin at position 0 - assert(ha->MpqPos == 0); - - // Calculate the number of extra bytes for data bitmap - DataBlockCount = (DWORD)(((ha->pHeader->ArchiveSize64 - 1) / DataBitmap.dwBlockSize) + 1); - BitmapByteSize = ((DataBlockCount - 1) / 8) + 1; - - // Verify the data block size - BitmapOffset = ((ULONGLONG)DataBitmap.dwMapOffsetHi << 32) | DataBitmap.dwMapOffsetLo; - assert((DWORD)(FileSize - BitmapOffset) == BitmapByteSize); - - // Allocate space for the data bitmap - pBitmap = (TMPQBitmap *)STORM_ALLOC(BYTE, sizeof(TMPQBitmap) + BitmapByteSize); - if(pBitmap != NULL) - { - // Copy the bitmap header - memcpy(pBitmap, &DataBitmap, sizeof(TMPQBitmap)); - - // Read the remaining part - if(!FileStream_Read(ha->pStream, &BitmapOffset, (pBitmap + 1), BitmapByteSize)) - { - STORM_FREE(pBitmap); - pBitmap = NULL; - } - } - } - } - } - - // If the caller asks for file completeness, check it - if(pBitmap != NULL && pbFileIsComplete != NULL) - { - LPBYTE pbBitmap = (LPBYTE)(pBitmap + 1); - DWORD i; - bool bFileIsComplete = true; - - // Calculate the number of whole bytes and extra bits of the bitmap - WholeByteCount = (DataBlockCount / 8); - ExtraBitsCount = (DataBlockCount & 7); - - // Verify the whole bytes - their value must be 0xFF - for(i = 0; i < WholeByteCount; i++) - { - if(pbBitmap[i] != 0xFF) - bFileIsComplete = false; - } - - // If there are extra bits, calculate the mask - if(ExtraBitsCount != 0) - { - BYTE ExpectedValue = (BYTE)((1 << ExtraBitsCount) - 1); - - if(pbBitmap[i] != ExpectedValue) - bFileIsComplete = false; - } - - // Give the result to the caller - *pbFileIsComplete = bFileIsComplete; - } - - ha->pBitmap = pBitmap; - return ERROR_SUCCESS; -} - -//----------------------------------------------------------------------------- -// Support for file tables - hash table, block table, hi-block table - -int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize) -{ - TMPQHash * pHashTable; - - // Sanity checks - assert((dwHashTableSize & (dwHashTableSize - 1)) == 0); - assert(ha->pHashTable == NULL); - - // Create the hash table - pHashTable = STORM_ALLOC(TMPQHash, dwHashTableSize); - if(pHashTable == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Fill it - memset(pHashTable, 0xFF, dwHashTableSize * sizeof(TMPQHash)); - ha->pHashTable = pHashTable; - - // Set the max file count, if needed - if(ha->pHetTable == NULL) - ha->dwMaxFileCount = dwHashTableSize; - return ERROR_SUCCESS; -} - -TMPQHash * LoadHashTable(TMPQArchive * ha) -{ - TMPQHeader * pHeader = ha->pHeader; - ULONGLONG ByteOffset; - TMPQHash * pHashTable; - DWORD dwTableSize; - DWORD dwCmpSize; - int nError; - - // If the MPQ has no hash table, do nothing - if(pHeader->dwHashTablePos == 0 && pHeader->wHashTablePosHi == 0) - return NULL; - - // If the hash table size is zero, do nothing - if(pHeader->dwHashTableSize == 0) - return NULL; - - // Allocate buffer for the hash table - dwTableSize = pHeader->dwHashTableSize * sizeof(TMPQHash); - pHashTable = STORM_ALLOC(TMPQHash, pHeader->dwHashTableSize); - if(pHashTable == NULL) - return NULL; - - // Compressed size of the hash table - dwCmpSize = (DWORD)pHeader->HashTableSize64; - - // - // Load the table from the MPQ, with decompression - // - // Note: We will NOT check if the hash table is properly decrypted. - // Some MPQ protectors corrupt the hash table by rewriting part of it. - // Hash table, the way how it works, allows arbitrary values for unused entries. - // - - ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos); - nError = LoadMpqTable(ha, ByteOffset, pHashTable, dwCmpSize, dwTableSize, MPQ_KEY_HASH_TABLE); - if(nError != ERROR_SUCCESS) - { - STORM_FREE(pHashTable); - pHashTable = NULL; - } - - // Return the hash table - return pHashTable; -} - -static void FixBlockTableSize( - TMPQArchive * ha, - TMPQBlock * pBlockTable, - DWORD dwClaimedSize) -{ - TMPQHeader * pHeader = ha->pHeader; - ULONGLONG BlockTableStart; - ULONGLONG BlockTableEnd; - ULONGLONG FileDataStart; - - // Only perform this check on MPQs version 1.0 - if(pHeader->dwHeaderSize == MPQ_HEADER_SIZE_V1) - { - // Calculate claimed block table begin and end - BlockTableStart = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); - BlockTableEnd = BlockTableStart + (pHeader->dwBlockTableSize * sizeof(TMPQBlock)); - - for(DWORD i = 0; i < dwClaimedSize; i++) - { - // If the block table end goes into that file, fix the block table end - FileDataStart = ha->MpqPos + pBlockTable[i].dwFilePos; - if(BlockTableStart < FileDataStart && BlockTableEnd > FileDataStart) - { - dwClaimedSize = (DWORD)((FileDataStart - BlockTableStart) / sizeof(TMPQBlock)); - BlockTableEnd = FileDataStart; - } - } - } - - // Fix the block table size - pHeader->BlockTableSize64 = dwClaimedSize * sizeof(TMPQBlock); - pHeader->dwBlockTableSize = dwClaimedSize; -} - -TMPQBlock * LoadBlockTable(TMPQArchive * ha, ULONGLONG FileSize) -{ - TMPQHeader * pHeader = ha->pHeader; - TMPQBlock * pBlockTable; - ULONGLONG ByteOffset; - DWORD dwTableSize; - DWORD dwCmpSize; - int nError; - - // Do nothing if the block table position is zero - if(pHeader->dwBlockTablePos == 0 && pHeader->wBlockTablePosHi == 0) - return NULL; - - // Do nothing if the block table size is zero - if(pHeader->dwBlockTableSize == 0) - return NULL; - - // Sanity check, enforced by LoadAnyHashTable - assert(ha->dwMaxFileCount >= pHeader->dwBlockTableSize); - - // Calculate sizes of both tables - ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); - dwTableSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock); - dwCmpSize = (DWORD)pHeader->BlockTableSize64; - - // Allocate space for the block table - // Note: pHeader->dwBlockTableSize can be zero !!! - pBlockTable = STORM_ALLOC(TMPQBlock, ha->dwMaxFileCount); - if(pBlockTable == NULL) - return NULL; - - // Fill the block table with zeros - memset(pBlockTable, 0, dwTableSize); - - // I found a MPQ which claimed 0x200 entries in the block table, - // but the file was cut and there was only 0x1A0 entries. - // We will handle this case properly. - if(dwTableSize == dwCmpSize && (ByteOffset + dwTableSize) > FileSize) - { - pHeader->dwBlockTableSize = (DWORD)((FileSize - ByteOffset) / sizeof(TMPQBlock)); - pHeader->BlockTableSize64 = pHeader->dwBlockTableSize * sizeof(TMPQBlock); - dwTableSize = dwCmpSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock); - } - - // - // One of the first cracked versions of Diablo I had block table unencrypted - // StormLib does NOT support such MPQs anymore, as they are incompatible - // with compressed block table feature - // - - // Load the block table - nError = LoadMpqTable(ha, ByteOffset, pBlockTable, dwCmpSize, dwTableSize, MPQ_KEY_BLOCK_TABLE); - if(nError != ERROR_SUCCESS) - { - // Failed, sorry - STORM_FREE(pBlockTable); - return NULL; - } - - // Defense against MPQs that claim block table to be bigger than it really is - FixBlockTableSize(ha, pBlockTable, pHeader->dwBlockTableSize); - return pBlockTable; -} - -int LoadHetTable(TMPQArchive * ha) -{ - TMPQExtTable * pExtTable; - TMPQHeader * pHeader = ha->pHeader; - int nError = ERROR_SUCCESS; - - // If the HET table position is not NULL, we expect - // both HET and BET tables to be present. - if(pHeader->HetTablePos64 != 0) - { - // Attempt to load the HET table (Hash Extended Table) - pExtTable = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE); - if(pExtTable != NULL) - { - // If succeeded, we have to limit the maximum file count - // to the values saved in the HET table - // If loading HET table fails, we ignore the result. - ha->pHetTable = TranslateHetTable(pExtTable); - if(ha->pHetTable != NULL) - ha->dwMaxFileCount = ha->pHetTable->dwMaxFileCount; - - STORM_FREE(pExtTable); - } - - // If the HET hable failed to load, it's corrupt. - if(ha->pHetTable == NULL) - nError = ERROR_FILE_CORRUPT; - } - - return nError; -} - -TMPQBetTable * LoadBetTable(TMPQArchive * ha) -{ - TMPQExtTable * pExtTable; - TMPQBetTable * pBetTable = NULL; - TMPQHeader * pHeader = ha->pHeader; - - // If the HET table position is not NULL, we expect - // both HET and BET tables to be present. - if(pHeader->BetTablePos64 != 0) - { - // Attempt to load the HET table (Hash Extended Table) - pExtTable = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE); - if(pExtTable != NULL) - { - // If succeeded, we translate the BET table - // to more readable form - pBetTable = TranslateBetTable(ha, pExtTable); - STORM_FREE(pExtTable); - } - } - - return pBetTable; -} - -int LoadAnyHashTable(TMPQArchive * ha) -{ - TMPQHeader * pHeader = ha->pHeader; - - // If the MPQ archive is empty, don't bother trying to load anything - if(pHeader->dwHashTableSize == 0 && pHeader->HetTableSize64 == 0) - return CreateHashTable(ha, HASH_TABLE_SIZE_DEFAULT); - - // Try to load HET and/or classic hash table - LoadHetTable(ha); - - // Load the HASH table - ha->pHashTable = LoadHashTable(ha); - - // Set the maximum file count to the size of the hash table - // In case there is HET table, we have to keep the file limit - if(ha->pHetTable == NULL) - ha->dwMaxFileCount = pHeader->dwHashTableSize; - - // Did at least one succeed? - if(ha->pHetTable == NULL && ha->pHashTable == NULL) - return ERROR_FILE_CORRUPT; - - // In theory, a MPQ could have bigger block table than hash table - if(ha->pHeader->dwBlockTableSize > ha->dwMaxFileCount) - { - ha->dwMaxFileCount = ha->pHeader->dwBlockTableSize; - ha->dwFlags |= MPQ_FLAG_READ_ONLY; - } - - return ERROR_SUCCESS; -} - -int BuildFileTable_Classic( - TMPQArchive * ha, - TFileEntry * pFileTable, - ULONGLONG FileSize) -{ - TFileEntry * pFileEntry; - TMPQHeader * pHeader = ha->pHeader; - TMPQBlock * pBlockTable; - TMPQBlock * pBlock; - int nError = ERROR_SUCCESS; - - // Sanity checks - assert(ha->pHashTable != NULL); - - // Load the block table - pBlockTable = LoadBlockTable(ha, FileSize); - if(pBlockTable != NULL) - { - TMPQHash * pHashEnd = ha->pHashTable + pHeader->dwHashTableSize; - TMPQHash * pHash; - - // If we don't have HET table, we build the file entries from the hash&block tables - if(ha->pHetTable == NULL) - { - for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++) - { - if(pHash->dwBlockIndex < pHeader->dwBlockTableSize) - { - pFileEntry = pFileTable + pHash->dwBlockIndex; - pBlock = pBlockTable + pHash->dwBlockIndex; - - // - // Yet another silly map protector: For each valid file, - // there are 4 items in the hash table, that appears to be valid: - // - // a6d79af0 e61a0932 001e0000 0000770b <== Fake valid - // a6d79af0 e61a0932 0000d761 0000dacb <== Fake valid - // a6d79af0 e61a0932 00000000 0000002f <== Real file entry - // a6d79af0 e61a0932 00005a4f 000093bc <== Fake valid - // - - if(!(pBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS) && (pBlock->dwFlags & MPQ_FILE_EXISTS)) - { - // Fill the entry - pFileEntry->ByteOffset = pBlock->dwFilePos; - pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable); - pFileEntry->dwFileSize = pBlock->dwFSize; - pFileEntry->dwCmpSize = pBlock->dwCSize; - pFileEntry->dwFlags = pBlock->dwFlags; - pFileEntry->lcLocale = pHash->lcLocale; - pFileEntry->wPlatform = pHash->wPlatform; - } - else - { - // If the hash table entry doesn't point to the valid file item, - // we invalidate the entire hash table entry - pHash->dwName1 = 0xFFFFFFFF; - pHash->dwName2 = 0xFFFFFFFF; - pHash->lcLocale = 0xFFFF; - pHash->wPlatform = 0xFFFF; - pHash->dwBlockIndex = HASH_ENTRY_DELETED; - } - } - } - } - else - { - for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++) - { - if(pHash->dwBlockIndex < ha->dwFileTableSize) - { - pFileEntry = pFileTable + pHash->dwBlockIndex; - if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) - { - pFileEntry->dwHashIndex = (DWORD)(pHash - ha->pHashTable); - pFileEntry->lcLocale = pHash->lcLocale; - pFileEntry->wPlatform = pHash->wPlatform; - } - } - } - } - - // Free the block table - STORM_FREE(pBlockTable); - } - else - { - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Load the hi-block table - if(nError == ERROR_SUCCESS && pHeader->HiBlockTablePos64 != 0) - { - ULONGLONG ByteOffset; - USHORT * pHiBlockTable = NULL; - DWORD dwTableSize = pHeader->dwBlockTableSize * sizeof(USHORT); - - // Allocate space for the hi-block table - // Note: pHeader->dwBlockTableSize can be zero !!! - pHiBlockTable = STORM_ALLOC(USHORT, pHeader->dwBlockTableSize + 1); - if(pHiBlockTable != NULL) - { - // Load the hi-block table. It is not encrypted, nor compressed - ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64; - if(!FileStream_Read(ha->pStream, &ByteOffset, pHiBlockTable, dwTableSize)) - nError = GetLastError(); - - // Now merge the hi-block table to the file table - if(nError == ERROR_SUCCESS) - { - pFileEntry = pFileTable; - - // Add the high file offset to the base file offset. - // We also need to swap it during the process. - for(DWORD i = 0; i < pHeader->dwBlockTableSize; i++) - { - pFileEntry->ByteOffset |= ((ULONGLONG)BSWAP_INT16_UNSIGNED(pHiBlockTable[i]) << 32); - pFileEntry++; - } - } - - // Free the hi-block table - STORM_FREE(pHiBlockTable); - } - else - { - nError = ERROR_NOT_ENOUGH_MEMORY; - } - } - - // Set the current size of the file table - ha->dwFileTableSize = pHeader->dwBlockTableSize; - return nError; -} - -int BuildFileTable_HetBet( - TMPQArchive * ha, - TFileEntry * pFileTable) -{ - TMPQHetTable * pHetTable = ha->pHetTable; - TMPQBetTable * pBetTable; - TFileEntry * pFileEntry = pFileTable; - TBitArray * pBitArray; - DWORD dwBitPosition = 0; - DWORD i; - int nError = ERROR_FILE_CORRUPT; - - // Load the BET table from the MPQ - pBetTable = LoadBetTable(ha); - if(pBetTable != NULL) - { - // Step one: Fill the indexes to the HET table - for(i = 0; i < pHetTable->dwHashTableSize; i++) - { - DWORD dwFileIndex = 0; - - // Is the entry in the HET table occupied? - if(pHetTable->pHetHashes[i] != 0) - { - // Load the index to the BET table - pHetTable->pBetIndexes->GetBits(pHetTable->dwIndexSizeTotal * i, - pHetTable->dwIndexSize, - &dwFileIndex, - 4); - // Overflow test - if(dwFileIndex < pBetTable->dwFileCount) - { - // Get the file entry and save HET index - pFileEntry = pFileTable + dwFileIndex; - pFileEntry->dwHetIndex = i; - - // Load the BET hash - pBetTable->pBetHashes->GetBits(pBetTable->dwBetHashSizeTotal * dwFileIndex, - pBetTable->dwBetHashSize, - &pFileEntry->BetHash, - 8); - } - } - } - - // Go through the entire BET table and convert it to the file table. - pFileEntry = pFileTable; - pBitArray = pBetTable->pFileTable; - for(i = 0; i < pBetTable->dwFileCount; i++) - { - DWORD dwFlagIndex = 0; - - // Read the file position - pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FilePos, - pBetTable->dwBitCount_FilePos, - &pFileEntry->ByteOffset, - 8); - - // Read the file size - pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FileSize, - pBetTable->dwBitCount_FileSize, - &pFileEntry->dwFileSize, - 4); - - // Read the compressed size - pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_CmpSize, - pBetTable->dwBitCount_CmpSize, - &pFileEntry->dwCmpSize, - 4); - - - // Read the flag index - if(pBetTable->dwFlagCount != 0) - { - pBitArray->GetBits(dwBitPosition + pBetTable->dwBitIndex_FlagIndex, - pBetTable->dwBitCount_FlagIndex, - &dwFlagIndex, - 4); - - pFileEntry->dwFlags = pBetTable->pFileFlags[dwFlagIndex]; - } - - // - // TODO: Locale (?) - // - - // Move the current bit position - dwBitPosition += pBetTable->dwTableEntrySize; - pFileEntry++; - } - - // Set the current size of the file table - ha->dwFileTableSize = pBetTable->dwFileCount; - FreeBetTable(pBetTable); - nError = ERROR_SUCCESS; - } - else - { - nError = ERROR_FILE_CORRUPT; - } - - return nError; -} - -int BuildFileTable(TMPQArchive * ha, ULONGLONG FileSize) -{ - TFileEntry * pFileTable; - bool bFileTableCreated = false; - - // Sanity checks - assert(ha->dwFileTableSize == 0); - assert(ha->dwMaxFileCount != 0); - - // Allocate the file table with size determined before - pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount); - if(pFileTable == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Fill the table with zeros - memset(pFileTable, 0, ha->dwMaxFileCount * sizeof(TFileEntry)); - - // If we have HET table, we load file table from the BET table - // Note: If BET table is corrupt or missing, we set the archive as read only - if(ha->pHetTable != NULL) - { - if(BuildFileTable_HetBet(ha, pFileTable) != ERROR_SUCCESS) - ha->dwFlags |= MPQ_FLAG_READ_ONLY; - else - bFileTableCreated = true; - } - - // If we have hash table, we load the file table from the block table - // Note: If block table is corrupt or missing, we set the archive as read only - if(ha->pHashTable != NULL) - { - if(BuildFileTable_Classic(ha, pFileTable, FileSize) != ERROR_SUCCESS) - ha->dwFlags |= MPQ_FLAG_READ_ONLY; - else - bFileTableCreated = true; - } - - // If something failed, we free the file table entry - if(bFileTableCreated == false) - { - STORM_FREE(pFileTable); - return ERROR_FILE_CORRUPT; - } - - // Assign it to the archive structure - ha->pFileTable = pFileTable; - return ERROR_SUCCESS; -} - -// Saves MPQ header, hash table, block table and hi-block table. -int SaveMPQTables(TMPQArchive * ha) -{ - TMPQExtTable * pHetTable = NULL; - TMPQExtTable * pBetTable = NULL; - TMPQHeader * pHeader = ha->pHeader; - TMPQBlock * pBlockTable = NULL; - TMPQHash * pHashTable = NULL; - ULONGLONG HetTableSize64 = 0; - ULONGLONG BetTableSize64 = 0; - ULONGLONG HashTableSize64 = 0; - ULONGLONG BlockTableSize64 = 0; - ULONGLONG HiBlockTableSize64 = 0; - ULONGLONG TablePos = 0; // A table position, relative to the begin of the MPQ - USHORT * pHiBlockTable = NULL; - DWORD cbTotalSize; - bool bNeedHiBlockTable = false; - int nError = ERROR_SUCCESS; - - // We expect this function to be called only when tables have been changed - assert(ha->dwFlags & MPQ_FLAG_CHANGED); - - // Find the space where the MPQ tables will be saved - FindFreeMpqSpace(ha, &TablePos); - - // If the MPQ has HET table, we prepare a ready-to-save version - if(nError == ERROR_SUCCESS && ha->pHetTable != NULL) - { - pHetTable = TranslateHetTable(ha->pHetTable, &HetTableSize64); - if(pHetTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // If the MPQ has HET table, we also must create BET table to be saved - if(nError == ERROR_SUCCESS && ha->pHetTable != NULL) - { - pBetTable = TranslateBetTable(ha, &BetTableSize64); - if(pBetTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Now create hash table - if(nError == ERROR_SUCCESS && ha->pHashTable != NULL) - { - pHashTable = TranslateHashTable(ha, &HashTableSize64); - if(pHashTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Create block table - if(nError == ERROR_SUCCESS && ha->pHashTable != NULL) - { - pBlockTable = TranslateBlockTable(ha, &BlockTableSize64, &bNeedHiBlockTable); - if(pBlockTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Create hi-block table, if needed - if(nError == ERROR_SUCCESS && bNeedHiBlockTable) - { - pHiBlockTable = TranslateHiBlockTable(ha, &HiBlockTableSize64); - if(pHiBlockTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Write the HET table, if any - if(nError == ERROR_SUCCESS && pHetTable != NULL) - { - pHeader->HetTableSize64 = HetTableSize64; - pHeader->HetTablePos64 = TablePos; - nError = SaveExtTable(ha, pHetTable, TablePos, (DWORD)HetTableSize64, pHeader->MD5_HetTable, MPQ_KEY_HASH_TABLE, false, &cbTotalSize); - TablePos += cbTotalSize; - } - - // Write the BET table, if any - if(nError == ERROR_SUCCESS && pBetTable != NULL) - { - pHeader->BetTableSize64 = BetTableSize64; - pHeader->BetTablePos64 = TablePos; - nError = SaveExtTable(ha, pBetTable, TablePos, (DWORD)BetTableSize64, pHeader->MD5_BetTable, MPQ_KEY_BLOCK_TABLE, false, &cbTotalSize); - TablePos += cbTotalSize; - } - - // Write the hash table, if we have any - if(nError == ERROR_SUCCESS && pHashTable != NULL) - { - pHeader->HashTableSize64 = HashTableSize64; - pHeader->wHashTablePosHi = (USHORT)(TablePos >> 32); - pHeader->dwHashTableSize = (DWORD)(HashTableSize64 / sizeof(TMPQHash)); - pHeader->dwHashTablePos = (DWORD)TablePos; - nError = SaveMpqTable(ha, pHashTable, TablePos, (size_t)HashTableSize64, pHeader->MD5_HashTable, MPQ_KEY_HASH_TABLE, false); - TablePos += HashTableSize64; - } - - // Write the block table, if we have any - if(nError == ERROR_SUCCESS && pBlockTable != NULL) - { - pHeader->BlockTableSize64 = BlockTableSize64; - pHeader->wBlockTablePosHi = (USHORT)(TablePos >> 32); - pHeader->dwBlockTableSize = (DWORD)(BlockTableSize64 / sizeof(TMPQBlock)); - pHeader->dwBlockTablePos = (DWORD)TablePos; - nError = SaveMpqTable(ha, pBlockTable, TablePos, (size_t)BlockTableSize64, pHeader->MD5_BlockTable, MPQ_KEY_BLOCK_TABLE, false); - TablePos += BlockTableSize64; - } - - // Write the hi-block table, if we have any - if(nError == ERROR_SUCCESS && pHiBlockTable != NULL) - { - ULONGLONG ByteOffset = ha->MpqPos + TablePos; - - pHeader->HiBlockTableSize64 = HiBlockTableSize64; - pHeader->HiBlockTablePos64 = TablePos; - BSWAP_ARRAY16_UNSIGNED(pHiBlockTable, HiBlockTableSize64); - - if(!FileStream_Write(ha->pStream, &ByteOffset, pHiBlockTable, (DWORD)HiBlockTableSize64)) - nError = GetLastError(); - TablePos += HiBlockTableSize64; - } - - // Cut the MPQ - if(nError == ERROR_SUCCESS) - { - ULONGLONG FileSize = ha->MpqPos + TablePos; - - if(!FileStream_SetSize(ha->pStream, FileSize)) - nError = GetLastError(); - } - - // Write the MPQ header - if(nError == ERROR_SUCCESS) - { - // Update the size of the archive - pHeader->ArchiveSize64 = TablePos; - pHeader->dwArchiveSize = (DWORD)TablePos; - - // Update the MD5 of the archive header - CalculateDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader); - - // Write the MPQ header to the file - BSWAP_TMPQHEADER(pHeader); - if(!FileStream_Write(ha->pStream, &ha->MpqPos, pHeader, pHeader->dwHeaderSize)) - nError = GetLastError(); - BSWAP_TMPQHEADER(pHeader); - } - - // Clear the changed flag - if(nError == ERROR_SUCCESS) - ha->dwFlags &= ~MPQ_FLAG_CHANGED; - - // Cleanup and exit - if(pHetTable != NULL) - STORM_FREE(pHetTable); - if(pBetTable != NULL) - STORM_FREE(pBetTable); - if(pHashTable != NULL) - STORM_FREE(pHashTable); - if(pBlockTable != NULL) - STORM_FREE(pBlockTable); - if(pHiBlockTable != NULL) - STORM_FREE(pHiBlockTable); - return nError; -} diff --git a/dep/StormLib/src/SCompression.cpp b/dep/StormLib/src/SCompression.cpp deleted file mode 100644 index 5c7432248dc..00000000000 --- a/dep/StormLib/src/SCompression.cpp +++ /dev/null @@ -1,1135 +0,0 @@ -/*****************************************************************************/ -/* SCompression.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* This module serves as a bridge between StormLib code and (de)compression */ -/* functions. All (de)compression calls go (and should only go) through this */ -/* module. No system headers should be included in this module to prevent */ -/* compile-time problems. */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 01.04.03 1.00 Lad The first version of SCompression.cpp */ -/* 19.11.03 1.01 Dan Big endian handling */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local structures - -// Information about the input and output buffers for pklib -typedef struct -{ - char * pbInBuff; // Pointer to input data buffer - char * pbInBuffEnd; // End of the input buffer - char * pbOutBuff; // Pointer to output data buffer - char * pbOutBuffEnd; // Pointer to output data buffer -} TDataInfo; - -// Prototype of the compression function -// Function doesn't return an error. A success means that the size of compressed buffer -// is lower than size of uncompressed buffer. -typedef void (*COMPRESS)( - char * pbOutBuffer, // [out] Pointer to the buffer where the compressed data will be stored - int * pcbOutBuffer, // [in] Pointer to length of the buffer pointed by pbOutBuffer - // [out] Contains length of the compressed data - char * pbInBuffer, // [in] Pointer to the buffer with data to compress - int cbInBuffer, // [in] Length of the buffer pointer by pbInBuffer - int * pCmpType, // [in] Compression-method specific value. ADPCM Setups this for the following Huffman compression - int nCmpLevel); // [in] Compression specific value. ADPCM uses this. Should be set to zero. - -// Prototype of the decompression function -// Returns 1 if success, 0 if failure -typedef int (*DECOMPRESS)( - char * pbOutBuffer, // [out] Pointer to the buffer where to store decompressed data - int * pcbOutBuffer, // [in] Pointer to total size of the buffer pointed by pbOutBuffer - // [out] Contains length of the decompressed data - char * pbInBuffer, // [in] Pointer to data to be decompressed - int cbInBuffer); // [in] Length of the data to be decompressed - -// Table of compression functions -typedef struct -{ - unsigned long uMask; // Compression mask - COMPRESS Compress; // Compression function -} TCompressTable; - -// Table of decompression functions -typedef struct -{ - unsigned long uMask; // Decompression bit - DECOMPRESS Decompress; // Decompression function -} TDecompressTable; - - -/*****************************************************************************/ -/* */ -/* Support for Huffman compression (0x01) */ -/* */ -/*****************************************************************************/ - -// 1500F4C0 -void Compress_huff( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * pCmpType, - int /* nCmpLevel */) -{ - THuffmannTree ht; // Huffmann tree for compression - TOutputStream os; // Output stream - - // Initialize output stream - os.pbOutBuffer = (unsigned char *)pbOutBuffer; - os.cbOutSize = *pcbOutBuffer; - os.pbOutPos = (unsigned char *)pbOutBuffer; - os.dwBitBuff = 0; - os.nBits = 0; - - // Initialize the Huffmann tree for compression - ht.InitTree(true); - - *pcbOutBuffer = ht.DoCompression(&os, (unsigned char *)pbInBuffer, cbInBuffer, *pCmpType); - - // The following code is not necessary to run, because it has no - // effect on the output data. It only clears the huffmann tree, but when - // the tree is on the stack, who cares ? -// ht.UninitTree(); -} - -// 1500F5F0 -int Decompress_huff(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - THuffmannTree ht; - TInputStream is; - - // Initialize input stream - is.pbInBufferEnd = (unsigned char *)pbInBuffer + cbInBuffer; - is.pbInBuffer = (unsigned char *)pbInBuffer; - is.BitBuffer = 0; - is.BitCount = 0; - - // Initialize the Huffmann tree for compression - ht.InitTree(false); - *pcbOutBuffer = ht.DoDecompression((unsigned char *)pbOutBuffer, *pcbOutBuffer, &is); - if(*pcbOutBuffer == 0) - return 0; - - // The following code is not necessary to run, because it has no - // effect on the output data. It only clears the huffmann tree, but when - // the tree is on the stack, who cares ? -// ht.UninitTree(); - return 1; -} - -/******************************************************************************/ -/* */ -/* Support for ZLIB compression (0x02) */ -/* */ -/******************************************************************************/ - -void Compress_ZLIB( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * /* pCmpType */, - int /* nCmpLevel */) -{ - z_stream z; // Stream information for zlib - int windowBits; - int nResult; - - // Fill the stream structure for zlib - z.next_in = (Bytef *)pbInBuffer; - z.avail_in = (uInt)cbInBuffer; - z.total_in = cbInBuffer; - z.next_out = (Bytef *)pbOutBuffer; - z.avail_out = *pcbOutBuffer; - z.total_out = 0; - z.zalloc = NULL; - z.zfree = NULL; - - // Determine the proper window bits (WoW.exe build 12694) - if(cbInBuffer <= 0x100) - windowBits = 8; - else if(cbInBuffer <= 0x200) - windowBits = 9; - else if(cbInBuffer <= 0x400) - windowBits = 10; - else if(cbInBuffer <= 0x800) - windowBits = 11; - else if(cbInBuffer <= 0x1000) - windowBits = 12; - else if(cbInBuffer <= 0x2000) - windowBits = 13; - else if(cbInBuffer <= 0x4000) - windowBits = 14; - else - windowBits = 15; - - // Initialize the compression. - // Storm.dll uses zlib version 1.1.3 - // Wow.exe uses zlib version 1.2.3 - nResult = deflateInit2(&z, - 6, // Compression level used by WoW MPQs - Z_DEFLATED, - windowBits, - 8, - Z_DEFAULT_STRATEGY); - if(nResult == Z_OK) - { - // Call zlib to compress the data - nResult = deflate(&z, Z_FINISH); - - if(nResult == Z_OK || nResult == Z_STREAM_END) - *pcbOutBuffer = z.total_out; - - deflateEnd(&z); - } -} - -int Decompress_ZLIB(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - z_stream z; // Stream information for zlib - int nResult; - - // Fill the stream structure for zlib - z.next_in = (Bytef *)pbInBuffer; - z.avail_in = (uInt)cbInBuffer; - z.total_in = cbInBuffer; - z.next_out = (Bytef *)pbOutBuffer; - z.avail_out = *pcbOutBuffer; - z.total_out = 0; - z.zalloc = NULL; - z.zfree = NULL; - - // Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 - if((nResult = inflateInit(&z)) == 0) - { - // Call zlib to decompress the data - nResult = inflate(&z, Z_FINISH); - *pcbOutBuffer = z.total_out; - inflateEnd(&z); - } - return nResult; -} - -/******************************************************************************/ -/* */ -/* Support functions for PKWARE Data Compression Library compression (0x08) */ -/* */ -/******************************************************************************/ - -// Function loads data from the input buffer. Used by Pklib's "implode" -// and "explode" function as user-defined callback -// Returns number of bytes loaded -// -// char * buf - Pointer to a buffer where to store loaded data -// unsigned int * size - Max. number of bytes to read -// void * param - Custom pointer, parameter of implode/explode - -static unsigned int ReadInputData(char * buf, unsigned int * size, void * param) -{ - TDataInfo * pInfo = (TDataInfo *)param; - unsigned int nMaxAvail = (unsigned int)(pInfo->pbInBuffEnd - pInfo->pbInBuff); - unsigned int nToRead = *size; - - // Check the case when not enough data available - if(nToRead > nMaxAvail) - nToRead = nMaxAvail; - - // Load data and increment offsets - memcpy(buf, pInfo->pbInBuff, nToRead); - pInfo->pbInBuff += nToRead; - assert(pInfo->pbInBuff <= pInfo->pbInBuffEnd); - return nToRead; -} - -// Function for store output data. Used by Pklib's "implode" and "explode" -// as user-defined callback -// -// char * buf - Pointer to data to be written -// unsigned int * size - Number of bytes to write -// void * param - Custom pointer, parameter of implode/explode - -static void WriteOutputData(char * buf, unsigned int * size, void * param) -{ - TDataInfo * pInfo = (TDataInfo *)param; - unsigned int nMaxWrite = (unsigned int)(pInfo->pbOutBuffEnd - pInfo->pbOutBuff); - unsigned int nToWrite = *size; - - // Check the case when not enough space in the output buffer - if(nToWrite > nMaxWrite) - nToWrite = nMaxWrite; - - // Write output data and increments offsets - memcpy(pInfo->pbOutBuff, buf, nToWrite); - pInfo->pbOutBuff += nToWrite; - assert(pInfo->pbOutBuff <= pInfo->pbOutBuffEnd); -} - -static void Compress_PKLIB( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * /* pCmpType */, - int /* nCmpLevel */) -{ - TDataInfo Info; // Data information - char * work_buf = STORM_ALLOC(char, CMP_BUFFER_SIZE);// Pklib's work buffer - unsigned int dict_size; // Dictionary size - unsigned int ctype = CMP_BINARY; // Compression type - - // Fill data information structure - memset(work_buf, 0, CMP_BUFFER_SIZE); - Info.pbInBuff = pbInBuffer; - Info.pbInBuffEnd = pbInBuffer + cbInBuffer; - Info.pbOutBuff = pbOutBuffer; - Info.pbOutBuffEnd = pbOutBuffer + *pcbOutBuffer; - - // - // Set the dictionary size - // - // Diablo I ues fixed dictionary size of CMP_IMPLODE_DICT_SIZE3 - // Starcraft uses the variable dictionary size based on algorithm below - // - - if (cbInBuffer < 0x600) - dict_size = CMP_IMPLODE_DICT_SIZE1; - else if(0x600 <= cbInBuffer && cbInBuffer < 0xC00) - dict_size = CMP_IMPLODE_DICT_SIZE2; - else - dict_size = CMP_IMPLODE_DICT_SIZE3; - - // Do the compression - if(implode(ReadInputData, WriteOutputData, work_buf, &Info, &ctype, &dict_size) == CMP_NO_ERROR) - *pcbOutBuffer = (int)(Info.pbOutBuff - pbOutBuffer); - - STORM_FREE(work_buf); -} - -static int Decompress_PKLIB(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - TDataInfo Info; // Data information - char * work_buf = STORM_ALLOC(char, EXP_BUFFER_SIZE);// Pklib's work buffer - - // Fill data information structure - memset(work_buf, 0, EXP_BUFFER_SIZE); - Info.pbInBuff = pbInBuffer; - Info.pbInBuffEnd = pbInBuffer + cbInBuffer; - Info.pbOutBuff = pbOutBuffer; - Info.pbOutBuffEnd = pbOutBuffer + *pcbOutBuffer; - - // Do the decompression - explode(ReadInputData, WriteOutputData, work_buf, &Info); - - // If PKLIB is unable to decompress the data, return 0; - if(Info.pbOutBuff == pbOutBuffer) - return 0; - - // Give away the number of decompressed bytes - *pcbOutBuffer = (int)(Info.pbOutBuff - pbOutBuffer); - STORM_FREE(work_buf); - return 1; -} - -/******************************************************************************/ -/* */ -/* Support for Bzip2 compression (0x10) */ -/* */ -/******************************************************************************/ - -static void Compress_BZIP2( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * /* pCmpType */, - int /* nCmpLevel */) -{ - bz_stream strm; - int blockSize100k = 9; - int workFactor = 30; - int bzError; - - // Initialize the BZIP2 compression - strm.bzalloc = NULL; - strm.bzfree = NULL; - - // Blizzard uses 9 as blockSize100k, (0x30 as workFactor) - // Last checked on Starcraft II - if(BZ2_bzCompressInit(&strm, blockSize100k, 0, workFactor) == BZ_OK) - { - strm.next_in = pbInBuffer; - strm.avail_in = cbInBuffer; - strm.next_out = pbOutBuffer; - strm.avail_out = *pcbOutBuffer; - - // Perform the compression - for(;;) - { - bzError = BZ2_bzCompress(&strm, (strm.avail_in != 0) ? BZ_RUN : BZ_FINISH); - if(bzError == BZ_STREAM_END || bzError < 0) - break; - } - - // Put the stream into idle state - BZ2_bzCompressEnd(&strm); - - if(bzError > 0) - *pcbOutBuffer = strm.total_out_lo32; - } -} - -static int Decompress_BZIP2(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - bz_stream strm; - int nResult = BZ_OK; - - // Initialize the BZIP2 decompression - strm.bzalloc = NULL; - strm.bzfree = NULL; - if(BZ2_bzDecompressInit(&strm, 0, 0) == BZ_OK) - { - strm.next_in = pbInBuffer; - strm.avail_in = cbInBuffer; - strm.next_out = pbOutBuffer; - strm.avail_out = *pcbOutBuffer; - - // Perform the decompression - while(nResult != BZ_STREAM_END) - { - nResult = BZ2_bzDecompress(&strm); - - // If any error there, break the loop - if(nResult < BZ_OK) - break; - } - - // Put the stream into idle state - BZ2_bzDecompressEnd(&strm); - - // If all succeeded, set the number of output bytes - if(nResult >= BZ_OK) - { - *pcbOutBuffer = strm.total_out_lo32; - return 1; - } - } - - // Something failed, so set number of output bytes to zero - *pcbOutBuffer = 0; - return 1; -} - -/******************************************************************************/ -/* */ -/* Support functions for LZMA compression (0x12) */ -/* */ -/******************************************************************************/ - -#define LZMA_HEADER_SIZE (1 + LZMA_PROPS_SIZE + 8) - -static SRes LZMA_Callback_Progress(void * /* p */, UInt64 /* inSize */, UInt64 /* outSize */) -{ - return SZ_OK; -} - -static void * LZMA_Callback_Alloc(void *p, size_t size) -{ - p = p; - return STORM_ALLOC(BYTE, size); -} - -/* address can be 0 */ -static void LZMA_Callback_Free(void *p, void *address) -{ - p = p; - if(address != NULL) - STORM_FREE(address); -} - -// -// Note: So far, I haven't seen any files compressed by LZMA. -// This code haven't been verified against code ripped from Starcraft II Beta, -// but we know that Starcraft LZMA decompression code is able to decompress -// the data compressed by StormLib. -// - -/*static */ void Compress_LZMA( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * /* pCmpType */, - int /* nCmpLevel */) -{ - ICompressProgress Progress; - CLzmaEncProps props; - ISzAlloc SzAlloc; - Byte * destBuffer; - SizeT destLen = *pcbOutBuffer; - SizeT srcLen = cbInBuffer; - Byte encodedProps[LZMA_PROPS_SIZE]; - size_t encodedPropsSize = LZMA_PROPS_SIZE; - SRes nResult; - - // Fill the callbacks in structures - Progress.Progress = LZMA_Callback_Progress; - SzAlloc.Alloc = LZMA_Callback_Alloc; - SzAlloc.Free = LZMA_Callback_Free; - - // Initialize properties - LzmaEncProps_Init(&props); - - // Perform compression - destBuffer = (Byte *)pbOutBuffer + LZMA_HEADER_SIZE; - destLen = *pcbOutBuffer - LZMA_HEADER_SIZE; - nResult = LzmaEncode(destBuffer, - &destLen, - (Byte *)pbInBuffer, - srcLen, - &props, - encodedProps, - &encodedPropsSize, - 0, - &Progress, - &SzAlloc, - &SzAlloc); - if(nResult != SZ_OK) - return; - - // If we failed to compress the data - if(destLen >= (SizeT)(*pcbOutBuffer - LZMA_HEADER_SIZE)) - return; - - // Write "useFilter" variable. Blizzard MPQ must not use filter. - *pbOutBuffer++ = 0; - - // Copy the encoded properties to the output buffer - memcpy(pbOutBuffer, encodedProps, encodedPropsSize); - pbOutBuffer += encodedPropsSize; - - // Copy the size of the data - *pbOutBuffer++ = (unsigned char)(srcLen >> 0x00); - *pbOutBuffer++ = (unsigned char)(srcLen >> 0x08); - *pbOutBuffer++ = (unsigned char)(srcLen >> 0x10); - *pbOutBuffer++ = (unsigned char)(srcLen >> 0x18); - *pbOutBuffer++ = 0; - *pbOutBuffer++ = 0; - *pbOutBuffer++ = 0; - *pbOutBuffer++ = 0; - - // Give the size of the data to the caller - *pcbOutBuffer = (unsigned int)(destLen + LZMA_HEADER_SIZE); -} - -static int Decompress_LZMA(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - ELzmaStatus LzmaStatus; - ISzAlloc SzAlloc; - Byte * destBuffer = (Byte *)pbOutBuffer; - Byte * srcBuffer = (Byte *)pbInBuffer; - SizeT destLen = *pcbOutBuffer; - SizeT srcLen = cbInBuffer; - SRes nResult; - - // There must be at least 0x0E bytes in the buffer - if(srcLen <= LZMA_HEADER_SIZE) - return 0; - - // We only accept blocks that have no filter used - if(*srcBuffer != 0) - return 0; - - // Fill the callbacks in structures - SzAlloc.Alloc = LZMA_Callback_Alloc; - SzAlloc.Free = LZMA_Callback_Free; - - // Perform compression - srcLen = cbInBuffer - LZMA_HEADER_SIZE; - nResult = LzmaDecode(destBuffer, - &destLen, - srcBuffer + LZMA_HEADER_SIZE, - &srcLen, - srcBuffer + 1, - LZMA_PROPS_SIZE, - LZMA_FINISH_END, - &LzmaStatus, - &SzAlloc); - if(nResult != SZ_OK) - return 0; - - *pcbOutBuffer = (unsigned int)destLen; - return 1; -} - -/******************************************************************************/ -/* */ -/* Support functions for SPARSE compression (0x20) */ -/* */ -/******************************************************************************/ - -void Compress_SPARSE( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * /* pCmpType */, - int /* nCmpLevel */) -{ - CompressSparse((unsigned char *)pbOutBuffer, pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer); -} - -int Decompress_SPARSE(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - return DecompressSparse((unsigned char *)pbOutBuffer, pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer); -} - -/******************************************************************************/ -/* */ -/* Support for ADPCM mono compression (0x40) */ -/* */ -/******************************************************************************/ - -static void Compress_ADPCM_mono( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * pCmpType, - int nCmpLevel) -{ - // Prepare the compression level for Huffmann compression, - // which will be called as next step - if(0 < nCmpLevel && nCmpLevel <= 2) - { - nCmpLevel = 4; - *pCmpType = 6; - } - else if(nCmpLevel == 3) - { - nCmpLevel = 6; - *pCmpType = 8; - } - else - { - nCmpLevel = 5; - *pCmpType = 7; - } - *pcbOutBuffer = CompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (short *)pbInBuffer, cbInBuffer, 1, nCmpLevel); -} - -static int Decompress_ADPCM_mono(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - *pcbOutBuffer = DecompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer, 1); - return 1; -} - -/******************************************************************************/ -/* */ -/* Support for ADPCM stereo compression (0x80) */ -/* */ -/******************************************************************************/ - -static void Compress_ADPCM_stereo( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - int * pCmpType, - int nCmpLevel) -{ - // Prepare the compression level for Huffmann compression, - // which will be called as next step - if(0 < nCmpLevel && nCmpLevel <= 2) - { - nCmpLevel = 4; - *pCmpType = 6; - } - else if(nCmpLevel == 3) - { - nCmpLevel = 6; - *pCmpType = 8; - } - else - { - nCmpLevel = 5; - *pCmpType = 7; - } - *pcbOutBuffer = CompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (short *)pbInBuffer, cbInBuffer, 2, nCmpLevel); -} - -static int Decompress_ADPCM_stereo(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - *pcbOutBuffer = DecompressADPCM((unsigned char *)pbOutBuffer, *pcbOutBuffer, (unsigned char *)pbInBuffer, cbInBuffer, 2); - return 1; -} - -/*****************************************************************************/ -/* */ -/* SCompImplode */ -/* */ -/*****************************************************************************/ - -int WINAPI SCompImplode(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - int cbOutBuffer = *pcbOutBuffer; - - // Check for valid parameters - if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pbOutBuffer || !pbInBuffer) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - // Perform the compression - Compress_PKLIB(pbOutBuffer, &cbOutBuffer, pbInBuffer, cbInBuffer, NULL, 0); - - // If the compression was unsuccessful, copy the data as-is - if(cbOutBuffer >= *pcbOutBuffer) - { - memcpy(pbOutBuffer, pbInBuffer, cbInBuffer); - cbOutBuffer = *pcbOutBuffer; - } - - *pcbOutBuffer = cbOutBuffer; - return 1; -} - -/*****************************************************************************/ -/* */ -/* SCompExplode */ -/* */ -/*****************************************************************************/ - -int WINAPI SCompExplode(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer) -{ - int cbOutBuffer = *pcbOutBuffer; - - // Check for valid parameters - if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pbOutBuffer || !pbInBuffer) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - // If the input length is the same as output length, do nothing. - if(cbInBuffer == cbOutBuffer) - { - // If the buffers are equal, don't copy anything. - if(pbInBuffer == pbOutBuffer) - return 1; - - memcpy(pbOutBuffer, pbInBuffer, cbInBuffer); - return 1; - } - - // Perform decompression - if(!Decompress_PKLIB(pbOutBuffer, &cbOutBuffer, pbInBuffer, cbInBuffer)) - { - SetLastError(ERROR_FILE_CORRUPT); - return false; - } - - *pcbOutBuffer = cbOutBuffer; - return 1; -} - -/*****************************************************************************/ -/* */ -/* SCompCompress */ -/* */ -/*****************************************************************************/ - -// This table contains compress functions which can be applied to -// uncompressed data. Each bit means the corresponding -// compression method/function must be applied. -// -// WAVes compression Data compression -// ------------------ ------------------- -// 1st sector - 0x08 0x08 (D, HF, W2, SC, D2) -// Next sectors - 0x81 0x02 (W3) - -static TCompressTable cmp_table[] = -{ - {MPQ_COMPRESSION_SPARSE, Compress_SPARSE}, // Sparse compression - {MPQ_COMPRESSION_ADPCM_MONO, Compress_ADPCM_mono}, // IMA ADPCM mono compression - {MPQ_COMPRESSION_ADPCM_STEREO, Compress_ADPCM_stereo}, // IMA ADPCM stereo compression - {MPQ_COMPRESSION_HUFFMANN, Compress_huff}, // Huffmann compression - {MPQ_COMPRESSION_ZLIB, Compress_ZLIB}, // Compression with the "zlib" library - {MPQ_COMPRESSION_PKWARE, Compress_PKLIB}, // Compression with Pkware DCL - {MPQ_COMPRESSION_BZIP2, Compress_BZIP2} // Compression Bzip2 library -}; - -int WINAPI SCompCompress( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer, - unsigned uCompressionMask, - int nCmpType, - int nCmpLevel) -{ - COMPRESS CompressFuncArray[0x10]; // Array of compression functions, applied sequentially - unsigned char CompressByte[0x10]; // CompressByte for each method in the CompressFuncArray array - char * pbWorkBuffer = NULL; // Temporary storage for decompressed data - char * pbOutput = pbOutBuffer; // Current output buffer - char * pbInput = pbInBuffer; // Current input buffer - int nCompressCount = 0; - int nCompressIndex = 0; - int nAtLeastOneCompressionDone = 0; - int cbOutBuffer = 0; - int cbInLength = cbInBuffer; - int nResult = 1; - - // Check for valid parameters - if(!pcbOutBuffer || *pcbOutBuffer < cbInBuffer || !pbOutBuffer || !pbInBuffer) - { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - // Zero input length brings zero output length - if(cbInBuffer == 0) - { - *pcbOutBuffer = 0; - return true; - } - - // Setup the compression function array - if(uCompressionMask == MPQ_COMPRESSION_LZMA) - { - CompressFuncArray[0] = Compress_LZMA; - CompressByte[0] = (char)uCompressionMask; - nCompressCount = 1; - } - else - { - // Fill the compressions array - for(size_t i = 0; i < (sizeof(cmp_table) / sizeof(TCompressTable)); i++) - { - // If the mask agrees, insert the compression function to the array - if(uCompressionMask & cmp_table[i].uMask) - { - CompressFuncArray[nCompressCount] = cmp_table[i].Compress; - CompressByte[nCompressCount] = (unsigned char)cmp_table[i].uMask; - uCompressionMask &= ~cmp_table[i].uMask; - nCompressCount++; - } - } - - // If at least one of the compressions remaing unknown, return an error - if(uCompressionMask != 0) - { - SetLastError(ERROR_NOT_SUPPORTED); - return 0; - } - } - - // If there is at least one compression, do it - if(nCompressCount > 0) - { - // If we need to do more than 1 compression, allocate intermediate buffer - if(nCompressCount > 1) - { - pbWorkBuffer = STORM_ALLOC(char, *pcbOutBuffer); - if(pbWorkBuffer == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - } - - // Get the current compression index - nCompressIndex = nCompressCount - 1; - - // Perform all compressions in the array - for(int i = 0; i < nCompressCount; i++) - { - // Choose the proper output buffer - pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer; - nCompressIndex--; - - // Perform the (next) compression - // Note that if the compression method is unable to compress the input data block - // by at least 2 bytes, we consider it as failure and will use source data instead - cbOutBuffer = *pcbOutBuffer - 1; - CompressFuncArray[i](pbOutput + 1, &cbOutBuffer, pbInput, cbInLength, &nCmpType, nCmpLevel); - - // If the compression failed, we copy the input buffer as-is. - // Note that there is one extra byte at the end of the intermediate buffer, so it should be OK - if(cbOutBuffer > (cbInLength - 2)) - { - memcpy(pbOutput + nAtLeastOneCompressionDone, pbInput, cbInLength); - cbOutBuffer = cbInLength; - } - else - { - // Remember that we have done at least one compression - nAtLeastOneCompressionDone = 1; - uCompressionMask |= CompressByte[i]; - } - - // Now point input buffer to the output buffer - pbInput = pbOutput + nAtLeastOneCompressionDone; - cbInLength = cbOutBuffer; - } - - // If at least one compression succeeded, put the compression - // mask to the begin of the output buffer - if(nAtLeastOneCompressionDone) - *pbOutBuffer = (char)uCompressionMask; - *pcbOutBuffer = cbOutBuffer + nAtLeastOneCompressionDone; - } - else - { - memcpy(pbOutBuffer, pbInBuffer, cbInBuffer); - *pcbOutBuffer = cbInBuffer; - } - - // Cleanup and return - if(pbWorkBuffer != NULL) - STORM_FREE(pbWorkBuffer); - return nResult; -} - -/*****************************************************************************/ -/* */ -/* SCompDecompress */ -/* */ -/*****************************************************************************/ - -// This table contains decompress functions which can be applied to -// uncompressed data. The compression mask is stored in the first byte -// of compressed data -static TDecompressTable dcmp_table[] = -{ - {MPQ_COMPRESSION_BZIP2, Decompress_BZIP2}, // Decompression with Bzip2 library - {MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library - {MPQ_COMPRESSION_ZLIB, Decompress_ZLIB}, // Decompression with the "zlib" library - {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression - {MPQ_COMPRESSION_ADPCM_STEREO, Decompress_ADPCM_stereo}, // IMA ADPCM stereo decompression - {MPQ_COMPRESSION_ADPCM_MONO, Decompress_ADPCM_mono}, // IMA ADPCM mono decompression - {MPQ_COMPRESSION_SPARSE, Decompress_SPARSE} // Sparse decompression -}; - -int WINAPI SCompDecompress( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer) -{ - char * pbWorkBuffer = NULL; // Temporary storage for decompressed data - char * pbOutput = pbOutBuffer; // Where to store decompressed data - char * pbInput; // Where to store decompressed data - unsigned uCompressionMask; // Decompressions applied to the data - unsigned uCompressionCopy; // Decompressions applied to the data - int cbOutBuffer = *pcbOutBuffer; // Current size of the output buffer - int cbInLength; // Current size of the input buffer - int nCompressCount = 0; // Number of compressions to be applied - int nCompressIndex = 0; - int nResult = 1; - - // Verify buffer sizes - if(cbOutBuffer < cbInBuffer || cbInBuffer < 1) - return 0; - - // If the input length is the same as output length, do nothing. - if(cbOutBuffer == cbInBuffer) - { - // If the buffers are equal, don't copy anything. - if(pbInBuffer != pbOutBuffer) - memcpy(pbOutBuffer, pbInBuffer, cbInBuffer); - return 1; - } - - // Get applied compression types and decrement data length - uCompressionMask = uCompressionCopy = (unsigned char)*pbInBuffer++; - cbInBuffer--; - - // Get current compressed data and length of it - pbInput = pbInBuffer; - cbInLength = cbInBuffer; - - // This compression function doesn't support LZMA - assert(uCompressionMask != MPQ_COMPRESSION_LZMA); - - // Parse the compression mask - for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++) - { - // If the mask agrees, insert the compression function to the array - if(uCompressionMask & dcmp_table[i].uMask) - { - uCompressionCopy &= ~dcmp_table[i].uMask; - nCompressCount++; - } - } - - // If at least one of the compressions remaing unknown, return an error - if(nCompressCount == 0 || uCompressionCopy != 0) - { - SetLastError(ERROR_NOT_SUPPORTED); - return 0; - } - - // If there is more than one compression, we have to allocate extra buffer - if(nCompressCount > 1) - { - pbWorkBuffer = STORM_ALLOC(char, cbOutBuffer); - if(pbWorkBuffer == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - } - - // Get the current compression index - nCompressIndex = nCompressCount - 1; - - // Apply all decompressions - for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++) - { - // Perform the (next) decompression - if(uCompressionMask & dcmp_table[i].uMask) - { - // Get the correct output buffer - pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer; - nCompressIndex--; - - // Perform the decompression - cbOutBuffer = *pcbOutBuffer; - nResult = dcmp_table[i].Decompress(pbOutput, &cbOutBuffer, pbInput, cbInLength); - if(nResult == 0 || cbOutBuffer == 0) - { - SetLastError(ERROR_FILE_CORRUPT); - nResult = 0; - break; - } - - // Switch buffers - cbInLength = cbOutBuffer; - pbInput = pbOutput; - } - } - - // Put the length of the decompressed data to the output buffer - *pcbOutBuffer = cbOutBuffer; - - // Cleanup and return - if(pbWorkBuffer != NULL) - STORM_FREE(pbWorkBuffer); - return nResult; -} - -int WINAPI SCompDecompress2( - char * pbOutBuffer, - int * pcbOutBuffer, - char * pbInBuffer, - int cbInBuffer) -{ - DECOMPRESS pfnDecompress1 = NULL; - DECOMPRESS pfnDecompress2 = NULL; - char * pbWorkBuffer = pbOutBuffer; - int cbWorkBuffer = *pcbOutBuffer; - int nResult; - char CompressionMethod; - - // Verify buffer sizes - if(*pcbOutBuffer < cbInBuffer || cbInBuffer < 1) - return 0; - - // If the outputbuffer is as big as input buffer, just copy the block - if(*pcbOutBuffer == cbInBuffer) - { - if(pbOutBuffer != pbInBuffer) - memcpy(pbOutBuffer, pbInBuffer, cbInBuffer); - return 1; - } - - // Get the compression methods - CompressionMethod = *pbInBuffer++; - cbInBuffer--; - - // We only recognize a fixed set of compression methods - switch((unsigned char)CompressionMethod) - { - case MPQ_COMPRESSION_ZLIB: - pfnDecompress1 = Decompress_ZLIB; - break; - - case MPQ_COMPRESSION_PKWARE: - pfnDecompress1 = Decompress_PKLIB; - break; - - case MPQ_COMPRESSION_BZIP2: - pfnDecompress1 = Decompress_BZIP2; - break; - - case MPQ_COMPRESSION_LZMA: - pfnDecompress1 = Decompress_LZMA; - break; - - case MPQ_COMPRESSION_SPARSE: - pfnDecompress1 = Decompress_SPARSE; - break; - - case (MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_ZLIB): - pfnDecompress1 = Decompress_ZLIB; - pfnDecompress2 = Decompress_SPARSE; - break; - - case (MPQ_COMPRESSION_SPARSE | MPQ_COMPRESSION_BZIP2): - pfnDecompress1 = Decompress_BZIP2; - pfnDecompress2 = Decompress_SPARSE; - break; - - // - // Note: Any combination including MPQ_COMPRESSION_ADPCM_MONO, - // MPQ_COMPRESSION_ADPCM_STEREO or MPQ_COMPRESSION_HUFFMANN - // is not supported by newer MPQs. - // - - default: - SetLastError(ERROR_FILE_CORRUPT); - return 0; - } - - // If we have to use two decompressions, allocate temporary buffer - if(pfnDecompress2 != NULL) - { - pbWorkBuffer = STORM_ALLOC(char, *pcbOutBuffer); - if(pbWorkBuffer == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - } - - // Apply the first decompression method - nResult = pfnDecompress1(pbWorkBuffer, &cbWorkBuffer, pbInBuffer, cbInBuffer); - - // Apply the second decompression method, if any - if(pfnDecompress2 != NULL && nResult != 0) - { - cbInBuffer = cbWorkBuffer; - cbWorkBuffer = *pcbOutBuffer; - nResult = pfnDecompress2(pbOutBuffer, &cbWorkBuffer, pbWorkBuffer, cbInBuffer); - } - - // Supply the output buffer size - *pcbOutBuffer = cbWorkBuffer; - - // Free temporary buffer - if(pbWorkBuffer != pbOutBuffer) - STORM_FREE(pbWorkBuffer); - - if(nResult == 0) - SetLastError(ERROR_FILE_CORRUPT); - return nResult; -} diff --git a/dep/StormLib/src/SFileAddFile.cpp b/dep/StormLib/src/SFileAddFile.cpp deleted file mode 100644 index dda47370bd1..00000000000 --- a/dep/StormLib/src/SFileAddFile.cpp +++ /dev/null @@ -1,1286 +0,0 @@ -/*****************************************************************************/ -/* SFileAddFile.cpp Copyright (c) Ladislav Zezula 2010 */ -/*---------------------------------------------------------------------------*/ -/* MPQ Editing functions */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 27.03.10 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local structures - -#define FILE_SIGNATURE_RIFF 0x46464952 -#define FILE_SIGNATURE_WAVE 0x45564157 -#define FILE_SIGNATURE_FMT 0x20746D66 -#define AUDIO_FORMAT_PCM 1 - -typedef struct _WAVE_FILE_HEADER -{ - DWORD dwChunkId; // 0x52494646 ("RIFF") - DWORD dwChunkSize; // Size of that chunk, in bytes - DWORD dwFormat; // Must be 0x57415645 ("WAVE") - - // Format sub-chunk - DWORD dwSubChunk1Id; // 0x666d7420 ("fmt ") - DWORD dwSubChunk1Size; // 0x16 for PCM - USHORT wAudioFormat; // 1 = PCM. Other value means some sort of compression - USHORT wChannels; // Number of channels - DWORD dwSampleRate; // 8000, 44100, etc. - DWORD dwBytesRate; // SampleRate * NumChannels * BitsPerSample/8 - USHORT wBlockAlign; // NumChannels * BitsPerSample/8 - USHORT wBitsPerSample; // 8 bits = 8, 16 bits = 16, etc. - - // Followed by "data" sub-chunk (we don't care) -} WAVE_FILE_HEADER, *PWAVE_FILE_HEADER; - -//----------------------------------------------------------------------------- -// Local variables - -// Data compression for SFileAddFile -// Kept here for compatibility with code that was created with StormLib version < 6.50 -static DWORD DefaultDataCompression = MPQ_COMPRESSION_PKWARE; - -static SFILE_ADDFILE_CALLBACK AddFileCB = NULL; -static void * pvUserData = NULL; - -//----------------------------------------------------------------------------- -// MPQ write data functions - -#define LOSSY_COMPRESSION_MASK (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN) - -static int IsWaveFile( - LPBYTE pbFileData, - DWORD cbFileData, - LPDWORD pdwChannels) -{ - PWAVE_FILE_HEADER pWaveHdr = (PWAVE_FILE_HEADER)pbFileData; - - if(cbFileData > sizeof(WAVE_FILE_HEADER)) - { - if(pWaveHdr->dwChunkId == FILE_SIGNATURE_RIFF && pWaveHdr->dwFormat == FILE_SIGNATURE_WAVE) - { - if(pWaveHdr->dwSubChunk1Id == FILE_SIGNATURE_FMT && pWaveHdr->wAudioFormat == AUDIO_FORMAT_PCM) - { - *pdwChannels = pWaveHdr->wChannels; - return true; - } - } - } - - return false; -} - - -static int WriteDataToMpqFile( - TMPQArchive * ha, - TMPQFile * hf, - LPBYTE pbFileData, - DWORD dwDataSize, - DWORD dwCompression) -{ - TFileEntry * pFileEntry = hf->pFileEntry; - ULONGLONG ByteOffset; - LPBYTE pbCompressed = NULL; // Compressed (target) data - LPBYTE pbToWrite = NULL; // Data to write to the file - int nCompressionLevel = -1; // ADPCM compression level (only used for wave files) - int nError = ERROR_SUCCESS; - - // If the caller wants ADPCM compression, we will set wave compression level to 4, - // which corresponds to medium quality - if(dwCompression & LOSSY_COMPRESSION_MASK) - nCompressionLevel = 4; - - // Make sure that the caller won't overrun the previously initiated file size - assert(hf->dwFilePos + dwDataSize <= pFileEntry->dwFileSize); - assert(hf->dwSectorCount != 0); - assert(hf->pbFileSector != NULL); - if((hf->dwFilePos + dwDataSize) > pFileEntry->dwFileSize) - return ERROR_DISK_FULL; - pbToWrite = hf->pbFileSector; - - // Now write all data to the file sector buffer - if(nError == ERROR_SUCCESS) - { - DWORD dwBytesInSector = hf->dwFilePos % hf->dwSectorSize; - DWORD dwSectorIndex = hf->dwFilePos / hf->dwSectorSize; - DWORD dwBytesToCopy; - - // Process all data. - while(dwDataSize != 0) - { - dwBytesToCopy = dwDataSize; - - // Check for sector overflow - if(dwBytesToCopy > (hf->dwSectorSize - dwBytesInSector)) - dwBytesToCopy = (hf->dwSectorSize - dwBytesInSector); - - // Copy the data to the file sector - memcpy(hf->pbFileSector + dwBytesInSector, pbFileData, dwBytesToCopy); - dwBytesInSector += dwBytesToCopy; - pbFileData += dwBytesToCopy; - dwDataSize -= dwBytesToCopy; - - // Update the file position - hf->dwFilePos += dwBytesToCopy; - - // If the current sector is full, or if the file is already full, - // then write the data to the MPQ - if(dwBytesInSector >= hf->dwSectorSize || hf->dwFilePos >= pFileEntry->dwFileSize) - { - // Set the position in the file - ByteOffset = hf->RawFilePos + pFileEntry->dwCmpSize; - - // Update CRC32 and MD5 of the file - md5_process((hash_state *)hf->hctx, hf->pbFileSector, dwBytesInSector); - hf->dwCrc32 = crc32(hf->dwCrc32, hf->pbFileSector, dwBytesInSector); - - // Compress the file sector, if needed - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED) - { - int nOutBuffer = (int)dwBytesInSector; - int nInBuffer = (int)dwBytesInSector; - - // If the file is compressed, allocate buffer for the compressed data. - // Note that we allocate buffer that is a bit longer than sector size, - // for case if the compression method performs a buffer overrun - if(pbCompressed == NULL) - { - pbToWrite = pbCompressed = STORM_ALLOC(BYTE, hf->dwSectorSize + 0x100); - if(pbCompressed == NULL) - { - nError = ERROR_NOT_ENOUGH_MEMORY; - break; - } - } - - // - // Note that both SCompImplode and SCompCompress give original buffer, - // if they are unable to comperss the data. - // - - if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) - { - SCompImplode((char *)pbCompressed, - &nOutBuffer, - (char *)hf->pbFileSector, - nInBuffer); - } - - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) - { - SCompCompress((char *)pbCompressed, - &nOutBuffer, - (char *)hf->pbFileSector, - nInBuffer, - (unsigned)dwCompression, - 0, - nCompressionLevel); - } - - // Update sector positions - dwBytesInSector = nOutBuffer; - if(hf->SectorOffsets != NULL) - hf->SectorOffsets[dwSectorIndex+1] = hf->SectorOffsets[dwSectorIndex] + dwBytesInSector; - - // We have to calculate sector CRC, if enabled - if(hf->SectorChksums != NULL) - hf->SectorChksums[dwSectorIndex] = adler32(0, pbCompressed, nOutBuffer); - } - - // Encrypt the sector, if necessary - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - { - BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector); - EncryptMpqBlock(pbToWrite, dwBytesInSector, hf->dwFileKey + dwSectorIndex); - BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector); - } - - // Write the file sector - if(!FileStream_Write(ha->pStream, &ByteOffset, pbToWrite, dwBytesInSector)) - { - nError = GetLastError(); - break; - } - - // Call the compact callback, if any - if(AddFileCB != NULL) - AddFileCB(pvUserData, hf->dwFilePos, hf->dwDataSize, false); - - // Update the compressed file size - pFileEntry->dwCmpSize += dwBytesInSector; - dwBytesInSector = 0; - dwSectorIndex++; - } - } - } - - // Cleanup - if(pbCompressed != NULL) - STORM_FREE(pbCompressed); - return nError; -} - -//----------------------------------------------------------------------------- -// Recrypts file data for file renaming - -static int RecryptFileData( - TMPQArchive * ha, - TMPQFile * hf, - const char * szFileName, - const char * szNewFileName) -{ - ULONGLONG RawFilePos; - TFileEntry * pFileEntry = hf->pFileEntry; - DWORD dwBytesToRecrypt = pFileEntry->dwCmpSize; - DWORD dwOldKey; - DWORD dwNewKey; - int nError = ERROR_SUCCESS; - - // The file must be encrypted - assert(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED); - - // File decryption key is calculated from the plain name - szNewFileName = GetPlainFileNameA(szNewFileName); - szFileName = GetPlainFileNameA(szFileName); - - // Calculate both file keys - dwOldKey = DecryptFileKey(szFileName, pFileEntry->ByteOffset, pFileEntry->dwFileSize, pFileEntry->dwFlags); - dwNewKey = DecryptFileKey(szNewFileName, pFileEntry->ByteOffset, pFileEntry->dwFileSize, pFileEntry->dwFlags); - - // Incase the keys are equal, don't recrypt the file - if(dwNewKey == dwOldKey) - return ERROR_SUCCESS; - hf->dwFileKey = dwOldKey; - - // Calculate the raw position of the file in the archive - hf->MpqFilePos = pFileEntry->ByteOffset; - hf->RawFilePos = ha->MpqPos + hf->MpqFilePos; - - // Allocate buffer for file transfer - nError = AllocateSectorBuffer(hf); - if(nError != ERROR_SUCCESS) - return nError; - - // Also allocate buffer for sector offsets - // Note: Don't load sector checksums, we don't need to recrypt them - nError = AllocateSectorOffsets(hf, true); - if(nError != ERROR_SUCCESS) - return nError; - - // If we have sector offsets, recrypt these as well - if(hf->SectorOffsets != NULL) - { - // Allocate secondary buffer for sectors copy - DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]); - DWORD dwSectorOffsLen = hf->SectorOffsets[0]; - - if(SectorOffsetsCopy == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Recrypt the array of sector offsets - memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen); - EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwNewKey - 1); - BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen); - - // Write the recrypted array back - if(!FileStream_Write(ha->pStream, &hf->RawFilePos, SectorOffsetsCopy, dwSectorOffsLen)) - nError = GetLastError(); - STORM_FREE(SectorOffsetsCopy); - } - - // Now we have to recrypt all file sectors. We do it without - // recompression, because recompression is not necessary in this case - if(nError == ERROR_SUCCESS) - { - for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++) - { - DWORD dwRawDataInSector = hf->dwSectorSize; - DWORD dwRawByteOffset = dwSector * hf->dwSectorSize; - - // Last sector: If there is not enough bytes remaining in the file, cut the raw size - if(dwRawDataInSector > dwBytesToRecrypt) - dwRawDataInSector = dwBytesToRecrypt; - - // Fix the raw data length if the file is compressed - if(hf->SectorOffsets != NULL) - { - dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector]; - dwRawByteOffset = hf->SectorOffsets[dwSector]; - } - - // Calculate the raw file offset of the file sector - CalculateRawSectorOffset(RawFilePos, hf, dwRawByteOffset); - - // Read the file sector - if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector)) - { - nError = GetLastError(); - break; - } - - // If necessary, re-encrypt the sector - // Note: Recompression is not necessary here. Unlike encryption, - // the compression does not depend on the position of the file in MPQ. - BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); - DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwOldKey + dwSector); - EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwNewKey + dwSector); - BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); - - // Write the sector back - if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector)) - { - nError = GetLastError(); - break; - } - - // Decrement number of bytes remaining - dwBytesToRecrypt -= hf->dwSectorSize; - } - } - - return nError; -} - -//----------------------------------------------------------------------------- -// Support functions for adding files to the MPQ - -int SFileAddFile_Init( - TMPQArchive * ha, - const char * szFileName, - ULONGLONG FileTime, - DWORD dwFileSize, - LCID lcLocale, - DWORD dwFlags, - TMPQFile ** phf) -{ - TFileEntry * pFileEntry = NULL; - ULONGLONG TempPos; // For various file offset calculations - TMPQFile * hf = NULL; // File structure for newly added file - int nError = ERROR_SUCCESS; - - // - // Note: This is an internal function so no validity checks are done. - // It is the caller's responsibility to make sure that no invalid - // flags get to this point - // - - // Sestor CRC is not allowed with single unit files - if(dwFlags & MPQ_FILE_SINGLE_UNIT) - dwFlags &= ~MPQ_FILE_SECTOR_CRC; - - // Sector CRC is not allowed if the file is not compressed - if(!(dwFlags & MPQ_FILE_COMPRESSED)) - dwFlags &= ~MPQ_FILE_SECTOR_CRC; - - // Fix Key is not allowed if the file is not enrypted - if(!(dwFlags & MPQ_FILE_ENCRYPTED)) - dwFlags &= ~MPQ_FILE_FIX_KEY; - - // If the MPQ is of version 3.0 or higher, we ignore file locale. - // This is because HET and BET tables have no known support for it - if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3) - lcLocale = 0; - - // Allocate the TMPQFile entry for newly added file - hf = CreateMpqFile(ha); - if(hf == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - - // Find a free space in the MPQ, as well as free block table entry - if(nError == ERROR_SUCCESS) - { - // Find the position where the file will be stored - FindFreeMpqSpace(ha, &hf->MpqFilePos); - hf->RawFilePos = ha->MpqPos + hf->MpqFilePos; - hf->bIsWriteHandle = true; - - // Sanity check: The MPQ must be marked as changed at this point - assert((ha->dwFlags & MPQ_FLAG_CHANGED) != 0); - - // When format V1, the size of the archive cannot exceed 4 GB - if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) - { - TempPos = hf->MpqFilePos + dwFileSize; - TempPos += ha->pHeader->dwHashTableSize * sizeof(TMPQHash); - TempPos += ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock); - TempPos += ha->pHeader->dwBlockTableSize * sizeof(USHORT); - if((TempPos >> 32) != 0) - nError = ERROR_DISK_FULL; - } - } - - // Allocate file entry in the MPQ - if(nError == ERROR_SUCCESS) - { - // Check if the file already exists in the archive - pFileEntry = GetFileEntryExact(ha, szFileName, lcLocale); - if(pFileEntry == NULL) - { - pFileEntry = AllocateFileEntry(ha, szFileName, lcLocale); - if(pFileEntry == NULL) - nError = ERROR_DISK_FULL; - } - else - { - // If the file exists and "replace existing" is not set, fail it - if((dwFlags & MPQ_FILE_REPLACEEXISTING) == 0) - nError = ERROR_ALREADY_EXISTS; - - // If the file entry already contains a file - // and it is a pseudo-name, replace it - if(nError == ERROR_SUCCESS) - { - AllocateFileName(pFileEntry, szFileName); - } - } - } - - // - // At this point, the file name in file entry must be non-NULL - // - - // Create key for file encryption - if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_ENCRYPTED)) - { - hf->dwFileKey = DecryptFileKey(szFileName, hf->MpqFilePos, dwFileSize, dwFlags); - } - - if(nError == ERROR_SUCCESS) - { - // Initialize the hash entry for the file - hf->pFileEntry = pFileEntry; - hf->dwDataSize = dwFileSize; - - // Initialize the block table entry for the file - pFileEntry->ByteOffset = hf->MpqFilePos; - pFileEntry->dwFileSize = dwFileSize; - pFileEntry->dwCmpSize = 0; - pFileEntry->dwFlags = dwFlags | MPQ_FILE_EXISTS; - pFileEntry->lcLocale = (USHORT)lcLocale; - - // Initialize the file time, CRC32 and MD5 - assert(sizeof(hf->hctx) >= sizeof(hash_state)); - memset(pFileEntry->md5, 0, MD5_DIGEST_SIZE); - md5_init((hash_state *)hf->hctx); - pFileEntry->dwCrc32 = crc32(0, Z_NULL, 0); - - // If the caller gave us a file time, use it. - pFileEntry->FileTime = FileTime; - - // Call the callback, if needed - if(AddFileCB != NULL) - AddFileCB(pvUserData, 0, hf->dwDataSize, false); - } - - // If an error occured, remember it - if(nError != ERROR_SUCCESS) - hf->bErrorOccured = true; - *phf = hf; - return nError; -} - -int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD dwCompression) -{ - TMPQArchive * ha; - TFileEntry * pFileEntry; - int nError = ERROR_SUCCESS; - - // Don't bother if the caller gave us zero size - if(pvData == NULL || dwSize == 0) - return ERROR_SUCCESS; - - // Get pointer to the MPQ archive - pFileEntry = hf->pFileEntry; - ha = hf->ha; - - // Allocate file buffers - if(hf->pbFileSector == NULL) - { - ULONGLONG RawFilePos = hf->RawFilePos; - - // Allocate buffer for file sector - nError = AllocateSectorBuffer(hf); - if(nError != ERROR_SUCCESS) - { - hf->bErrorOccured = true; - return nError; - } - - // Allocate patch info, if the data is patch - if(hf->pPatchInfo == NULL && IsIncrementalPatchFile(pvData, dwSize, &hf->dwPatchedFileSize)) - { - // Set the MPQ_FILE_PATCH_FILE flag - hf->pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE; - - // Allocate the patch info - nError = AllocatePatchInfo(hf, false); - if(nError != ERROR_SUCCESS) - { - hf->bErrorOccured = true; - return nError; - } - } - - // Allocate sector offsets - if(hf->SectorOffsets == NULL) - { - nError = AllocateSectorOffsets(hf, false); - if(nError != ERROR_SUCCESS) - { - hf->bErrorOccured = true; - return nError; - } - } - - // Create array of sector checksums - if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC)) - { - nError = AllocateSectorChecksums(hf, false); - if(nError != ERROR_SUCCESS) - { - hf->bErrorOccured = true; - return nError; - } - } - - // Pre-save the patch info, if any - if(hf->pPatchInfo != NULL) - { - if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pPatchInfo, hf->pPatchInfo->dwLength)) - nError = GetLastError(); - - pFileEntry->dwCmpSize += hf->pPatchInfo->dwLength; - RawFilePos += hf->pPatchInfo->dwLength; - } - - // Pre-save the sector offset table, just to reserve space in the file. - // Note that we dont need to swap the sector positions, nor encrypt the table - // at the moment, as it will be written again after writing all file sectors. - if(hf->SectorOffsets != NULL) - { - if(!FileStream_Write(ha->pStream, &RawFilePos, hf->SectorOffsets, hf->SectorOffsets[0])) - nError = GetLastError(); - - pFileEntry->dwCmpSize += hf->SectorOffsets[0]; - RawFilePos += hf->SectorOffsets[0]; - } - } - - // Write the MPQ data to the file - if(nError == ERROR_SUCCESS) - nError = WriteDataToMpqFile(ha, hf, (LPBYTE)pvData, dwSize, dwCompression); - - // If it succeeded and we wrote all the file data, - // we need to re-save sector offset table - if(nError == ERROR_SUCCESS) - { - if(hf->dwFilePos >= pFileEntry->dwFileSize) - { - // Finish calculating CRC32 - hf->pFileEntry->dwCrc32 = hf->dwCrc32; - - // Finish calculating MD5 - md5_done((hash_state *)hf->hctx, hf->pFileEntry->md5); - - // If we also have sector checksums, write them to the file - if(hf->SectorChksums != NULL) - { - nError = WriteSectorChecksums(hf); - if(nError != ERROR_SUCCESS) - hf->bErrorOccured = true; - } - - // Now write patch info - if(hf->pPatchInfo != NULL) - { - memcpy(hf->pPatchInfo->md5, hf->pFileEntry->md5, MD5_DIGEST_SIZE); - hf->pPatchInfo->dwDataSize = hf->pFileEntry->dwFileSize; - hf->pFileEntry->dwFileSize = hf->dwPatchedFileSize; - nError = WritePatchInfo(hf); - if(nError != ERROR_SUCCESS) - hf->bErrorOccured = true; - } - - // Now write sector offsets to the file - if(hf->SectorOffsets != NULL) - { - nError = WriteSectorOffsets(hf); - if(nError != ERROR_SUCCESS) - hf->bErrorOccured = true; - } - - // Write the MD5 hashes of each file chunk, if required - if(ha->pHeader->dwRawChunkSize != 0) - { - nError = WriteMpqDataMD5(ha->pStream, - ha->MpqPos + hf->pFileEntry->ByteOffset, - hf->pFileEntry->dwCmpSize, - ha->pHeader->dwRawChunkSize); - if(nError != ERROR_SUCCESS) - hf->bErrorOccured = true; - } - } - } - else - { - hf->bErrorOccured = true; - } - - return nError; -} - -int SFileAddFile_Finish(TMPQFile * hf) -{ - TMPQArchive * ha = hf->ha; - TFileEntry * pFileEntry = hf->pFileEntry; - int nError = ERROR_SUCCESS; - - // If all previous operations succeeded, we can update the MPQ - if(!hf->bErrorOccured) - { - // Verify if the caller wrote the file properly - if(hf->pPatchInfo == NULL) - { - assert(pFileEntry != NULL); - if(hf->dwFilePos != pFileEntry->dwFileSize) - { - nError = ERROR_CAN_NOT_COMPLETE; - hf->bErrorOccured = true; - } - } - else - { - if(hf->dwFilePos != hf->pPatchInfo->dwDataSize) - { - nError = ERROR_CAN_NOT_COMPLETE; - hf->bErrorOccured = true; - } - } - } - - if(!hf->bErrorOccured) - { - // Call the user callback, if any - if(AddFileCB != NULL) - AddFileCB(pvUserData, hf->dwDataSize, hf->dwDataSize, true); - - // Update the size of the block table - ha->pHeader->dwBlockTableSize = ha->dwFileTableSize; - } - else - { - // Free the file entry in MPQ tables - if(pFileEntry != NULL) - FreeFileEntry(ha, pFileEntry); - } - - // Clear the add file callback - FreeMPQFile(hf); - pvUserData = NULL; - AddFileCB = NULL; - return nError; -} - -//----------------------------------------------------------------------------- -// Adds data as file to the archive - -bool WINAPI SFileCreateFile( - HANDLE hMpq, - const char * szArchivedName, - ULONGLONG FileTime, - DWORD dwFileSize, - LCID lcLocale, - DWORD dwFlags, - HANDLE * phFile) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - int nError = ERROR_SUCCESS; - - // Check valid parameters - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(szArchivedName == NULL || *szArchivedName == 0) - nError = ERROR_INVALID_PARAMETER; - if(phFile == NULL) - nError = ERROR_INVALID_PARAMETER; - - // Don't allow to add file if the MPQ is open for read only - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - nError = ERROR_ACCESS_DENIED; - - // Don't allow to add a file under pseudo-file name - if(IsPseudoFileName(szArchivedName, NULL)) - nError = ERROR_INVALID_PARAMETER; - - // Don't allow to add any of the internal files - if(IsInternalMpqFileName(szArchivedName)) - nError = ERROR_INTERNAL_FILE; - - // Perform validity check of the MPQ flags - if(nError == ERROR_SUCCESS) - { - // Mask all unsupported flags out - dwFlags &= MPQ_FILE_VALID_FLAGS; - - // Check for valid flag combinations - if((dwFlags & (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS)) == (MPQ_FILE_IMPLODE | MPQ_FILE_COMPRESS)) - nError = ERROR_INVALID_PARAMETER; - } - - // Create the file in MPQ - if(nError == ERROR_SUCCESS) - { - // Invalidate the entries for (listfile) and (attributes) - // After we are done with MPQ changes, we need to re-create them anyway - InvalidateInternalFiles(ha); - - // Initiate the add file operation - nError = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcLocale, dwFlags, (TMPQFile **)phFile); - } - - // Deal with the errors - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -bool WINAPI SFileWriteFile( - HANDLE hFile, - const void * pvData, - DWORD dwSize, - DWORD dwCompression) -{ - TMPQFile * hf = (TMPQFile *)hFile; - int nError = ERROR_SUCCESS; - - // Check the proper parameters - if(!IsValidFileHandle(hf)) - nError = ERROR_INVALID_HANDLE; - if(hf->bIsWriteHandle == false) - nError = ERROR_INVALID_HANDLE; - - // Special checks for single unit files - if(nError == ERROR_SUCCESS && (hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT)) - { - // - // Note: Blizzard doesn't support single unit files - // that are stored as encrypted or imploded. We will allow them here, - // the calling application must ensure that such flag combination doesn't get here - // - -// if(dwFlags & MPQ_FILE_IMPLODE) -// nError = ERROR_INVALID_PARAMETER; -// -// if(dwFlags & MPQ_FILE_ENCRYPTED) -// nError = ERROR_INVALID_PARAMETER; - - // Lossy compression is not allowed on single unit files - if(dwCompression & LOSSY_COMPRESSION_MASK) - nError = ERROR_INVALID_PARAMETER; - } - - - // Write the data to the file - if(nError == ERROR_SUCCESS) - nError = SFileAddFile_Write(hf, pvData, dwSize, dwCompression); - - // Deal with errors - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -bool WINAPI SFileFinishFile(HANDLE hFile) -{ - TMPQFile * hf = (TMPQFile *)hFile; - int nError = ERROR_SUCCESS; - - // Check the proper parameters - if(!IsValidFileHandle(hf)) - nError = ERROR_INVALID_HANDLE; - if(hf->bIsWriteHandle == false) - nError = ERROR_INVALID_HANDLE; - - // Finish the file - if(nError == ERROR_SUCCESS) - nError = SFileAddFile_Finish(hf); - - // Deal with errors - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// Adds a file to the archive - -bool WINAPI SFileAddFileEx( - HANDLE hMpq, - const TCHAR * szFileName, - const char * szArchivedName, - DWORD dwFlags, - DWORD dwCompression, // Compression of the first sector - DWORD dwCompressionNext) // Compression of next sectors -{ - ULONGLONG FileSize = 0; - ULONGLONG FileTime = 0; - TFileStream * pStream = NULL; - HANDLE hMpqFile = NULL; - LPBYTE pbFileData = NULL; - DWORD dwBytesRemaining = 0; - DWORD dwBytesToRead; - DWORD dwSectorSize = 0x1000; - DWORD dwChannels = 0; - bool bIsAdpcmCompression = false; - bool bIsFirstSector = true; - int nError = ERROR_SUCCESS; - - // Check parameters - if(szFileName == NULL || *szFileName == 0) - nError = ERROR_INVALID_PARAMETER; - - // Open added file - if(nError == ERROR_SUCCESS) - { - pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); - if(pStream == NULL) - nError = GetLastError(); - } - - // Get the file size and file time - if(nError == ERROR_SUCCESS) - { - FileStream_GetTime(pStream, &FileTime); - FileStream_GetSize(pStream, FileSize); - - // Files bigger than 4GB cannot be added to MPQ - if(FileSize >> 32) - nError = ERROR_DISK_FULL; - } - - // Allocate data buffer for reading from the source file - if(nError == ERROR_SUCCESS) - { - dwBytesRemaining = (DWORD)FileSize; - pbFileData = STORM_ALLOC(BYTE, dwSectorSize); - if(pbFileData == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Deal with various combination of compressions - if(nError == ERROR_SUCCESS) - { - // When the compression for next blocks is set to default, - // we will copy the compression for the first sector - if(dwCompressionNext == MPQ_COMPRESSION_NEXT_SAME) - dwCompressionNext = dwCompression; - - // If the caller wants ADPCM compression, we make sure - // that the first sector is not compressed with lossy compression - if(dwCompressionNext & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO)) - { - // The first compression must not be WAVE - if(dwCompression & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO)) - dwCompression = MPQ_COMPRESSION_PKWARE; - - dwCompressionNext &= ~(MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO); - bIsAdpcmCompression = true; - } - - // Initiate adding file to the MPQ - if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, lcFileLocale, dwFlags, &hMpqFile)) - nError = GetLastError(); - } - - // Write the file data to the MPQ - while(nError == ERROR_SUCCESS && dwBytesRemaining != 0) - { - // Get the number of bytes remaining in the source file - dwBytesToRead = dwBytesRemaining; - if(dwBytesToRead > dwSectorSize) - dwBytesToRead = dwSectorSize; - - // Read data from the local file - if(!FileStream_Read(pStream, NULL, pbFileData, dwBytesToRead)) - { - nError = GetLastError(); - break; - } - - // If the file being added is a WAVE file, we check number of channels - if(bIsFirstSector && bIsAdpcmCompression) - { - // The file must really be a wave file, otherwise it's data corruption - if(!IsWaveFile(pbFileData, dwBytesToRead, &dwChannels)) - { - nError = ERROR_BAD_FORMAT; - break; - } - - // Setup the compression according to number of channels - dwCompressionNext |= (dwChannels == 1) ? MPQ_COMPRESSION_ADPCM_MONO : MPQ_COMPRESSION_ADPCM_STEREO; - bIsFirstSector = false; - } - - // Add the file sectors to the MPQ - if(!SFileWriteFile(hMpqFile, pbFileData, dwBytesToRead, dwCompression)) - { - nError = GetLastError(); - break; - } - - // Set the next data compression - dwBytesRemaining -= dwBytesToRead; - dwCompression = dwCompressionNext; - } - - // Finish the file writing - if(hMpqFile != NULL) - { - if(!SFileFinishFile(hMpqFile)) - nError = GetLastError(); - } - - // Cleanup and exit - if(pbFileData != NULL) - STORM_FREE(pbFileData); - if(pStream != NULL) - FileStream_Close(pStream); - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -// Adds a data file into the archive -bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags) -{ - return SFileAddFileEx(hMpq, - szFileName, - szArchivedName, - dwFlags, - DefaultDataCompression, - DefaultDataCompression); -} - -// Adds a WAVE file into the archive -bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality) -{ - DWORD dwCompression = 0; - - // - // Note to wave compression level: - // The following conversion table applied: - // High quality: WaveCompressionLevel = -1 - // Medium quality: WaveCompressionLevel = 4 - // Low quality: WaveCompressionLevel = 2 - // - // Starcraft files are packed as Mono (0x41) on medium quality. - // Because this compression is not used anymore, our compression functions - // will default to WaveCompressionLevel = 4 when using ADPCM compression - // - - // Convert quality to data compression - switch(dwQuality) - { - case MPQ_WAVE_QUALITY_HIGH: -// WaveCompressionLevel = -1; - dwCompression = MPQ_COMPRESSION_PKWARE; - break; - - case MPQ_WAVE_QUALITY_MEDIUM: -// WaveCompressionLevel = 4; - dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN; - break; - - case MPQ_WAVE_QUALITY_LOW: -// WaveCompressionLevel = 2; - dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN; - break; - } - - return SFileAddFileEx(hMpq, - szFileName, - szArchivedName, - dwFlags, - MPQ_COMPRESSION_PKWARE, // First sector should be compressed as data - dwCompression); // Next sectors should be compressed as WAVE -} - -//----------------------------------------------------------------------------- -// bool SFileRemoveFile(HANDLE hMpq, char * szFileName) -// -// This function removes a file from the archive. The file content -// remains there, only the entries in the hash table and in the block -// table are updated. - -bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pFileEntry = NULL; // File entry of the file to be deleted - DWORD dwFileIndex = 0; - int nError = ERROR_SUCCESS; - - // Keep compiler happy - dwSearchScope = dwSearchScope; - - // Check the parameters - if(nError == ERROR_SUCCESS) - { - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(szFileName == NULL || *szFileName == 0) - nError = ERROR_INVALID_PARAMETER; - if(IsInternalMpqFileName(szFileName)) - nError = ERROR_INTERNAL_FILE; - } - - if(nError == ERROR_SUCCESS) - { - // Do not allow to remove files from MPQ open for read only - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - nError = ERROR_ACCESS_DENIED; - } - - // Get hash entry belonging to this file - if(nError == ERROR_SUCCESS) - { - if(!IsPseudoFileName(szFileName, &dwFileIndex)) - { - if((pFileEntry = GetFileEntryExact(ha, (char *)szFileName, lcFileLocale)) == NULL) - nError = ERROR_FILE_NOT_FOUND; - } - else - { - if((pFileEntry = GetFileEntryByIndex(ha, dwFileIndex)) == NULL) - nError = ERROR_FILE_NOT_FOUND; - } - } - - // Test if the file is not already deleted - if(nError == ERROR_SUCCESS) - { - if(!(pFileEntry->dwFlags & MPQ_FILE_EXISTS)) - nError = ERROR_FILE_NOT_FOUND; - } - - if(nError == ERROR_SUCCESS) - { - // Invalidate the entries for (listfile) and (attributes) - // After we are done with MPQ changes, we need to re-create them anyway - InvalidateInternalFiles(ha); - - // Mark the file entry as free - nError = FreeFileEntry(ha, pFileEntry); - } - - // Resolve error and exit - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -// Renames the file within the archive. -bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * szNewFileName) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pFileEntry = NULL; - ULONGLONG RawDataOffs; - TMPQFile * hf; - int nError = ERROR_SUCCESS; - - // Test the valid parameters - if(nError == ERROR_SUCCESS) - { - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(szFileName == NULL || *szFileName == 0 || szNewFileName == NULL || *szNewFileName == 0) - nError = ERROR_INVALID_PARAMETER; - } - - if(nError == ERROR_SUCCESS) - { - // Do not allow to rename files in MPQ open for read only - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - nError = ERROR_ACCESS_DENIED; - - // Do not allow renaming anything to a pseudo-file name - if(IsPseudoFileName(szFileName, NULL) || IsPseudoFileName(szNewFileName, NULL)) - nError = ERROR_INVALID_PARAMETER; - - // Do not allow to rename any of the internal files - // Also do not allow to rename any of files to an internal file - if(IsInternalMpqFileName(szFileName) || IsInternalMpqFileName(szNewFileName)) - nError = ERROR_INTERNAL_FILE; - } - - // Find the current file entry. - if(nError == ERROR_SUCCESS) - { - // Get the file entry - pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale); - if(pFileEntry == NULL) - nError = ERROR_FILE_NOT_FOUND; - } - - // Also try to find file entry for the new file. - // This verifies if we are not overwriting an existing file - // (whose name we perhaps don't know) - if(nError == ERROR_SUCCESS) - { - if(GetFileEntryLocale(ha, szNewFileName, pFileEntry->lcLocale) != NULL) - nError = ERROR_ALREADY_EXISTS; - } - - // Now we rename the existing file entry. - if(nError == ERROR_SUCCESS) - { - // Rename the file entry - nError = RenameFileEntry(ha, pFileEntry, szNewFileName); - } - - // Now we copy the existing file entry to the new one - if(nError == ERROR_SUCCESS) - { - // If the file is encrypted, we have to re-crypt the file content - // with the new decryption key - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - { - hf = CreateMpqFile(ha); - if(hf != NULL) - { - // Recrypt the file data in the MPQ - hf->pFileEntry = pFileEntry; - hf->dwDataSize = pFileEntry->dwFileSize; - nError = RecryptFileData(ha, hf, szFileName, szNewFileName); - - // Update the MD5 - if(ha->pHeader->dwRawChunkSize != 0) - { - RawDataOffs = ha->MpqPos + pFileEntry->ByteOffset; - WriteMpqDataMD5(ha->pStream, - RawDataOffs, - pFileEntry->dwCmpSize, - ha->pHeader->dwRawChunkSize); - } - - FreeMPQFile(hf); - } - else - { - nError = ERROR_NOT_ENOUGH_MEMORY; - } - } - } - - // - // Note: MPQ_FLAG_CHANGED is set by RenameFileEntry - // - - // Resolve error and return - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// Sets default data compression for SFileAddFile - -bool WINAPI SFileSetDataCompression(DWORD DataCompression) -{ - unsigned int uValidMask = (MPQ_COMPRESSION_ZLIB | MPQ_COMPRESSION_PKWARE | MPQ_COMPRESSION_BZIP2 | MPQ_COMPRESSION_SPARSE); - - if((DataCompression & uValidMask) != DataCompression) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - DefaultDataCompression = DataCompression; - return true; -} - -//----------------------------------------------------------------------------- -// Changes locale ID of a file - -bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale) -{ - TMPQArchive * ha; - TFileEntry * pFileEntry; - TMPQFile * hf = (TMPQFile *)hFile; - - // Invalid handle => do nothing - if(!IsValidFileHandle(hf)) - { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // Do not allow unnamed access - if(hf->pFileEntry->szFileName == NULL) - { - SetLastError(ERROR_CAN_NOT_COMPLETE); - return false; - } - - // Do not allow to change locale of any internal file - if(IsInternalMpqFileName(hf->pFileEntry->szFileName)) - { - SetLastError(ERROR_INTERNAL_FILE); - return false; - } - - // Do not allow changing file locales in MPQs version 3 or higher - ha = hf->ha; - if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3) - { - SetLastError(ERROR_NOT_SUPPORTED); - return false; - } - - // Do not allow to rename files in MPQ open for read only - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - { - SetLastError(ERROR_ACCESS_DENIED); - return false; - } - - // If the file already has that locale, return OK - if(hf->pFileEntry->lcLocale == lcNewLocale) - return true; - - // We have to check if the file+locale is not already there - pFileEntry = GetFileEntryExact(ha, hf->pFileEntry->szFileName, lcNewLocale); - if(pFileEntry != NULL) - { - SetLastError(ERROR_ALREADY_EXISTS); - return false; - } - - // Set the locale and return success - pFileEntry = hf->pFileEntry; - pFileEntry->lcLocale = (USHORT)lcNewLocale; - - // Save the new locale to the hash table, if any - if(ha->pHashTable != NULL) - ha->pHashTable[pFileEntry->dwHashIndex].lcLocale = (USHORT)lcNewLocale; - - // Remember that the MPQ tables have been changed - ha->dwFlags |= MPQ_FLAG_CHANGED; - return true; -} - -//----------------------------------------------------------------------------- -// Sets add file callback - -bool WINAPI SFileSetAddFileCallback(HANDLE /* hMpq */, SFILE_ADDFILE_CALLBACK aAddFileCB, void * pvData) -{ - pvUserData = pvData; - AddFileCB = aAddFileCB; - return true; -} diff --git a/dep/StormLib/src/SFileAttributes.cpp b/dep/StormLib/src/SFileAttributes.cpp deleted file mode 100644 index 0f056088fa3..00000000000 --- a/dep/StormLib/src/SFileAttributes.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/*****************************************************************************/ -/* SAttrFile.cpp Copyright (c) Ladislav Zezula 2007 */ -/*---------------------------------------------------------------------------*/ -/* Description: */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 12.06.04 1.00 Lad The first version of SAttrFile.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local structures - -typedef struct _MPQ_ATTRIBUTES_HEADER -{ - DWORD dwVersion; // Version of the (attributes) file. Must be 100 (0x64) - DWORD dwFlags; // See MPQ_ATTRIBUTE_XXXX - - // Followed by an array of CRC32 - // Followed by an array of file times - // Followed by an array of MD5 - // Followed by an array of patch bits -} MPQ_ATTRIBUTES_HEADER, *PMPQ_ATTRIBUTES_HEADER; - -//----------------------------------------------------------------------------- -// Public functions (internal use by StormLib) - -int SAttrLoadAttributes(TMPQArchive * ha) -{ - MPQ_ATTRIBUTES_HEADER AttrHeader; - TMPQFile * hf; - HANDLE hFile = NULL; - DWORD dwBlockTableSize = ha->pHeader->dwBlockTableSize; - DWORD dwArraySize; - DWORD dwBytesRead; - DWORD i; - int nError = ERROR_SUCCESS; - - // File table must be initialized - assert(ha->pFileTable != NULL); - - // Attempt to open the "(attributes)" file. - // If it's not there, then the archive doesn't support attributes - if(SFileOpenFileEx((HANDLE)ha, ATTRIBUTES_NAME, SFILE_OPEN_ANY_LOCALE, &hFile)) - { - // Remember the flags for (attributes) - hf = (TMPQFile *)hFile; - ha->dwFileFlags2 = hf->pFileEntry->dwFlags; - - // Load the content of the attributes file - SFileReadFile(hFile, &AttrHeader, sizeof(MPQ_ATTRIBUTES_HEADER), &dwBytesRead, NULL); - if(dwBytesRead != sizeof(MPQ_ATTRIBUTES_HEADER)) - nError = ERROR_FILE_CORRUPT; - - // Verify the header of the (attributes) file - if(nError == ERROR_SUCCESS) - { - AttrHeader.dwVersion = BSWAP_INT32_UNSIGNED(AttrHeader.dwVersion); - AttrHeader.dwFlags = BSWAP_INT32_UNSIGNED(AttrHeader.dwFlags); - ha->dwAttrFlags = AttrHeader.dwFlags; - if(dwBytesRead != sizeof(MPQ_ATTRIBUTES_HEADER)) - nError = ERROR_FILE_CORRUPT; - } - - // Verify format of the attributes - if(nError == ERROR_SUCCESS) - { - if(AttrHeader.dwVersion > MPQ_ATTRIBUTES_V1) - nError = ERROR_BAD_FORMAT; - } - - // Load the CRC32 (if any) - if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_CRC32)) - { - LPDWORD pArrayCRC32 = STORM_ALLOC(DWORD, dwBlockTableSize); - - if(pArrayCRC32 != NULL) - { - dwArraySize = dwBlockTableSize * sizeof(DWORD); - SFileReadFile(hFile, pArrayCRC32, dwArraySize, &dwBytesRead, NULL); - if(dwBytesRead == dwArraySize) - { - for(i = 0; i < dwBlockTableSize; i++) - ha->pFileTable[i].dwCrc32 = BSWAP_INT32_UNSIGNED(pArrayCRC32[i]); - } - else - nError = ERROR_FILE_CORRUPT; - - STORM_FREE(pArrayCRC32); - } - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Read the array of file times - if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_FILETIME)) - { - ULONGLONG * pArrayFileTime = STORM_ALLOC(ULONGLONG, dwBlockTableSize); - - if(pArrayFileTime != NULL) - { - dwArraySize = dwBlockTableSize * sizeof(ULONGLONG); - SFileReadFile(hFile, pArrayFileTime, dwArraySize, &dwBytesRead, NULL); - if(dwBytesRead == dwArraySize) - { - for(i = 0; i < dwBlockTableSize; i++) - ha->pFileTable[i].FileTime = BSWAP_INT64_UNSIGNED(pArrayFileTime[i]); - } - else - nError = ERROR_FILE_CORRUPT; - - STORM_FREE(pArrayFileTime); - } - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Read the MD5 (if any) - // Note: MD5 array can be incomplete, if it's the last array in the (attributes) - if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_MD5)) - { - unsigned char * pArrayMD5 = STORM_ALLOC(unsigned char, (dwBlockTableSize * MD5_DIGEST_SIZE)); - unsigned char * md5; - - if(pArrayMD5 != NULL) - { - dwArraySize = dwBlockTableSize * MD5_DIGEST_SIZE; - SFileReadFile(hFile, pArrayMD5, dwArraySize, &dwBytesRead, NULL); - if(dwBytesRead == dwArraySize) - { - md5 = pArrayMD5; - for(i = 0; i < dwBlockTableSize; i++) - { - memcpy(ha->pFileTable[i].md5, md5, MD5_DIGEST_SIZE); - md5 += MD5_DIGEST_SIZE; - } - } - else - nError = ERROR_FILE_CORRUPT; - - STORM_FREE(pArrayMD5); - } - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Read the patch bit for each file - if(nError == ERROR_SUCCESS && (AttrHeader.dwFlags & MPQ_ATTRIBUTE_PATCH_BIT)) - { - LPBYTE pbBitArray; - DWORD dwByteSize = ((dwBlockTableSize - 1) / 8) + 1; - - pbBitArray = STORM_ALLOC(BYTE, dwByteSize); - if(pbBitArray != NULL) - { - SFileReadFile(hFile, pbBitArray, dwByteSize, &dwBytesRead, NULL); - if(dwBytesRead == dwByteSize) - { - for(i = 0; i < dwBlockTableSize; i++) - { - DWORD dwByteIndex = i / 8; - DWORD dwBitMask = 0x80 >> (i & 7); - - // Is the appropriate bit set? - if(pbBitArray[dwByteIndex] & dwBitMask) - { - // At the moment, we assume that the patch bit is present - // in both file table and (attributes) - assert((ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE) != 0); - ha->pFileTable[i].dwFlags |= MPQ_FILE_PATCH_FILE; - } - } - } - else - nError = ERROR_FILE_CORRUPT; - - STORM_FREE(pbBitArray); - } - } - - // - // Note: Version 7.00 of StormLib saved the (attributes) incorrectly. - // Sometimes, number of entries in the (attributes) was 1 item less - // than block table size. - // If we encounter such table, we will zero all three arrays - // - - if(nError != ERROR_SUCCESS) - ha->dwAttrFlags = 0; - - // Cleanup & exit - SFileCloseFile(hFile); - } - return nError; -} - -int SAttrFileSaveToMpq(TMPQArchive * ha) -{ - MPQ_ATTRIBUTES_HEADER AttrHeader; - TFileEntry * pFileEntry; - TMPQFile * hf = NULL; - DWORD dwFinalBlockTableSize = ha->dwFileTableSize; - DWORD dwFileSize = 0; - DWORD dwToWrite; - DWORD i; - int nError = ERROR_SUCCESS; - - // Now we have to check if we need patch bits in the (attributes) - if(nError == ERROR_SUCCESS) - { - for(i = 0; i < ha->dwFileTableSize; i++) - { - if(ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE) - { - ha->dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT; - break; - } - } - } - - // If the (attributes) is not in the file table yet, - // we have to increase the final block table size - pFileEntry = GetFileEntryExact(ha, ATTRIBUTES_NAME, LANG_NEUTRAL); - if(pFileEntry != NULL) - { - // If "(attributes)" file exists, and it's set to 0, then remove it - if(ha->dwAttrFlags == 0) - { - FreeFileEntry(ha, pFileEntry); - return ERROR_SUCCESS; - } - } - else - { - // If we don't want to create file atributes, do nothing - if(ha->dwAttrFlags == 0) - return ERROR_SUCCESS; - - // Check where the file entry is going to be allocated. - // If at the end of the file table, we have to increment - // the expected size of the (attributes) file. - pFileEntry = FindFreeFileEntry(ha); - if(pFileEntry == ha->pFileTable + ha->dwFileTableSize) - dwFinalBlockTableSize++; - } - - // Calculate the size of the attributes file - if(nError == ERROR_SUCCESS) - { - dwFileSize = sizeof(MPQ_ATTRIBUTES_HEADER); // Header - if(ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32) - dwFileSize += dwFinalBlockTableSize * sizeof(DWORD); - if(ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME) - dwFileSize += dwFinalBlockTableSize * sizeof(ULONGLONG); - if(ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5) - dwFileSize += dwFinalBlockTableSize * MD5_DIGEST_SIZE; - if(ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT) - dwFileSize += ((dwFinalBlockTableSize - 1)) / 8 + 1; - } - - // Determine the flags for (attributes) - if(ha->dwFileFlags2 == 0) - ha->dwFileFlags2 = GetDefaultSpecialFileFlags(ha, dwFileSize); - - // Create the attributes file in the MPQ - nError = SFileAddFile_Init(ha, ATTRIBUTES_NAME, - 0, - dwFileSize, - LANG_NEUTRAL, - ha->dwFileFlags2 | MPQ_FILE_REPLACEEXISTING, - &hf); - - // Write all parts of the (attributes) file - if(nError == ERROR_SUCCESS) - { - assert(ha->dwFileTableSize == dwFinalBlockTableSize); - - // Note that we don't know what the new bit (0x08) means. - AttrHeader.dwVersion = BSWAP_INT32_UNSIGNED(100); - AttrHeader.dwFlags = BSWAP_INT32_UNSIGNED((ha->dwAttrFlags & MPQ_ATTRIBUTE_ALL)); - dwToWrite = sizeof(MPQ_ATTRIBUTES_HEADER); - nError = SFileAddFile_Write(hf, &AttrHeader, dwToWrite, MPQ_COMPRESSION_ZLIB); - } - - // Write the array of CRC32 - if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_CRC32)) - { - LPDWORD pArrayCRC32 = STORM_ALLOC(DWORD, dwFinalBlockTableSize); - - if(pArrayCRC32 != NULL) - { - // Copy from file table - for(i = 0; i < ha->dwFileTableSize; i++) - pArrayCRC32[i] = BSWAP_INT32_UNSIGNED(ha->pFileTable[i].dwCrc32); - - dwToWrite = ha->dwFileTableSize * sizeof(DWORD); - nError = SFileAddFile_Write(hf, pArrayCRC32, dwToWrite, MPQ_COMPRESSION_ZLIB); - STORM_FREE(pArrayCRC32); - } - } - - // Write the array of file time - if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_FILETIME)) - { - ULONGLONG * pArrayFileTime = STORM_ALLOC(ULONGLONG, ha->dwFileTableSize); - - if(pArrayFileTime != NULL) - { - // Copy from file table - for(i = 0; i < ha->dwFileTableSize; i++) - pArrayFileTime[i] = BSWAP_INT64_UNSIGNED(ha->pFileTable[i].FileTime); - - dwToWrite = ha->dwFileTableSize * sizeof(ULONGLONG); - nError = SFileAddFile_Write(hf, pArrayFileTime, dwToWrite, MPQ_COMPRESSION_ZLIB); - STORM_FREE(pArrayFileTime); - } - } - - // Write the array of MD5s - if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_MD5)) - { - char * pArrayMD5 = STORM_ALLOC(char, ha->dwFileTableSize * MD5_DIGEST_SIZE); - - if(pArrayMD5 != NULL) - { - // Copy from file table - for(i = 0; i < ha->dwFileTableSize; i++) - memcpy(&pArrayMD5[i * MD5_DIGEST_SIZE], ha->pFileTable[i].md5, MD5_DIGEST_SIZE); - - dwToWrite = ha->dwFileTableSize * MD5_DIGEST_SIZE; - nError = SFileAddFile_Write(hf, pArrayMD5, dwToWrite, MPQ_COMPRESSION_ZLIB); - STORM_FREE(pArrayMD5); - } - } - - // Write the array of patch bits - if(nError == ERROR_SUCCESS && (ha->dwAttrFlags & MPQ_ATTRIBUTE_PATCH_BIT)) - { - LPBYTE pbBitArray; - DWORD dwByteSize = ((ha->dwFileTableSize - 1) / 8) + 1; - - pbBitArray = STORM_ALLOC(BYTE, dwByteSize); - if(pbBitArray != NULL) - { - memset(pbBitArray, 0, dwByteSize); - for(i = 0; i < ha->dwFileTableSize; i++) - { - DWORD dwByteIndex = i / 8; - DWORD dwBitMask = 0x80 >> (i & 7); - - if(ha->pFileTable[i].dwFlags & MPQ_FILE_PATCH_FILE) - pbBitArray[dwByteIndex] |= dwBitMask; - } - - nError = SFileAddFile_Write(hf, pbBitArray, dwByteSize, MPQ_COMPRESSION_ZLIB); - STORM_FREE(pbBitArray); - } - } - - // Finalize the file in the archive - if(hf != NULL) - { - SFileAddFile_Finish(hf); - } - - if(nError == ERROR_SUCCESS) - ha->dwFlags &= ~MPQ_FLAG_INV_ATTRIBUTES; - return nError; -} - -//----------------------------------------------------------------------------- -// Public functions - -DWORD WINAPI SFileGetAttributes(HANDLE hMpq) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - - // Verify the parameters - if(!IsValidMpqHandle(ha)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return SFILE_INVALID_ATTRIBUTES; - } - - return ha->dwAttrFlags; -} - -bool WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - - // Verify the parameters - if(!IsValidMpqHandle(ha)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // Not allowed when the archive is read-only - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - { - SetLastError(ERROR_ACCESS_DENIED); - return false; - } - - // Set the attributes - InvalidateInternalFiles(ha); - ha->dwAttrFlags = (dwFlags & MPQ_ATTRIBUTE_ALL); - return true; -} - -bool WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName) -{ - hash_state md5_state; - TMPQArchive * ha = (TMPQArchive *)hMpq; - TMPQFile * hf; - BYTE Buffer[0x1000]; - HANDLE hFile = NULL; - DWORD dwTotalBytes = 0; - DWORD dwBytesRead; - DWORD dwCrc32; - - // Verify the parameters - if(!IsValidMpqHandle(ha)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // Not allowed when the archive is read-only - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - { - SetLastError(ERROR_ACCESS_DENIED); - return false; - } - - // Attempt to open the file - if(!SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_FROM_MPQ, &hFile)) - return false; - - // Get the file size - hf = (TMPQFile *)hFile; - SFileGetFileInfo(hFile, SFILE_INFO_FILE_SIZE, &dwTotalBytes, sizeof(DWORD)); - - // Initialize the CRC32 and MD5 contexts - md5_init(&md5_state); - dwCrc32 = crc32(0, Z_NULL, 0); - - // Go through entire file and calculate both CRC32 and MD5 - while(dwTotalBytes != 0) - { - // Read data from file - SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); - if(dwBytesRead == 0) - break; - - // Update CRC32 and MD5 - dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead); - md5_process(&md5_state, Buffer, dwBytesRead); - - // Decrement the total size - dwTotalBytes -= dwBytesRead; - } - - // Update both CRC32 and MD5 - hf->pFileEntry->dwCrc32 = dwCrc32; - md5_done(&md5_state, hf->pFileEntry->md5); - - // Remember that we need to save the MPQ tables - InvalidateInternalFiles(ha); - SFileCloseFile(hFile); - return true; -} diff --git a/dep/StormLib/src/SFileCompactArchive.cpp b/dep/StormLib/src/SFileCompactArchive.cpp deleted file mode 100644 index 319108b08f4..00000000000 --- a/dep/StormLib/src/SFileCompactArchive.cpp +++ /dev/null @@ -1,765 +0,0 @@ -/*****************************************************************************/ -/* SFileCompactArchive.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Archive compacting function */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 14.04.03 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */ -/* 19.11.03 1.01 Dan Big endian handling */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -/*****************************************************************************/ -/* Local variables */ -/*****************************************************************************/ - -static SFILE_COMPACT_CALLBACK CompactCB = NULL; -static ULONGLONG CompactBytesProcessed = 0; -static ULONGLONG CompactTotalBytes = 0; -static void * pvUserData = NULL; - -/*****************************************************************************/ -/* Local functions */ -/*****************************************************************************/ - -static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, LPDWORD pFileKeys) -{ - TFileEntry * pFileTableEnd; - TFileEntry * pFileEntry; - DWORD dwBlockIndex = 0; - int nError = ERROR_SUCCESS; - - // Add the listfile to the MPQ - if(nError == ERROR_SUCCESS && szListFile != NULL) - { - // Notify the user - if(CompactCB != NULL) - CompactCB(pvUserData, CCB_CHECKING_FILES, CompactBytesProcessed, CompactTotalBytes); - - nError = SFileAddListFile((HANDLE)ha, szListFile); - } - - // Verify the file table - if(nError == ERROR_SUCCESS) - { - pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++, dwBlockIndex++) - { - if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) - { - if(pFileEntry->szFileName != NULL && !IsPseudoFileName(pFileEntry->szFileName, NULL)) - { - DWORD dwFileKey = 0; - - // Resolve the file key. Use plain file name for it - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - { - dwFileKey = DecryptFileKey(pFileEntry->szFileName, - pFileEntry->ByteOffset, - pFileEntry->dwFileSize, - pFileEntry->dwFlags); - } - - // Give the key to the caller - if(pFileKeys != NULL) - pFileKeys[dwBlockIndex] = dwFileKey; - } - else - { - nError = ERROR_CAN_NOT_COMPLETE; - break; - } - } - } - } - - return nError; -} - -static int CopyNonMpqData( - TFileStream * pSrcStream, - TFileStream * pTrgStream, - ULONGLONG & ByteOffset, - ULONGLONG & ByteCount) -{ - ULONGLONG DataSize = ByteCount; - DWORD dwToRead; - char DataBuffer[0x1000]; - int nError = ERROR_SUCCESS; - - // Copy the data - while(DataSize > 0) - { - // Get the proper size of data - dwToRead = sizeof(DataBuffer); - if(DataSize < dwToRead) - dwToRead = (DWORD)DataSize; - - // Read from the source stream - if(!FileStream_Read(pSrcStream, &ByteOffset, DataBuffer, dwToRead)) - { - nError = GetLastError(); - break; - } - - // Write to the target stream - if(!FileStream_Write(pTrgStream, NULL, DataBuffer, dwToRead)) - { - nError = GetLastError(); - break; - } - - // Update the progress - if(CompactCB != NULL) - { - CompactBytesProcessed += dwToRead; - CompactCB(pvUserData, CCB_COPYING_NON_MPQ_DATA, CompactBytesProcessed, CompactTotalBytes); - } - - // Decrement the number of data to be copied - ByteOffset += dwToRead; - DataSize -= dwToRead; - } - - return ERROR_SUCCESS; -} - -// Copies all file sectors into another archive. -static int CopyMpqFileSectors( - TMPQArchive * ha, - TMPQFile * hf, - TFileStream * pNewStream) -{ - TFileEntry * pFileEntry = hf->pFileEntry; - ULONGLONG RawFilePos; // Used for calculating sector offset in the old MPQ archive - ULONGLONG MpqFilePos; // MPQ file position in the new archive - DWORD dwBytesToCopy = pFileEntry->dwCmpSize; - DWORD dwPatchSize = 0; // Size of patch header - DWORD dwFileKey1 = 0; // File key used for decryption - DWORD dwFileKey2 = 0; // File key used for encryption - DWORD dwCmpSize = 0; // Compressed file size, including patch header - int nError = ERROR_SUCCESS; - - // Remember the position in the destination file - FileStream_GetPos(pNewStream, MpqFilePos); - MpqFilePos -= ha->MpqPos; - - // Resolve decryption keys. Note that the file key given - // in the TMPQFile structure also includes the key adjustment - if(nError == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)) - { - dwFileKey2 = dwFileKey1 = hf->dwFileKey; - if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY) - { - dwFileKey2 = (dwFileKey1 ^ pFileEntry->dwFileSize) - (DWORD)pFileEntry->ByteOffset; - dwFileKey2 = (dwFileKey2 + (DWORD)MpqFilePos) ^ pFileEntry->dwFileSize; - } - } - - // If we have to save patch header, do it - if(nError == ERROR_SUCCESS && hf->pPatchInfo != NULL) - { - BSWAP_ARRAY32_UNSIGNED(hf->pPatchInfo, sizeof(DWORD) * 3); - if(!FileStream_Write(pNewStream, NULL, hf->pPatchInfo, hf->pPatchInfo->dwLength)) - nError = GetLastError(); - - // Save the size of the patch info - dwPatchSize = hf->pPatchInfo->dwLength; - } - - // If we have to save sector offset table, do it. - if(nError == ERROR_SUCCESS && hf->SectorOffsets != NULL) - { - DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]); - DWORD dwSectorOffsLen = hf->SectorOffsets[0]; - - assert((pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) == 0); - assert(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED); - - if(SectorOffsetsCopy == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - - // Encrypt the secondary sector offset table and write it to the target file - if(nError == ERROR_SUCCESS) - { - memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen); - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwFileKey2 - 1); - - BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen); - if(!FileStream_Write(pNewStream, NULL, SectorOffsetsCopy, dwSectorOffsLen)) - nError = GetLastError(); - - dwBytesToCopy -= dwSectorOffsLen; - dwCmpSize += dwSectorOffsLen; - } - - // Update compact progress - if(CompactCB != NULL) - { - CompactBytesProcessed += dwSectorOffsLen; - CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes); - } - - STORM_FREE(SectorOffsetsCopy); - } - - // Now we have to copy all file sectors. We do it without - // recompression, because recompression is not necessary in this case - if(nError == ERROR_SUCCESS) - { - for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++) - { - DWORD dwRawDataInSector = hf->dwSectorSize; - DWORD dwRawByteOffset = dwSector * hf->dwSectorSize; - - // Fix the raw data length if the file is compressed - if(hf->SectorOffsets != NULL) - { - dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector]; - dwRawByteOffset = hf->SectorOffsets[dwSector]; - } - - // Last sector: If there is not enough bytes remaining in the file, cut the raw size - if(dwRawDataInSector > dwBytesToCopy) - dwRawDataInSector = dwBytesToCopy; - - // Calculate the raw file offset of the file sector - CalculateRawSectorOffset(RawFilePos, hf, dwRawByteOffset); - - // Read the file sector - if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector)) - { - nError = GetLastError(); - break; - } - - // If necessary, re-encrypt the sector - // Note: Recompression is not necessary here. Unlike encryption, - // the compression does not depend on the position of the file in MPQ. - if((pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey1 != dwFileKey2) - { - BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); - DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey1 + dwSector); - EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey2 + dwSector); - BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); - } - - // Now write the sector back to the file - if(!FileStream_Write(pNewStream, NULL, hf->pbFileSector, dwRawDataInSector)) - { - nError = GetLastError(); - break; - } - - // Update compact progress - if(CompactCB != NULL) - { - CompactBytesProcessed += dwRawDataInSector; - CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes); - } - - // Adjust byte counts - dwBytesToCopy -= dwRawDataInSector; - dwCmpSize += dwRawDataInSector; - } - } - - // Copy the sector CRCs, if any - // Sector CRCs are always compressed (not imploded) and unencrypted - if(nError == ERROR_SUCCESS && hf->SectorOffsets != NULL && hf->SectorChksums != NULL) - { - DWORD dwCrcLength; - - dwCrcLength = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount]; - if(dwCrcLength != 0) - { - if(!FileStream_Read(ha->pStream, NULL, hf->SectorChksums, dwCrcLength)) - nError = GetLastError(); - - if(!FileStream_Write(pNewStream, NULL, hf->SectorChksums, dwCrcLength)) - nError = GetLastError(); - - // Update compact progress - if(CompactCB != NULL) - { - CompactBytesProcessed += dwCrcLength; - CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes); - } - - // Size of the CRC block is also included in the compressed file size - dwBytesToCopy -= dwCrcLength; - dwCmpSize += dwCrcLength; - } - } - - // There might be extra data beyond sector checksum table - // Sometimes, these data are even part of sector offset table - // Examples: - // 2012 - WoW\15354\locale-enGB.MPQ:DBFilesClient\SpellLevels.dbc - // 2012 - WoW\15354\locale-enGB.MPQ:Interface\AddOns\Blizzard_AuctionUI\Blizzard_AuctionUI.xml - if(nError == ERROR_SUCCESS && dwBytesToCopy != 0) - { - LPBYTE pbExtraData; - - // Allocate space for the extra data - pbExtraData = STORM_ALLOC(BYTE, dwBytesToCopy); - if(pbExtraData != NULL) - { - if(!FileStream_Read(ha->pStream, NULL, pbExtraData, dwBytesToCopy)) - nError = GetLastError(); - - if(!FileStream_Write(pNewStream, NULL, pbExtraData, dwBytesToCopy)) - nError = GetLastError(); - - // Include these extra data in the compressed size - dwCmpSize += dwBytesToCopy; - dwBytesToCopy = 0; - STORM_FREE(pbExtraData); - } - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Write the MD5's of the raw file data, if needed - if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0) - { - nError = WriteMpqDataMD5(pNewStream, - ha->MpqPos + MpqFilePos, - pFileEntry->dwCmpSize, - ha->pHeader->dwRawChunkSize); - } - - // Update file position in the block table - if(nError == ERROR_SUCCESS) - { - // At this point, number of bytes written should be exactly - // the same like the compressed file size. If it isn't, - // there's something wrong (an unknown archive version, MPQ protection, ...) - // - // Note: Diablo savegames have very weird layout, and the file "hero" - // seems to have improper compressed size. Instead of real compressed size, - // the "dwCmpSize" member of the block table entry contains - // uncompressed size of file data + size of the sector table. - // If we compact the archive, Diablo will refuse to load the game - // Seems like some sort of protection to me. - // - // Note: Some patch files in WOW patches don't count the patch header - // into compressed size - // - - if(dwCmpSize <= pFileEntry->dwCmpSize && pFileEntry->dwCmpSize <= dwCmpSize + dwPatchSize) - { - // Note: DO NOT update the compressed size in the file entry, no matter how bad it is. - pFileEntry->ByteOffset = MpqFilePos; - } - else - { - nError = ERROR_FILE_CORRUPT; - assert(false); - } - } - - return nError; -} - -static int CopyMpqFiles(TMPQArchive * ha, LPDWORD pFileKeys, TFileStream * pNewStream) -{ - TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pFileEntry; - TMPQFile * hf = NULL; - int nError = ERROR_SUCCESS; - - // Walk through all files and write them to the destination MPQ archive - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) - { - // Copy all the file sectors - // Only do that when the file has nonzero size - if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->dwFileSize != 0) - { - // Allocate structure for the MPQ file - hf = CreateMpqFile(ha); - if(hf == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Store file entry - hf->pFileEntry = pFileEntry; - - // Set the raw file position - hf->MpqFilePos = pFileEntry->ByteOffset; - hf->RawFilePos = ha->MpqPos + hf->MpqFilePos; - - // Set the file decryption key - hf->dwFileKey = pFileKeys[pFileEntry - ha->pFileTable]; - hf->dwDataSize = pFileEntry->dwFileSize; - - // If the file is a patch file, load the patch header - if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) - { - nError = AllocatePatchInfo(hf, true); - if(nError != ERROR_SUCCESS) - break; - } - - // Allocate buffers for file sector and sector offset table - nError = AllocateSectorBuffer(hf); - if(nError != ERROR_SUCCESS) - break; - - // Also allocate sector offset table and sector checksum table - nError = AllocateSectorOffsets(hf, true); - if(nError != ERROR_SUCCESS) - break; - - // Also load sector checksums, if any - if(pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) - { - nError = AllocateSectorChecksums(hf, false); - if(nError != ERROR_SUCCESS) - break; - } - - // Copy all file sectors - nError = CopyMpqFileSectors(ha, hf, pNewStream); - if(nError != ERROR_SUCCESS) - break; - - // Free buffers. This also sets "hf" to NULL. - FreeMPQFile(hf); - } - } - - // Cleanup and exit - if(hf != NULL) - FreeMPQFile(hf); - return nError; -} - - -/*****************************************************************************/ -/* Public functions */ -/*****************************************************************************/ - -bool WINAPI SFileSetCompactCallback(HANDLE /* hMpq */, SFILE_COMPACT_CALLBACK aCompactCB, void * pvData) -{ - CompactCB = aCompactCB; - pvUserData = pvData; - return true; -} - -//----------------------------------------------------------------------------- -// Archive compacting - -bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bReserved */) -{ - TFileStream * pTempStream = NULL; - TMPQArchive * ha = (TMPQArchive *)hMpq; - ULONGLONG ByteOffset; - ULONGLONG ByteCount; - LPDWORD pFileKeys = NULL; - TCHAR szTempFile[MAX_PATH] = _T(""); - TCHAR * szTemp = NULL; - int nError = ERROR_SUCCESS; - - // Test the valid parameters - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - nError = ERROR_ACCESS_DENIED; - - // If the MPQ is changed at this moment, we have to flush the archive - if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_CHANGED)) - { - SFileFlushArchive(hMpq); - } - - // Create the table with file keys - if(nError == ERROR_SUCCESS) - { - if((pFileKeys = STORM_ALLOC(DWORD, ha->dwFileTableSize)) != NULL) - memset(pFileKeys, 0, sizeof(DWORD) * ha->dwFileTableSize); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // First of all, we have to check of we are able to decrypt all files. - // If not, sorry, but the archive cannot be compacted. - if(nError == ERROR_SUCCESS) - { - // Initialize the progress variables for compact callback - FileStream_GetSize(ha->pStream, CompactTotalBytes); - CompactBytesProcessed = 0; - nError = CheckIfAllFilesKnown(ha, szListFile, pFileKeys); - } - - // Get the temporary file name and create it - if(nError == ERROR_SUCCESS) - { - _tcscpy(szTempFile, FileStream_GetFileName(ha->pStream)); - if((szTemp = _tcsrchr(szTempFile, '.')) != NULL) - _tcscpy(szTemp + 1, _T("mp_")); - else - _tcscat(szTempFile, _T("_")); - - pTempStream = FileStream_CreateFile(szTempFile, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); - if(pTempStream == NULL) - nError = GetLastError(); - } - - // Write the data before MPQ user data (if any) - if(nError == ERROR_SUCCESS && ha->UserDataPos != 0) - { - // Inform the application about the progress - if(CompactCB != NULL) - CompactCB(pvUserData, CCB_COPYING_NON_MPQ_DATA, CompactBytesProcessed, CompactTotalBytes); - - ByteOffset = 0; - ByteCount = ha->UserDataPos; - nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount); - } - - // Write the MPQ user data (if any) - if(nError == ERROR_SUCCESS && ha->MpqPos > ha->UserDataPos) - { - // At this point, we assume that the user data size is equal - // to pUserData->dwHeaderOffs. - // If this assumption doesn't work, then we have an unknown version of MPQ - ByteOffset = ha->UserDataPos; - ByteCount = ha->MpqPos - ha->UserDataPos; - - assert(ha->pUserData != NULL); - assert(ha->pUserData->dwHeaderOffs == ByteCount); - nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount); - } - - // Write the MPQ header - if(nError == ERROR_SUCCESS) - { - // Remember the header size before swapping - DWORD dwBytesToWrite = ha->pHeader->dwHeaderSize; - - BSWAP_TMPQHEADER(ha->pHeader); - if(!FileStream_Write(pTempStream, NULL, ha->pHeader, dwBytesToWrite)) - nError = GetLastError(); - BSWAP_TMPQHEADER(ha->pHeader); - - // Update the progress - CompactBytesProcessed += ha->pHeader->dwHeaderSize; - } - - // Now copy all files - if(nError == ERROR_SUCCESS) - { - nError = CopyMpqFiles(ha, pFileKeys, pTempStream); - ha->dwFlags |= MPQ_FLAG_CHANGED; - } - - // If succeeded, switch the streams - if(nError == ERROR_SUCCESS) - { - if(FileStream_Switch(ha->pStream, pTempStream)) - pTempStream = NULL; - else - nError = ERROR_CAN_NOT_COMPLETE; - } - - // If all succeeded, save the MPQ tables - if(nError == ERROR_SUCCESS) - { - // - // Note: We don't recalculate position of the MPQ tables at this point. - // SaveMPQTables does it automatically. - // - - nError = SaveMPQTables(ha); - if(nError == ERROR_SUCCESS && CompactCB != NULL) - { - CompactBytesProcessed += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)); - CompactBytesProcessed += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock)); - CompactCB(pvUserData, CCB_CLOSING_ARCHIVE, CompactBytesProcessed, CompactTotalBytes); - } - } - - // Invalidate the compact callback - pvUserData = NULL; - CompactCB = NULL; - - // Cleanup and return - if(pTempStream != NULL) - FileStream_Close(pTempStream); - if(pFileKeys != NULL) - STORM_FREE(pFileKeys); - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// Changing hash table size - -DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - - return ha->dwMaxFileCount; -} - -bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount) -{ - TMPQHetTable * pOldHetTable = NULL; - TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pOldFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pOldFileTable = NULL; - TFileEntry * pOldFileEntry; - TFileEntry * pFileEntry; - TMPQHash * pOldHashTable = NULL; - DWORD dwOldHashTableSize = 0; - DWORD dwOldFileTableSize = 0; - int nError = ERROR_SUCCESS; - - // Test the valid parameters - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(ha->dwFlags & MPQ_FLAG_READ_ONLY) - nError = ERROR_ACCESS_DENIED; - - // The new limit must not be lower than the index of the last file entry in the table - if(nError == ERROR_SUCCESS && ha->dwFileTableSize > dwMaxFileCount) - nError = ERROR_DISK_FULL; - - // ALL file names must be known in order to be able - // to rebuild hash table size - if(nError == ERROR_SUCCESS) - { - nError = CheckIfAllFilesKnown(ha, NULL, NULL); - } - - // If the MPQ has a hash table, then we relocate the hash table - if(nError == ERROR_SUCCESS && ha->pHashTable != NULL) - { - // Save parameters for the current hash table - dwOldHashTableSize = ha->pHeader->dwHashTableSize; - pOldHashTable = ha->pHashTable; - - // Allocate new hash table - ha->pHeader->dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount); - ha->pHashTable = STORM_ALLOC(TMPQHash, ha->pHeader->dwHashTableSize); - if(ha->pHashTable != NULL) - memset(ha->pHashTable, 0xFF, ha->pHeader->dwHashTableSize * sizeof(TMPQHash)); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // If the MPQ has HET table, allocate new one as well - if(nError == ERROR_SUCCESS && ha->pHetTable != NULL) - { - // Save the original HET table - pOldHetTable = ha->pHetTable; - - // Create new one - ha->pHetTable = CreateHetTable(dwMaxFileCount, 0x40, true); - if(ha->pHetTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Now reallocate the file table - if(nError == ERROR_SUCCESS) - { - // Save the current file table - dwOldFileTableSize = ha->dwFileTableSize; - pOldFileTable = ha->pFileTable; - - // Create new one - ha->pFileTable = STORM_ALLOC(TFileEntry, dwMaxFileCount); - if(ha->pFileTable != NULL) - memset(ha->pFileTable, 0, dwMaxFileCount * sizeof(TFileEntry)); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Now we have to build both classic hash table and HET table. - if(nError == ERROR_SUCCESS) - { - DWORD dwFileIndex = 0; - DWORD dwHashIndex = 0; - - // Create new hash and HET entry for each file - pFileEntry = ha->pFileTable; - for(pOldFileEntry = pOldFileTable; pOldFileEntry < pOldFileTableEnd; pOldFileEntry++) - { - if(pOldFileEntry->dwFlags & MPQ_FILE_EXISTS) - { - // Copy the old file entry to the new one - memcpy(pFileEntry, pOldFileEntry, sizeof(TFileEntry)); - assert(pFileEntry->szFileName != NULL); - - // Create new entry in the hash table - if(ha->pHashTable != NULL) - { - dwHashIndex = AllocateHashEntry(ha, pFileEntry); - if(dwHashIndex == HASH_ENTRY_FREE) - { - nError = ERROR_CAN_NOT_COMPLETE; - break; - } - } - - // Create new entry in the HET table, if needed - if(ha->pHetTable != NULL) - { - dwHashIndex = AllocateHetEntry(ha, pFileEntry); - if(dwHashIndex == HASH_ENTRY_FREE) - { - nError = ERROR_CAN_NOT_COMPLETE; - break; - } - } - - // Move to the next file entry in the new table - pFileEntry++; - dwFileIndex++; - } - } - } - - // Mark the archive as changed - // Note: We always have to rebuild the (attributes) file due to file table change - if(nError == ERROR_SUCCESS) - { - ha->dwMaxFileCount = dwMaxFileCount; - InvalidateInternalFiles(ha); - } - else - { - // Revert the hash table - if(ha->pHashTable != NULL && pOldHashTable != NULL) - { - STORM_FREE(ha->pHashTable); - ha->pHeader->dwHashTableSize = dwOldHashTableSize; - ha->pHashTable = pOldHashTable; - } - - // Revert the HET table - if(ha->pHetTable != NULL && pOldHetTable != NULL) - { - FreeHetTable(ha->pHetTable); - ha->pHetTable = pOldHetTable; - } - - // Revert the file table - if(pOldFileTable != NULL) - { - STORM_FREE(ha->pFileTable); - ha->pFileTable = pOldFileTable; - } - - SetLastError(nError); - } - - // Return the result - return (nError == ERROR_SUCCESS); -} diff --git a/dep/StormLib/src/SFileCreateArchive.cpp b/dep/StormLib/src/SFileCreateArchive.cpp deleted file mode 100644 index 59f3d3fa9e8..00000000000 --- a/dep/StormLib/src/SFileCreateArchive.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/*****************************************************************************/ -/* SFileCreateArchive.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* MPQ Editing functions */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 24.03.03 1.00 Lad Splitted from SFileOpenArchive.cpp */ -/* 08.06.10 1.00 Lad Renamed to SFileCreateArchive.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local variables - -static const DWORD MpqHeaderSizes[] = -{ - MPQ_HEADER_SIZE_V1, - MPQ_HEADER_SIZE_V2, - MPQ_HEADER_SIZE_V3, - MPQ_HEADER_SIZE_V4 -}; - -//----------------------------------------------------------------------------- -// Local functions - -static USHORT GetSectorSizeShift(DWORD dwSectorSize) -{ - USHORT wSectorSizeShift = 0; - - while(dwSectorSize > 0x200) - { - dwSectorSize >>= 1; - wSectorSizeShift++; - } - - return wSectorSizeShift; -} - -static int WriteNakedMPQHeader(TMPQArchive * ha) -{ - TMPQHeader * pHeader = ha->pHeader; - TMPQHeader Header; - DWORD dwBytesToWrite = pHeader->dwHeaderSize; - int nError = ERROR_SUCCESS; - - // Prepare the naked MPQ header - memset(&Header, 0, sizeof(TMPQHeader)); - Header.dwID = pHeader->dwID; - Header.dwHeaderSize = pHeader->dwHeaderSize; - Header.dwArchiveSize = pHeader->dwHeaderSize; - Header.wFormatVersion = pHeader->wFormatVersion; - Header.wSectorSize = pHeader->wSectorSize; - - // Write it to the file - BSWAP_TMPQHEADER(&Header); - if(!FileStream_Write(ha->pStream, &ha->MpqPos, &Header, dwBytesToWrite)) - nError = GetLastError(); - - return nError; -} - -//----------------------------------------------------------------------------- -// Creates a new MPQ archive. - -bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq) -{ - SFILE_CREATE_MPQ CreateInfo; - - // Fill the create structure - memset(&CreateInfo, 0, sizeof(SFILE_CREATE_MPQ)); - CreateInfo.cbSize = sizeof(SFILE_CREATE_MPQ); - CreateInfo.dwMpqVersion = (dwFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT; - CreateInfo.dwStreamFlags = STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE; - CreateInfo.dwAttrFlags = (dwFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_ATTRIBUTE_ALL : 0; - CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000; - CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0; - CreateInfo.dwMaxFileCount = dwMaxFileCount; - return SFileCreateArchive2(szMpqName, &CreateInfo, phMpq); -} - -bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq) -{ - TFileStream * pStream = NULL; // File stream - TMPQArchive * ha = NULL; // MPQ archive handle - ULONGLONG MpqPos = 0; // Position of MPQ header in the file - HANDLE hMpq = NULL; - DWORD dwBlockTableSize = 0; // Initial block table size - DWORD dwHashTableSize = 0; - DWORD dwMaxFileCount; - int nError = ERROR_SUCCESS; - - // Check the parameters, if they are valid - if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // Verify if all variables in SFILE_CREATE_MPQ are correct - if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ)) || - (pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4) || - (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0) || - (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL) || - (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1)) || - (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1)) || - (pCreateInfo->dwMaxFileCount < 4)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // One time initialization of MPQ cryptography - InitializeMpqCryptography(); - - // We verify if the file already exists and if it's a MPQ archive. - // If yes, we won't allow to overwrite it. - if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq)) - { - SFileCloseArchive(hMpq); - SetLastError(ERROR_ALREADY_EXISTS); - return false; - } - - // - // At this point, we have to create the archive. - // - If the file exists, convert it to MPQ archive. - // - If the file doesn't exist, create new empty file - // - - pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags); - if(pStream == NULL) - { - pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags); - if(pStream == NULL) - return false; - } - - // Increment the maximum amount of files to have space - // for listfile and attributes file - dwMaxFileCount = pCreateInfo->dwMaxFileCount; - if(pCreateInfo->dwAttrFlags != 0) - dwMaxFileCount++; - dwMaxFileCount++; - - // If file count is not zero, initialize the hash table size - dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount); - - // Retrieve the file size and round it up to 0x200 bytes - FileStream_GetSize(pStream, MpqPos); - MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL; - if(!FileStream_SetSize(pStream, MpqPos)) - nError = GetLastError(); - -#ifdef _DEBUG - // Debug code, used for testing StormLib -// dwBlockTableSize = dwHashTableSize * 2; -#endif - - // Create the archive handle - if(nError == ERROR_SUCCESS) - { - if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Fill the MPQ archive handle structure - if(nError == ERROR_SUCCESS) - { - memset(ha, 0, sizeof(TMPQArchive)); - ha->pStream = pStream; - ha->dwSectorSize = pCreateInfo->dwSectorSize; - ha->UserDataPos = MpqPos; - ha->MpqPos = MpqPos; - ha->pHeader = (TMPQHeader *)ha->HeaderData; - ha->dwMaxFileCount = dwMaxFileCount; - ha->dwFileTableSize = 0; - ha->dwFileFlags1 = pCreateInfo->dwFileFlags1; - ha->dwFileFlags2 = pCreateInfo->dwFileFlags2; - ha->dwFlags = 0; - - // Setup the attributes - ha->dwAttrFlags = pCreateInfo->dwAttrFlags; - pStream = NULL; - } - - // Fill the MPQ header - if(nError == ERROR_SUCCESS) - { - TMPQHeader * pHeader = ha->pHeader; - - // Fill the MPQ header - memset(pHeader, 0, sizeof(ha->HeaderData)); - pHeader->dwID = ID_MPQ; - pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion]; - pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash); - pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion; - pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize); - pHeader->dwHashTablePos = pHeader->dwHeaderSize; - pHeader->dwHashTableSize = dwHashTableSize; - pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash); - pHeader->dwBlockTableSize = dwBlockTableSize; - - // For MPQs version 4 and higher, we set the size of raw data block - // for calculating MD5 - if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4) - pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize; - - // Write the naked MPQ header - nError = WriteNakedMPQHeader(ha); - - // Remember that the (listfile) and (attributes) need to be saved - ha->dwFlags |= MPQ_FLAG_CHANGED | MPQ_FLAG_INV_LISTFILE | MPQ_FLAG_INV_ATTRIBUTES; - } - - // Create initial HET table, if the caller required an MPQ format 3.0 or newer - if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3) - { - ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true); - if(ha->pHetTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Create initial hash table - if(nError == ERROR_SUCCESS) - { - nError = CreateHashTable(ha, dwHashTableSize); - } - - // Create initial file table - if(nError == ERROR_SUCCESS) - { - ha->pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount); - if(ha->pFileTable != NULL) - memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * ha->dwMaxFileCount); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Cleanup : If an error, delete all buffers and return - if(nError != ERROR_SUCCESS) - { - FileStream_Close(pStream); - FreeMPQArchive(ha); - SetLastError(nError); - ha = NULL; - } - - // Return the values - *phMpq = (HANDLE)ha; - return (nError == ERROR_SUCCESS); -} diff --git a/dep/StormLib/src/SFileExtractFile.cpp b/dep/StormLib/src/SFileExtractFile.cpp deleted file mode 100644 index c8053ed4e62..00000000000 --- a/dep/StormLib/src/SFileExtractFile.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/*****************************************************************************/ -/* SFileExtractFile.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Simple extracting utility */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 20.06.03 1.00 Lad The first version of SFileExtractFile.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope) -{ - TFileStream * pLocalFile = NULL; - HANDLE hMpqFile = NULL; - int nError = ERROR_SUCCESS; - - // Open the MPQ file - if(nError == ERROR_SUCCESS) - { - if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile)) - nError = GetLastError(); - } - - // Create the local file - if(nError == ERROR_SUCCESS) - { - pLocalFile = FileStream_CreateFile(szExtracted, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); - if(pLocalFile == NULL) - nError = GetLastError(); - } - - // Copy the file's content - if(nError == ERROR_SUCCESS) - { - char szBuffer[0x1000]; - DWORD dwTransferred; - - for(;;) - { - // dwTransferred is only set to nonzero if something has been read. - // nError can be ERROR_SUCCESS or ERROR_HANDLE_EOF - if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL)) - nError = GetLastError(); - if(nError == ERROR_HANDLE_EOF) - nError = ERROR_SUCCESS; - if(dwTransferred == 0) - break; - - // If something has been actually read, write it - if(!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred)) - nError = GetLastError(); - } - } - - // Close the files - if(hMpqFile != NULL) - SFileCloseFile(hMpqFile); - if(pLocalFile != NULL) - FileStream_Close(pLocalFile); - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} diff --git a/dep/StormLib/src/SFileFindFile.cpp b/dep/StormLib/src/SFileFindFile.cpp deleted file mode 100644 index 337be7d2c54..00000000000 --- a/dep/StormLib/src/SFileFindFile.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/*****************************************************************************/ -/* SFileFindFile.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* A module for file searching within MPQs */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 25.03.03 1.00 Lad The first version of SFileFindFile.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Defines - -#define LISTFILE_CACHE_SIZE 0x1000 - -//----------------------------------------------------------------------------- -// Private structure used for file search (search handle) - -struct TMPQSearch; -typedef int (*MPQSEARCH)(TMPQSearch *, SFILE_FIND_DATA *); - -// Used by searching in MPQ archives -struct TMPQSearch -{ - TMPQArchive * ha; // Handle to MPQ, where the search runs - TFileEntry ** pSearchTable; // Table for files that have been already found - DWORD dwSearchTableItems; // Number of items in the search table - DWORD dwNextIndex; // Next file index to be checked - DWORD dwFlagMask; // For checking flag mask - char szSearchMask[1]; // Search mask (variable length) -}; - -//----------------------------------------------------------------------------- -// Local functions - -static bool IsValidSearchHandle(TMPQSearch * hs) -{ - if(hs == NULL) - return false; - - return IsValidMpqHandle(hs->ha); -} - -bool CheckWildCard(const char * szString, const char * szWildCard) -{ - const char * szSubString; - int nSubStringLength; - int nMatchCount = 0; - - // When the mask is empty, it never matches - if(szWildCard == NULL || *szWildCard == 0) - return false; - - // If the wildcard contains just "*", then it always matches - if(szWildCard[0] == '*' && szWildCard[1] == 0) - return true; - - // Do normal test - for(;;) - { - // If there is '?' in the wildcard, we skip one char - while(*szWildCard == '?') - { - szWildCard++; - szString++; - } - - // If there is '*', means zero or more chars. We have to - // find the sequence after '*' - if(*szWildCard == '*') - { - // More stars is equal to one star - while(*szWildCard == '*' || *szWildCard == '?') - szWildCard++; - - // If we found end of the wildcard, it's a match - if(*szWildCard == 0) - return true; - - // Determine the length of the substring in szWildCard - szSubString = szWildCard; - while(*szSubString != 0 && *szSubString != '?' && *szSubString != '*') - szSubString++; - nSubStringLength = (int)(szSubString - szWildCard); - nMatchCount = 0; - - // Now we have to find a substring in szString, - // that matches the substring in szWildCard - while(*szString != 0) - { - // Calculate match count - while(nMatchCount < nSubStringLength) - { - if(toupper(szString[nMatchCount]) != toupper(szWildCard[nMatchCount])) - break; - if(szString[nMatchCount] == 0) - break; - nMatchCount++; - } - - // If the match count has reached substring length, we found a match - if(nMatchCount == nSubStringLength) - { - szWildCard += nMatchCount; - szString += nMatchCount; - break; - } - - // No match, move to the next char in szString - nMatchCount = 0; - szString++; - } - } - else - { - // If we came to the end of the string, compare it to the wildcard - if(toupper(*szString) != toupper(*szWildCard)) - return false; - - // If we arrived to the end of the string, it's a match - if(*szString == 0) - return true; - - // Otherwise, continue in comparing - szWildCard++; - szString++; - } - } -} - -static DWORD GetSearchTableItems(TMPQArchive * ha) -{ - DWORD dwMergeItems = 0; - - // Loop over all patches - while(ha != NULL) - { - // Append the number of files - dwMergeItems += (ha->pHetTable != NULL) ? ha->pHetTable->dwMaxFileCount - : ha->pHeader->dwBlockTableSize; - // Move to the patched archive - ha = ha->haPatch; - } - - // Return the double size of number of items - return (dwMergeItems | 1); -} - -static bool FileWasFoundBefore( - TMPQArchive * ha, - TMPQSearch * hs, - TFileEntry * pFileEntry) -{ - TFileEntry * pEntry; - char * szRealFileName = pFileEntry->szFileName; - DWORD dwStartIndex; - DWORD dwNameHash; - DWORD dwIndex; - - if(hs->pSearchTable != NULL && szRealFileName != NULL) - { - // If we are in patch MPQ, we check if patch prefix matches - // and then trim the patch prefix - if(ha->cchPatchPrefix != 0) - { - // If the patch prefix doesn't fit, we pretend that the file - // was there before and it will be skipped - if(_strnicmp(szRealFileName, ha->szPatchPrefix, ha->cchPatchPrefix)) - return true; - - szRealFileName += ha->cchPatchPrefix; - } - - // Calculate the hash to the table - dwNameHash = HashString(szRealFileName, MPQ_HASH_NAME_A); - dwStartIndex = dwIndex = (dwNameHash % hs->dwSearchTableItems); - - // The file might have been found before - // only if this is not the first MPQ being searched - if(ha->haBase != NULL) - { - // Enumerate all entries in the search table - for(;;) - { - // Get the file entry at that position - pEntry = hs->pSearchTable[dwIndex]; - if(pEntry == NULL) - break; - - if(pEntry->szFileName != NULL) - { - // Does the name match? - if(!_stricmp(pEntry->szFileName, szRealFileName)) - return true; - } - - // Move to the next entry - dwIndex = (dwIndex + 1) % hs->dwSearchTableItems; - if(dwIndex == dwStartIndex) - break; - } - } - - // Put the entry to the table for later use - hs->pSearchTable[dwIndex] = pFileEntry; - } - return false; -} - -static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry) -{ - TFileEntry * pPatchEntry = NULL; - TFileEntry * pTempEntry; - char szFileName[MAX_PATH]; - LCID lcLocale = pFileEntry->lcLocale; - - // Go while there are patches - while(ha->haPatch != NULL) - { - // Move to the patch archive - ha = ha->haPatch; - - // Prepare the prefix for the file name - strcpy(szFileName, ha->szPatchPrefix); - strcat(szFileName, pFileEntry->szFileName); - - // Try to find the file there - pTempEntry = GetFileEntryExact(ha, szFileName, lcLocale); - if(pTempEntry != NULL) - pPatchEntry = pTempEntry; - } - - // Return the found patch entry - return pPatchEntry; -} - -// Performs one MPQ search -static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData) -{ - TMPQArchive * ha = hs->ha; - TFileEntry * pFileTableEnd; - TFileEntry * pPatchEntry; - TFileEntry * pFileEntry; - const char * szFileName; - HANDLE hFile; - char szPseudoName[20]; - DWORD dwBlockIndex; - size_t nPrefixLength; - - // Start searching with base MPQ - while(ha != NULL) - { - // Now parse the file entry table in order to get all files. - pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - pFileEntry = ha->pFileTable + hs->dwNextIndex; - - // Get the length of the patch prefix (0 if none) - nPrefixLength = strlen(ha->szPatchPrefix); - - // Parse the file table - while(pFileEntry < pFileTableEnd) - { - // Increment the next index for subsequent search - hs->dwNextIndex++; - - // Is it a file and not a patch file? - if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS) - { - // Now we have to check if this file was not enumerated before - if(!FileWasFoundBefore(ha, hs, pFileEntry)) - { - // Find a patch to this file - pPatchEntry = FindPatchEntry(ha, pFileEntry); - if(pPatchEntry == NULL) - pPatchEntry = pFileEntry; - - // Prepare the block index - dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable); - - // Get the file name. If it's not known, we will create pseudo-name - szFileName = pFileEntry->szFileName; - if(szFileName == NULL) - { - // Open the file by its pseudo-name. - // This also generates the file name with a proper extension - sprintf(szPseudoName, "File%08u.xxx", dwBlockIndex); - if(SFileOpenFileEx((HANDLE)hs->ha, szPseudoName, SFILE_OPEN_FROM_MPQ, &hFile)) - { - szFileName = (pFileEntry->szFileName != NULL) ? pFileEntry->szFileName : szPseudoName; - SFileCloseFile(hFile); - } - } - - // Check the file name against the wildcard - if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask)) - { - // Fill the found entry - lpFindFileData->dwHashIndex = pPatchEntry->dwHashIndex; - lpFindFileData->dwBlockIndex = dwBlockIndex; - lpFindFileData->dwFileSize = pPatchEntry->dwFileSize; - lpFindFileData->dwFileFlags = pPatchEntry->dwFlags; - lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize; - lpFindFileData->lcLocale = pPatchEntry->lcLocale; - - // Fill the filetime - lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32); - lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime); - - // Fill the file name and plain file name - strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength); - lpFindFileData->szPlainName = (char *)GetPlainFileNameA(lpFindFileData->cFileName); - return ERROR_SUCCESS; - } - - } - } - - pFileEntry++; - } - - // Move to the next patch in the patch chain - hs->ha = ha = ha->haPatch; - hs->dwNextIndex = 0; - } - - // No more files found, return error - return ERROR_NO_MORE_FILES; -} - -static void FreeMPQSearch(TMPQSearch *& hs) -{ - if(hs != NULL) - { - if(hs->pSearchTable != NULL) - STORM_FREE(hs->pSearchTable); - STORM_FREE(hs); - hs = NULL; - } -} - -//----------------------------------------------------------------------------- -// Public functions - -HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TMPQSearch * hs = NULL; - size_t nSize = 0; - int nError = ERROR_SUCCESS; - - // Check for the valid parameters - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(szMask == NULL || lpFindFileData == NULL) - nError = ERROR_INVALID_PARAMETER; - - // Include the listfile into the MPQ's internal listfile - // Note that if the listfile name is NULL, do nothing because the - // internal listfile is always included. - if(nError == ERROR_SUCCESS && szListFile != NULL && *szListFile != 0) - nError = SFileAddListFile((HANDLE)ha, szListFile); - - // Allocate the structure for MPQ search - if(nError == ERROR_SUCCESS) - { - nSize = sizeof(TMPQSearch) + strlen(szMask) + 1; - if((hs = (TMPQSearch *)STORM_ALLOC(char, nSize)) == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Perform the first search - if(nError == ERROR_SUCCESS) - { - memset(hs, 0, sizeof(TMPQSearch)); - strcpy(&hs->szSearchMask[0], szMask); - hs->dwFlagMask = MPQ_FILE_EXISTS; - hs->ha = ha; - - // If the archive is patched archive, we have to create a merge table - // to prevent files being repeated - if(ha->haPatch != NULL) - { - hs->dwSearchTableItems = GetSearchTableItems(ha); - hs->pSearchTable = STORM_ALLOC(TFileEntry *, hs->dwSearchTableItems); - hs->dwFlagMask = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE; - if(hs->pSearchTable != NULL) - memset(hs->pSearchTable, 0, hs->dwSearchTableItems * sizeof(TFileEntry *)); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - } - - // Perform first item searching - if(nError == ERROR_SUCCESS) - { - nError = DoMPQSearch(hs, lpFindFileData); - } - - // Cleanup - if(nError != ERROR_SUCCESS) - { - FreeMPQSearch(hs); - SetLastError(nError); - } - - // Return the result value - return (HANDLE)hs; -} - -bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData) -{ - TMPQSearch * hs = (TMPQSearch *)hFind; - int nError = ERROR_SUCCESS; - - // Check the parameters - if(!IsValidSearchHandle(hs)) - nError = ERROR_INVALID_HANDLE; - if(lpFindFileData == NULL) - nError = ERROR_INVALID_PARAMETER; - - if(nError == ERROR_SUCCESS) - nError = DoMPQSearch(hs, lpFindFileData); - - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -bool WINAPI SFileFindClose(HANDLE hFind) -{ - TMPQSearch * hs = (TMPQSearch *)hFind; - - // Check the parameters - if(!IsValidSearchHandle(hs)) - { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - FreeMPQSearch(hs); - return true; -} diff --git a/dep/StormLib/src/SFileListFile.cpp b/dep/StormLib/src/SFileListFile.cpp deleted file mode 100644 index 4604206ed0a..00000000000 --- a/dep/StormLib/src/SFileListFile.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/*****************************************************************************/ -/* SListFile.cpp Copyright (c) Ladislav Zezula 2004 */ -/*---------------------------------------------------------------------------*/ -/* Description: */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 12.06.04 1.00 Lad The first version of SListFile.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" -#include <assert.h> - -//----------------------------------------------------------------------------- -// Listfile entry structure - -#define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer - -struct TListFileCache -{ - HANDLE hFile; // Stormlib file handle - char * szMask; // File mask - DWORD dwFileSize; // Total size of the cached file - DWORD dwFilePos; // Position of the cache in the file - BYTE * pBegin; // The begin of the listfile cache - BYTE * pPos; - BYTE * pEnd; // The last character in the file cache - - BYTE Buffer[CACHE_BUFFER_SIZE]; // Listfile cache itself -}; - -//----------------------------------------------------------------------------- -// Local functions (cache) - -static TListFileCache * CreateListFileCache(HANDLE hMpq, const char * szListFile) -{ - TListFileCache * pCache = NULL; - HANDLE hListFile = NULL; - DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE; - DWORD dwBytesRead = 0; - int nError = ERROR_SUCCESS; - - // If the szListFile is NULL, it means we have to open internal listfile - if(szListFile == NULL) - { - // Use SFILE_OPEN_ANY_LOCALE for listfile. This will allow us to load - // the listfile even if there is only non-neutral version of the listfile in the MPQ - dwSearchScope = SFILE_OPEN_ANY_LOCALE; - szListFile = LISTFILE_NAME; - } - - // Open the local/internal listfile - if(SFileOpenFileEx(hMpq, szListFile, dwSearchScope, &hListFile)) - { - TMPQArchive * ha = (TMPQArchive *)hMpq; - TMPQFile * hf = (TMPQFile *)hListFile; - - // Remember flags for (listfile) - if(hf->pFileEntry != NULL) - ha->dwFileFlags1 = hf->pFileEntry->dwFlags; - } - else - nError = GetLastError(); - - // Allocate cache for one file block - if(nError == ERROR_SUCCESS) - { - pCache = (TListFileCache *)STORM_ALLOC(TListFileCache, 1); - if(pCache == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - if(nError == ERROR_SUCCESS) - { - // Initialize the file cache - memset(pCache, 0, sizeof(TListFileCache)); - pCache->dwFileSize = SFileGetFileSize(hListFile, NULL); - pCache->hFile = hListFile; - - // Fill the cache - SFileReadFile(hListFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL); - if(dwBytesRead == 0) - nError = GetLastError(); - } - - // Initialize the pointers - if(nError == ERROR_SUCCESS) - { - pCache->pBegin = - pCache->pPos = &pCache->Buffer[0]; - pCache->pEnd = pCache->pBegin + dwBytesRead; - } - else - { - SListFileFindClose((HANDLE)pCache); - SetLastError(nError); - pCache = NULL; - } - - // Return the cache - return pCache; -} - -// Reloads the cache. Returns number of characters -// that has been loaded into the cache. -static DWORD ReloadListFileCache(TListFileCache * pCache) -{ - DWORD dwBytesToRead; - DWORD dwBytesRead = 0; - - // Only do something if the cache is empty - if(pCache->pPos >= pCache->pEnd) - { -// __TryReadBlock: - - // Move the file position forward - pCache->dwFilePos += CACHE_BUFFER_SIZE; - if(pCache->dwFilePos >= pCache->dwFileSize) - return 0; - - // Get the number of bytes remaining - dwBytesToRead = pCache->dwFileSize - pCache->dwFilePos; - if(dwBytesToRead > CACHE_BUFFER_SIZE) - dwBytesToRead = CACHE_BUFFER_SIZE; - - // Load the next data chunk to the cache - SFileSetFilePointer(pCache->hFile, pCache->dwFilePos, NULL, FILE_BEGIN); - SFileReadFile(pCache->hFile, pCache->Buffer, CACHE_BUFFER_SIZE, &dwBytesRead, NULL); - - // If we didn't read anything, it might mean that the block - // of the file is not available (in case of partial MPQs). - // We stop reading the file at this point, because the rest - // of the listfile is unreliable - if(dwBytesRead == 0) - return 0; - - // Set the buffer pointers - pCache->pBegin = - pCache->pPos = &pCache->Buffer[0]; - pCache->pEnd = pCache->pBegin + dwBytesRead; - } - - return dwBytesRead; -} - -static size_t ReadListFileLine(TListFileCache * pCache, char * szLine, int nMaxChars) -{ - char * szLineBegin = szLine; - char * szLineEnd = szLine + nMaxChars - 1; - char * szExtraString = NULL; - - // Skip newlines, spaces, tabs and another non-printable stuff - for(;;) - { - // If we need to reload the cache, do it - if(pCache->pPos == pCache->pEnd) - { - if(ReloadListFileCache(pCache) == 0) - break; - } - - // If we found a non-whitespace character, stop - if(*pCache->pPos > 0x20) - break; - - // Skip the character - pCache->pPos++; - } - - // Copy the remaining characters - while(szLine < szLineEnd) - { - // If we need to reload the cache, do it now and resume copying - if(pCache->pPos == pCache->pEnd) - { - if(ReloadListFileCache(pCache) == 0) - break; - } - - // If we have found a newline, stop loading - if(*pCache->pPos == 0x0D || *pCache->pPos == 0x0A) - break; - - // Blizzard listfiles can also contain information about patch: - // Pass1\Files\MacOS\unconditional\user\Background Downloader.app\Contents\Info.plist~Patch(Data#frFR#base-frFR,1326) - if(*pCache->pPos == '~') - szExtraString = szLine; - - // Copy the character - *szLine++ = *pCache->pPos++; - } - - // Terminate line with zero - *szLine = 0; - - // If there was extra string after the file name, clear it - if(szExtraString != NULL) - { - if(szExtraString[0] == '~' && szExtraString[1] == 'P') - { - szLine = szExtraString; - *szExtraString = 0; - } - } - - // Return the length of the line - return (szLine - szLineBegin); -} - -static int CompareFileNodes(const void * p1, const void * p2) -{ - char * szFileName1 = *(char **)p1; - char * szFileName2 = *(char **)p2; - - return _stricmp(szFileName1, szFileName2); -} - -static int WriteListFileLine( - TMPQFile * hf, - const char * szLine) -{ - char szNewLine[2] = {0x0D, 0x0A}; - size_t nLength = strlen(szLine); - int nError; - - nError = SFileAddFile_Write(hf, szLine, (DWORD)nLength, MPQ_COMPRESSION_ZLIB); - if(nError != ERROR_SUCCESS) - return nError; - - return SFileAddFile_Write(hf, szNewLine, sizeof(szNewLine), MPQ_COMPRESSION_ZLIB); -} - -//----------------------------------------------------------------------------- -// Local functions (listfile nodes) - -// Adds a name into the list of all names. For each locale in the MPQ, -// one entry will be created -// If the file name is already there, does nothing. -int SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szFileName) -{ - TMPQHeader * pHeader = ha->pHeader; - TFileEntry * pFileEntry; - TMPQHash * pFirstHash; - TMPQHash * pHash; - bool bNameEntryCreated = false; - - // If we have HET table, use that one - if(ha->pHetTable != NULL) - { - pFileEntry = GetFileEntryAny(ha, szFileName); - if(pFileEntry != NULL) - { - // Allocate file name for the file entry - AllocateFileName(pFileEntry, szFileName); - bNameEntryCreated = true; - } - - return ERROR_SUCCESS; - } - - // If we have hash table, we use it - if(bNameEntryCreated == false && ha->pHashTable != NULL) - { - // Look for the first hash table entry for the file - pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); - - // Go while we found something - while(pHash != NULL) - { - // Is it a valid file table index ? - if(pHash->dwBlockIndex < pHeader->dwBlockTableSize) - { - // Allocate file name for the file entry - AllocateFileName(ha->pFileTable + pHash->dwBlockIndex, szFileName); - bNameEntryCreated = true; - } - - // Now find the next language version of the file - pHash = GetNextHashEntry(ha, pFirstHash, pHash); - } - } - - return ERROR_CAN_NOT_COMPLETE; -} - -// Saves the whole listfile into the MPQ. -int SListFileSaveToMpq(TMPQArchive * ha) -{ - TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pFileEntry; - TMPQFile * hf = NULL; - char * szPrevItem; - char ** SortTable = NULL; - DWORD dwFileSize = 0; - size_t nFileNodes = 0; - size_t i; - int nError = ERROR_SUCCESS; - - // Allocate the table for sorting listfile - SortTable = STORM_ALLOC(char*, ha->dwFileTableSize); - if(SortTable == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Construct the sort table - // Note: in MPQs with multiple locale versions of the same file, - // this code causes adding multiple listfile entries. - // Since those MPQs were last time used in Starcraft, - // we leave it as it is. - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) - { - // Only take existing items - if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) && pFileEntry->szFileName != NULL) - { - // Ignore pseudo-names - if(!IsPseudoFileName(pFileEntry->szFileName, NULL) && !IsInternalMpqFileName(pFileEntry->szFileName)) - { - SortTable[nFileNodes++] = pFileEntry->szFileName; - } - } - } - - // Sort the table - qsort(SortTable, nFileNodes, sizeof(char *), CompareFileNodes); - - // Now parse the table of file names again - remove duplicates - // and count file size. - if(nFileNodes != 0) - { - // Count the 0-th item - dwFileSize += (DWORD)strlen(SortTable[0]) + 2; - szPrevItem = SortTable[0]; - - // Count all next items - for(i = 1; i < nFileNodes; i++) - { - // If the item is the same like the last one, skip it - if(_stricmp(SortTable[i], szPrevItem)) - { - dwFileSize += (DWORD)strlen(SortTable[i]) + 2; - szPrevItem = SortTable[i]; - } - } - - // Determine the flags for (listfile) - if(ha->dwFileFlags1 == 0) - ha->dwFileFlags1 = GetDefaultSpecialFileFlags(ha, dwFileSize); - - // Create the listfile in the MPQ - nError = SFileAddFile_Init(ha, LISTFILE_NAME, - 0, - dwFileSize, - LANG_NEUTRAL, - ha->dwFileFlags1 | MPQ_FILE_REPLACEEXISTING, - &hf); - // Add all file names - if(nError == ERROR_SUCCESS) - { - // Each name is followed by newline ("\x0D\x0A") - szPrevItem = SortTable[0]; - nError = WriteListFileLine(hf, SortTable[0]); - - // Count all next items - for(i = 1; i < nFileNodes; i++) - { - // If the item is the same like the last one, skip it - if(_stricmp(SortTable[i], szPrevItem)) - { - WriteListFileLine(hf, SortTable[i]); - szPrevItem = SortTable[i]; - } - } - } - } - else - { - // Create the listfile in the MPQ - dwFileSize = (DWORD)strlen(LISTFILE_NAME) + 2; - nError = SFileAddFile_Init(ha, LISTFILE_NAME, - 0, - dwFileSize, - LANG_NEUTRAL, - MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING, - &hf); - - // Just add "(listfile)" there - if(nError == ERROR_SUCCESS) - { - WriteListFileLine(hf, LISTFILE_NAME); - } - } - - // Finalize the file in the MPQ - if(hf != NULL) - { - SFileAddFile_Finish(hf); - } - - // Free buffers - if(nError == ERROR_SUCCESS) - ha->dwFlags &= ~MPQ_FLAG_INV_LISTFILE; - if(SortTable != NULL) - STORM_FREE(SortTable); - return nError; -} - -//----------------------------------------------------------------------------- -// File functions - -// Adds a listfile into the MPQ archive. -// Note that the function does not remove the -int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile) -{ - TListFileCache * pCache = NULL; - TMPQArchive * ha = (TMPQArchive *)hMpq; - char szFileName[MAX_PATH]; - size_t nLength = 0; - int nError = ERROR_SUCCESS; - - // Add the listfile for each MPQ in the patch chain - while(ha != NULL) - { - // Load the listfile to cache - pCache = CreateListFileCache(hMpq, szListFile); - if(pCache == NULL) - { - nError = GetLastError(); - break; - } - - // Load the node list. Add the node for every locale in the archive - while((nLength = ReadListFileLine(pCache, szFileName, sizeof(szFileName))) > 0) - SListFileCreateNodeForAllLocales(ha, szFileName); - - // Also, add three special files to the listfile: - // (listfile) itself, (attributes) and (signature) - SListFileCreateNodeForAllLocales(ha, LISTFILE_NAME); - SListFileCreateNodeForAllLocales(ha, SIGNATURE_NAME); - SListFileCreateNodeForAllLocales(ha, ATTRIBUTES_NAME); - - // Delete the cache - SListFileFindClose((HANDLE)pCache); - - // Move to the next archive in the chain - ha = ha->haPatch; - } - - return nError; -} - -//----------------------------------------------------------------------------- -// Passing through the listfile - -HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData) -{ - TListFileCache * pCache = NULL; - size_t nLength = 0; - int nError = ERROR_SUCCESS; - - // Initialize the structure with zeros - memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); - - // Load the listfile to cache - pCache = CreateListFileCache(hMpq, szListFile); - if(pCache == NULL) - nError = GetLastError(); - - // Allocate file mask - if(nError == ERROR_SUCCESS && szMask != NULL) - { - pCache->szMask = STORM_ALLOC(char, strlen(szMask) + 1); - if(pCache->szMask != NULL) - strcpy(pCache->szMask, szMask); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Perform file search - if(nError == ERROR_SUCCESS) - { - for(;;) - { - // Read the (next) line - nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName)); - if(nLength == 0) - { - nError = ERROR_NO_MORE_FILES; - break; - } - - // If some mask entered, check it - if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask)) - break; - } - } - - // Cleanup & exit - if(nError != ERROR_SUCCESS) - { - memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); - SListFileFindClose((HANDLE)pCache); - pCache = NULL; - - SetLastError(nError); - } - return (HANDLE)pCache; -} - -bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData) -{ - TListFileCache * pCache = (TListFileCache *)hFind; - size_t nLength; - bool bResult = false; - int nError = ERROR_SUCCESS; - - for(;;) - { - // Read the (next) line - nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName)); - if(nLength == 0) - { - nError = ERROR_NO_MORE_FILES; - break; - } - - // If some mask entered, check it - if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask)) - { - bResult = true; - break; - } - } - - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return bResult; -} - -bool WINAPI SListFileFindClose(HANDLE hFind) -{ - TListFileCache * pCache = (TListFileCache *)hFind; - - if(pCache != NULL) - { - if(pCache->hFile != NULL) - SFileCloseFile(pCache->hFile); - if(pCache->szMask != NULL) - STORM_FREE(pCache->szMask); - - STORM_FREE(pCache); - return true; - } - - return false; -} - diff --git a/dep/StormLib/src/SFileOpenArchive.cpp b/dep/StormLib/src/SFileOpenArchive.cpp deleted file mode 100644 index b36b7d35ea7..00000000000 --- a/dep/StormLib/src/SFileOpenArchive.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/*****************************************************************************/ -/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */ -/* */ -/* Author : Ladislav Zezula */ -/* E-mail : ladik@zezula.net */ -/* WWW : www.zezula.net */ -/*---------------------------------------------------------------------------*/ -/* Archive functions of Storm.dll */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.xx 1.00 Lad The first version of SFileOpenArchive.cpp */ -/* 19.11.03 1.01 Dan Big endian handling */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -/*****************************************************************************/ -/* Local functions */ -/*****************************************************************************/ - -static bool IsAviFile(void * pvFileBegin) -{ - LPDWORD AviHeader = (DWORD *)pvFileBegin; - DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(AviHeader[0]); - DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(AviHeader[2]); - DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(AviHeader[3]); - - // Test for 'RIFF', 'AVI ' or 'LIST' - return (DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C); -} - -static TFileBitmap * CreateFileBitmap(TMPQArchive * ha, TMPQBitmap * pMpqBitmap, bool bFileIsComplete) -{ - TFileBitmap * pBitmap; - size_t nLength; - - // Calculate the length of the bitmap in blocks and in bytes - nLength = (size_t)(((ha->pHeader->ArchiveSize64 - 1) / pMpqBitmap->dwBlockSize) + 1); - nLength = (size_t)(((nLength - 1) / 8) + 1); - - // Allocate the file bitmap - pBitmap = (TFileBitmap *)STORM_ALLOC(BYTE, sizeof(TFileBitmap) + nLength); - if(pBitmap != NULL) - { - // Fill the structure - pBitmap->StartOffset = ha->MpqPos; - pBitmap->EndOffset = ha->MpqPos + ha->pHeader->ArchiveSize64; - pBitmap->IsComplete = bFileIsComplete ? 1 : 0; - pBitmap->BitmapSize = (DWORD)nLength; - pBitmap->BlockSize = pMpqBitmap->dwBlockSize; - pBitmap->Reserved = 0; - - // Copy the file bitmap - memcpy((pBitmap + 1), (pMpqBitmap + 1), nLength); - } - - return pBitmap; -} - -// This function gets the right positions of the hash table and the block table. -static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize) -{ - TMPQHeader * pHeader = ha->pHeader; - ULONGLONG ByteOffset; - - // Check the begin of HET table - if(pHeader->HetTablePos64) - { - ByteOffset = ha->MpqPos + pHeader->HetTablePos64; - if(ByteOffset > FileSize) - return ERROR_BAD_FORMAT; - } - - // Check the begin of BET table - if(pHeader->BetTablePos64) - { - ByteOffset = ha->MpqPos + pHeader->BetTablePos64; - if(ByteOffset > FileSize) - return ERROR_BAD_FORMAT; - } - - // Check the begin of hash table - if(pHeader->wHashTablePosHi || pHeader->dwHashTablePos) - { - ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos); - if(ByteOffset > FileSize) - return ERROR_BAD_FORMAT; - } - - // Check the begin of block table - if(pHeader->wBlockTablePosHi || pHeader->dwBlockTablePos) - { - ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos); - if(ByteOffset > FileSize) - return ERROR_BAD_FORMAT; - } - - // Check the begin of hi-block table - if(pHeader->HiBlockTablePos64 != 0) - { - ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64; - if(ByteOffset > FileSize) - return ERROR_BAD_FORMAT; - } - - // All OK. - return ERROR_SUCCESS; -} - - -/*****************************************************************************/ -/* Public functions */ -/*****************************************************************************/ - -//----------------------------------------------------------------------------- -// SFileGetLocale and SFileSetLocale -// Set the locale for all newly opened files - -LCID WINAPI SFileGetLocale() -{ - return lcFileLocale; -} - -LCID WINAPI SFileSetLocale(LCID lcNewLocale) -{ - lcFileLocale = lcNewLocale; - return lcFileLocale; -} - -//----------------------------------------------------------------------------- -// SFileOpenArchive -// -// szFileName - MPQ archive file name to open -// dwPriority - When SFileOpenFileEx called, this contains the search priority for searched archives -// dwFlags - See MPQ_OPEN_XXX in StormLib.h -// phMpq - Pointer to store open archive handle - -bool WINAPI SFileOpenArchive( - const TCHAR * szMpqName, - DWORD dwPriority, - DWORD dwFlags, - HANDLE * phMpq) -{ - TFileStream * pStream = NULL; // Open file stream - TMPQArchive * ha = NULL; // Archive handle - ULONGLONG FileSize = 0; // Size of the file - int nError = ERROR_SUCCESS; - - // Verify the parameters - if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL) - nError = ERROR_INVALID_PARAMETER; - - // One time initialization of MPQ cryptography - InitializeMpqCryptography(); - dwPriority = dwPriority; - - // Open the MPQ archive file - if(nError == ERROR_SUCCESS) - { - // Initialize the stream - pStream = FileStream_OpenFile(szMpqName, (dwFlags & STREAM_OPTIONS_MASK)); - if(pStream == NULL) - nError = GetLastError(); - } - - // Allocate the MPQhandle - if(nError == ERROR_SUCCESS) - { - FileStream_GetSize(pStream, FileSize); - if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Initialize handle structure and allocate structure for MPQ header - if(nError == ERROR_SUCCESS) - { - memset(ha, 0, sizeof(TMPQArchive)); - ha->pStream = pStream; - pStream = NULL; - - // Remember if the archive is open for write - if(FileStream_IsReadOnly(ha->pStream)) - ha->dwFlags |= MPQ_FLAG_READ_ONLY; - - // Also remember if we shall check sector CRCs when reading file - if(dwFlags & MPQ_OPEN_CHECK_SECTOR_CRC) - ha->dwFlags |= MPQ_FLAG_CHECK_SECTOR_CRC; - } - - // Find the offset of MPQ header within the file - if(nError == ERROR_SUCCESS) - { - ULONGLONG SearchPos = 0; - DWORD dwHeaderID; - - while(SearchPos < FileSize) - { - DWORD dwBytesAvailable = MPQ_HEADER_SIZE_V4; - - // Cut the bytes available, if needed - if((FileSize - SearchPos) < MPQ_HEADER_SIZE_V4) - dwBytesAvailable = (DWORD)(FileSize - SearchPos); - - // Read the eventual MPQ header - if(!FileStream_Read(ha->pStream, &SearchPos, ha->HeaderData, dwBytesAvailable)) - { - nError = GetLastError(); - break; - } - - // There are AVI files from Warcraft III with 'MPQ' extension. - if(SearchPos == 0 && IsAviFile(ha->HeaderData)) - { - nError = ERROR_AVI_FILE; - break; - } - - // If there is the MPQ user data signature, process it - dwHeaderID = BSWAP_INT32_UNSIGNED(*(LPDWORD)ha->HeaderData); - if(dwHeaderID == ID_MPQ_USERDATA && ha->pUserData == NULL) - { - // Ignore the MPQ user data completely if the caller wants to open the MPQ as V1.0 - if((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0) - { - // Fill the user data header - ha->pUserData = &ha->UserData; - memcpy(ha->pUserData, ha->HeaderData, sizeof(TMPQUserData)); - BSWAP_TMPQUSERDATA(ha->pUserData); - - // Remember the position of the user data and continue search - ha->UserDataPos = SearchPos; - SearchPos += ha->pUserData->dwHeaderOffs; - continue; - } - } - - // There must be MPQ header signature - if(dwHeaderID == ID_MPQ) - { - // Save the position where the MPQ header has been found - if(ha->pUserData == NULL) - ha->UserDataPos = SearchPos; - ha->pHeader = (TMPQHeader *)ha->HeaderData; - ha->MpqPos = SearchPos; - - // Now convert the header to version 4 - BSWAP_TMPQHEADER(ha->pHeader); - nError = ConvertMpqHeaderToFormat4(ha, FileSize, dwFlags); - break; - } - - // Move to the next possible offset - SearchPos += 0x200; - } - - // If we haven't found MPQ header in the file, it's an error - if(ha->pHeader == NULL) - nError = ERROR_BAD_FORMAT; - } - - // Fix table positions according to format - if(nError == ERROR_SUCCESS) - { - // Dump the header -// DumpMpqHeader(ha->pHeader); - - // W3x Map Protectors use the fact that War3's Storm.dll ignores the MPQ user data, - // and probably ignores the MPQ format version as well. The trick is to - // fake MPQ format 2, with an improper hi-word position of hash table and block table - // We can overcome such protectors by forcing opening the archive as MPQ v 1.0 - if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) - { - ha->pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1; - ha->pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; - ha->dwFlags |= MPQ_FLAG_READ_ONLY; - ha->pUserData = NULL; - } - - // Both MPQ_OPEN_NO_LISTFILE or MPQ_OPEN_NO_ATTRIBUTES trigger read only mode - if(dwFlags & (MPQ_OPEN_NO_LISTFILE | MPQ_OPEN_NO_ATTRIBUTES)) - ha->dwFlags |= MPQ_FLAG_READ_ONLY; - - // Set the size of file sector - ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize); - - // Verify if any of the tables doesn't start beyond the end of the file - nError = VerifyMpqTablePositions(ha, FileSize); - } - - // Check if the MPQ has data bitmap. If yes, we can verify if the MPQ is complete - if(nError == ERROR_SUCCESS && ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4) - { - TFileBitmap * pBitmap; - bool bFileIsComplete = true; - - LoadMpqDataBitmap(ha, FileSize, &bFileIsComplete); - if(ha->pBitmap != NULL && bFileIsComplete == false) - { - // Convert the MPQ bitmap to the file bitmap - pBitmap = CreateFileBitmap(ha, ha->pBitmap, bFileIsComplete); - - // Set the data bitmap into the file stream for additional checks - FileStream_SetBitmap(ha->pStream, pBitmap); - ha->dwFlags |= MPQ_FLAG_READ_ONLY; - } - } - - // Read the hash table. Ignore the result, as hash table is no longer required - // Read HET table. Ignore the result, as HET table is no longer required - if(nError == ERROR_SUCCESS) - { - nError = LoadAnyHashTable(ha); - } - - // Now, build the file table. It will be built by combining - // the block table, BET table, hi-block table, (attributes) and (listfile). - if(nError == ERROR_SUCCESS) - { - nError = BuildFileTable(ha, FileSize); - } - - // Verify the file table, if no kind of protection was detected - if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_PROTECTED) == 0) - { - TFileEntry * pFileTableEnd = ha->pFileTable + ha->pHeader->dwBlockTableSize; - TFileEntry * pFileEntry = ha->pFileTable; -// ULONGLONG ArchiveSize = 0; - ULONGLONG RawFilePos; - - // Parse all file entries - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) - { - // If that file entry is valid, check the file position - if(pFileEntry->dwFlags & MPQ_FILE_EXISTS) - { - // Get the 64-bit file position, - // relative to the begin of the file - RawFilePos = ha->MpqPos + pFileEntry->ByteOffset; - - // Begin of the file must be within range - if(RawFilePos > FileSize) - { - nError = ERROR_FILE_CORRUPT; - break; - } - - // End of the file must be within range - RawFilePos += pFileEntry->dwCmpSize; - if(RawFilePos > FileSize) - { - nError = ERROR_FILE_CORRUPT; - break; - } - - // Also, we remember end of the file -// if(RawFilePos > ArchiveSize) -// ArchiveSize = RawFilePos; - } - } - } - - // Load the internal listfile and include it to the file table - if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_LISTFILE) == 0) - { - // Ignore result of the operation. (listfile) is optional. - SFileAddListFile((HANDLE)ha, NULL); - } - - // Load the "(attributes)" file and merge it to the file table - if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_ATTRIBUTES) == 0) - { - // Ignore result of the operation. (attributes) is optional. - SAttrLoadAttributes(ha); - } - - // Cleanup and exit - if(nError != ERROR_SUCCESS) - { - FileStream_Close(pStream); - FreeMPQArchive(ha); - SetLastError(nError); - ha = NULL; - } - - *phMpq = ha; - return (nError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// SFileGetArchiveBitmap - -bool WINAPI SFileGetArchiveBitmap(HANDLE hMpq, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - - return FileStream_GetBitmap(ha->pStream, pBitmap, Length, LengthNeeded); -} - -//----------------------------------------------------------------------------- -// bool SFileFlushArchive(HANDLE hMpq) -// -// Saves all dirty data into MPQ archive. -// Has similar effect like SFileCloseArchive, but the archive is not closed. -// Use on clients who keep MPQ archive open even for write operations, -// and terminating without calling SFileCloseArchive might corrupt the archive. -// - -bool WINAPI SFileFlushArchive(HANDLE hMpq) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - int nResultError = ERROR_SUCCESS; - int nError; - - // Do nothing if 'hMpq' is bad parameter - if(!IsValidMpqHandle(ha)) - { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // If the (listfile) has been invalidated, save it - if(ha->dwFlags & MPQ_FLAG_INV_LISTFILE) - { - nError = SListFileSaveToMpq(ha); - if(nError != ERROR_SUCCESS) - nResultError = nError; - } - - // If the (attributes) has been invalidated, save it - if(ha->dwFlags & MPQ_FLAG_INV_ATTRIBUTES) - { - nError = SAttrFileSaveToMpq(ha); - if(nError != ERROR_SUCCESS) - nResultError = nError; - } - - // Save HET table, BET table, hash table, block table, hi-block table - if(ha->dwFlags & MPQ_FLAG_CHANGED) - { - nError = SaveMPQTables(ha); - if(nError != ERROR_SUCCESS) - nResultError = nError; - } - - // Return the error - if(nResultError != ERROR_SUCCESS) - SetLastError(nResultError); - return (nResultError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// bool SFileCloseArchive(HANDLE hMpq); -// - -bool WINAPI SFileCloseArchive(HANDLE hMpq) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - bool bResult; - - // Flush all unsaved data to the storage - bResult = SFileFlushArchive(hMpq); - - // Free all memory used by MPQ archive - FreeMPQArchive(ha); - return bResult; -} - diff --git a/dep/StormLib/src/SFileOpenFileEx.cpp b/dep/StormLib/src/SFileOpenFileEx.cpp deleted file mode 100644 index e03a8b17998..00000000000 --- a/dep/StormLib/src/SFileOpenFileEx.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/*****************************************************************************/ -/* SFileOpenFileEx.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Description : */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.99 1.00 Lad The first version of SFileOpenFileEx.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -/*****************************************************************************/ -/* Local functions */ -/*****************************************************************************/ - -static bool OpenLocalFile(const char * szFileName, HANDLE * phFile) -{ - TFileStream * pStream; - TMPQFile * hf = NULL; - - // We have to convert the local file name to UNICODE, if needed -#ifdef _UNICODE - TCHAR szFileNameT[MAX_PATH]; - int i; - - for(i = 0; szFileName[i] != 0; i++) - szFileNameT[i] = szFileName[i]; - szFileNameT[i] = 0; - pStream = FileStream_OpenFile(szFileNameT, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); - -#else - pStream = FileStream_OpenFile(szFileName, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE); -#endif - - if(pStream != NULL) - { - // Allocate and initialize file handle - hf = CreateMpqFile(NULL); - if(hf != NULL) - { - hf->pStream = pStream; - *phFile = hf; - return true; - } - else - { - FileStream_Close(pStream); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - } - } - *phFile = NULL; - return false; -} - -bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, DWORD dwReserved, HANDLE * phFile) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TMPQFile * hfPatch; // Pointer to patch file - TMPQFile * hfBase = NULL; // Pointer to base open file - TMPQFile * hfLast = NULL; // The highest file in the chain that is not patch file - TMPQFile * hf = NULL; - HANDLE hPatchFile; - char szPatchFileName[MAX_PATH]; - - // Keep this flag here for future updates - dwReserved = dwReserved; - - // First of all, try to open the original version of the file in any of the patch chain - while(ha != NULL) - { - // Construct the name of the patch file - strcpy(szPatchFileName, ha->szPatchPrefix); - strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName); - if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_FROM_MPQ, (HANDLE *)&hfBase)) - { - // The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE - if((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) - { - hf = hfLast = hfBase; - break; - } - - SFileCloseFile((HANDLE)hfBase); - } - - // Move to the next file in the patch chain - ha = ha->haPatch; - } - - // If we couldn't find the file in any of the patches, it doesn't exist - if(hf == NULL) - { - SetLastError(ERROR_FILE_NOT_FOUND); - return false; - } - - // Now keep going in the patch chain and open every patch file that is there - for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch) - { - // Construct patch file name - strcpy(szPatchFileName, ha->szPatchPrefix); - strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName); - if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_FROM_MPQ, &hPatchFile)) - { - // Remember the new version - hfPatch = (TMPQFile *)hPatchFile; - - // If we encountered a full replacement of the file, - // we have to remember the highest full file - if((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) - hfLast = hfPatch; - - // Set current patch to base file and move on - hf->hfPatchFile = hfPatch; - hf = hfPatch; - } - } - - // Now we need to free all files that are below the highest unpatched version - while(hfBase != hfLast) - { - TMPQFile * hfNext = hfBase->hfPatchFile; - - // Free the file below - hfBase->hfPatchFile = NULL; - FreeMPQFile(hfBase); - - // Move the base to the next file - hfBase = hfNext; - } - - // Give the updated base MPQ - if(phFile != NULL) - *phFile = (HANDLE)hfBase; - return true; -} - -/*****************************************************************************/ -/* Public functions */ -/*****************************************************************************/ - -//----------------------------------------------------------------------------- -// SFileEnumLocales enums all locale versions within MPQ. -// Functions fills all available language identifiers on a file into the buffer -// pointed by plcLocales. There must be enough entries to copy the localed, -// otherwise the function returns ERROR_INSUFFICIENT_BUFFER. - -int WINAPI SFileEnumLocales( - HANDLE hMpq, - const char * szFileName, - LCID * plcLocales, - LPDWORD pdwMaxLocales, - DWORD dwSearchScope) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pFileEntry; - TMPQHash * pFirstHash; - TMPQHash * pHash; - DWORD dwFileIndex = 0; - DWORD dwLocales = 0; - - // Test the parameters - if(!IsValidMpqHandle(ha)) - return ERROR_INVALID_HANDLE; - if(szFileName == NULL || *szFileName == 0) - return ERROR_INVALID_PARAMETER; - if(pdwMaxLocales == NULL) - return ERROR_INVALID_PARAMETER; - - // Keep compiler happy - dwSearchScope = dwSearchScope; - - // Parse hash table entries for all locales - if(!IsPseudoFileName(szFileName, &dwFileIndex)) - { - // Calculate the number of locales - pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); - while(pHash != NULL) - { - dwLocales++; - pHash = GetNextHashEntry(ha, pFirstHash, pHash); - } - - // Test if there is enough space to copy the locales - if(*pdwMaxLocales < dwLocales) - { - *pdwMaxLocales = dwLocales; - return ERROR_INSUFFICIENT_BUFFER; - } - - // Enum the locales - pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); - while(pHash != NULL) - { - *plcLocales++ = pHash->lcLocale; - pHash = GetNextHashEntry(ha, pFirstHash, pHash); - } - } - else - { - // There must be space for 1 locale - if(*pdwMaxLocales < 1) - { - *pdwMaxLocales = 1; - return ERROR_INSUFFICIENT_BUFFER; - } - - // For nameless access, always return 1 locale - pFileEntry = GetFileEntryByIndex(ha, dwFileIndex); - pHash = ha->pHashTable + pFileEntry->dwHashIndex; - *plcLocales = pHash->lcLocale; - dwLocales = 1; - } - - // Give the caller the total number of found locales - *pdwMaxLocales = dwLocales; - return ERROR_SUCCESS; -} - -//----------------------------------------------------------------------------- -// SFileHasFile -// -// hMpq - Handle of opened MPQ archive -// szFileName - Name of file to look for - -bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pFileEntry; - DWORD dwFlagsToCheck = MPQ_FILE_EXISTS; - DWORD dwFileIndex = 0; - char szPatchFileName[MAX_PATH]; - bool bIsPseudoName; - int nError = ERROR_SUCCESS; - - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(szFileName == NULL || *szFileName == 0) - nError = ERROR_INVALID_PARAMETER; - - // Prepare the file opening - if(nError == ERROR_SUCCESS) - { - // Different processing for pseudo-names - bIsPseudoName = IsPseudoFileName(szFileName, &dwFileIndex); - - // Walk through the MPQ and all patches - while(ha != NULL) - { - // Verify presence of the file - pFileEntry = (bIsPseudoName == false) ? GetFileEntryLocale(ha, szFileName, lcFileLocale) - : GetFileEntryByIndex(ha, dwFileIndex); - // Verify the file flags - if(pFileEntry != NULL && (pFileEntry->dwFlags & dwFlagsToCheck) == MPQ_FILE_EXISTS) - return true; - - // If this is patched archive, go to the patch - dwFlagsToCheck = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE; - ha = ha->haPatch; - - // Prepare the patched file name - if(ha != NULL) - { - strcpy(szPatchFileName, ha->szPatchPrefix); - strcat(szPatchFileName, szFileName); - szFileName = szPatchFileName; - } - } - - // Not found, sorry - nError = ERROR_FILE_NOT_FOUND; - } - - // Cleanup - SetLastError(nError); - return false; -} - - -//----------------------------------------------------------------------------- -// SFileOpenFileEx -// -// hMpq - Handle of opened MPQ archive -// szFileName - Name of file to open -// dwSearchScope - Where to search -// phFile - Pointer to store opened file handle - -bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pFileEntry = NULL; - TMPQFile * hf = NULL; - DWORD dwFileIndex = 0; - bool bOpenByIndex = false; - int nError = ERROR_SUCCESS; - - // Don't accept NULL pointer to file handle - if(phFile == NULL) - nError = ERROR_INVALID_PARAMETER; - - // Prepare the file opening - if(nError == ERROR_SUCCESS) - { - switch(dwSearchScope) - { - case SFILE_OPEN_PATCHED_FILE: - - // We want to open the updated version of the file - return OpenPatchedFile(hMpq, szFileName, 0, phFile); - - case SFILE_OPEN_FROM_MPQ: - - if(!IsValidMpqHandle(ha)) - { - nError = ERROR_INVALID_HANDLE; - break; - } - - if(szFileName == NULL || *szFileName == 0) - { - nError = ERROR_INVALID_PARAMETER; - break; - } - - // First of all, check the name as-is - if(!IsPseudoFileName(szFileName, &dwFileIndex)) - { - pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale); - if(pFileEntry == NULL) - nError = ERROR_FILE_NOT_FOUND; - } - else - { - bOpenByIndex = true; - pFileEntry = GetFileEntryByIndex(ha, dwFileIndex); - if(pFileEntry == NULL) - nError = ERROR_FILE_NOT_FOUND; - } - break; - - case SFILE_OPEN_ANY_LOCALE: - - // This open option is reserved for opening MPQ internal listfile. - // No argument validation. Tries to open file with neutral locale first, - // then any other available. - dwSearchScope = SFILE_OPEN_FROM_MPQ; - pFileEntry = GetFileEntryAny(ha, szFileName); - if(pFileEntry == NULL) - nError = ERROR_FILE_NOT_FOUND; - break; - - case SFILE_OPEN_LOCAL_FILE: - - if(szFileName == NULL || *szFileName == 0) - { - nError = ERROR_INVALID_PARAMETER; - break; - } - - return OpenLocalFile(szFileName, phFile); - - default: - - // Don't accept any other value - nError = ERROR_INVALID_PARAMETER; - break; - } - - // Quick return if something failed - if(nError != ERROR_SUCCESS) - { - SetLastError(nError); - return false; - } - } - - // Test if the file was not already deleted. - if(nError == ERROR_SUCCESS) - { - if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) - nError = ERROR_FILE_NOT_FOUND; - if(pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS) - nError = ERROR_NOT_SUPPORTED; - } - - // Allocate file handle - if(nError == ERROR_SUCCESS) - { - if((hf = STORM_ALLOC(TMPQFile, 1)) == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Initialize file handle - if(nError == ERROR_SUCCESS) - { - memset(hf, 0, sizeof(TMPQFile)); - hf->pFileEntry = pFileEntry; - hf->dwMagic = ID_MPQ_FILE; - hf->ha = ha; - - hf->MpqFilePos = pFileEntry->ByteOffset; - hf->RawFilePos = ha->MpqPos + hf->MpqFilePos; - hf->dwDataSize = pFileEntry->dwFileSize; - - // If the MPQ has sector CRC enabled, enable if for the file - if(ha->dwFlags & MPQ_FLAG_CHECK_SECTOR_CRC) - hf->bCheckSectorCRCs = true; - - // If we know the real file name, copy it to the file entry - if(bOpenByIndex == false) - { - // If there is no file name yet, allocate it - AllocateFileName(pFileEntry, szFileName); - - // If the file is encrypted, we should detect the file key - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - { - hf->dwFileKey = DecryptFileKey(szFileName, - pFileEntry->ByteOffset, - pFileEntry->dwFileSize, - pFileEntry->dwFlags); - } - } - else - { - // Try to auto-detect the file name - if(!SFileGetFileName(hf, NULL)) - nError = GetLastError(); - } - } - - // If the file is actually a patch file, we have to load the patch file header - if(nError == ERROR_SUCCESS && pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) - { - assert(hf->pPatchInfo == NULL); - nError = AllocatePatchInfo(hf, true); - } - - // Cleanup - if(nError != ERROR_SUCCESS) - { - SetLastError(nError); - FreeMPQFile(hf); - } - - *phFile = hf; - return (nError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// bool WINAPI SFileCloseFile(HANDLE hFile); - -bool WINAPI SFileCloseFile(HANDLE hFile) -{ - TMPQFile * hf = (TMPQFile *)hFile; - - if(!IsValidFileHandle(hf)) - { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // Free the structure - FreeMPQFile(hf); - return true; -} diff --git a/dep/StormLib/src/SFilePatchArchives.cpp b/dep/StormLib/src/SFilePatchArchives.cpp deleted file mode 100644 index 24ae2c52c37..00000000000 --- a/dep/StormLib/src/SFilePatchArchives.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/*****************************************************************************/ -/* SFilePatchArchives.cpp Copyright (c) Ladislav Zezula 2010 */ -/*---------------------------------------------------------------------------*/ -/* Description: */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 18.08.10 1.00 Lad The first version of SFilePatchArchives.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local structures - -typedef struct _BLIZZARD_BSDIFF40_FILE -{ - ULONGLONG Signature; - ULONGLONG CtrlBlockSize; - ULONGLONG DataBlockSize; - ULONGLONG NewFileSize; -} BLIZZARD_BSDIFF40_FILE, *PBLIZZARD_BSDIFF40_FILE; - -//----------------------------------------------------------------------------- -// Local functions - -static bool GetDefaultPatchPrefix( - const TCHAR * szBaseMpqName, - char * szBuffer) -{ - const TCHAR * szExtension; - const TCHAR * szDash; - - // Ensure that both names are plain names - szBaseMpqName = GetPlainFileNameT(szBaseMpqName); - - // Patch prefix is for the Cataclysm MPQs, whose names - // are like "locale-enGB.MPQ" or "speech-enGB.MPQ" - szExtension = _tcsrchr(szBaseMpqName, _T('.')); - szDash = _tcsrchr(szBaseMpqName, _T('-')); - strcpy(szBuffer, "Base"); - - // If the length of the prefix doesn't match, use default one - if(szExtension != NULL && szDash != NULL && (szExtension - szDash) == 5) - { - // Copy the prefix - szBuffer[0] = (char)szDash[1]; - szBuffer[1] = (char)szDash[2]; - szBuffer[2] = (char)szDash[3]; - szBuffer[3] = (char)szDash[4]; - szBuffer[4] = 0; - } - - return true; -} - -static void Decompress_RLE(LPBYTE pbDecompressed, DWORD cbDecompressed, LPBYTE pbCompressed, DWORD cbCompressed) -{ - LPBYTE pbDecompressedEnd = pbDecompressed + cbDecompressed; - LPBYTE pbCompressedEnd = pbCompressed + cbCompressed; - BYTE RepeatCount; - BYTE OneByte; - - // Cut the initial DWORD from the compressed chunk - pbCompressed += sizeof(DWORD); - cbCompressed -= sizeof(DWORD); - - // Pre-fill decompressed buffer with zeros - memset(pbDecompressed, 0, cbDecompressed); - - // Unpack - while(pbCompressed < pbCompressedEnd && pbDecompressed < pbDecompressedEnd) - { - OneByte = *pbCompressed++; - - // Is it a repetition byte ? - if(OneByte & 0x80) - { - RepeatCount = (OneByte & 0x7F) + 1; - for(BYTE i = 0; i < RepeatCount; i++) - { - if(pbDecompressed == pbDecompressedEnd || pbCompressed == pbCompressedEnd) - break; - - *pbDecompressed++ = *pbCompressed++; - } - } - else - { - pbDecompressed += (OneByte + 1); - } - } -} - -static int LoadMpqPatch_COPY(TMPQFile * hf, TPatchHeader * pPatchHeader) -{ - int nError = ERROR_SUCCESS; - - // Allocate space for patch header and compressed data - hf->pPatchHeader = (TPatchHeader *)STORM_ALLOC(BYTE, pPatchHeader->dwSizeOfPatchData); - if(hf->pPatchHeader == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - - // Load the patch data and decide if they are compressed or not - if(nError == ERROR_SUCCESS) - { - LPBYTE pbPatchFile = (LPBYTE)hf->pPatchHeader; - - // Copy the patch header itself - memcpy(pbPatchFile, pPatchHeader, sizeof(TPatchHeader)); - pbPatchFile += sizeof(TPatchHeader); - - // Load the rest of the patch - if(!SFileReadFile((HANDLE)hf, pbPatchFile, pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader))) - nError = GetLastError(); - } - - return nError; -} - -static int LoadMpqPatch_BSD0(TMPQFile * hf, TPatchHeader * pPatchHeader) -{ - LPBYTE pbDecompressed = NULL; - LPBYTE pbCompressed = NULL; - DWORD cbDecompressed = 0; - DWORD cbCompressed = 0; - DWORD dwBytesRead = 0; - int nError = ERROR_SUCCESS; - - // Allocate space for compressed data - cbCompressed = pPatchHeader->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER; - pbCompressed = STORM_ALLOC(BYTE, cbCompressed); - if(pbCompressed == NULL) - nError = ERROR_SUCCESS; - - // Read the compressed patch data - if(nError == ERROR_SUCCESS) - { - // Load the rest of the header - SFileReadFile((HANDLE)hf, pbCompressed, cbCompressed, &dwBytesRead); - if(dwBytesRead != cbCompressed) - nError = ERROR_FILE_CORRUPT; - } - - // Get the uncompressed size of the patch - if(nError == ERROR_SUCCESS) - { - cbDecompressed = pPatchHeader->dwSizeOfPatchData - sizeof(TPatchHeader); - hf->pPatchHeader = (TPatchHeader *)STORM_ALLOC(BYTE, pPatchHeader->dwSizeOfPatchData); - if(hf->pPatchHeader == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Now decompress the patch data - if(nError == ERROR_SUCCESS) - { - // Copy the patch header - memcpy(hf->pPatchHeader, pPatchHeader, sizeof(TPatchHeader)); - pbDecompressed = (LPBYTE)hf->pPatchHeader + sizeof(TPatchHeader); - - // Uncompress or copy the patch data - if(cbCompressed < cbDecompressed) - { - Decompress_RLE(pbDecompressed, cbDecompressed, pbCompressed, cbCompressed); - } - else - { - assert(cbCompressed == cbDecompressed); - memcpy(pbDecompressed, pbCompressed, cbCompressed); - } - } - - // Free buffers and exit - if(pbCompressed != NULL) - STORM_FREE(pbCompressed); - return nError; -} - -static int ApplyMpqPatch_COPY( - TMPQFile * hf, - TPatchHeader * pPatchHeader) -{ - LPBYTE pbNewFileData; - DWORD cbNewFileData; - - // Allocate space for new file data - cbNewFileData = pPatchHeader->dwXfrmBlockSize - SIZE_OF_XFRM_HEADER; - pbNewFileData = STORM_ALLOC(BYTE, cbNewFileData); - if(pbNewFileData == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Copy the patch data as-is - memcpy(pbNewFileData, (LPBYTE)pPatchHeader + sizeof(TPatchHeader), cbNewFileData); - - // Free the old file data - STORM_FREE(hf->pbFileData); - - // Put the new file data there - hf->pbFileData = pbNewFileData; - hf->cbFileData = cbNewFileData; - return ERROR_SUCCESS; -} - -static int ApplyMpqPatch_BSD0( - TMPQFile * hf, - TPatchHeader * pPatchHeader) -{ - PBLIZZARD_BSDIFF40_FILE pBsdiff; - LPDWORD pCtrlBlock; - LPBYTE pbPatchData = (LPBYTE)pPatchHeader + sizeof(TPatchHeader); - LPBYTE pDataBlock; - LPBYTE pExtraBlock; - LPBYTE pbNewData = NULL; - LPBYTE pbOldData = (LPBYTE)hf->pbFileData; - DWORD dwNewOffset = 0; // Current position to patch - DWORD dwOldOffset = 0; // Current source position - DWORD dwNewSize; // Patched file size - DWORD dwOldSize = hf->cbFileData; // File size before patch - - // Get pointer to the patch header - // Format of BSDIFF header corresponds to original BSDIFF, which is: - // 0000 8 bytes signature "BSDIFF40" - // 0008 8 bytes size of the control block - // 0010 8 bytes size of the data block - // 0018 8 bytes new size of the patched file - pBsdiff = (PBLIZZARD_BSDIFF40_FILE)pbPatchData; - pbPatchData += sizeof(BLIZZARD_BSDIFF40_FILE); - - // Get pointer to the 32-bit BSDIFF control block - // The control block follows immediately after the BSDIFF header - // and consists of three 32-bit integers - // 0000 4 bytes Length to copy from the BSDIFF data block the new file - // 0004 4 bytes Length to copy from the BSDIFF extra block - // 0008 4 bytes Size to increment source file offset - pCtrlBlock = (LPDWORD)pbPatchData; - pbPatchData += (size_t)BSWAP_INT64_UNSIGNED(pBsdiff->CtrlBlockSize); - - // Get the pointer to the data block - pDataBlock = (LPBYTE)pbPatchData; - pbPatchData += (size_t)BSWAP_INT64_UNSIGNED(pBsdiff->DataBlockSize); - - // Get the pointer to the extra block - pExtraBlock = (LPBYTE)pbPatchData; - dwNewSize = (DWORD)BSWAP_INT64_UNSIGNED(pBsdiff->NewFileSize); - - // Allocate new buffer - pbNewData = STORM_ALLOC(BYTE, dwNewSize); - if(pbNewData == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Now patch the file - while(dwNewOffset < dwNewSize) - { - DWORD dwAddDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[0]); - DWORD dwMovDataLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[1]); - DWORD dwOldMoveLength = BSWAP_INT32_UNSIGNED(pCtrlBlock[2]); - DWORD i; - - // Sanity check - if((dwNewOffset + dwAddDataLength) > dwNewSize) - { - STORM_FREE(pbNewData); - return ERROR_FILE_CORRUPT; - } - - // Read the diff string to the target buffer - memcpy(pbNewData + dwNewOffset, pDataBlock, dwAddDataLength); - pDataBlock += dwAddDataLength; - - // Now combine the patch data with the original file - for(i = 0; i < dwAddDataLength; i++) - { - if(dwOldOffset < dwOldSize) - pbNewData[dwNewOffset] = pbNewData[dwNewOffset] + pbOldData[dwOldOffset]; - - dwNewOffset++; - dwOldOffset++; - } - - // Sanity check - if((dwNewOffset + dwMovDataLength) > dwNewSize) - { - STORM_FREE(pbNewData); - return ERROR_FILE_CORRUPT; - } - - // Copy the data from the extra block in BSDIFF patch - memcpy(pbNewData + dwNewOffset, pExtraBlock, dwMovDataLength); - pExtraBlock += dwMovDataLength; - dwNewOffset += dwMovDataLength; - - // Move the old offset - if(dwOldMoveLength & 0x80000000) - dwOldMoveLength = 0x80000000 - dwOldMoveLength; - dwOldOffset += dwOldMoveLength; - pCtrlBlock += 3; - } - - // Free the old file data - STORM_FREE(hf->pbFileData); - - // Put the new data to the fil structure - hf->pbFileData = pbNewData; - hf->cbFileData = dwNewSize; - return ERROR_SUCCESS; -} - - -static int LoadMpqPatch(TMPQFile * hf) -{ - TPatchHeader PatchHeader; - DWORD dwBytesRead; - int nError = ERROR_SUCCESS; - - // Read the patch header - SFileReadFile((HANDLE)hf, &PatchHeader, sizeof(TPatchHeader), &dwBytesRead); - if(dwBytesRead != sizeof(TPatchHeader)) - nError = ERROR_FILE_CORRUPT; - - // Verify the signatures in the patch header - if(nError == ERROR_SUCCESS) - { - // BSWAP the entire header, if needed - BSWAP_ARRAY32_UNSIGNED(&PatchHeader, sizeof(DWORD) * 6); - PatchHeader.dwXFRM = BSWAP_INT32_UNSIGNED(PatchHeader.dwXFRM); - PatchHeader.dwXfrmBlockSize = BSWAP_INT32_UNSIGNED(PatchHeader.dwXfrmBlockSize); - PatchHeader.dwPatchType = BSWAP_INT32_UNSIGNED(PatchHeader.dwPatchType); - - if(PatchHeader.dwSignature != 0x48435450 || PatchHeader.dwMD5 != 0x5f35444d || PatchHeader.dwXFRM != 0x4d524658) - nError = ERROR_FILE_CORRUPT; - } - - // Read the patch, depending on patch type - if(nError == ERROR_SUCCESS) - { - switch(PatchHeader.dwPatchType) - { - case 0x59504f43: // 'COPY' - nError = LoadMpqPatch_COPY(hf, &PatchHeader); - break; - - case 0x30445342: // 'BSD0' - nError = LoadMpqPatch_BSD0(hf, &PatchHeader); - break; - - default: - nError = ERROR_FILE_CORRUPT; - break; - } - } - - return nError; -} - -static int ApplyMpqPatch( - TMPQFile * hf, - TPatchHeader * pPatchHeader) -{ - int nError = ERROR_SUCCESS; - - // Verify the original file before patching - if(pPatchHeader->dwSizeBeforePatch != 0) - { - if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_before_patch)) - nError = ERROR_FILE_CORRUPT; - } - - // Apply the patch - if(nError == ERROR_SUCCESS) - { - switch(pPatchHeader->dwPatchType) - { - case 0x59504f43: // 'COPY' - nError = ApplyMpqPatch_COPY(hf, pPatchHeader); - break; - - case 0x30445342: // 'BSD0' - nError = ApplyMpqPatch_BSD0(hf, pPatchHeader); - break; - - default: - nError = ERROR_FILE_CORRUPT; - break; - } - } - - // Verify MD5 after patch - if(nError == ERROR_SUCCESS && pPatchHeader->dwSizeAfterPatch != 0) - { - // Verify the patched file - if(!VerifyDataBlockHash(hf->pbFileData, hf->cbFileData, pPatchHeader->md5_after_patch)) - nError = ERROR_FILE_CORRUPT; - } - - return nError; -} - -//----------------------------------------------------------------------------- -// Public functions (StormLib internals) - -bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize) -{ - TPatchHeader * pPatchHeader = (TPatchHeader *)pvData; - BLIZZARD_BSDIFF40_FILE DiffFile; - DWORD dwPatchType; - - if(cbData >= sizeof(TPatchHeader) + sizeof(BLIZZARD_BSDIFF40_FILE)) - { - dwPatchType = BSWAP_INT32_UNSIGNED(pPatchHeader->dwPatchType); - if(dwPatchType == 0x30445342) - { - // Give the caller the patch file size - if(pdwPatchedFileSize != NULL) - { - Decompress_RLE((LPBYTE)&DiffFile, sizeof(BLIZZARD_BSDIFF40_FILE), (LPBYTE)(pPatchHeader + 1), sizeof(BLIZZARD_BSDIFF40_FILE)); - DiffFile.NewFileSize = BSWAP_INT64_UNSIGNED(DiffFile.NewFileSize); - *pdwPatchedFileSize = (DWORD)DiffFile.NewFileSize; - return true; - } - } - } - - return false; -} - -int PatchFileData(TMPQFile * hf) -{ - TMPQFile * hfBase = hf; - int nError = ERROR_SUCCESS; - - // Move to the first patch - hf = hf->hfPatchFile; - - // Now go through all patches and patch the original data - while(hf != NULL) - { - // This must be true - assert(hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE); - - // Make sure that the patch data is loaded - nError = LoadMpqPatch(hf); - if(nError != ERROR_SUCCESS) - break; - - // Apply the patch - nError = ApplyMpqPatch(hfBase, hf->pPatchHeader); - if(nError != ERROR_SUCCESS) - break; - - // Move to the next patch - hf = hf->hfPatchFile; - } - - return nError; -} - -//----------------------------------------------------------------------------- -// Public functions - -// -// Patch prefix is the path subdirectory where the patched files are within MPQ. -// -// Example 1: -// Main MPQ: locale-enGB.MPQ -// Patch MPQ: wow-update-12694.MPQ -// File in main MPQ: DBFilesClient\Achievement.dbc -// File in patch MPQ: enGB\DBFilesClient\Achievement.dbc -// Path prefix: enGB -// -// Example 2: -// Main MPQ: expansion1.MPQ -// Patch MPQ: wow-update-12694.MPQ -// File in main MPQ: DBFilesClient\Achievement.dbc -// File in patch MPQ: Base\DBFilesClient\Achievement.dbc -// Path prefix: Base -// - -bool WINAPI SFileOpenPatchArchive( - HANDLE hMpq, - const TCHAR * szPatchMpqName, - const char * szPatchPathPrefix, - DWORD dwFlags) -{ - TMPQArchive * haPatch; - TMPQArchive * ha = (TMPQArchive *)hMpq; - HANDLE hPatchMpq = NULL; - char szPatchPrefixBuff[MPQ_PATCH_PREFIX_LEN]; - int nError = ERROR_SUCCESS; - - // Keep compiler happy - dwFlags = dwFlags; - - // Verify input parameters - if(!IsValidMpqHandle(ha)) - nError = ERROR_INVALID_HANDLE; - if(szPatchMpqName == NULL || *szPatchMpqName == 0) - nError = ERROR_INVALID_PARAMETER; - - // If the user didn't give the patch prefix, get default one - if(szPatchPathPrefix != NULL) - { - // Save length of the patch prefix - if(strlen(szPatchPathPrefix) > MPQ_PATCH_PREFIX_LEN - 2) - nError = ERROR_INVALID_PARAMETER; - } - - // - // We don't allow adding patches to archives that have been open for write - // - // Error scenario: - // - // 1) Open archive for writing - // 2) Modify or replace a file - // 3) Add patch archive to the opened MPQ - // 4) Read patched file - // 5) Now what ? - // - - if(nError == ERROR_SUCCESS) - { - if(!FileStream_IsReadOnly(ha->pStream)) - nError = ERROR_ACCESS_DENIED; - } - - // Open the archive like it is normal archive - if(nError == ERROR_SUCCESS) - { - if(!SFileOpenArchive(szPatchMpqName, 0, MPQ_OPEN_READ_ONLY, &hPatchMpq)) - return false; - haPatch = (TMPQArchive *)hPatchMpq; - - // Older WoW patches (build 13914) used to have - // several language versions in one patch file - // Those patches needed to have a path prefix - // We can distinguish such patches by not having the (patch_metadata) file - if(szPatchPathPrefix == NULL) - { - if(!SFileHasFile(hPatchMpq, PATCH_METADATA_NAME)) - { - GetDefaultPatchPrefix(FileStream_GetFileName(ha->pStream), szPatchPrefixBuff); - szPatchPathPrefix = szPatchPrefixBuff; - } - } - - // Save the prefix for patch file names. - // Make sure that there is backslash after it - if(szPatchPathPrefix != NULL && *szPatchPathPrefix != 0) - { - strcpy(haPatch->szPatchPrefix, szPatchPathPrefix); - strcat(haPatch->szPatchPrefix, "\\"); - haPatch->cchPatchPrefix = strlen(haPatch->szPatchPrefix); - } - - // Now add the patch archive to the list of patches to the original MPQ - while(ha != NULL) - { - if(ha->haPatch == NULL) - { - haPatch->haBase = ha; - ha->haPatch = haPatch; - return true; - } - - // Move to the next archive - ha = ha->haPatch; - } - - // Should never happen - nError = ERROR_CAN_NOT_COMPLETE; - } - - SetLastError(nError); - return false; -} - -bool WINAPI SFileIsPatchedArchive(HANDLE hMpq) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - - // Verify input parameters - if(!IsValidMpqHandle(ha)) - return false; - - return (ha->haPatch != NULL); -} diff --git a/dep/StormLib/src/SFileReadFile.cpp b/dep/StormLib/src/SFileReadFile.cpp deleted file mode 100644 index 5570fd466c5..00000000000 --- a/dep/StormLib/src/SFileReadFile.cpp +++ /dev/null @@ -1,1183 +0,0 @@ -/*****************************************************************************/ -/* SFileReadFile.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Description : */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.99 1.00 Lad The first version of SFileReadFile.cpp */ -/* 24.03.99 1.00 Lad Added the SFileGetFileInfo function */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local structures - -struct TFileHeader2Ext -{ - DWORD dwOffset00Data; // Required data at offset 00 (32-bits) - DWORD dwOffset00Mask; // Mask for data at offset 00 (32 bits). 0 = data are ignored - DWORD dwOffset04Data; // Required data at offset 04 (32-bits) - DWORD dwOffset04Mask; // Mask for data at offset 04 (32 bits). 0 = data are ignored - const char * szExt; // Supplied extension, if the condition is true -}; - -//----------------------------------------------------------------------------- -// Local functions - -static void CopyFileName(char * szTarget, const TCHAR * szSource) -{ - while(*szSource != 0) - *szTarget++ = (char)*szSource++; - *szTarget = 0; -} - -static DWORD GetMpqFileCount(TMPQArchive * ha) -{ - TFileEntry * pFileTableEnd; - TFileEntry * pFileEntry; - DWORD dwFileCount = 0; - - // Go through all open MPQs, including patches - while(ha != NULL) - { - // Only count files that are not patch files - pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) - { - // If the file is patch file and this is not primary archive, skip it - // BUGBUG: This errorneously counts non-patch files that are in both - // base MPQ and in patches, and increases the number of files by cca 50% - if((pFileEntry->dwFlags & (MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE)) == MPQ_FILE_EXISTS) - dwFileCount++; - } - - // Move to the next patch archive - ha = ha->haPatch; - } - - return dwFileCount; -} - -static bool GetFilePatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded) -{ - TMPQFile * hfTemp; - TCHAR * szPatchChain = (TCHAR *)pvFileInfo; - TCHAR * szFileName; - size_t cchCharsNeeded = 1; - size_t nLength; - DWORD cbLengthNeeded; - - // Check if the "hf" is a MPQ file - if(hf->pStream != NULL) - { - // Calculate the length needed - szFileName = FileStream_GetFileName(hf->pStream); - cchCharsNeeded += _tcslen(szFileName) + 1; - cbLengthNeeded = (DWORD)(cchCharsNeeded * sizeof(TCHAR)); - - // If we have enough space, copy the file name - if(cbFileInfo >= cbLengthNeeded) - { - nLength = _tcslen(szFileName) + 1; - memcpy(szPatchChain, szFileName, nLength * sizeof(TCHAR)); - szPatchChain += nLength; - - // Terminate the multi-string - *szPatchChain = 0; - } - } - else - { - // Calculate number of characters needed - for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatchFile) - cchCharsNeeded += _tcslen(FileStream_GetFileName(hfTemp->ha->pStream)) + 1; - cbLengthNeeded = (DWORD)(cchCharsNeeded * sizeof(TCHAR)); - - // If we have enough space, the copy the patch chain - if(cbFileInfo >= cbLengthNeeded) - { - for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatchFile) - { - szFileName = FileStream_GetFileName(hfTemp->ha->pStream); - nLength = _tcslen(szFileName) + 1; - memcpy(szPatchChain, szFileName, nLength * sizeof(TCHAR)); - szPatchChain += nLength; - } - - // Terminate the multi-string - *szPatchChain = 0; - } - } - - // Give result length, terminate multi-string and return - *pcbLengthNeeded = cbLengthNeeded; - return true; -} - -// hf - MPQ File handle. -// pbBuffer - Pointer to target buffer to store sectors. -// dwByteOffset - Position of sector in the file (relative to file begin) -// dwBytesToRead - Number of bytes to read. Must be multiplier of sector size. -// pdwBytesRead - Stored number of bytes loaded -static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DWORD dwBytesToRead, LPDWORD pdwBytesRead) -{ - ULONGLONG RawFilePos; - TMPQArchive * ha = hf->ha; - TFileEntry * pFileEntry = hf->pFileEntry; - LPBYTE pbRawSector = NULL; - LPBYTE pbOutSector = pbBuffer; - LPBYTE pbInSector = pbBuffer; - DWORD dwRawBytesToRead; - DWORD dwRawSectorOffset = dwByteOffset; - DWORD dwSectorsToRead = dwBytesToRead / ha->dwSectorSize; - DWORD dwSectorIndex = dwByteOffset / ha->dwSectorSize; - DWORD dwSectorsDone = 0; - DWORD dwBytesRead = 0; - int nError = ERROR_SUCCESS; - - // Note that dwByteOffset must be aligned to size of one sector - // Note that dwBytesToRead must be a multiplier of one sector size - // This is local function, so we won't check if that's true. - // Note that files stored in single units are processed by a separate function - - // If there is not enough bytes remaining, cut dwBytesToRead - if((dwByteOffset + dwBytesToRead) > hf->dwDataSize) - dwBytesToRead = hf->dwDataSize - dwByteOffset; - dwRawBytesToRead = dwBytesToRead; - - // Perform all necessary work to do with compressed files - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED) - { - // If the sector positions are not loaded yet, do it - if(hf->SectorOffsets == NULL) - { - nError = AllocateSectorOffsets(hf, true); - if(nError != ERROR_SUCCESS) - return nError; - } - - // If the sector checksums are not loaded yet, load them now. - if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->bLoadedSectorCRCs == false) - { - // - // Sector CRCs is plain crap feature. It is almost never present, - // often it's empty, or the end offset of sector CRCs is zero. - // We only try to load sector CRCs once, and regardless if it fails - // or not, we won't try that again for the given file. - // - - AllocateSectorChecksums(hf, true); - hf->bLoadedSectorCRCs = true; - } - - // TODO: If the raw data MD5s are not loaded yet, load them now - // Only do it if the MPQ is of format 4.0 -// if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4 && ha->pHeader->dwRawChunkSize != 0) -// { -// nError = AllocateRawMD5s(hf, true); -// if(nError != ERROR_SUCCESS) -// return nError; -// } - - // If the file is compressed, also allocate secondary buffer - pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwBytesToRead); - if(pbRawSector == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Assign the temporary buffer as target for read operation - dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex]; - dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset; - } - - // Calculate raw file offset where the sector(s) are stored. - CalculateRawSectorOffset(RawFilePos, hf, dwRawSectorOffset); - - // Set file pointer and read all required sectors - if(!FileStream_Read(ha->pStream, &RawFilePos, pbInSector, dwRawBytesToRead)) - return GetLastError(); - dwBytesRead = 0; - - // Now we have to decrypt and decompress all file sectors that have been loaded - for(DWORD i = 0; i < dwSectorsToRead; i++) - { - DWORD dwRawBytesInThisSector = ha->dwSectorSize; - DWORD dwBytesInThisSector = ha->dwSectorSize; - DWORD dwIndex = dwSectorIndex + i; - - // If there is not enough bytes in the last sector, - // cut the number of bytes in this sector - if(dwRawBytesInThisSector > dwBytesToRead) - dwRawBytesInThisSector = dwBytesToRead; - if(dwBytesInThisSector > dwBytesToRead) - dwBytesInThisSector = dwBytesToRead; - - // If the file is compressed, we have to adjust the raw sector size - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED) - dwRawBytesInThisSector = hf->SectorOffsets[dwIndex + 1] - hf->SectorOffsets[dwIndex]; - - // If the file is encrypted, we have to decrypt the sector - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - { - BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector); - - // If we don't know the key, try to detect it by file content - if(hf->dwFileKey == 0) - { - hf->dwFileKey = DetectFileKeyByContent(pbInSector, dwBytesInThisSector); - if(hf->dwFileKey == 0) - { - nError = ERROR_UNKNOWN_FILE_KEY; - break; - } - } - - DecryptMpqBlock(pbInSector, dwRawBytesInThisSector, hf->dwFileKey + dwIndex); - BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector); - } - - // If the file has sector CRC check turned on, perform it - if(hf->bCheckSectorCRCs && hf->SectorChksums != NULL) - { - DWORD dwAdlerExpected = hf->SectorChksums[dwIndex]; - DWORD dwAdlerValue = 0; - - // We can only check sector CRC when it's not zero - // Neither can we check it if it's 0xFFFFFFFF. - if(dwAdlerExpected != 0 && dwAdlerExpected != 0xFFFFFFFF) - { - dwAdlerValue = adler32(0, pbInSector, dwRawBytesInThisSector); - if(dwAdlerValue != dwAdlerExpected) - { - nError = ERROR_CHECKSUM_ERROR; - break; - } - } - } - - // If the sector is really compressed, decompress it. - // WARNING : Some sectors may not be compressed, it can be determined only - // by comparing uncompressed and compressed size !!! - if(dwRawBytesInThisSector < dwBytesInThisSector) - { - int cbOutSector = dwBytesInThisSector; - int cbInSector = dwRawBytesInThisSector; - int nResult = 0; - - // Is the file compressed by Blizzard's multiple compression ? - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) - { - if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) - nResult = SCompDecompress2((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector); - else - nResult = SCompDecompress((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector); - } - - // Is the file compressed by PKWARE Data Compression Library ? - else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) - { - nResult = SCompExplode((char *)pbOutSector, &cbOutSector, (char *)pbInSector, cbInSector); - } - - // Did the decompression fail ? - if(nResult == 0) - { - nError = ERROR_FILE_CORRUPT; - break; - } - } - else - { - if(pbOutSector != pbInSector) - memcpy(pbOutSector, pbInSector, dwBytesInThisSector); - } - - // Move pointers - dwBytesToRead -= dwBytesInThisSector; - dwByteOffset += dwBytesInThisSector; - dwBytesRead += dwBytesInThisSector; - pbOutSector += dwBytesInThisSector; - pbInSector += dwRawBytesInThisSector; - dwSectorsDone++; - } - - // Free all used buffers - if(pbRawSector != NULL) - STORM_FREE(pbRawSector); - - // Give the caller thenumber of bytes read - *pdwBytesRead = dwBytesRead; - return nError; -} - -static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) -{ - ULONGLONG RawFilePos = hf->RawFilePos; - TMPQArchive * ha = hf->ha; - TFileEntry * pFileEntry = hf->pFileEntry; - LPBYTE pbCompressed = NULL; - LPBYTE pbRawData = NULL; - int nError = ERROR_SUCCESS; - - // If the file buffer is not allocated yet, do it. - if(hf->pbFileSector == NULL) - { - nError = AllocateSectorBuffer(hf); - if(nError != ERROR_SUCCESS) - return nError; - pbRawData = hf->pbFileSector; - } - - // If the file is a patch file, adjust raw data offset - if(hf->pPatchInfo != NULL) - RawFilePos += hf->pPatchInfo->dwLength; - - // If the file sector is not loaded yet, do it - if(hf->dwSectorOffs != 0) - { - // Is the file compressed? - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED) - { - // Allocate space for compressed data - pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize); - if(pbCompressed == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - pbRawData = pbCompressed; - } - - // Load the raw (compressed, encrypted) data - if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize)) - { - STORM_FREE(pbCompressed); - return GetLastError(); - } - - // If the file is encrypted, we have to decrypt the data first - if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) - { - BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize); - DecryptMpqBlock(pbRawData, pFileEntry->dwCmpSize, hf->dwFileKey); - BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize); - } - - // If the file is compressed, we have to decompress it now - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED) - { - int cbOutBuffer = (int)hf->dwDataSize; - int cbInBuffer = (int)pFileEntry->dwCmpSize; - int nResult = 0; - - // - // If the file is an incremental patch, the size of compressed data - // is determined as pFileEntry->dwCmpSize - sizeof(TPatchInfo) - // - // In "wow-update-12694.MPQ" from Wow-Cataclysm BETA: - // - // File CmprSize DcmpSize DataSize Compressed? - // -------------------------------------- ---------- -------- -------- --------------- - // esES\DBFilesClient\LightSkyBox.dbc 0xBE->0xA2 0xBC 0xBC Yes - // deDE\DBFilesClient\MountCapability.dbc 0x93->0x77 0x77 0x77 No - // - - if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) - cbInBuffer = cbInBuffer - sizeof(TPatchInfo); - - // Is the file compressed by Blizzard's multiple compression ? - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) - { - if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) - nResult = SCompDecompress2((char *)hf->pbFileSector, &cbOutBuffer, (char *)pbRawData, cbInBuffer); - else - nResult = SCompDecompress((char *)hf->pbFileSector, &cbOutBuffer, (char *)pbRawData, cbInBuffer); - } - - // Is the file compressed by PKWARE Data Compression Library ? - // Note: Single unit files compressed with IMPLODE are not supported by Blizzard - else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) - nResult = SCompExplode((char *)hf->pbFileSector, &cbOutBuffer, (char *)pbRawData, cbInBuffer); - - nError = (nResult != 0) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; - } - else - { - if(pbRawData != hf->pbFileSector) - memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize); - } - - // Free the decompression buffer. - if(pbCompressed != NULL) - STORM_FREE(pbCompressed); - - // The file sector is now properly loaded - hf->dwSectorOffs = 0; - } - - // At this moment, we have the file loaded into the file buffer. - // Copy as much as the caller wants - if(nError == ERROR_SUCCESS && hf->dwSectorOffs == 0) - { - // File position is greater or equal to file size ? - if(dwFilePos >= hf->dwDataSize) - { - *pdwBytesRead = 0; - return ERROR_SUCCESS; - } - - // If not enough bytes remaining in the file, cut them - if((hf->dwDataSize - dwFilePos) < dwToRead) - dwToRead = (hf->dwDataSize - dwFilePos); - - // Copy the bytes - memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead); - - // Give the number of bytes read - *pdwBytesRead = dwToRead; - return ERROR_SUCCESS; - } - - // An error, sorry - return ERROR_CAN_NOT_COMPLETE; -} - -static int ReadMpqFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwBytesToRead, LPDWORD pdwBytesRead) -{ - TMPQArchive * ha = hf->ha; - LPBYTE pbBuffer = (BYTE *)pvBuffer; - DWORD dwTotalBytesRead = 0; // Total bytes read in all three parts - DWORD dwSectorSizeMask = ha->dwSectorSize - 1; // Mask for block size, usually 0x0FFF - DWORD dwFileSectorPos; // File offset of the loaded sector - DWORD dwBytesRead; // Number of bytes read (temporary variable) - int nError; - - // If the file position is at or beyond end of file, do nothing - if(dwFilePos >= hf->dwDataSize) - { - *pdwBytesRead = 0; - return ERROR_SUCCESS; - } - - // If not enough bytes in the file remaining, cut them - if(dwBytesToRead > (hf->dwDataSize - dwFilePos)) - dwBytesToRead = (hf->dwDataSize - dwFilePos); - - // Compute sector position in the file - dwFileSectorPos = dwFilePos & ~dwSectorSizeMask; // Position in the block - - // If the file sector buffer is not allocated yet, do it now - if(hf->pbFileSector == NULL) - { - nError = AllocateSectorBuffer(hf); - if(nError != ERROR_SUCCESS) - return nError; - } - - // Load the first (incomplete) file sector - if(dwFilePos & dwSectorSizeMask) - { - DWORD dwBytesInSector = ha->dwSectorSize; - DWORD dwBufferOffs = dwFilePos & dwSectorSizeMask; - DWORD dwToCopy; - - // Is the file sector already loaded ? - if(hf->dwSectorOffs != dwFileSectorPos) - { - // Load one MPQ sector into archive buffer - nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesInSector); - if(nError != ERROR_SUCCESS) - return nError; - - // Remember that the data loaded to the sector have new file offset - hf->dwSectorOffs = dwFileSectorPos; - } - else - { - if((dwFileSectorPos + dwBytesInSector) > hf->dwDataSize) - dwBytesInSector = hf->dwDataSize - dwFileSectorPos; - } - - // Copy the data from the offset in the loaded sector to the end of the sector - dwToCopy = dwBytesInSector - dwBufferOffs; - if(dwToCopy > dwBytesToRead) - dwToCopy = dwBytesToRead; - - // Copy data from sector buffer into target buffer - memcpy(pbBuffer, hf->pbFileSector + dwBufferOffs, dwToCopy); - - // Update pointers and byte counts - dwTotalBytesRead += dwToCopy; - dwFileSectorPos += dwBytesInSector; - pbBuffer += dwToCopy; - dwBytesToRead -= dwToCopy; - } - - // Load the whole ("middle") sectors only if there is at least one full sector to be read - if(dwBytesToRead >= ha->dwSectorSize) - { - DWORD dwBlockBytes = dwBytesToRead & ~dwSectorSizeMask; - - // Load all sectors to the output buffer - nError = ReadMpqSectors(hf, pbBuffer, dwFileSectorPos, dwBlockBytes, &dwBytesRead); - if(nError != ERROR_SUCCESS) - return nError; - - // Update pointers - dwTotalBytesRead += dwBytesRead; - dwFileSectorPos += dwBytesRead; - pbBuffer += dwBytesRead; - dwBytesToRead -= dwBytesRead; - } - - // Read the terminating sector - if(dwBytesToRead > 0) - { - DWORD dwToCopy = ha->dwSectorSize; - - // Is the file sector already loaded ? - if(hf->dwSectorOffs != dwFileSectorPos) - { - // Load one MPQ sector into archive buffer - nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesRead); - if(nError != ERROR_SUCCESS) - return nError; - - // Remember that the data loaded to the sector have new file offset - hf->dwSectorOffs = dwFileSectorPos; - } - - // Check number of bytes read - if(dwToCopy > dwBytesToRead) - dwToCopy = dwBytesToRead; - - // Copy the data from the cached last sector to the caller's buffer - memcpy(pbBuffer, hf->pbFileSector, dwToCopy); - - // Update pointers - dwTotalBytesRead += dwToCopy; - } - - // Store total number of bytes read to the caller - *pdwBytesRead = dwTotalBytesRead; - return ERROR_SUCCESS; -} - -static int ReadMpqFilePatchFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) -{ - DWORD dwBytesToRead = dwToRead; - DWORD dwBytesRead = 0; - int nError = ERROR_SUCCESS; - - // Make sure that the patch file is loaded completely - if(hf->pbFileData == NULL) - { - // Load the original file and store its content to "pbOldData" - hf->pbFileData = STORM_ALLOC(BYTE, hf->pFileEntry->dwFileSize); - hf->cbFileData = hf->pFileEntry->dwFileSize; - if(hf->pbFileData == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Read the file data - if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) - nError = ReadMpqFileSingleUnit(hf, hf->pbFileData, 0, hf->cbFileData, &dwBytesRead); - else - nError = ReadMpqFile(hf, hf->pbFileData, 0, hf->cbFileData, &dwBytesRead); - - // Fix error code - if(nError == ERROR_SUCCESS && dwBytesRead != hf->cbFileData) - nError = ERROR_FILE_CORRUPT; - - // Patch the file data - if(nError == ERROR_SUCCESS) - nError = PatchFileData(hf); - - // Reset number of bytes read to zero - dwBytesRead = 0; - } - - // If there is something to read, do it - if(nError == ERROR_SUCCESS) - { - if(dwFilePos < hf->cbFileData) - { - // Make sure we don't copy more than file size - if((dwFilePos + dwToRead) > hf->cbFileData) - dwToRead = hf->cbFileData - dwFilePos; - - // Copy the appropriate amount of the file data to the caller's buffer - memcpy(pvBuffer, hf->pbFileData + dwFilePos, dwToRead); - dwBytesRead = dwToRead; - } - - // Set the proper error code - nError = (dwBytesRead == dwBytesToRead) ? ERROR_SUCCESS : ERROR_HANDLE_EOF; - } - - // Give the result to the caller - if(pdwBytesRead != NULL) - *pdwBytesRead = dwBytesRead; - return nError; -} - -//----------------------------------------------------------------------------- -// SFileReadFile - -bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped) -{ - TMPQFile * hf = (TMPQFile *)hFile; - DWORD dwBytesRead = 0; // Number of bytes read - int nError = ERROR_SUCCESS; - - // Keep compilers happy - lpOverlapped = lpOverlapped; - - // Check valid parameters - if(!IsValidFileHandle(hf)) - { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - if(pvBuffer == NULL) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // If the file is local file, read the data directly from the stream - if(hf->pStream != NULL) - { - ULONGLONG FilePosition1; - ULONGLONG FilePosition2; - - // Because stream I/O functions are designed to read - // "all or nothing", we compare file position before and after, - // and if they differ, we assume that number of bytes read - // is the difference between them - - FileStream_GetPos(hf->pStream, FilePosition1); - if(!FileStream_Read(hf->pStream, NULL, pvBuffer, dwToRead)) - { - // If not all bytes have been read, then return the number - // of bytes read - if((nError = GetLastError()) == ERROR_HANDLE_EOF) - { - FileStream_GetPos(hf->pStream, FilePosition2); - dwBytesRead = (DWORD)(FilePosition2 - FilePosition1); - } - else - { - nError = GetLastError(); - } - } - else - { - dwBytesRead = dwToRead; - } - } - else - { - // If the file is a patch file, we have to read it special way - if(hf->hfPatchFile != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) - { - nError = ReadMpqFilePatchFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); - } - - // If the file is single unit file, redirect it to read file - else if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) - { - nError = ReadMpqFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); - } - - // Otherwise read it as sector based MPQ file - else - { - nError = ReadMpqFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); - } - - // Increment the file position - hf->dwFilePos += dwBytesRead; - } - - // Give the caller the number of bytes read - if(pdwRead != NULL) - *pdwRead = dwBytesRead; - - // If the read operation succeeded, but not full number of bytes was read, - // set the last error to ERROR_HANDLE_EOF - if(nError == ERROR_SUCCESS && (dwBytesRead < dwToRead)) - nError = ERROR_HANDLE_EOF; - - // If something failed, set the last error value - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// SFileGetFileSize - -DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh) -{ - ULONGLONG FileSize; - TMPQFile * hf = (TMPQFile *)hFile; - - // Validate the file handle before we go on - if(IsValidFileHandle(hf)) - { - // Make sure that the variable is initialized - FileSize = 0; - - // If the file is patched file, we have to get the size of the last version - if(hf->hfPatchFile != NULL) - { - // Walk through the entire patch chain, take the last version - while(hf != NULL) - { - // Get the size of the currently pointed version - FileSize = hf->pFileEntry->dwFileSize; - - // Move to the next patch file in the hierarchy - hf = hf->hfPatchFile; - } - } - else - { - // Is it a local file ? - if(hf->pStream != NULL) - { - FileStream_GetSize(hf->pStream, FileSize); - } - else - { - FileSize = hf->dwDataSize; - } - } - - // If opened from archive, return file size - if(pdwFileSizeHigh != NULL) - *pdwFileSizeHigh = (DWORD)(FileSize >> 32); - return (DWORD)FileSize; - } - - SetLastError(ERROR_INVALID_HANDLE); - return SFILE_INVALID_SIZE; -} - -DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod) -{ - TMPQFile * hf = (TMPQFile *)hFile; - ULONGLONG FilePosition; - ULONGLONG MoveOffset; - DWORD dwFilePosHi; - - // If the hFile is not a valid file handle, return an error. - if(!IsValidFileHandle(hf)) - { - SetLastError(ERROR_INVALID_HANDLE); - return SFILE_INVALID_POS; - } - - // Get the relative point where to move from - switch(dwMoveMethod) - { - case FILE_BEGIN: - FilePosition = 0; - break; - - case FILE_CURRENT: - if(hf->pStream != NULL) - { - FileStream_GetPos(hf->pStream, FilePosition); - } - else - { - FilePosition = hf->dwFilePos; - } - break; - - case FILE_END: - if(hf->pStream != NULL) - { - FileStream_GetSize(hf->pStream, FilePosition); - } - else - { - FilePosition = SFileGetFileSize(hFile, NULL); - } - break; - - default: - SetLastError(ERROR_INVALID_PARAMETER); - return SFILE_INVALID_POS; - } - - // Now get the move offset. Note that both values form - // a signed 64-bit value (a file pointer can be moved backwards) - if(plFilePosHigh != NULL) - dwFilePosHi = *plFilePosHigh; - else - dwFilePosHi = (lFilePos & 0x80000000) ? 0xFFFFFFFF : 0; - MoveOffset = MAKE_OFFSET64(dwFilePosHi, lFilePos); - - // Now calculate the new file pointer - // Do not allow the file pointer to go before the begin of the file - FilePosition += MoveOffset; - if(FilePosition < 0) - FilePosition = 0; - - // Now apply the file pointer to the file - if(hf->pStream != NULL) - { - // Apply the new file position - if(!FileStream_Read(hf->pStream, &FilePosition, NULL, 0)) - return SFILE_INVALID_POS; - - // Return the new file position - if(plFilePosHigh != NULL) - *plFilePosHigh = (LONG)(FilePosition >> 32); - return (DWORD)FilePosition; - } - else - { - // Files in MPQ can't be bigger than 4 GB. - // We don't allow to go past 4 GB - if(FilePosition >> 32) - { - SetLastError(ERROR_INVALID_PARAMETER); - return SFILE_INVALID_POS; - } - - // Change the file position - hf->dwFilePos = (DWORD)FilePosition; - - // Return the new file position - if(plFilePosHigh != NULL) - *plFilePosHigh = 0; - return (DWORD)FilePosition; - } -} - -//----------------------------------------------------------------------------- -// Tries to retrieve the file name - -static TFileHeader2Ext data2ext[] = -{ - {0x00005A4D, 0x0000FFFF, 0x00000000, 0x00000000, "exe"}, // EXE files - {0x00000006, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, "dc6"}, // EXE files - {0x1A51504D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mpq"}, // MPQ archive header ID ('MPQ\x1A') - {0x46464952, 0xFFFFFFFF, 0x00000000, 0x00000000, "wav"}, // WAVE header 'RIFF' - {0x324B4D53, 0xFFFFFFFF, 0x00000000, 0x00000000, "smk"}, // Old "Smacker Video" files 'SMK2' - {0x694B4942, 0xFFFFFFFF, 0x00000000, 0x00000000, "bik"}, // Bink video files (new) - {0x0801050A, 0xFFFFFFFF, 0x00000000, 0x00000000, "pcx"}, // PCX images used in Diablo I - {0x544E4F46, 0xFFFFFFFF, 0x00000000, 0x00000000, "fnt"}, // Font files used in Diablo II - {0x6D74683C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML '<htm' - {0x4D54483C, 0xFFFFFFFF, 0x00000000, 0x00000000, "html"}, // HTML '<HTM - {0x216F6F57, 0xFFFFFFFF, 0x00000000, 0x00000000, "tbl"}, // Table files - {0x31504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures - {0x32504C42, 0xFFFFFFFF, 0x00000000, 0x00000000, "blp"}, // BLP textures (v2) - {0x584C444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "mdx"}, // MDX files - {0x45505954, 0xFFFFFFFF, 0x00000000, 0x00000000, "pud"}, // Warcraft II maps - {0x38464947, 0xFFFFFFFF, 0x00000000, 0x00000000, "gif"}, // GIF images 'GIF8' - {0x3032444D, 0xFFFFFFFF, 0x00000000, 0x00000000, "m2"}, // WoW ??? .m2 - {0x43424457, 0xFFFFFFFF, 0x00000000, 0x00000000, "dbc"}, // ??? .dbc - {0x47585053, 0xFFFFFFFF, 0x00000000, 0x00000000, "bls"}, // WoW pixel shaders - {0xE0FFD8FF, 0xFFFFFFFF, 0x00000000, 0x00000000, "jpg"}, // JPEG image - {0x00000000, 0x00000000, 0x00000000, 0x00000000, "xxx"}, // Default extension - {0, 0, 0, 0, NULL} // Terminator -}; - -bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName) -{ - TFileEntry * pFileEntry; - TMPQFile * hf = (TMPQFile *)hFile; // MPQ File handle - char szPseudoName[20]; - DWORD FirstBytes[2]; // The first 4 bytes of the file - DWORD dwFilePos; // Saved file position - int nError = ERROR_SUCCESS; - int i; - - // Pre-zero the output buffer - if(szFileName != NULL) - *szFileName = 0; - - // Check valid parameters - if(!IsValidFileHandle(hf)) - nError = ERROR_INVALID_HANDLE; - pFileEntry = hf->pFileEntry; - - // Only do something if the file name is not filled - if(nError == ERROR_SUCCESS && pFileEntry != NULL && pFileEntry->szFileName == NULL) - { - // Read the first 2 DWORDs bytes from the file - FirstBytes[0] = FirstBytes[1] = 0; - dwFilePos = SFileSetFilePointer(hf, 0, NULL, FILE_CURRENT); - SFileReadFile(hFile, FirstBytes, sizeof(FirstBytes), NULL); - BSWAP_ARRAY32_UNSIGNED(FirstBytes, sizeof(FirstBytes)); - SFileSetFilePointer(hf, dwFilePos, NULL, FILE_BEGIN); - - // Try to guess file extension from those 2 DWORDs - for(i = 0; data2ext[i].szExt != NULL; i++) - { - if((FirstBytes[0] & data2ext[i].dwOffset00Mask) == data2ext[i].dwOffset00Data && - (FirstBytes[1] & data2ext[i].dwOffset04Mask) == data2ext[i].dwOffset04Data) - { - sprintf(szPseudoName, "File%08u.%s", (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt); - break; - } - } - - // Put the file name to the file table - AllocateFileName(pFileEntry, szPseudoName); - } - - // Now put the file name to the file structure - if(nError == ERROR_SUCCESS && szFileName != NULL) - { - if(pFileEntry != NULL && pFileEntry->szFileName != NULL) - strcpy(szFileName, pFileEntry->szFileName); - else if(hf->pStream != NULL) - CopyFileName(szFileName, FileStream_GetFileName(hf->pStream)); - } - return (nError == ERROR_SUCCESS); -} - -//----------------------------------------------------------------------------- -// Retrieves an information about an archive or about a file within the archive -// -// hMpqOrFile - Handle to an MPQ archive or to a file -// dwInfoType - Information to obtain - -#define VERIFY_MPQ_HANDLE(h) \ - if(!IsValidMpqHandle(h)) \ - { \ - nError = ERROR_INVALID_HANDLE; \ - break; \ - } - -#define VERIFY_FILE_HANDLE(h) \ - if(!IsValidFileHandle(h)) \ - { \ - nError = ERROR_INVALID_HANDLE; \ - break; \ - } - -bool WINAPI SFileGetFileInfo( - HANDLE hMpqOrFile, - DWORD dwInfoType, - void * pvFileInfo, - DWORD cbFileInfo, - LPDWORD pcbLengthNeeded) -{ - TMPQArchive * ha = (TMPQArchive *)hMpqOrFile; - TMPQBlock * pBlock; - TMPQFile * hf = (TMPQFile *)hMpqOrFile; - void * pvSrcFileInfo = NULL; - DWORD cbLengthNeeded = 0; - DWORD dwIsReadOnly; - DWORD dwFileCount = 0; - DWORD dwFileIndex; - DWORD dwFileKey; - DWORD i; - int nError = ERROR_SUCCESS; - - switch(dwInfoType) - { - case SFILE_INFO_ARCHIVE_NAME: - VERIFY_MPQ_HANDLE(ha); - - // pvFileInfo receives the name of the archive, terminated by 0 - pvSrcFileInfo = FileStream_GetFileName(ha->pStream); - cbLengthNeeded = (DWORD)(_tcslen((TCHAR *)pvSrcFileInfo) + 1) * sizeof(TCHAR); - break; - - case SFILE_INFO_ARCHIVE_SIZE: // Size of the archive - VERIFY_MPQ_HANDLE(ha); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &ha->pHeader->dwArchiveSize; - break; - - case SFILE_INFO_MAX_FILE_COUNT: // Max. number of files in the MPQ - VERIFY_MPQ_HANDLE(ha); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &ha->dwMaxFileCount; - break; - - case SFILE_INFO_HASH_TABLE_SIZE: // Size of the hash table - VERIFY_MPQ_HANDLE(ha); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &ha->pHeader->dwHashTableSize; - break; - - case SFILE_INFO_BLOCK_TABLE_SIZE: // Size of the block table - VERIFY_MPQ_HANDLE(ha); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &ha->pHeader->dwBlockTableSize; - break; - - case SFILE_INFO_SECTOR_SIZE: - VERIFY_MPQ_HANDLE(ha); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &ha->dwSectorSize; - break; - - case SFILE_INFO_HASH_TABLE: - VERIFY_MPQ_HANDLE(ha); - cbLengthNeeded = ha->pHeader->dwHashTableSize * sizeof(TMPQHash); - pvSrcFileInfo = ha->pHashTable; - break; - - case SFILE_INFO_BLOCK_TABLE: - VERIFY_MPQ_HANDLE(ha); - cbLengthNeeded = ha->dwFileTableSize * sizeof(TMPQBlock); - if(cbFileInfo < cbLengthNeeded) - { - nError = ERROR_INSUFFICIENT_BUFFER; - break; - } - - // Construct block table from file table size - pBlock = (TMPQBlock *)pvFileInfo; - for(i = 0; i < ha->dwFileTableSize; i++) - { - pBlock->dwFilePos = (DWORD)ha->pFileTable[i].ByteOffset; - pBlock->dwFSize = ha->pFileTable[i].dwFileSize; - pBlock->dwCSize = ha->pFileTable[i].dwCmpSize; - pBlock->dwFlags = ha->pFileTable[i].dwFlags; - pBlock++; - } - break; - - case SFILE_INFO_NUM_FILES: - VERIFY_MPQ_HANDLE(ha); - dwFileCount = GetMpqFileCount(ha); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &dwFileCount; - break; - - case SFILE_INFO_STREAM_FLAGS: // Deprecated - nError = ERROR_INVALID_PARAMETER; - break; - - case SFILE_INFO_IS_READ_ONLY: - VERIFY_MPQ_HANDLE(ha); - dwIsReadOnly = (FileStream_IsReadOnly(ha->pStream) || (ha->dwFlags & MPQ_FLAG_READ_ONLY)); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &dwIsReadOnly; - break; - - case SFILE_INFO_HASH_INDEX: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &hf->pFileEntry->dwHashIndex; - break; - - case SFILE_INFO_CODENAME1: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &hf->pFileEntry->dwHashIndex; - if(ha->pHashTable != NULL) - pvSrcFileInfo = &ha->pHashTable[hf->pFileEntry->dwHashIndex].dwName1; - break; - - case SFILE_INFO_CODENAME2: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - if(ha->pHashTable != NULL) - pvSrcFileInfo = &ha->pHashTable[hf->pFileEntry->dwHashIndex].dwName2; - break; - - case SFILE_INFO_LOCALEID: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &hf->pFileEntry->lcLocale; - break; - - case SFILE_INFO_BLOCKINDEX: - VERIFY_FILE_HANDLE(hf); - dwFileIndex = (DWORD)(hf->pFileEntry - hf->ha->pFileTable); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &dwFileIndex; - break; - - case SFILE_INFO_FILE_SIZE: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &hf->pFileEntry->dwFileSize; - break; - - case SFILE_INFO_COMPRESSED_SIZE: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &hf->pFileEntry->dwCmpSize; - break; - - case SFILE_INFO_FLAGS: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &hf->pFileEntry->dwFlags; - break; - - case SFILE_INFO_POSITION: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(ULONGLONG); - pvSrcFileInfo = &hf->pFileEntry->ByteOffset; - break; - - case SFILE_INFO_KEY: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &hf->dwFileKey; - break; - - case SFILE_INFO_KEY_UNFIXED: - VERIFY_FILE_HANDLE(hf); - dwFileKey = hf->dwFileKey; - if(hf->pFileEntry->dwFlags & MPQ_FILE_FIX_KEY) - dwFileKey = (dwFileKey ^ hf->pFileEntry->dwFileSize) - (DWORD)hf->MpqFilePos; - cbLengthNeeded = sizeof(DWORD); - pvSrcFileInfo = &dwFileKey; - break; - - case SFILE_INFO_FILETIME: - VERIFY_FILE_HANDLE(hf); - cbLengthNeeded = sizeof(ULONGLONG); - pvSrcFileInfo = &hf->pFileEntry->FileTime; - break; - - case SFILE_INFO_PATCH_CHAIN: - VERIFY_FILE_HANDLE(hf); - GetFilePatchChain(hf, pvFileInfo, cbFileInfo, &cbLengthNeeded); - break; - - default: - nError = ERROR_INVALID_PARAMETER; - break; - } - - // If everything is OK so far, copy the information - if(nError == ERROR_SUCCESS) - { - // Is the output buffer large enough? - if(cbFileInfo >= cbLengthNeeded) - { - // Copy the data - if(pvSrcFileInfo != NULL) - memcpy(pvFileInfo, pvSrcFileInfo, cbLengthNeeded); - } - else - { - nError = ERROR_INSUFFICIENT_BUFFER; - } - - // Give the size to the caller - if(pcbLengthNeeded != NULL) - *pcbLengthNeeded = cbLengthNeeded; - } - - // Set the last error value, if needed - if(nError != ERROR_SUCCESS) - SetLastError(nError); - return (nError == ERROR_SUCCESS); -} diff --git a/dep/StormLib/src/SFileVerify.cpp b/dep/StormLib/src/SFileVerify.cpp deleted file mode 100644 index 7457171d88f..00000000000 --- a/dep/StormLib/src/SFileVerify.cpp +++ /dev/null @@ -1,921 +0,0 @@ -/*****************************************************************************/ -/* SFileVerify.cpp Copyright (c) Ladislav Zezula 2010 */ -/*---------------------------------------------------------------------------*/ -/* MPQ files and MPQ archives verification. */ -/* */ -/* The MPQ signature verification has been written by Jean-Francois Roy */ -/* <bahamut@macstorm.org> and Justin Olbrantz (Quantam). */ -/* The MPQ public keys have been created by MPQKit, using OpenSSL library. */ -/* */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 04.05.10 1.00 Lad The first version of SFileVerify.cpp */ -/*****************************************************************************/ - -#define __STORMLIB_SELF__ -#include "StormLib.h" -#include "StormCommon.h" - -//----------------------------------------------------------------------------- -// Local defines - -#define SIGNATURE_TYPE_NONE 0 -#define SIGNATURE_TYPE_WEAK 1 -#define SIGNATURE_TYPE_STRONG 2 - -#define MPQ_DIGEST_UNIT_SIZE 0x10000 - -typedef struct _MPQ_SIGNATURE_INFO -{ - ULONGLONG BeginMpqData; // File offset where the hashing starts - ULONGLONG BeginExclude; // Begin of the excluded area (used for (signature) file) - ULONGLONG EndExclude; // End of the excluded area (used for (signature) file) - ULONGLONG EndMpqData; // File offset where the hashing ends - ULONGLONG EndOfFile; // Size of the entire file - BYTE Signature[MPQ_STRONG_SIGNATURE_SIZE + 0x10]; - DWORD cbSignatureSize; // Length of the signature - int nSignatureType; // See SIGNATURE_TYPE_XXX - -} MPQ_SIGNATURE_INFO, *PMPQ_SIGNATURE_INFO; - -//----------------------------------------------------------------------------- -// Known Blizzard public keys -// Created by Jean-Francois Roy using OpenSSL - -static const char * szBlizzardWeakPublicKey = - "-----BEGIN PUBLIC KEY-----" - "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJJidwS/uILMBSO5DLGsBFknIXWWjQJe" - "2kfdfEk3G/j66w4KkhZ1V61Rt4zLaMVCYpDun7FLwRjkMDSepO1q2DcCAwEAAQ==" - "-----END PUBLIC KEY-----"; - -static const char * szBlizzardStrongPublicKey = - "-----BEGIN PUBLIC KEY-----" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsQZ+ziT2h8h+J/iMQpgd" - "tH1HaJzOBE3agjU4yMPcrixaPOZoA4t8bwfey7qczfWywocYo3pleytFF+IuD4HD" - "Fl9OXN1SFyupSgMx1EGZlgbFAomnbq9MQJyMqQtMhRAjFgg4TndS7YNb+JMSAEKp" - "kXNqY28n/EVBHD5TsMuVCL579gIenbr61dI92DDEdy790IzIG0VKWLh/KOTcTJfm" - "Ds/7HQTkGouVW+WUsfekuqNQo7ND9DBnhLjLjptxeFE2AZqYcA1ao3S9LN3GL1tW" - "lVXFIX9c7fWqaVTQlZ2oNsI/ARVApOK3grNgqvwH6YoVYVXjNJEo5sQJsPsdV/hk" - "dwIDAQAB" - "-----END PUBLIC KEY-----"; - -static const char * szWarcraft3MapPublicKey = - "-----BEGIN PUBLIC KEY-----" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1BwklUUQ3UvjizOBRoF5" - "yyOVc7KD+oGOQH5i6eUk1yfs0luCC70kNucNrfqhmviywVtahRse1JtXCPrx2bd3" - "iN8Dx91fbkxjYIOGTsjYoHKTp0BbaFkJih776fcHgnFSb+7mJcDuJVvJOXxEH6w0" - "1vo6VtujCqj1arqbyoal+xtAaczF3us5cOEp45sR1zAWTn1+7omN7VWV4QqJPaDS" - "gBSESc0l1grO0i1VUSumayk7yBKIkb+LBvcG6WnYZHCi7VdLmaxER5m8oZfER66b" - "heHoiSQIZf9PAY6Guw2DT5BTc54j/AaLQAKf2qcRSgQLVo5kQaddF3rCpsXoB/74" - "6QIDAQAB" - "-----END PUBLIC KEY-----"; - -static const char * szWowPatchPublicKey = - "-----BEGIN PUBLIC KEY-----" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwOsMV0LagAWPEtEQM6b9" - "6FHFkUyGbbyda2/Dfc9dyl21E9QvX+Yw7qKRMAKPzA2TlQQLZKvXpnKXF/YIK5xa" - "5uwg9CEHCEAYolLG4xn0FUOE0E/0PuuytI0p0ICe6rk00PifZzTr8na2wI/l/GnQ" - "bvnIVF1ck6cslATpQJ5JJVMXzoFlUABS19WESw4MXuJAS3AbMhxNWdEhVv7eO51c" - "yGjRLy9QjogZODZTY0fSEksgBqQxNCoYVJYI/sF5K2flDsGqrIp0OdJ6teJlzg1Y" - "UjYnb6bKjlidXoHEXI2TgA/mD6O3XFIt08I9s3crOCTgICq7cgX35qrZiIVWZdRv" - "TwIDAQAB" - "-----END PUBLIC KEY-----"; - -static const char * szWowSurveyPublicKey = - "-----BEGIN PUBLIC KEY-----" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnIt1DR6nRyyKsy2qahHe" - "MKLtacatn/KxieHcwH87wLBxKy+jZ0gycTmJ7SaTdBAEMDs/V5IPIXEtoqYnid2c" - "63TmfGDU92oc3Ph1PWUZ2PWxBhT06HYxRdbrgHw9/I29pNPi/607x+lzPORITOgU" - "BR6MR8au8HsQP4bn4vkJNgnSgojh48/XQOB/cAln7As1neP61NmVimoLR4Bwi3zt" - "zfgrZaUpyeNCUrOYJmH09YIjbBySTtXOUidoPHjFrMsCWpr6xs8xbETbs7MJFL6a" - "vcUfTT67qfIZ9RsuKfnXJTIrV0kwDSjjuNXiPTmWAehSsiHIsrUXX5RNcwsSjClr" - "nQIDAQAB" - "-----END PUBLIC KEY-----"; - -static const char * szStarcraft2MapPublicKey = - "-----BEGIN PUBLIC KEY-----" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmk4GT8zb+ICC25a17KZB" - "q/ygKGJ2VSO6IT5PGHJlm1KfnHBA4B6SH3xMlJ4c6eG2k7QevZv+FOhjsAHubyWq" - "2VKqWbrIFKv2ILc2RfMn8J9EDVRxvcxh6slRrVL69D0w1tfVGjMiKq2Fym5yGoRT" - "E7CRgDqbAbXP9LBsCNWHiJLwfxMGzHbk8pIl9oia5pvM7ofZamSHchxlpy6xa4GJ" - "7xKN01YCNvklTL1D7uol3wkwcHc7vrF8QwuJizuA5bSg4poEGtH62BZOYi+UL/z0" - "31YK+k9CbQyM0X0pJoJoYz1TK+Y5J7vBnXCZtfcTYQ/ZzN6UcxTa57dJaiOlCh9z" - "nQIDAQAB" - "-----END PUBLIC KEY-----"; - -//----------------------------------------------------------------------------- -// Local functions - -static void memrev(unsigned char *buf, size_t count) -{ - unsigned char *r; - - for (r = buf + count - 1; buf < r; buf++, r--) - { - *buf ^= *r; - *r ^= *buf; - *buf ^= *r; - } -} - -static bool is_valid_md5(void * pvMd5) -{ - LPDWORD Md5 = (LPDWORD)pvMd5; - - return (Md5[0] | Md5[1] | Md5[2] | Md5[3]) ? true : false; -} - -static bool decode_base64_key(const char * szKeyBase64, rsa_key * key) -{ - unsigned char decoded_key[0x200]; - const char * szBase64Begin; - const char * szBase64End; - unsigned long decoded_length = sizeof(decoded_key); - unsigned long length; - - // Find out the begin of the BASE64 data - szBase64Begin = szKeyBase64 + strlen("-----BEGIN PUBLIC KEY-----"); - szBase64End = szBase64Begin + strlen(szBase64Begin) - strlen("-----END PUBLIC KEY-----"); - if(szBase64End[0] != '-') - return false; - - // decode the base64 string - length = (unsigned long)(szBase64End - szBase64Begin); - if(base64_decode((unsigned char *)szBase64Begin, length, decoded_key, &decoded_length) != CRYPT_OK) - return false; - - // Create RSA key - if(rsa_import(decoded_key, decoded_length, key) != CRYPT_OK) - return false; - - return true; -} - -static void GetPlainAnsiFileName( - const TCHAR * szFileName, - char * szPlainName) -{ - const TCHAR * szPlainNameT = GetPlainFileNameT(szFileName); - - // Convert the plain name to ANSI - while(*szPlainNameT != 0) - *szPlainName++ = (char)*szPlainNameT++; - *szPlainName = 0; -} - -// Calculate begin and end of the MPQ archive -static void CalculateArchiveRange( - TMPQArchive * ha, - PMPQ_SIGNATURE_INFO pSI) -{ - ULONGLONG TempPos = 0; - char szMapHeader[0x200]; - - // Get the MPQ begin - pSI->BeginMpqData = ha->MpqPos; - - // Warcraft III maps are signed from the map header to the end - if(FileStream_Read(ha->pStream, &TempPos, szMapHeader, sizeof(szMapHeader))) - { - // Is it a map header ? - if(szMapHeader[0] == 'H' && szMapHeader[1] == 'M' && szMapHeader[2] == '3' && szMapHeader[3] == 'W') - { - // We will have to hash since the map header - pSI->BeginMpqData = 0; - } - } - - // Get the MPQ data end. This is stored in our MPQ header, - // and it's been already prepared by SFileOpenArchive, - pSI->EndMpqData = ha->MpqPos + ha->pHeader->ArchiveSize64; - - // Get the size of the entire file - FileStream_GetSize(ha->pStream, pSI->EndOfFile); -} - -static bool QueryMpqSignatureInfo( - TMPQArchive * ha, - PMPQ_SIGNATURE_INFO pSI) -{ - ULONGLONG ExtraBytes; - TMPQFile * hf; - HANDLE hFile; - DWORD dwFileSize; - - // Calculate the range of the MPQ - CalculateArchiveRange(ha, pSI); - - // If there is "(signature)" file in the MPQ, it has a weak signature - if(SFileOpenFileEx((HANDLE)ha, SIGNATURE_NAME, SFILE_OPEN_FROM_MPQ, &hFile)) - { - // Get the content of the signature - SFileReadFile(hFile, pSI->Signature, sizeof(pSI->Signature), &pSI->cbSignatureSize); - - // Verify the size of the signature - hf = (TMPQFile *)hFile; - - // We have to exclude the signature file from the digest - pSI->BeginExclude = ha->MpqPos + hf->pFileEntry->ByteOffset; - pSI->EndExclude = pSI->BeginExclude + hf->pFileEntry->dwCmpSize; - dwFileSize = hf->dwDataSize; - - // Close the file - SFileCloseFile(hFile); - pSI->nSignatureType = SIGNATURE_TYPE_WEAK; - return (dwFileSize == (MPQ_WEAK_SIGNATURE_SIZE + 8)) ? true : false; - } - - // If there is extra bytes beyond the end of the archive, - // it's the strong signature - ExtraBytes = pSI->EndOfFile - pSI->EndMpqData; - if(ExtraBytes >= (MPQ_STRONG_SIGNATURE_SIZE + 4)) - { - // Read the strong signature - if(!FileStream_Read(ha->pStream, &pSI->EndMpqData, pSI->Signature, (MPQ_STRONG_SIGNATURE_SIZE + 4))) - return false; - - // Check the signature header "NGIS" - if(pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S') - return false; - - pSI->nSignatureType = SIGNATURE_TYPE_STRONG; - return true; - } - - // Succeeded, but no known signature found - return true; -} - -static bool CalculateMpqHashMd5( - TMPQArchive * ha, - PMPQ_SIGNATURE_INFO pSI, - LPBYTE pMd5Digest) -{ - hash_state md5_state; - ULONGLONG BeginBuffer; - ULONGLONG EndBuffer; - LPBYTE pbDigestBuffer = NULL; - - // Allocate buffer for creating the MPQ digest. - pbDigestBuffer = STORM_ALLOC(BYTE, MPQ_DIGEST_UNIT_SIZE); - if(pbDigestBuffer == NULL) - return false; - - // Initialize the MD5 hash state - md5_init(&md5_state); - - // Set the byte offset of begin of the data - BeginBuffer = pSI->BeginMpqData; - - // Create the digest - for(;;) - { - ULONGLONG BytesRemaining; - LPBYTE pbSigBegin = NULL; - LPBYTE pbSigEnd = NULL; - DWORD dwToRead = MPQ_DIGEST_UNIT_SIZE; - - // Check the number of bytes remaining - BytesRemaining = pSI->EndMpqData - BeginBuffer; - if(BytesRemaining < MPQ_DIGEST_UNIT_SIZE) - dwToRead = (DWORD)BytesRemaining; - if(dwToRead == 0) - break; - - // Read the next chunk - if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead)) - { - STORM_FREE(pbDigestBuffer); - return false; - } - - // Move the current byte offset - EndBuffer = BeginBuffer + dwToRead; - - // Check if the signature is within the loaded digest - if(BeginBuffer <= pSI->BeginExclude && pSI->BeginExclude < EndBuffer) - pbSigBegin = pbDigestBuffer + (size_t)(pSI->BeginExclude - BeginBuffer); - if(BeginBuffer <= pSI->EndExclude && pSI->EndExclude < EndBuffer) - pbSigEnd = pbDigestBuffer + (size_t)(pSI->EndExclude - BeginBuffer); - - // Zero the part that belongs to the signature - if(pbSigBegin != NULL || pbSigEnd != NULL) - { - if(pbSigBegin == NULL) - pbSigBegin = pbDigestBuffer; - if(pbSigEnd == NULL) - pbSigEnd = pbDigestBuffer + dwToRead; - - memset(pbSigBegin, 0, (pbSigEnd - pbSigBegin)); - } - - // Pass the buffer to the hashing function - md5_process(&md5_state, pbDigestBuffer, dwToRead); - - // Move pointers - BeginBuffer += dwToRead; - } - - // Finalize the MD5 hash - md5_done(&md5_state, pMd5Digest); - STORM_FREE(pbDigestBuffer); - return true; -} - -static void AddTailToSha1( - hash_state * psha1_state, - const char * szTail) -{ - unsigned char szUpperCase[0x200]; - unsigned long nLength = 0; - - // Convert the tail to uppercase - // Note that we don't need to terminate the string with zero - while(*szTail != 0) - { - szUpperCase[nLength++] = (unsigned char)toupper(*szTail++); - } - - // Append the tail to the SHA1 - sha1_process(psha1_state, szUpperCase, nLength); -} - -static bool CalculateMpqHashSha1( - TMPQArchive * ha, - PMPQ_SIGNATURE_INFO pSI, - unsigned char * sha1_tail0, - unsigned char * sha1_tail1, - unsigned char * sha1_tail2) -{ - ULONGLONG BeginBuffer; - hash_state sha1_state_temp; - hash_state sha1_state; - LPBYTE pbDigestBuffer = NULL; - char szPlainName[MAX_PATH]; - - // Allocate buffer for creating the MPQ digest. - pbDigestBuffer = STORM_ALLOC(BYTE, MPQ_DIGEST_UNIT_SIZE); - if(pbDigestBuffer == NULL) - return false; - - // Initialize SHA1 state structure - sha1_init(&sha1_state); - - // Calculate begin of data to be hashed - BeginBuffer = pSI->BeginMpqData; - - // Create the digest - for(;;) - { - ULONGLONG BytesRemaining; - DWORD dwToRead = MPQ_DIGEST_UNIT_SIZE; - - // Check the number of bytes remaining - BytesRemaining = pSI->EndMpqData - BeginBuffer; - if(BytesRemaining < MPQ_DIGEST_UNIT_SIZE) - dwToRead = (DWORD)BytesRemaining; - if(dwToRead == 0) - break; - - // Read the next chunk - if(!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead)) - { - STORM_FREE(pbDigestBuffer); - return false; - } - - // Pass the buffer to the hashing function - sha1_process(&sha1_state, pbDigestBuffer, dwToRead); - - // Move pointers - BeginBuffer += dwToRead; - } - - // Add all three known tails and generate three hashes - memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); - sha1_done(&sha1_state_temp, sha1_tail0); - - memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); - GetPlainAnsiFileName(FileStream_GetFileName(ha->pStream), szPlainName); - AddTailToSha1(&sha1_state_temp, szPlainName); - sha1_done(&sha1_state_temp, sha1_tail1); - - memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); - AddTailToSha1(&sha1_state_temp, "ARCHIVE"); - sha1_done(&sha1_state_temp, sha1_tail2); - - // Finalize the MD5 hash - STORM_FREE(pbDigestBuffer); - return true; -} - -static int VerifyRawMpqData( - TMPQArchive * ha, - ULONGLONG ByteOffset, - DWORD dwDataSize) -{ - ULONGLONG DataOffset = ha->MpqPos + ByteOffset; - LPBYTE pbDataChunk; - LPBYTE pbMD5Array1; // Calculated MD5 array - LPBYTE pbMD5Array2; // MD5 array loaded from the MPQ - DWORD dwBytesInChunk; - DWORD dwChunkCount; - DWORD dwChunkSize = ha->pHeader->dwRawChunkSize; - DWORD dwMD5Size; - int nError = ERROR_SUCCESS; - - // Don't verify zero-sized blocks - if(dwDataSize == 0) - return ERROR_SUCCESS; - - // Get the number of data chunks to calculate MD5 - assert(dwChunkSize != 0); - dwChunkCount = ((dwDataSize - 1) / dwChunkSize) + 1; - dwMD5Size = dwChunkCount * MD5_DIGEST_SIZE; - - // Allocate space for data chunk and for the MD5 array - pbDataChunk = STORM_ALLOC(BYTE, dwChunkSize); - if(pbDataChunk == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - - // Allocate space for MD5 array - pbMD5Array1 = STORM_ALLOC(BYTE, dwMD5Size); - pbMD5Array2 = STORM_ALLOC(BYTE, dwMD5Size); - if(pbMD5Array1 == NULL || pbMD5Array2 == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - - // Calculate MD5 of each data chunk - if(nError == ERROR_SUCCESS) - { - LPBYTE pbMD5 = pbMD5Array1; - - for(DWORD i = 0; i < dwChunkCount; i++) - { - // Get the number of bytes in the chunk - dwBytesInChunk = STORMLIB_MIN(dwChunkSize, dwDataSize); - - // Read the data chunk - if(!FileStream_Read(ha->pStream, &DataOffset, pbDataChunk, dwBytesInChunk)) - { - nError = ERROR_FILE_CORRUPT; - break; - } - - // Calculate MD5 - CalculateDataBlockHash(pbDataChunk, dwBytesInChunk, pbMD5); - - // Move pointers and offsets - DataOffset += dwBytesInChunk; - dwDataSize -= dwBytesInChunk; - pbMD5 += MD5_DIGEST_SIZE; - } - } - - // Read the MD5 array - if(nError == ERROR_SUCCESS) - { - // Read the array of MD5 - if(!FileStream_Read(ha->pStream, &DataOffset, pbMD5Array2, dwMD5Size)) - nError = GetLastError(); - } - - // Compare the array of MD5 - if(nError == ERROR_SUCCESS) - { - // Compare the MD5 - if(memcmp(pbMD5Array1, pbMD5Array2, dwMD5Size)) - nError = ERROR_FILE_CORRUPT; - } - - // Free memory and return result - if(pbMD5Array2 != NULL) - STORM_FREE(pbMD5Array2); - if(pbMD5Array1 != NULL) - STORM_FREE(pbMD5Array1); - if(pbDataChunk != NULL) - STORM_FREE(pbDataChunk); - return nError; -} - -static DWORD VerifyWeakSignature( - TMPQArchive * ha, - PMPQ_SIGNATURE_INFO pSI) -{ - BYTE RevSignature[MPQ_WEAK_SIGNATURE_SIZE]; - BYTE Md5Digest[MD5_DIGEST_SIZE]; - rsa_key key; - int hash_idx = find_hash("md5"); - int result = 0; - - // Calculate hash of the entire archive, skipping the (signature) file - if(!CalculateMpqHashMd5(ha, pSI, Md5Digest)) - return ERROR_VERIFY_FAILED; - - // Import the Blizzard key in OpenSSL format - if(!decode_base64_key(szBlizzardWeakPublicKey, &key)) - return ERROR_VERIFY_FAILED; - - // Verify the signature - memcpy(RevSignature, &pSI->Signature[8], MPQ_WEAK_SIGNATURE_SIZE); - memrev(RevSignature, MPQ_WEAK_SIGNATURE_SIZE); - rsa_verify_hash_ex(RevSignature, MPQ_WEAK_SIGNATURE_SIZE, Md5Digest, sizeof(Md5Digest), LTC_LTC_PKCS_1_V1_5, hash_idx, 0, &result, &key); - rsa_free(&key); - - // Return the result - return result ? ERROR_WEAK_SIGNATURE_OK : ERROR_WEAK_SIGNATURE_ERROR; -} - -static DWORD VerifyStrongSignatureWithKey( - unsigned char * reversed_signature, - unsigned char * padded_digest, - const char * szPublicKey) -{ - rsa_key key; - int result = 0; - - // Import the Blizzard key in OpenSSL format - if(!decode_base64_key(szPublicKey, &key)) - { - assert(false); - return ERROR_VERIFY_FAILED; - } - - // Verify the signature - if(rsa_verify_simple(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE, padded_digest, MPQ_STRONG_SIGNATURE_SIZE, &result, &key) != CRYPT_OK) - return ERROR_VERIFY_FAILED; - - // Free the key and return result - rsa_free(&key); - return result ? ERROR_STRONG_SIGNATURE_OK : ERROR_STRONG_SIGNATURE_ERROR; -} - -static DWORD VerifyStrongSignature( - TMPQArchive * ha, - PMPQ_SIGNATURE_INFO pSI) -{ - unsigned char reversed_signature[MPQ_STRONG_SIGNATURE_SIZE]; - unsigned char Sha1Digest_tail0[SHA1_DIGEST_SIZE]; - unsigned char Sha1Digest_tail1[SHA1_DIGEST_SIZE]; - unsigned char Sha1Digest_tail2[SHA1_DIGEST_SIZE]; - unsigned char padded_digest[MPQ_STRONG_SIGNATURE_SIZE]; - DWORD dwResult; - size_t digest_offset; - - // Calculate SHA1 hash of the archive - if(!CalculateMpqHashSha1(ha, pSI, Sha1Digest_tail0, Sha1Digest_tail1, Sha1Digest_tail2)) - return ERROR_VERIFY_FAILED; - - // Prepare the signature for decryption - memcpy(reversed_signature, &pSI->Signature[4], MPQ_STRONG_SIGNATURE_SIZE); - memrev(reversed_signature, MPQ_STRONG_SIGNATURE_SIZE); - - // Prepare the padded digest for comparison - digest_offset = sizeof(padded_digest) - SHA1_DIGEST_SIZE; - memset(padded_digest, 0xbb, digest_offset); - padded_digest[0] = 0x0b; - - // Try Blizzard Strong public key with no SHA1 tail - memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE); - memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); - dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szBlizzardStrongPublicKey); - if(dwResult == ERROR_STRONG_SIGNATURE_OK) - return dwResult; - - // Try War 3 map public key with plain file name as SHA1 tail - memcpy(padded_digest + digest_offset, Sha1Digest_tail1, SHA1_DIGEST_SIZE); - memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); - dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWarcraft3MapPublicKey); - if(dwResult == ERROR_STRONG_SIGNATURE_OK) - return dwResult; - - // Try WoW-TBC public key with "ARCHIVE" as SHA1 tail - memcpy(padded_digest + digest_offset, Sha1Digest_tail2, SHA1_DIGEST_SIZE); - memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); - dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWowPatchPublicKey); - if(dwResult == ERROR_STRONG_SIGNATURE_OK) - return dwResult; - - // Try Survey public key with no SHA1 tail - memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE); - memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); - dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szWowSurveyPublicKey); - if(dwResult == ERROR_STRONG_SIGNATURE_OK) - return dwResult; - - // Try Starcraft II public key with no SHA1 tail - memcpy(padded_digest + digest_offset, Sha1Digest_tail0, SHA1_DIGEST_SIZE); - memrev(padded_digest + digest_offset, SHA1_DIGEST_SIZE); - dwResult = VerifyStrongSignatureWithKey(reversed_signature, padded_digest, szStarcraft2MapPublicKey); - if(dwResult == ERROR_STRONG_SIGNATURE_OK) - return dwResult; - - return ERROR_STRONG_SIGNATURE_ERROR; -} - -static DWORD VerifyFile( - HANDLE hMpq, - const char * szFileName, - LPDWORD pdwCrc32, - char * pMD5, - DWORD dwFlags) -{ - hash_state md5_state; - unsigned char * pFileMd5; - unsigned char md5[MD5_DIGEST_SIZE]; - TFileEntry * pFileEntry; - TMPQFile * hf; - BYTE Buffer[0x1000]; - HANDLE hFile = NULL; - DWORD dwVerifyResult = 0; - DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ; - DWORD dwTotalBytes = 0; - DWORD dwBytesRead; - DWORD dwCrc32 = 0; - - // Fix the open type for patched archives - if(SFileIsPatchedArchive(hMpq)) - dwSearchScope = SFILE_OPEN_PATCHED_FILE; - - // If we have to verify raw data MD5, do it before file open - if(dwFlags & SFILE_VERIFY_RAW_MD5) - { - TMPQArchive * ha = (TMPQArchive *)hMpq; - - // Parse the base MPQ and all patches - while(ha != NULL) - { - // Does the archive have support for raw MD5? - if(ha->pHeader->dwRawChunkSize != 0) - { - // The file has raw MD5 if the archive supports it - dwVerifyResult |= VERIFY_FILE_HAS_RAW_MD5; - - // Find file entry for the file - pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale); - if(pFileEntry != NULL) - { - // If the file's raw MD5 doesn't match, don't bother with more checks - if(VerifyRawMpqData(ha, pFileEntry->ByteOffset, pFileEntry->dwCmpSize) != ERROR_SUCCESS) - return dwVerifyResult | VERIFY_FILE_RAW_MD5_ERROR; - } - } - - // Move to the next patch - ha = ha->haPatch; - } - } - - // Attempt to open the file - if(SFileOpenFileEx(hMpq, szFileName, dwSearchScope, &hFile)) - { - // Get the file size - hf = (TMPQFile *)hFile; - pFileEntry = hf->pFileEntry; - dwTotalBytes = SFileGetFileSize(hFile, NULL); - - // Initialize the CRC32 and MD5 contexts - md5_init(&md5_state); - dwCrc32 = crc32(0, Z_NULL, 0); - - // Also turn on sector checksum verification - if(dwFlags & SFILE_VERIFY_SECTOR_CRC) - hf->bCheckSectorCRCs = true; - - // Go through entire file and update both CRC32 and MD5 - for(;;) - { - // Read data from file - SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); - if(dwBytesRead == 0) - { - if(GetLastError() == ERROR_CHECKSUM_ERROR) - dwVerifyResult |= VERIFY_FILE_SECTOR_CRC_ERROR; - break; - } - - // Update CRC32 value - if(dwFlags & SFILE_VERIFY_FILE_CRC) - dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead); - - // Update MD5 value - if(dwFlags & SFILE_VERIFY_FILE_MD5) - md5_process(&md5_state, Buffer, dwBytesRead); - - // Decrement the total size - dwTotalBytes -= dwBytesRead; - } - - // If the file has sector checksums, indicate it in the flags - if(dwFlags & SFILE_VERIFY_SECTOR_CRC) - { - if((hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->SectorChksums != NULL && hf->SectorChksums[0] != 0) - dwVerifyResult |= VERIFY_FILE_HAS_SECTOR_CRC; - } - - // Check if the entire file has been read - // No point in checking CRC32 and MD5 if not - // Skip checksum checks if the file has patches - if(dwTotalBytes == 0) - { - // Check CRC32 and MD5 only if there is no patches - if(hf->hfPatchFile == NULL) - { - // Check if the CRC32 matches. - if(dwFlags & SFILE_VERIFY_FILE_CRC) - { - // Only check the CRC32 if it is valid - if(pFileEntry->dwCrc32 != 0) - { - dwVerifyResult |= VERIFY_FILE_HAS_CHECKSUM; - if(dwCrc32 != pFileEntry->dwCrc32) - dwVerifyResult |= VERIFY_FILE_CHECKSUM_ERROR; - } - } - - // Check if MD5 matches - if(dwFlags & SFILE_VERIFY_FILE_MD5) - { - // Patch files have their MD5 saved in the patch info - pFileMd5 = (hf->pPatchInfo != NULL) ? hf->pPatchInfo->md5 : pFileEntry->md5; - md5_done(&md5_state, md5); - - // Only check the MD5 if it is valid - if(is_valid_md5(pFileMd5)) - { - dwVerifyResult |= VERIFY_FILE_HAS_MD5; - if(memcmp(md5, pFileMd5, MD5_DIGEST_SIZE)) - dwVerifyResult |= VERIFY_FILE_MD5_ERROR; - } - } - } - else - { - // Patched files are MD5-checked automatically - dwVerifyResult |= VERIFY_FILE_HAS_MD5; - } - } - else - { - dwVerifyResult |= VERIFY_READ_ERROR; - } - - SFileCloseFile(hFile); - } - else - { - // Remember that the file couldn't be open - dwVerifyResult |= VERIFY_OPEN_ERROR; - } - - // If the caller required CRC32 and/or MD5, give it to him - if(pdwCrc32 != NULL) - *pdwCrc32 = dwCrc32; - if(pMD5 != NULL) - memcpy(pMD5, md5, MD5_DIGEST_SIZE); - - return dwVerifyResult; -} - -//----------------------------------------------------------------------------- -// Public (exported) functions - -bool WINAPI SFileGetFileChecksums(HANDLE hMpq, const char * szFileName, LPDWORD pdwCrc32, char * pMD5) -{ - DWORD dwVerifyResult; - DWORD dwVerifyFlags = 0; - - if(pdwCrc32 != NULL) - dwVerifyFlags |= SFILE_VERIFY_FILE_CRC; - if(pMD5 != NULL) - dwVerifyFlags |= SFILE_VERIFY_FILE_MD5; - - dwVerifyResult = VerifyFile(hMpq, - szFileName, - pdwCrc32, - pMD5, - dwVerifyFlags); - - // If verification failed, return zero - if(dwVerifyResult & VERIFY_FILE_ERROR_MASK) - { - SetLastError(ERROR_FILE_CORRUPT); - return false; - } - - return true; -} - - -DWORD WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags) -{ - return VerifyFile(hMpq, - szFileName, - NULL, - NULL, - dwFlags); -} - -// Verifies raw data of the archive Only works for MPQs version 4 or newer -int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName) -{ - TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pFileEntry; - TMPQHeader * pHeader; - - // Verify input parameters - if(!IsValidMpqHandle(ha)) - return ERROR_INVALID_PARAMETER; - pHeader = ha->pHeader; - - // If the archive doesn't have raw data MD5, report it as OK - if(pHeader->dwRawChunkSize == 0) - return ERROR_SUCCESS; - - // If we have to verify MPQ header, do it - switch(dwWhatToVerify) - { - case SFILE_VERIFY_MPQ_HEADER: - - // Only if the header is of version 4 or newer - if(pHeader->dwHeaderSize >= (MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE)) - return VerifyRawMpqData(ha, 0, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE); - return ERROR_SUCCESS; - - case SFILE_VERIFY_HET_TABLE: - - // Only if we have HET table - if(pHeader->HetTablePos64 && pHeader->HetTableSize64) - return VerifyRawMpqData(ha, pHeader->HetTablePos64, (DWORD)pHeader->HetTableSize64); - return ERROR_SUCCESS; - - case SFILE_VERIFY_BET_TABLE: - - // Only if we have BET table - if(pHeader->BetTablePos64 && pHeader->BetTableSize64) - return VerifyRawMpqData(ha, pHeader->BetTablePos64, (DWORD)pHeader->BetTableSize64); - return ERROR_SUCCESS; - - case SFILE_VERIFY_HASH_TABLE: - - // Hash table is not protected by MD5 - return ERROR_SUCCESS; - - case SFILE_VERIFY_BLOCK_TABLE: - - // Block table is not protected by MD5 - return ERROR_SUCCESS; - - case SFILE_VERIFY_HIBLOCK_TABLE: - - // It is unknown if the hi-block table is protected my MD5 or not. - return ERROR_SUCCESS; - - case SFILE_VERIFY_FILE: - - // Verify parameters - if(szFileName == NULL || *szFileName == 0) - return ERROR_INVALID_PARAMETER; - - // Get the offset of a file - pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale); - if(pFileEntry == NULL) - return ERROR_FILE_NOT_FOUND; - - return VerifyRawMpqData(ha, pFileEntry->ByteOffset, pFileEntry->dwCmpSize); - } - - return ERROR_INVALID_PARAMETER; -} - - -// Verifies the archive against the signature -DWORD WINAPI SFileVerifyArchive(HANDLE hMpq) -{ - MPQ_SIGNATURE_INFO si; - TMPQArchive * ha = (TMPQArchive *)hMpq; - - // Verify input parameters - if(!IsValidMpqHandle(ha)) - return ERROR_VERIFY_FAILED; - - // Get the MPQ signature and signature type - memset(&si, 0, sizeof(MPQ_SIGNATURE_INFO)); - if(!QueryMpqSignatureInfo(ha, &si)) - return ERROR_VERIFY_FAILED; - - // Verify the signature - switch(si.nSignatureType) - { - case SIGNATURE_TYPE_NONE: - return ERROR_NO_SIGNATURE; - - case SIGNATURE_TYPE_WEAK: - return VerifyWeakSignature(ha, &si); - - case SIGNATURE_TYPE_STRONG: - return VerifyStrongSignature(ha, &si); - } - - return ERROR_VERIFY_FAILED; -} diff --git a/dep/StormLib/src/StormCommon.h b/dep/StormLib/src/StormCommon.h deleted file mode 100644 index 9a85c4bd5ac..00000000000 --- a/dep/StormLib/src/StormCommon.h +++ /dev/null @@ -1,274 +0,0 @@ -/*****************************************************************************/ -/* SCommon.h Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Common functions for encryption/decryption from Storm.dll. Included by */ -/* SFile*** functions, do not include and do not use this file directly */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 24.03.03 1.00 Lad The first version of SFileCommon.h */ -/* 12.06.04 1.00 Lad Renamed to SCommon.h */ -/* 06.09.10 1.00 Lad Renamed to StormCommon.h */ -/*****************************************************************************/ - -#ifndef __STORMCOMMON_H__ -#define __STORMCOMMON_H__ - -//----------------------------------------------------------------------------- -// Compression support - -// Include functions from Pkware Data Compression Library -#include "pklib/pklib.h" - -// Include functions from Huffmann compression -#include "huffman/huff.h" - -// Include functions from IMA ADPCM compression -#include "adpcm/adpcm.h" - -// Include functions from SPARSE compression -#include "sparse/sparse.h" - -// Include functions from LZMA compression -#include "lzma/C/LzmaEnc.h" -#include "lzma/C/LzmaDec.h" - -// Include functions from zlib -#ifndef __SYS_ZLIB - #include "zlib/zlib.h" -#else - #include <zlib.h> -#endif - -// Include functions from bzlib -#ifndef __SYS_BZLIB - #include "bzip2/bzlib.h" -#else - #include <bzlib.h> -#endif - -//----------------------------------------------------------------------------- -// Cryptography support - -// Headers from LibTomCrypt -#include "libtomcrypt/src/headers/tomcrypt.h" - -// For HashStringJenkins -#include "jenkins/lookup.h" - -//----------------------------------------------------------------------------- -// StormLib private defines - -#define ID_MPQ_FILE 0x46494c45 // Used internally for checking TMPQFile ('FILE') - -#define MPQ_WEAK_SIGNATURE_SIZE 64 -#define MPQ_STRONG_SIGNATURE_SIZE 256 - -// Prevent problems with CRT "min" and "max" functions, -// as they are not defined on all platforms -#define STORMLIB_MIN(a, b) ((a < b) ? a : b) -#define STORMLIB_MAX(a, b) ((a > b) ? a : b) - -// Macro for building 64-bit file offset from two 32-bit -#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | lo) - -//----------------------------------------------------------------------------- -// Memory management -// -// We use our own macros for allocating/freeing memory. If you want -// to redefine them, please keep the following rules -// -// - The memory allocation must return NULL if not enough memory -// (i.e not to throw exception) -// - It is not necessary to fill the allocated buffer with zeros -// - Memory freeing function doesn't have to test the pointer to NULL. -// - -#if defined(_MSC_VER) && defined(_DEBUG) -__inline void * DebugMalloc(char * /* szFile */, int /* nLine */, size_t nSize) -{ -// return new BYTE[nSize]; - return HeapAlloc(GetProcessHeap(), 0, nSize); -} - -__inline void DebugFree(void * ptr) -{ -// delete [] ptr; - HeapFree(GetProcessHeap(), 0, ptr); -} - -#define STORM_ALLOC(type, nitems) (type *)DebugMalloc(__FILE__, __LINE__, (nitems) * sizeof(type)) -#define STORM_FREE(ptr) DebugFree(ptr) -#else - -#define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type)) -#define STORM_FREE(ptr) free(ptr) - -#endif - -//----------------------------------------------------------------------------- -// StormLib internal global variables - -extern LCID lcFileLocale; // Preferred file locale - -//----------------------------------------------------------------------------- -// Encryption and decryption functions - -#define MPQ_HASH_TABLE_INDEX 0x000 -#define MPQ_HASH_NAME_A 0x100 -#define MPQ_HASH_NAME_B 0x200 -#define MPQ_HASH_FILE_KEY 0x300 - -DWORD HashString(const char * szFileName, DWORD dwHashType); - -void InitializeMpqCryptography(); - -DWORD GetHashTableSizeForFileCount(DWORD dwFileCount); - -bool IsPseudoFileName(const char * szFileName, LPDWORD pdwFileIndex); -ULONGLONG HashStringJenkins(const char * szFileName); - -int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags); - -DWORD GetDefaultSpecialFileFlags(TMPQArchive * ha, DWORD dwFileSize); - -void EncryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwKey); -void DecryptMpqBlock(void * pvFileBlock, DWORD dwLength, DWORD dwKey); - -DWORD DetectFileKeyBySectorSize(LPDWORD SectorOffsets, DWORD decrypted); -DWORD DetectFileKeyByContent(void * pvFileContent, DWORD dwFileSize); -DWORD DecryptFileKey(const char * szFileName, ULONGLONG MpqPos, DWORD dwFileSize, DWORD dwFlags); - -bool IsValidMD5(LPBYTE pbMd5); -bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5); -void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash); - -//----------------------------------------------------------------------------- -// Handle validation functions - -bool IsValidMpqHandle(TMPQArchive * ha); -bool IsValidFileHandle(TMPQFile * hf); - -//----------------------------------------------------------------------------- -// Hash table and block table manipulation - -TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName); -TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash); -DWORD AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry); -DWORD AllocateHetEntry(TMPQArchive * ha, TFileEntry * pFileEntry); - -void FindFreeMpqSpace(TMPQArchive * ha, ULONGLONG * pFreeSpacePos); - -// Functions that loads and verifies MPQ data bitmap -int LoadMpqDataBitmap(TMPQArchive * ha, ULONGLONG FileSize, bool * pbFileIsComplete); - -// Functions that load the HET and BET tables -int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize); -int LoadAnyHashTable(TMPQArchive * ha); -int BuildFileTable(TMPQArchive * ha, ULONGLONG FileSize); -int SaveMPQTables(TMPQArchive * ha); - -TMPQHetTable * CreateHetTable(DWORD dwMaxFileCount, DWORD dwHashBitSize, bool bCreateEmpty); -void FreeHetTable(TMPQHetTable * pHetTable); - -TMPQBetTable * CreateBetTable(DWORD dwMaxFileCount); -void FreeBetTable(TMPQBetTable * pBetTable); - -// Functions for finding files in the file table -TFileEntry * GetFileEntryAny(TMPQArchive * ha, const char * szFileName); -TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale); -TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale); -TFileEntry * GetFileEntryByIndex(TMPQArchive * ha, DWORD dwIndex); - -// Allocates file name in the file entry -void AllocateFileName(TFileEntry * pFileEntry, const char * szFileName); - -// Allocates new file entry in the MPQ tables. Reuses existing, if possible -TFileEntry * FindFreeFileEntry(TMPQArchive * ha); -TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale); -int RenameFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szNewFileName); -void ClearFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry); -int FreeFileEntry(TMPQArchive * ha, TFileEntry * pFileEntry); - -// Invalidates entries for (listfile) and (attributes) -void InvalidateInternalFiles(TMPQArchive * ha); - -//----------------------------------------------------------------------------- -// Common functions - MPQ File - -TMPQFile * CreateMpqFile(TMPQArchive * ha); -int LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, void * pvTable, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey); -int AllocateSectorBuffer(TMPQFile * hf); -int AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile); -int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile); -int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile); -void CalculateRawSectorOffset(ULONGLONG & RawFilePos, TMPQFile * hf, DWORD dwSectorOffset); -int WritePatchInfo(TMPQFile * hf); -int WriteSectorOffsets(TMPQFile * hf); -int WriteSectorChecksums(TMPQFile * hf); -int WriteMemDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, void * pvRawData, DWORD dwRawDataSize, DWORD dwChunkSize, LPDWORD pcbTotalSize); -int WriteMpqDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, DWORD dwRawDataSize, DWORD dwChunkSize); -void FreeMPQFile(TMPQFile *& hf); - -bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize); -int PatchFileData(TMPQFile * hf); - -void FreeMPQArchive(TMPQArchive *& ha); - -//----------------------------------------------------------------------------- -// Utility functions - -bool CheckWildCard(const char * szString, const char * szWildCard); -const char * GetPlainFileNameA(const char * szFileName); -const TCHAR * GetPlainFileNameT(const TCHAR * szFileName); -bool IsInternalMpqFileName(const char * szFileName); - -//----------------------------------------------------------------------------- -// Support for adding files to the MPQ - -int SFileAddFile_Init( - TMPQArchive * ha, - const char * szArchivedName, - ULONGLONG ft, - DWORD dwFileSize, - LCID lcLocale, - DWORD dwFlags, - TMPQFile ** phf - ); - -int SFileAddFile_Write( - TMPQFile * hf, - const void * pvData, - DWORD dwSize, - DWORD dwCompression - ); - -int SFileAddFile_Finish( - TMPQFile * hf - ); - -//----------------------------------------------------------------------------- -// Attributes support - -int SAttrLoadAttributes(TMPQArchive * ha); -int SAttrFileSaveToMpq(TMPQArchive * ha); - -//----------------------------------------------------------------------------- -// Listfile functions - -int SListFileSaveToMpq(TMPQArchive * ha); - -//----------------------------------------------------------------------------- -// Dump data support - -#ifdef __STORMLIB_DUMP_DATA__ -void DumpMpqHeader(TMPQHeader * pHeader); -void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable); - -#else -#define DumpMpqHeader(h) /* */ -#define DumpHetAndBetTable(h, b) /* */ -#endif - -#endif // __STORMCOMMON_H__ - diff --git a/dep/StormLib/src/StormLib.h b/dep/StormLib/src/StormLib.h deleted file mode 100644 index a07ae46ca48..00000000000 --- a/dep/StormLib/src/StormLib.h +++ /dev/null @@ -1,984 +0,0 @@ -/*****************************************************************************/ -/* StormLib.h Copyright (c) Ladislav Zezula 1999-2010 */ -/*---------------------------------------------------------------------------*/ -/* StormLib library v 7.02 */ -/* */ -/* Author : Ladislav Zezula */ -/* E-mail : ladik@zezula.net */ -/* WWW : http://www.zezula.net */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.99 1.00 Lad Created */ -/* 24.03.03 2.50 Lad Version 2.50 */ -/* 02.04.03 3.00 Lad Version 3.00 with compression */ -/* 11.04.03 3.01 Lad Renamed to StormLib.h for compatibility with */ -/* original headers for Storm.dll */ -/* 10.05.03 3.02 Lad Added Pkware DCL compression */ -/* 26.05.03 4.00 Lad Completed all compressions */ -/* 18.06.03 4.01 Lad Added SFileSetFileLocale */ -/* Added SFileExtractFile */ -/* 26.07.03 4.02 Lad Implemented nameless rename and delete */ -/* 26.07.03 4.03 Lad Added support for protected MPQs */ -/* 28.08.03 4.10 Lad Fixed bugs that caused StormLib incorrectly work */ -/* with Diablo I savegames and with files having full */ -/* hash table */ -/* 08.12.03 4.11 DCH Fixed bug in reading file sector larger than 0x1000 */ -/* on certain files. */ -/* Fixed bug in AddFile with MPQ_FILE_REPLACE_EXISTING */ -/* (Thanx Daniel Chiamarello, dchiamarello@madvawes.com)*/ -/* 21.12.03 4.50 Lad Completed port for Mac */ -/* Fixed bug in compacting (if fsize is mul of 0x1000) */ -/* Fixed bug in SCompCompress */ -/* 27.05.04 4.51 Lad Changed memory management from new/delete to our */ -/* own macros */ -/* 22.06.04 4.60 Lad Optimized search. Support for multiple listfiles. */ -/* 30.09.04 4.61 Lad Fixed some bugs (Aaargh !!!) */ -/* Correctly works if HashTableSize > BlockTableSize */ -/* 29.12.04 4.70 Lad Fixed compatibility problem with MPQs from WoW */ -/* 14.07.05 5.00 Lad Added the BZLIB compression support */ -/* Added suport of files stored as single unit */ -/* 17.04.06 5.01 Lad Converted to MS Visual Studio 8.0 */ -/* Fixed issue with protected Warcraft 3 protected maps */ -/* 15.05.06 5.02 Lad Fixed issue with WoW 1.10+ */ -/* 07.09.06 5.10 Lad Fixed processing files longer than 2GB */ -/* 22.11.06 6.00 Lad Support for MPQ archives V2 */ -/* 12.06.07 6.10 Lad Support for (attributes) file */ -/* 10.09.07 6.12 Lad Support for MPQs protected by corrupting hash table */ -/* 03.12.07 6.13 Lad Support for MPQs with hash tbl size > block tbl size */ -/* 07.04.08 6.20 Lad Added SFileFlushArchive */ -/* 09.04.08 Lad Removed FilePointer variable from MPQ handle */ -/* structure, as it caused more problems than benefits */ -/* 12.05.08 6.22 Lad Support for w3xMaster map protector */ -/* 05.10.08 6.23 Lad Support for protectors who set negative values in */ -/* the table of file blocks */ -/* 26.05.09 6.24 Lad Fixed search for multiple lang files with deleted */ -/* entries */ -/* 03.09.09 6.25 Lad Fixed decompression bug in huffmann decompression */ -/* 22.03.10 6.50 Lad New compressions in Starcraft II (LZMA, sparse) */ -/* Fixed compacting MPQs that contain single unit files */ -/* 26.04.10 7.00 Lad Major rewrite */ -/* 08.06.10 7.10 Lad Support for partial MPQs */ -/* 08.07.10 7.11 Lad Support for MPQs v 3.0 */ -/* 20.08.10 7.20 Lad Support for opening multiple MPQs in patch mode */ -/* 20.09.10 8.00 Lad MPQs v 4, HET and BET tables */ -/* 07.01.11 8.01 Lad Write support for MPQs v 3 and 4 */ -/* 15.09.11 8.04 Lad Bug fixes, testing for Diablo III MPQs */ -/* 26.04.12 8.10 Lad Support for data map, added SFileGetArchiveBitmap */ -/*****************************************************************************/ - -#ifndef __STORMLIB_H__ -#define __STORMLIB_H__ - -#ifdef _MSC_VER -#pragma warning(disable:4668) // 'XXX' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' -#pragma warning(disable:4820) // 'XXX' : '2' bytes padding added after data member 'XXX::yyy' -#endif - -#include "StormPort.h" - -#ifdef __cplusplus -extern "C" { -#endif - -//----------------------------------------------------------------------------- -// Use the apropriate library -// -// The library type is encoded in the library name as the following -// StormLibXYZ.lib -// -// X - D for Debug version, R for Release version -// Y - A for ANSI version, U for Unicode version -// Z - S for static-linked CRT library, D for multithreaded DLL CRT library -// - -#if 0 && defined(_MSC_VER) && !defined(__STORMLIB_SELF__) - - #ifdef _DEBUG // DEBUG VERSIONS - #ifndef _UNICODE - #ifdef _DLL - #pragma comment(lib, "StormLibDAD.lib") // Debug Ansi CRT-DLL version - #else - #pragma comment(lib, "StormLibDAS.lib") // Debug Ansi CRT-LIB version - #endif - #else - #ifdef _DLL - #pragma comment(lib, "StormLibDUD.lib") // Debug Unicode CRT-DLL version - #else - #pragma comment(lib, "StormLibDUS.lib") // Debug Unicode CRT-LIB version - #endif - #endif - #else // RELEASE VERSIONS - #ifndef _UNICODE - #ifdef _DLL - #pragma comment(lib, "StormLibRAD.lib") // Release Ansi CRT-DLL version - #else - #pragma comment(lib, "StormLibRAS.lib") // Release Ansi CRT-LIB version - #endif - #else - #ifdef _DLL - #pragma comment(lib, "StormLibRUD.lib") // Release Unicode CRT-DLL version - #else - #pragma comment(lib, "StormLibRUS.lib") // Release Unicode CRT-LIB version - #endif - #endif - #endif - -#endif - -//----------------------------------------------------------------------------- -// Defines - -#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A') -#define ID_MPQ_USERDATA 0x1B51504D // MPQ userdata entry ('MPQ\x1B') - -#define ERROR_AVI_FILE 10000 // No MPQ file, but AVI file. -#define ERROR_UNKNOWN_FILE_KEY 10001 // Returned by SFileReadFile when can't find file key -#define ERROR_CHECKSUM_ERROR 10002 // Returned by SFileReadFile when sector CRC doesn't match -#define ERROR_INTERNAL_FILE 10003 // The given operation is not allowed on internal file -#define ERROR_BASE_FILE_MISSING 10004 // The file is present as incremental patch file, but base file is missing -#define ERROR_MARKED_FOR_DELETE 10005 // The file was marked as "deleted" in the MPQ - -// Values for SFileCreateArchive -#define HASH_TABLE_SIZE_MIN 0x00000004 // Minimum acceptable hash table size -#define HASH_TABLE_SIZE_DEFAULT 0x00001000 // Default hash table size for empty MPQs -#define HASH_TABLE_SIZE_MAX 0x00080000 // Maximum acceptable hash table size - -#define HASH_ENTRY_DELETED 0xFFFFFFFE // Block index for deleted entry in the hash table -#define HASH_ENTRY_FREE 0xFFFFFFFF // Block index for free entry in the hash table - -#define HET_ENTRY_DELETED 0x80 // HET hash value for a deleted entry -#define HET_ENTRY_FREE 0x00 // HET hash value for free entry - -#define HASH_STATE_SIZE 0x60 // Size of LibTomCrypt's hash_state structure - -#define MPQ_PATCH_PREFIX_LEN 0x20 // Maximum length of the patch prefix - -// Values for SFileOpenArchive -#define SFILE_OPEN_HARD_DISK_FILE 2 // Open the archive on HDD -#define SFILE_OPEN_CDROM_FILE 3 // Open the archive only if it is on CDROM - -// Values for SFileOpenFile -#define SFILE_OPEN_FROM_MPQ 0x00000000 // Open the file from the MPQ archive -#define SFILE_OPEN_PATCHED_FILE 0x00000001 // Open the file from the MPQ archive -#define SFILE_OPEN_ANY_LOCALE 0xFFFFFFFE // Reserved for StormLib internal use -#define SFILE_OPEN_LOCAL_FILE 0xFFFFFFFF // Open a local file - -// Flags for TMPQArchive::dwFlags -#define MPQ_FLAG_READ_ONLY 0x00000001 // If set, the MPQ has been open for read-only access -#define MPQ_FLAG_CHANGED 0x00000002 // If set, the MPQ tables have been changed -#define MPQ_FLAG_PROTECTED 0x00000004 // Set on protected MPQs (like W3M maps) -#define MPQ_FLAG_CHECK_SECTOR_CRC 0x00000008 // Checking sector CRC when reading files -#define MPQ_FLAG_NEED_FIX_SIZE 0x00000010 // Used during opening the archive -#define MPQ_FLAG_INV_LISTFILE 0x00000020 // If set, it means that the (listfile) has been invalidated -#define MPQ_FLAG_INV_ATTRIBUTES 0x00000040 // If set, it means that the (attributes) has been invalidated - -// Return value for SFileGetFileSize and SFileSetFilePointer -#define SFILE_INVALID_SIZE 0xFFFFFFFF -#define SFILE_INVALID_POS 0xFFFFFFFF -#define SFILE_INVALID_ATTRIBUTES 0xFFFFFFFF - -// Flags for SFileAddFile -#define MPQ_FILE_IMPLODE 0x00000100 // Implode method (By PKWARE Data Compression Library) -#define MPQ_FILE_COMPRESS 0x00000200 // Compress methods (By multiple methods) -#define MPQ_FILE_COMPRESSED 0x0000FF00 // File is compressed -#define MPQ_FILE_ENCRYPTED 0x00010000 // Indicates whether file is encrypted -#define MPQ_FILE_FIX_KEY 0x00020000 // File decryption key has to be fixed -#define MPQ_FILE_PATCH_FILE 0x00100000 // The file is a patch file. Raw file data begin with TPatchInfo structure -#define MPQ_FILE_SINGLE_UNIT 0x01000000 // File is stored as a single unit, rather than split into sectors (Thx, Quantam) -#define MPQ_FILE_DELETE_MARKER 0x02000000 // File is a deletion marker. Used in MPQ patches, indicating that the file no longer exists. -#define MPQ_FILE_SECTOR_CRC 0x04000000 // File has checksums for each sector. - // Ignored if file is not compressed or imploded. -#define MPQ_FILE_EXISTS 0x80000000 // Set if file exists, reset when the file was deleted -#define MPQ_FILE_REPLACEEXISTING 0x80000000 // Replace when the file exist (SFileAddFile) - -#define MPQ_FILE_VALID_FLAGS (MPQ_FILE_IMPLODE | \ - MPQ_FILE_COMPRESS | \ - MPQ_FILE_ENCRYPTED | \ - MPQ_FILE_FIX_KEY | \ - MPQ_FILE_PATCH_FILE | \ - MPQ_FILE_SINGLE_UNIT | \ - MPQ_FILE_DELETE_MARKER | \ - MPQ_FILE_SECTOR_CRC | \ - MPQ_FILE_EXISTS) - -// Compression types for multiple compressions -#define MPQ_COMPRESSION_HUFFMANN 0x01 // Huffmann compression (used on WAVE files only) -#define MPQ_COMPRESSION_ZLIB 0x02 // ZLIB compression -#define MPQ_COMPRESSION_PKWARE 0x08 // PKWARE DCL compression -#define MPQ_COMPRESSION_BZIP2 0x10 // BZIP2 compression (added in Warcraft III) -#define MPQ_COMPRESSION_SPARSE 0x20 // Sparse compression (added in Starcraft 2) -#define MPQ_COMPRESSION_ADPCM_MONO 0x40 // IMA ADPCM compression (mono) -#define MPQ_COMPRESSION_ADPCM_STEREO 0x80 // IMA ADPCM compression (stereo) -#define MPQ_COMPRESSION_LZMA 0x12 // LZMA compression. Added in Starcraft 2. This value is NOT a combination of flags. -#define MPQ_COMPRESSION_NEXT_SAME 0xFFFFFFFF // Same compression - -// Constants for SFileAddWave -#define MPQ_WAVE_QUALITY_HIGH 0 // Best quality, the worst compression -#define MPQ_WAVE_QUALITY_MEDIUM 1 // Medium quality, medium compression -#define MPQ_WAVE_QUALITY_LOW 2 // Low quality, the best compression - -// Signatures for HET and BET table -#define HET_TABLE_SIGNATURE 0x1A544548 // 'HET\x1a' -#define BET_TABLE_SIGNATURE 0x1A544542 // 'BET\x1a' - -// Decryption keys for MPQ tables -#define MPQ_KEY_HASH_TABLE 0xC3AF3770 // Obtained by HashString("(hash table)", MPQ_HASH_FILE_KEY) -#define MPQ_KEY_BLOCK_TABLE 0xEC83B3A3 // Obtained by HashString("(block table)", MPQ_HASH_FILE_KEY) - -// Block map defines -#define MPQ_DATA_BITMAP_SIGNATURE 0x33767470 // Signature of the MPQ data bitmap ('ptv3') - -// Constants for SFileGetFileInfo -#define SFILE_INFO_ARCHIVE_NAME 1 // MPQ size (value from header) -#define SFILE_INFO_ARCHIVE_SIZE 2 // MPQ size (value from header) -#define SFILE_INFO_MAX_FILE_COUNT 3 // Max number of files in the MPQ -#define SFILE_INFO_HASH_TABLE_SIZE 4 // Size of hash table, in entries -#define SFILE_INFO_BLOCK_TABLE_SIZE 5 // Number of entries in the block table -#define SFILE_INFO_SECTOR_SIZE 6 // Size of file sector (in bytes) -#define SFILE_INFO_HASH_TABLE 7 // Pointer to Hash table (TMPQHash *) -#define SFILE_INFO_BLOCK_TABLE 8 // Pointer to Block Table (TMPQBlock *) -#define SFILE_INFO_NUM_FILES 9 // Real number of files within archive -#define SFILE_INFO_STREAM_FLAGS 10 // Stream flags for the MPQ. See STREAM_FLAG_XXX -#define SFILE_INFO_IS_READ_ONLY 11 // TRUE of the MPQ was open as read only -//------ -#define SFILE_INFO_HASH_INDEX 100 // Hash index of file in MPQ -#define SFILE_INFO_CODENAME1 101 // The first codename of the file -#define SFILE_INFO_CODENAME2 102 // The second codename of the file -#define SFILE_INFO_LOCALEID 103 // Locale ID of file in MPQ -#define SFILE_INFO_BLOCKINDEX 104 // Index to Block Table -#define SFILE_INFO_FILE_SIZE 105 // Original file size (from the block table) -#define SFILE_INFO_COMPRESSED_SIZE 106 // Compressed file size (from the block table) -#define SFILE_INFO_FLAGS 107 // File flags -#define SFILE_INFO_POSITION 108 // File position within archive -#define SFILE_INFO_KEY 109 // File decryption key -#define SFILE_INFO_KEY_UNFIXED 110 // Decryption key not fixed to file pos and size -#define SFILE_INFO_FILETIME 111 // TMPQFileTime -#define SFILE_INFO_PATCH_CHAIN 112 // Chain of patches - -#define LISTFILE_NAME "(listfile)" // Name of internal listfile -#define SIGNATURE_NAME "(signature)" // Name of internal signature -#define ATTRIBUTES_NAME "(attributes)" // Name of internal attributes file -#define PATCH_METADATA_NAME "(patch_metadata)" - -#define STORMLIB_VERSION 0x080A // Current version of StormLib (8.10) -#define STORMLIB_VERSION_STRING "8.10" - -#define MPQ_FORMAT_VERSION_1 0 // Up to The Burning Crusade -#define MPQ_FORMAT_VERSION_2 1 // The Burning Crusade and newer -#define MPQ_FORMAT_VERSION_3 2 // WoW Cataclysm Beta -#define MPQ_FORMAT_VERSION_4 3 // WoW Cataclysm and newer - -// Flags for MPQ attributes -#define MPQ_ATTRIBUTE_CRC32 0x00000001 // The "(attributes)" contains CRC32 for each file -#define MPQ_ATTRIBUTE_FILETIME 0x00000002 // The "(attributes)" contains file time for each file -#define MPQ_ATTRIBUTE_MD5 0x00000004 // The "(attributes)" contains MD5 for each file -#define MPQ_ATTRIBUTE_PATCH_BIT 0x00000008 // The "(attributes)" contains a patch bit for each file -#define MPQ_ATTRIBUTE_ALL 0x0000000F // Summary mask - -#define MPQ_ATTRIBUTES_V1 100 // (attributes) format version 1.00 - -// Flags for SFileOpenArchive -#define BASE_PROVIDER_FILE 0x00000000 // Base data source is a file -#define BASE_PROVIDER_MAP 0x00000001 // Base data source is memory-mapped file -#define BASE_PROVIDER_HTTP 0x00000002 // Base data source is a file on web server -#define BASE_PROVIDER_MASK 0x0000000F // Mask for base provider value - -#define STREAM_PROVIDER_LINEAR 0x00000000 // Stream is linear with no offset mapping -#define STREAM_PROVIDER_PARTIAL 0x00000010 // Stream is partial file (.part) -#define STREAM_PROVIDER_ENCRYPTED 0x00000020 // Stream is an encrypted MPQ -#define STREAM_PROVIDER_MASK 0x000000F0 // Mask for stream provider value - -#define STREAM_FLAG_READ_ONLY 0x00000100 // Stream is read only -#define STREAM_FLAG_WRITE_SHARE 0x00000200 // Allow write sharing when open for write -#define STREAM_FLAG_MASK 0x0000FF00 // Mask for stream flags -#define STREAM_OPTIONS_MASK 0x0000FFFF // Mask for all stream options - -#define MPQ_OPEN_NO_LISTFILE 0x00010000 // Don't load the internal listfile -#define MPQ_OPEN_NO_ATTRIBUTES 0x00020000 // Don't open the attributes -#define MPQ_OPEN_FORCE_MPQ_V1 0x00040000 // Always open the archive as MPQ v 1.00, ignore the "wFormatVersion" variable in the header -#define MPQ_OPEN_CHECK_SECTOR_CRC 0x00080000 // On files with MPQ_FILE_SECTOR_CRC, the CRC will be checked when reading file - -// Deprecated -#define MPQ_OPEN_READ_ONLY STREAM_FLAG_READ_ONLY -#define MPQ_OPEN_ENCRYPTED STREAM_PROVIDER_ENCRYPTED - -// Flags for SFileCreateArchive -#define MPQ_CREATE_ATTRIBUTES 0x00100000 // Also add the (attributes) file -#define MPQ_CREATE_ARCHIVE_V1 0x00000000 // Creates archive of version 1 (size up to 4GB) -#define MPQ_CREATE_ARCHIVE_V2 0x01000000 // Creates archive of version 2 (larger than 4 GB) -#define MPQ_CREATE_ARCHIVE_V3 0x02000000 // Creates archive of version 3 -#define MPQ_CREATE_ARCHIVE_V4 0x03000000 // Creates archive of version 4 -#define MPQ_CREATE_ARCHIVE_VMASK 0x0F000000 // Mask for archive version - -#define FLAGS_TO_FORMAT_SHIFT 24 // (MPQ_CREATE_ARCHIVE_V4 >> FLAGS_TO_FORMAT_SHIFT) => MPQ_FORMAT_VERSION_4 - -// Flags for SFileVerifyFile -#define SFILE_VERIFY_SECTOR_CRC 0x00000001 // Verify sector checksum for the file, if available -#define SFILE_VERIFY_FILE_CRC 0x00000002 // Verify file CRC, if available -#define SFILE_VERIFY_FILE_MD5 0x00000004 // Verify file MD5, if available -#define SFILE_VERIFY_RAW_MD5 0x00000008 // Verify raw file MD5, if available -#define SFILE_VERIFY_ALL 0x0000000F // Verify every checksum possible - -// Return values for SFileVerifyFile -#define VERIFY_OPEN_ERROR 0x0001 // Failed to open the file -#define VERIFY_READ_ERROR 0x0002 // Failed to read all data from the file -#define VERIFY_FILE_HAS_SECTOR_CRC 0x0004 // File has sector CRC -#define VERIFY_FILE_SECTOR_CRC_ERROR 0x0008 // Sector CRC check failed -#define VERIFY_FILE_HAS_CHECKSUM 0x0010 // File has CRC32 -#define VERIFY_FILE_CHECKSUM_ERROR 0x0020 // CRC32 check failed -#define VERIFY_FILE_HAS_MD5 0x0040 // File has data MD5 -#define VERIFY_FILE_MD5_ERROR 0x0080 // MD5 check failed -#define VERIFY_FILE_HAS_RAW_MD5 0x0100 // File has raw data MD5 -#define VERIFY_FILE_RAW_MD5_ERROR 0x0200 // Raw MD5 check failed -#define VERIFY_FILE_ERROR_MASK (VERIFY_OPEN_ERROR | VERIFY_READ_ERROR | VERIFY_FILE_SECTOR_CRC_ERROR | VERIFY_FILE_CHECKSUM_ERROR | VERIFY_FILE_MD5_ERROR | VERIFY_FILE_RAW_MD5_ERROR) - -// Flags for SFileVerifyRawData (for MPQs version 4.0 or higher) -#define SFILE_VERIFY_MPQ_HEADER 0x0001 // Verify raw MPQ header -#define SFILE_VERIFY_HET_TABLE 0x0002 // Verify raw data of the HET table -#define SFILE_VERIFY_BET_TABLE 0x0003 // Verify raw data of the BET table -#define SFILE_VERIFY_HASH_TABLE 0x0004 // Verify raw data of the hash table -#define SFILE_VERIFY_BLOCK_TABLE 0x0005 // Verify raw data of the block table -#define SFILE_VERIFY_HIBLOCK_TABLE 0x0006 // Verify raw data of the hi-block table -#define SFILE_VERIFY_FILE 0x0007 // Verify raw data of a file - -// Return values for SFileVerifyArchive -#define ERROR_NO_SIGNATURE 0 // There is no signature in the MPQ -#define ERROR_VERIFY_FAILED 1 // There was an error during verifying signature (like no memory) -#define ERROR_WEAK_SIGNATURE_OK 2 // There is a weak signature and sign check passed -#define ERROR_WEAK_SIGNATURE_ERROR 3 // There is a weak signature but sign check failed -#define ERROR_STRONG_SIGNATURE_OK 4 // There is a strong signature and sign check passed -#define ERROR_STRONG_SIGNATURE_ERROR 5 // There is a strong signature but sign check failed - -#ifndef MD5_DIGEST_SIZE -#define MD5_DIGEST_SIZE 0x10 -#endif - -#ifndef SHA1_DIGEST_SIZE -#define SHA1_DIGEST_SIZE 0x14 // 160 bits -#endif - -#ifndef LANG_NEUTRAL -#define LANG_NEUTRAL 0x00 // Neutral locale -#endif - -//----------------------------------------------------------------------------- -// Callback functions - -// Values for compact callback -#define CCB_CHECKING_FILES 1 // Checking archive (dwParam1 = current, dwParam2 = total) -#define CCB_CHECKING_HASH_TABLE 2 // Checking hash table (dwParam1 = current, dwParam2 = total) -#define CCB_COPYING_NON_MPQ_DATA 3 // Copying non-MPQ data: No params used -#define CCB_COMPACTING_FILES 4 // Compacting archive (dwParam1 = current, dwParam2 = total) -#define CCB_CLOSING_ARCHIVE 5 // Closing archive: No params used - -typedef void (WINAPI * SFILE_ADDFILE_CALLBACK)(void * pvUserData, DWORD dwBytesWritten, DWORD dwTotalBytes, bool bFinalCall); -typedef void (WINAPI * SFILE_COMPACT_CALLBACK)(void * pvUserData, DWORD dwWorkType, ULONGLONG BytesProcessed, ULONGLONG TotalBytes); - -struct TFileStream; - -//----------------------------------------------------------------------------- -// Structure for bit arrays used for HET and BET tables - -struct TBitArray -{ - void GetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize); - void SetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize); - - DWORD NumberOfBits; // Total number of bits that are available - BYTE Elements[1]; // Array of elements (variable length) -}; - -// Structure for file bitmap. Used by SFileGetArchiveBitmap -struct TFileBitmap -{ - ULONGLONG StartOffset; // Starting offset of the file, covered by bitmap - ULONGLONG EndOffset; // Ending offset of the file, covered by bitmap - DWORD IsComplete; // If nonzero, no blocks are missing - DWORD BitmapSize; // Size of the file bitmap (in bytes) - DWORD BlockSize; // Size of one block, in bytes - DWORD Reserved; // Alignment - - // Followed by file bitmap (variable length), array of BYTEs) -}; - -//----------------------------------------------------------------------------- -// Structures related to MPQ format -// -// Note: All structures in this header file are supposed to remain private -// to StormLib. The structures may (and will) change over time, as the MPQ -// file format evolves. Programmers directly using these structures need to -// be aware of this. And the last, but not least, NEVER do any modifications -// to those structures directly, always use SFile* functions. -// - -#define MPQ_HEADER_SIZE_V1 0x20 -#define MPQ_HEADER_SIZE_V2 0x2C -#define MPQ_HEADER_SIZE_V3 0x44 -#define MPQ_HEADER_SIZE_V4 0xD0 - -struct TMPQUserData -{ - // The ID_MPQ_USERDATA ('MPQ\x1B') signature - DWORD dwID; - - // Maximum size of the user data - DWORD cbUserDataSize; - - // Offset of the MPQ header, relative to the begin of this header - DWORD dwHeaderOffs; - - // Appears to be size of user data header (Starcraft II maps) - DWORD cbUserDataHeader; -}; - -// MPQ file header -// -// We have to make sure that the header is packed OK. -// Reason: A 64-bit integer at the beginning of 3.0 part, -// which is offset 0x2C -#pragma pack(push, 1) -struct TMPQHeader -{ - // The ID_MPQ ('MPQ\x1A') signature - DWORD dwID; - - // Size of the archive header - DWORD dwHeaderSize; - - // 32-bit size of MPQ archive - // This field is deprecated in the Burning Crusade MoPaQ format, and the size of the archive - // is calculated as the size from the beginning of the archive to the end of the hash table, - // block table, or hi-block table (whichever is largest). - DWORD dwArchiveSize; - - // 0 = Format 1 (up to The Burning Crusade) - // 1 = Format 2 (The Burning Crusade and newer) - // 2 = Format 3 (WoW - Cataclysm beta or newer) - // 3 = Format 4 (WoW - Cataclysm beta or newer) - USHORT wFormatVersion; - - // Power of two exponent specifying the number of 512-byte disk sectors in each file sector - // in the archive. The size of each file sector in the archive is 512 * 2 ^ wSectorSize. - USHORT wSectorSize; - - // Offset to the beginning of the hash table, relative to the beginning of the archive. - DWORD dwHashTablePos; - - // Offset to the beginning of the block table, relative to the beginning of the archive. - DWORD dwBlockTablePos; - - // Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for - // the original MoPaQ format, or less than 2^20 for the Burning Crusade format. - DWORD dwHashTableSize; - - // Number of entries in the block table - DWORD dwBlockTableSize; - - //-- MPQ HEADER v 2 ------------------------------------------- - - // Offset to the beginning of array of 16-bit high parts of file offsets. - ULONGLONG HiBlockTablePos64; - - // High 16 bits of the hash table offset for large archives. - USHORT wHashTablePosHi; - - // High 16 bits of the block table offset for large archives. - USHORT wBlockTablePosHi; - - //-- MPQ HEADER v 3 ------------------------------------------- - - // 64-bit version of the archive size - ULONGLONG ArchiveSize64; - - // 64-bit position of the BET table - ULONGLONG BetTablePos64; - - // 64-bit position of the HET table - ULONGLONG HetTablePos64; - - //-- MPQ HEADER v 4 ------------------------------------------- - - // Compressed size of the hash table - ULONGLONG HashTableSize64; - - // Compressed size of the block table - ULONGLONG BlockTableSize64; - - // Compressed size of the hi-block table - ULONGLONG HiBlockTableSize64; - - // Compressed size of the HET block - ULONGLONG HetTableSize64; - - // Compressed size of the BET block - ULONGLONG BetTableSize64; - - // Size of raw data chunk to calculate MD5. - // MD5 of each data chunk follows the raw file data. - DWORD dwRawChunkSize; - - // MD5 of MPQ tables - unsigned char MD5_BlockTable[MD5_DIGEST_SIZE]; // MD5 of the block table before decryption - unsigned char MD5_HashTable[MD5_DIGEST_SIZE]; // MD5 of the hash table before decryption - unsigned char MD5_HiBlockTable[MD5_DIGEST_SIZE]; // MD5 of the hi-block table - unsigned char MD5_BetTable[MD5_DIGEST_SIZE]; // MD5 of the BET table before decryption - unsigned char MD5_HetTable[MD5_DIGEST_SIZE]; // MD5 of the HET table before decryption - unsigned char MD5_MpqHeader[MD5_DIGEST_SIZE]; // MD5 of the MPQ header from signature to (including) MD5_HetTable -}; -#pragma pack(pop) - - -// Hash entry. All files in the archive are searched by their hashes. -struct TMPQHash -{ - // The hash of the file path, using method A. - DWORD dwName1; - - // The hash of the file path, using method B. - DWORD dwName2; - -#ifdef PLATFORM_LITTLE_ENDIAN - - // The language of the file. This is a Windows LANGID data type, and uses the same values. - // 0 indicates the default language (American English), or that the file is language-neutral. - USHORT lcLocale; - - // The platform the file is used for. 0 indicates the default platform. - // No other values have been observed. - // Note: wPlatform is actually just BYTE, but since it has never been used, we don't care. - USHORT wPlatform; - -#else - - USHORT wPlatform; - USHORT lcLocale; - -#endif - - // If the hash table entry is valid, this is the index into the block table of the file. - // Otherwise, one of the following two values: - // - FFFFFFFFh: Hash table entry is empty, and has always been empty. - // Terminates searches for a given file. - // - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file). - // Does not terminate searches for a given file. - DWORD dwBlockIndex; -}; - - -// File description block contains informations about the file -struct TMPQBlock -{ - // Offset of the beginning of the file, relative to the beginning of the archive. - DWORD dwFilePos; - - // Compressed file size - DWORD dwCSize; - - // Only valid if the block is a file; otherwise meaningless, and should be 0. - // If the file is compressed, this is the size of the uncompressed file data. - DWORD dwFSize; - - // Flags for the file. See MPQ_FILE_XXXX constants - DWORD dwFlags; -}; - -// Patch file information, preceding the sector offset table -struct TPatchInfo -{ - DWORD dwLength; // Length of patch info header, in bytes - DWORD dwFlags; // Flags. 0x80000000 = MD5 (?) - DWORD dwDataSize; // Uncompressed size of the patch file - BYTE md5[0x10]; // MD5 of the entire patch file after decompression - - // Followed by the sector table (variable length) -}; - -// Header for PTCH files -struct TPatchHeader -{ - //-- PATCH header ----------------------------------- - DWORD dwSignature; // 'PTCH' - DWORD dwSizeOfPatchData; // Size of the entire patch (decompressed) - DWORD dwSizeBeforePatch; // Size of the file before patch - DWORD dwSizeAfterPatch; // Size of file after patch - - //-- MD5 block -------------------------------------- - DWORD dwMD5; // 'MD5_' - DWORD dwMd5BlockSize; // Size of the MD5 block, including the signature and size itself - BYTE md5_before_patch[0x10]; // MD5 of the original (unpached) file - BYTE md5_after_patch[0x10]; // MD5 of the patched file - - //-- XFRM block ------------------------------------- - DWORD dwXFRM; // 'XFRM' - DWORD dwXfrmBlockSize; // Size of the XFRM block, includes XFRM header and patch data - DWORD dwPatchType; // Type of patch ('BSD0' or 'COPY') - - // Followed by the patch data -}; - -#define SIZE_OF_XFRM_HEADER 0x0C - -// This is the combined file entry for maintaining file list in the MPQ. -// This structure is combined from block table, hi-block table, -// (attributes) file and from (listfile). -struct TFileEntry -{ - ULONGLONG ByteOffset; // Position of the file content in the MPQ, relative to the MPQ header - ULONGLONG FileTime; // FileTime from the (attributes) file. 0 if not present. - ULONGLONG BetHash; // Lower part of the file name hash. Only used when the MPQ has BET table. - DWORD dwHashIndex; // Index to the hash table. Only used when the MPQ has classic hash table - DWORD dwHetIndex; // Index to the HET table. Only used when the MPQ has HET table - DWORD dwFileSize; // Decompressed size of the file - DWORD dwCmpSize; // Compressed size of the file (i.e., size of the file data in the MPQ) - DWORD dwFlags; // File flags (from block table) - USHORT lcLocale; // Locale ID for the file - USHORT wPlatform; // Platform ID for the file - DWORD dwCrc32; // CRC32 from (attributes) file. 0 if not present. - unsigned char md5[MD5_DIGEST_SIZE]; // File MD5 from the (attributes) file. 0 if not present. - char * szFileName; // File name. NULL if not known. -}; - -// Common header for HET and BET tables -struct TMPQExtTable -{ - DWORD dwSignature; // 'HET\x1A' or 'BET\x1A' - DWORD dwVersion; // Version. Seems to be always 1 - DWORD dwDataSize; // Size of the contained table - - // Followed by the table header - // Followed by the table data - -}; - -// -// MPQ data bitmap, can be found at (FileSize - sizeof(TMPQBlockMap)) -// -// There is bit map of the entire MPQ before TMPQBitmap. Each 0x4000-byte -// block is represented by one bit (including the last, eventually incomplete block). -// -struct TMPQBitmap -{ - DWORD dwSignature; // 'ptv3' (MPQ_BLOCK_MAP_SIGNATURE) - DWORD dwAlways3; // Unknown, seems to always have value of 3 - DWORD dwBuildNumber; // Game build number for that MPQ - DWORD dwMapOffsetLo; // Low 32-bits of the offset of the bit map - DWORD dwMapOffsetHi; // High 32-bits of the offset of the bit map - DWORD dwBlockSize; // Size of one block (usually 0x4000 bytes) -}; - -// Structure for parsed HET table -struct TMPQHetTable -{ - TBitArray * pBetIndexes; // Bit array of indexes to BET tables - LPBYTE pHetHashes; // Array of HET hashes. Each entry has size of 1 byte - ULONGLONG AndMask64; // AND mask used for calculating file name hash - ULONGLONG OrMask64; // OR mask used for setting the highest bit of the file name hash - - DWORD dwIndexSizeTotal; // Total size of one entry in pBetIndexes (in bits) - DWORD dwIndexSizeExtra; // Extra bits in the entry in pBetIndexes - DWORD dwIndexSize; // Effective size of one entry in pBetIndexes (in bits) - DWORD dwMaxFileCount; // Maximum number of files in the MPQ - DWORD dwHashTableSize; // Number of entries in pBetHashes - DWORD dwHashBitSize; // Effective number of bits in the hash -}; - -// Structure for parsed BET table -struct TMPQBetTable -{ - TBitArray * pBetHashes; // Array of BET hashes - TBitArray * pFileTable; // Bit-based file table - LPDWORD pFileFlags; // Array of file flags - - DWORD dwTableEntrySize; // Size of one table entry, in bits - DWORD dwBitIndex_FilePos; // Bit index of the file position in the table entry - DWORD dwBitIndex_FileSize; // Bit index of the file size in the table entry - DWORD dwBitIndex_CmpSize; // Bit index of the compressed size in the table entry - DWORD dwBitIndex_FlagIndex; // Bit index of the flag index in the table entry - DWORD dwBitIndex_Unknown; // Bit index of ??? in the table entry - DWORD dwBitCount_FilePos; // Size of file offset (in bits) within table entry - DWORD dwBitCount_FileSize; // Size of file size (in bits) within table entry - DWORD dwBitCount_CmpSize; // Size of compressed file size (in bits) within table entry - DWORD dwBitCount_FlagIndex; // Size of flag index (in bits) within table entry - DWORD dwBitCount_Unknown; // Size of ??? (in bits) within table entry - DWORD dwBetHashSizeTotal; // Total size of bet hash - DWORD dwBetHashSizeExtra; // Extra bits in the bet hash - DWORD dwBetHashSize; // Effective size of the bet hash - DWORD dwFileCount; // Number of files (usually equal to maximum number of files) - DWORD dwFlagCount; // Number of entries in pFileFlags -}; - -// Archive handle structure -struct TMPQArchive -{ - TFileStream * pStream; // Open stream for the MPQ - - ULONGLONG UserDataPos; // Position of user data (relative to the begin of the file) - ULONGLONG MpqPos; // MPQ header offset (relative to the begin of the file) - - TMPQArchive * haPatch; // Pointer to patch archive, if any - TMPQArchive * haBase; // Pointer to base ("previous version") archive, if any - char szPatchPrefix[MPQ_PATCH_PREFIX_LEN]; // Prefix for file names in patch MPQs - size_t cchPatchPrefix; // Length of the patch prefix, in characters - - TMPQUserData * pUserData; // MPQ user data (NULL if not present in the file) - TMPQHeader * pHeader; // MPQ file header - TMPQBitmap * pBitmap; // MPQ bitmap - TMPQHash * pHashTable; // Hash table - TMPQHetTable * pHetTable; // Het table - TFileEntry * pFileTable; // File table - - TMPQUserData UserData; // MPQ user data. Valid only when ID_MPQ_USERDATA has been found - BYTE HeaderData[MPQ_HEADER_SIZE_V4]; // Storage for MPQ header - - DWORD dwHETBlockSize; - DWORD dwBETBlockSize; - DWORD dwFileTableSize; // Current size of the file table, e.g. index of the entry past the last occupied one - DWORD dwMaxFileCount; // Maximum number of files in the MPQ - DWORD dwSectorSize; // Default size of one file sector - DWORD dwFileFlags1; // Flags for (listfile) - DWORD dwFileFlags2; // Flags for (attributes) - DWORD dwAttrFlags; // Flags for the (attributes) file, see MPQ_ATTRIBUTE_XXX - DWORD dwFlags; // See MPQ_FLAG_XXXXX -}; - -// File handle structure -struct TMPQFile -{ - TFileStream * pStream; // File stream. Only used on local files - TMPQArchive * ha; // Archive handle - TFileEntry * pFileEntry; // File entry for the file - DWORD dwFileKey; // Decryption key - DWORD dwFilePos; // Current file position - ULONGLONG RawFilePos; // Offset in MPQ archive (relative to file begin) - ULONGLONG MpqFilePos; // Offset in MPQ archive (relative to MPQ header) - DWORD dwMagic; // 'FILE' - - TMPQFile * hfPatchFile; // Pointer to opened patch file - TPatchHeader * pPatchHeader; // Patch header. Only used if the file is a patch file - LPBYTE pbFileData; // Loaded and patched file data. Only used if the file is a patch file - DWORD cbFileData; // Size of loaded patched data - - TPatchInfo * pPatchInfo; // Patch info block, preceding the sector table - DWORD * SectorOffsets; // Position of each file sector, relative to the begin of the file. Only for compressed files. - DWORD * SectorChksums; // Array of sector checksums (either ADLER32 or MD5) values for each file sector - DWORD dwSectorCount; // Number of sectors in the file - DWORD dwPatchedFileSize; // Size of patched file. Used when saving patch file to the MPQ - DWORD dwDataSize; // Size of data in the file (on patch files, this differs from file size in block table entry) - - LPBYTE pbFileSector; // Last loaded file sector. For single unit files, entire file content - DWORD dwSectorOffs; // File position of currently loaded file sector - DWORD dwSectorSize; // Size of the file sector. For single unit files, this is equal to the file size - - unsigned char hctx[HASH_STATE_SIZE];// Hash state for MD5. Used when saving file to MPQ - DWORD dwCrc32; // CRC32 value, used when saving file to MPQ - - bool bLoadedSectorCRCs; // If true, we already tried to load sector CRCs - bool bCheckSectorCRCs; // If true, then SFileReadFile will check sector CRCs when reading the file - bool bIsWriteHandle; // If true, this handle has been created by SFileCreateFile - bool bErrorOccured; // If true, then at least one error occured during saving the file to the archive -}; - -// Structure for SFileFindFirstFile and SFileFindNextFile -typedef struct _SFILE_FIND_DATA -{ - char cFileName[MAX_PATH]; // Full name of the found file - char * szPlainName; // Plain name of the found file - DWORD dwHashIndex; // Hash table index for the file - DWORD dwBlockIndex; // Block table index for the file - DWORD dwFileSize; // File size in bytes - DWORD dwFileFlags; // MPQ file flags - DWORD dwCompSize; // Compressed file size - DWORD dwFileTimeLo; // Low 32-bits of the file time (0 if not present) - DWORD dwFileTimeHi; // High 32-bits of the file time (0 if not present) - LCID lcLocale; // Locale version - -} SFILE_FIND_DATA, *PSFILE_FIND_DATA; - -typedef struct _SFILE_CREATE_MPQ -{ - DWORD cbSize; // Size of this structure, in bytes - DWORD dwMpqVersion; // Version of the MPQ to be created - void *pvUserData; // Reserved, must be NULL - DWORD cbUserData; // Reserved, must be 0 - DWORD dwStreamFlags; // Stream flags for creating the MPQ - DWORD dwFileFlags1; // File flags for (listfile). 0 = default - DWORD dwFileFlags2; // File flags for (attributes). 0 = default - DWORD dwAttrFlags; // Flags for the (attributes) file. If 0, no attributes will be created - DWORD dwSectorSize; // Sector size for compressed files - DWORD dwRawChunkSize; // Size of raw data chunk - DWORD dwMaxFileCount; // File limit for the MPQ - -} SFILE_CREATE_MPQ, *PSFILE_CREATE_MPQ; - -//----------------------------------------------------------------------------- -// Stream support - functions - -TFileStream * FileStream_CreateFile(const TCHAR * szFileName, DWORD dwStreamFlags); -TFileStream * FileStream_OpenFile(const TCHAR * szFileName, DWORD dwStreamFlags); -TCHAR * FileStream_GetFileName(TFileStream * pStream); -bool FileStream_IsReadOnly(TFileStream * pStream); -bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead); -bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite); -bool FileStream_GetPos(TFileStream * pStream, ULONGLONG & ByteOffset); -bool FileStream_SetPos(TFileStream * pStream, ULONGLONG ByteOffset); -bool FileStream_GetSize(TFileStream * pStream, ULONGLONG & FileSize); -bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize); -bool FileStream_GetTime(TFileStream * pStream, ULONGLONG * pFT); -bool FileStream_Switch(TFileStream * pStream, TFileStream * pTempStream); -bool FileStream_SetBitmap(TFileStream * pStream, TFileBitmap * pBitmap); -bool FileStream_GetBitmap(TFileStream * pStream, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded); -void FileStream_Close(TFileStream * pStream); - -//----------------------------------------------------------------------------- -// Functions prototypes for Storm.dll - -// Typedefs for functions exported by Storm.dll -typedef LCID (WINAPI * SFILESETLOCALE)(LCID); -typedef bool (WINAPI * SFILEOPENARCHIVE)(const char *, DWORD, DWORD, HANDLE *); -typedef bool (WINAPI * SFILECLOSEARCHIVE)(HANDLE); -typedef bool (WINAPI * SFILEOPENFILEEX)(HANDLE, const char *, DWORD, HANDLE *); -typedef bool (WINAPI * SFILECLOSEFILE)(HANDLE); -typedef DWORD (WINAPI * SFILEGETFILESIZE)(HANDLE, LPDWORD); -typedef DWORD (WINAPI * SFILESETFILEPOINTER)(HANDLE, LONG, LONG *, DWORD); -typedef bool (WINAPI * SFILEREADFILE)(HANDLE, void *, DWORD, LPDWORD, LPOVERLAPPED); - -//----------------------------------------------------------------------------- -// Functions for manipulation with StormLib global flags - -LCID WINAPI SFileGetLocale(); -LCID WINAPI SFileSetLocale(LCID lcNewLocale); - -//----------------------------------------------------------------------------- -// Functions for archive manipulation - -bool WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq); -bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq); -bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq); - -bool WINAPI SFileGetArchiveBitmap(HANDLE hMpq, TFileBitmap * pBitmap, DWORD Length, LPDWORD LengthNeeded); -bool WINAPI SFileFlushArchive(HANDLE hMpq); -bool WINAPI SFileCloseArchive(HANDLE hMpq); - -// Adds another listfile into MPQ. The currently added listfile(s) remain, -// so you can use this API to combining more listfiles. -// Note that this function is internally called by SFileFindFirstFile -int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile); - -// Archive compacting -bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK CompactCB, void * pvData); -bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile = NULL, bool bReserved = 0); - -// Changing the maximum file count -DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq); -bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount); - -// Changing (attributes) file -DWORD WINAPI SFileGetAttributes(HANDLE hMpq); -bool WINAPI SFileSetAttributes(HANDLE hMpq, DWORD dwFlags); -bool WINAPI SFileUpdateFileAttributes(HANDLE hMpq, const char * szFileName); - -//----------------------------------------------------------------------------- -// Functions for manipulation with patch archives - -bool WINAPI SFileOpenPatchArchive(HANDLE hMpq, const TCHAR * szPatchMpqName, const char * szPatchPathPrefix, DWORD dwFlags); -bool WINAPI SFileIsPatchedArchive(HANDLE hMpq); - -//----------------------------------------------------------------------------- -// Functions for file manipulation - -// Reading from MPQ file -bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile); -DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh = NULL); -DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod); -bool WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL); -bool WINAPI SFileCloseFile(HANDLE hFile); - -// Retrieving info about the file -bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName); -bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName); -bool WINAPI SFileGetFileInfo(HANDLE hMpqOrFile, DWORD dwInfoType, void * pvFileInfo, DWORD cbFileInfo, LPDWORD pcbLengthNeeded = NULL); - -// High-level extract function -bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ); - -//----------------------------------------------------------------------------- -// Functions for file and archive verification - -// Generates file CRC32 -bool WINAPI SFileGetFileChecksums(HANDLE hMpq, const char * szFileName, LPDWORD pdwCrc32, char * pMD5); - -// Verifies file against its checksums stored in (attributes) attributes (depending on dwFlags). -// For dwFlags, use one or more of MPQ_ATTRIBUTE_MD5 -DWORD WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags); - -// Verifies raw data of the archive. Only works for MPQs version 4 or newer -int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * szFileName); - -// Verifies the signature, if present -DWORD WINAPI SFileVerifyArchive(HANDLE hMpq); - -//----------------------------------------------------------------------------- -// Functions for file searching - -HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile); -bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); -bool WINAPI SFileFindClose(HANDLE hFind); - -HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData); -bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); -bool WINAPI SListFileFindClose(HANDLE hFind); - -// Locale support -int WINAPI SFileEnumLocales(HANDLE hMpq, const char * szFileName, LCID * plcLocales, LPDWORD pdwMaxLocales, DWORD dwSearchScope); - -//----------------------------------------------------------------------------- -// Support for adding files to the MPQ - -bool WINAPI SFileCreateFile(HANDLE hMpq, const char * szArchivedName, ULONGLONG FileTime, DWORD dwFileSize, LCID lcLocale, DWORD dwFlags, HANDLE * phFile); -bool WINAPI SFileWriteFile(HANDLE hFile, const void * pvData, DWORD dwSize, DWORD dwCompression); -bool WINAPI SFileFinishFile(HANDLE hFile); - -bool WINAPI SFileAddFileEx(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwCompression, DWORD dwCompressionNext = MPQ_COMPRESSION_NEXT_SAME); -bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags); -bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags, DWORD dwQuality); -bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ); -bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szOldFileName, const char * szNewFileName); -bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale); -bool WINAPI SFileSetDataCompression(DWORD DataCompression); - -bool WINAPI SFileSetAddFileCallback(HANDLE hMpq, SFILE_ADDFILE_CALLBACK AddFileCB, void * pvData); - -//----------------------------------------------------------------------------- -// Compression and decompression - -int WINAPI SCompImplode (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer); -int WINAPI SCompExplode (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer); -int WINAPI SCompCompress (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel); -int WINAPI SCompDecompress (char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer); -int WINAPI SCompDecompress2(char * pbOutBuffer, int * pcbOutBuffer, char * pbInBuffer, int cbInBuffer); - -//----------------------------------------------------------------------------- -// Non-Windows support for SetLastError/GetLastError - -#ifndef PLATFORM_WINDOWS - -void SetLastError(int err); -int GetLastError(); - -#endif - -//----------------------------------------------------------------------------- -// Functions from Storm.dll. They use slightly different names for keeping -// possibility to use them together with StormLib (StormXXX instead of SFileXXX) - -#ifdef __LINK_STORM_DLL__ - #define STORM_ALTERNATE_NAMES // Force storm_dll.h to use alternate fnc names - #include "..\storm_dll\storm_dll.h" -#endif // __LINK_STORM_DLL__ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // __STORMLIB_H__ diff --git a/dep/StormLib/src/StormPort.h b/dep/StormLib/src/StormPort.h deleted file mode 100644 index 0914654b9af..00000000000 --- a/dep/StormLib/src/StormPort.h +++ /dev/null @@ -1,235 +0,0 @@ -/*****************************************************************************/ -/* StormPort.h Copyright (c) Marko Friedemann 2001 */ -/*---------------------------------------------------------------------------*/ -/* Portability module for the StormLib library. Contains a wrapper symbols */ -/* to make the compilation under Linux work */ -/* */ -/* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de> */ -/* Created at: Mon Jan 29 18:26:01 CEST 2001 */ -/* Computer: whiplash.flachland-chemnitz.de */ -/* System: Linux 2.4.0 on i686 */ -/* */ -/* Author: Sam Wilkins <swilkins1337@gmail.com> */ -/* System: Mac OS X and port to big endian processor */ -/* */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 29.01.01 1.00 Mar Created */ -/* 24.03.03 1.01 Lad Some cosmetic changes */ -/* 12.11.03 1.02 Dan Macintosh compatibility */ -/* 24.07.04 1.03 Sam Mac OS X compatibility */ -/* 22.11.06 1.04 Sam Mac OS X compatibility (for StormLib 6.0) */ -/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */ -/*****************************************************************************/ - -#ifndef __STORMPORT_H__ -#define __STORMPORT_H__ - -#ifndef __cplusplus - #define bool char - #define true 1 - #define false 0 -#endif - -// Defines for Windows -#if !defined(PLATFORM_DEFINED) && (defined(WIN32) || defined(WIN64)) - - // In MSVC 8.0, there are some functions declared as deprecated. - #if _MSC_VER >= 1400 - #define _CRT_SECURE_NO_DEPRECATE - #define _CRT_NON_CONFORMING_SWPRINTFS - #endif - - #include <tchar.h> - #include <assert.h> - #include <ctype.h> - #include <stdio.h> - #include <windows.h> - #include <wininet.h> - #define PLATFORM_LITTLE_ENDIAN - - #ifdef WIN64 - #define PLATFORM_64BIT - #else - #define PLATFORM_32BIT - #endif - - #define PLATFORM_WINDOWS - #define PLATFORM_DEFINED // The platform is known now - -#endif - -// Defines for Mac -#if !defined(PLATFORM_DEFINED) && defined(__APPLE__) // Mac BSD API - - // Macintosh - #include <sys/types.h> - #include <sys/stat.h> - #include <sys/mman.h> - #include <unistd.h> - #include <fcntl.h> - #include <stdlib.h> - #include <errno.h> - - #define PKEXPORT - #define __SYS_ZLIB - #define __SYS_BZLIB - - #ifndef __BIG_ENDIAN__ - #define PLATFORM_LITTLE_ENDIAN - #endif - - #define PLATFORM_MAC - #define PLATFORM_DEFINED // The platform is known now - -#endif - -// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin* -#if !defined(PLATFORM_DEFINED) - - #include <sys/types.h> - #include <sys/stat.h> - #include <sys/mman.h> - #include <fcntl.h> - #include <unistd.h> - #include <stdint.h> - #include <stdlib.h> - #include <stdio.h> - #include <stdarg.h> - #include <string.h> - #include <ctype.h> - #include <assert.h> - #include <errno.h> - - #define PLATFORM_LITTLE_ENDIAN - #define PLATFORM_LINUX - #define PLATFORM_DEFINED - -#endif - -// Definition of Windows-specific structures for non-Windows platforms -#ifndef PLATFORM_WINDOWS - #if __LP64__ - #define PLATFORM_64BIT - #else - #define PLATFORM_32BIT - #endif - - // Typedefs for ANSI C - typedef unsigned char BYTE; - typedef unsigned short USHORT; - typedef int LONG; - typedef unsigned int DWORD; - typedef unsigned long DWORD_PTR; - typedef long LONG_PTR; - typedef long INT_PTR; - typedef long long LONGLONG; - typedef unsigned long long ULONGLONG; - typedef void * HANDLE; - typedef void * LPOVERLAPPED; // Unsupported on Linux and Mac - typedef char TCHAR; - typedef unsigned int LCID; - typedef LONG * PLONG; - typedef DWORD * LPDWORD; - typedef BYTE * LPBYTE; - - #ifdef PLATFORM_32BIT - #define _LZMA_UINT32_IS_ULONG - #endif - - // Some Windows-specific defines - #ifndef MAX_PATH - #define MAX_PATH 1024 - #endif - - #define WINAPI - - #define FILE_BEGIN SEEK_SET - #define FILE_CURRENT SEEK_CUR - #define FILE_END SEEK_END - - #define _T(x) x - #define _tcslen strlen - #define _tcscpy strcpy - #define _tcscat strcat - #define _tcsrchr strrchr - #define _tprintf printf - #define _stprintf sprintf - #define _tremove remove - - #define _stricmp strcasecmp - #define _strnicmp strncasecmp - #define _tcsnicmp strncasecmp - -#endif // !WIN32 - -// 64-bit calls are supplied by "normal" calls on Mac -#if defined(PLATFORM_MAC) - #define stat64 stat - #define fstat64 fstat - #define lseek64 lseek - #define off64_t off_t - #define O_LARGEFILE 0 -#endif - -// Platform-specific error codes for UNIX-based platforms -#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - #define ERROR_SUCCESS 0 - #define ERROR_FILE_NOT_FOUND ENOENT - #define ERROR_ACCESS_DENIED EPERM - #define ERROR_INVALID_HANDLE EBADF - #define ERROR_NOT_ENOUGH_MEMORY ENOMEM - #define ERROR_BAD_FORMAT 105 // No such error code under Linux - #define ERROR_NO_MORE_FILES 106 - #define ERROR_HANDLE_EOF 107 // No such error code under Linux - #define ERROR_NOT_SUPPORTED ENOTSUP - #define ERROR_INVALID_PARAMETER EINVAL - #define ERROR_DISK_FULL ENOSPC - #define ERROR_ALREADY_EXISTS EEXIST - #define ERROR_CAN_NOT_COMPLETE 108 // No such error code under Linux - #define ERROR_FILE_CORRUPT 109 // No such error code under Linux - #define ERROR_INSUFFICIENT_BUFFER ENOBUFS -#endif - -#ifdef PLATFORM_LITTLE_ENDIAN - #define BSWAP_INT16_UNSIGNED(a) (a) - #define BSWAP_INT16_SIGNED(a) (a) - #define BSWAP_INT32_UNSIGNED(a) (a) - #define BSWAP_INT32_SIGNED(a) (a) - #define BSWAP_INT64_SIGNED(a) (a) - #define BSWAP_INT64_UNSIGNED(a) (a) - #define BSWAP_ARRAY16_UNSIGNED(a,b) {} - #define BSWAP_ARRAY32_UNSIGNED(a,b) {} - #define BSWAP_ARRAY64_UNSIGNED(a,b) {} - #define BSWAP_PART_HEADER(a) {} - #define BSWAP_TMPQUSERDATA(a) {} - #define BSWAP_TMPQHEADER(a) {} -#else - int16_t SwapInt16(uint16_t); - uint16_t SwapUInt16(uint16_t); - int32_t SwapInt32(uint32_t); - uint32_t SwapUInt32(uint32_t); - int64_t SwapInt64(uint64_t); - uint64_t SwapUInt64(uint64_t); - void ConvertUInt16Buffer(void * ptr, size_t length); - void ConvertUInt32Buffer(void * ptr, size_t length); - void ConvertUInt64Buffer(void * ptr, size_t length); - void ConvertPartHeader(void * partHeader); - void ConvertTMPQUserData(void *userData); - void ConvertTMPQHeader(void *header); - #define BSWAP_INT16_SIGNED(a) SwapInt16((a)) - #define BSWAP_INT16_UNSIGNED(a) SwapUInt16((a)) - #define BSWAP_INT32_SIGNED(a) SwapInt32((a)) - #define BSWAP_INT32_UNSIGNED(a) SwapUInt32((a)) - #define BSWAP_INT64_SIGNED(a) SwapInt64((a)) - #define BSWAP_INT64_UNSIGNED(a) SwapUInt64((a)) - #define BSWAP_ARRAY16_UNSIGNED(a,b) ConvertUInt16Buffer((a),(b)) - #define BSWAP_ARRAY32_UNSIGNED(a,b) ConvertUInt32Buffer((a),(b)) - #define BSWAP_ARRAY64_UNSIGNED(a,b) ConvertUInt64Buffer((a),(b)) - #define BSWAP_PART_HEADER(a) ConvertPartHeader(a) - #define BSWAP_TMPQUSERDATA(a) ConvertTMPQUserData((a)) - #define BSWAP_TMPQHEADER(a) ConvertTMPQHeader((a)) -#endif - -#endif // __STORMPORT_H__ diff --git a/dep/StormLib/src/adpcm/adpcm.cpp b/dep/StormLib/src/adpcm/adpcm.cpp deleted file mode 100644 index 916fa3811a8..00000000000 --- a/dep/StormLib/src/adpcm/adpcm.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/*****************************************************************************/ -/* adpcm.cpp Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* This module contains implementation of adpcm decompression method used by */ -/* Storm.dll to decompress WAVE files. Thanks to Tom Amigo for releasing */ -/* his sources. */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ -/* 20.05.03 2.00 Lad Added compression */ -/* 19.11.03 2.01 Dan Big endian handling */ -/*****************************************************************************/ - -#include "adpcm.h" - -//------------------------------------------------------------------------------ -// Structures - -typedef union _BYTE_AND_WORD_PTR -{ - short * pw; - unsigned char * pb; -} BYTE_AND_WORD_PTR; - -typedef union _WORD_AND_BYTE_ARRAY -{ - short w; - unsigned char b[2]; -} WORD_AND_BYTE_ARRAY; - -//----------------------------------------------------------------------------- -// Tables necessary dor decompression - -static long Table1503F120[] = -{ - 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006, - 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, - 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, - 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008 -}; - -static long step_table[] = -{ - 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, - 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F, - 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042, - 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F, - 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133, - 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292, - 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583, - 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0, - 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954, - 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B, - 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462, - 0x00007FFF -}; - -//---------------------------------------------------------------------------- -// CompressWave - -// 1500EF70 -int CompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nChannels, int nCmpLevel) -// ECX EDX -{ - WORD_AND_BYTE_ARRAY Wcmp; - BYTE_AND_WORD_PTR out; // Pointer to the output buffer - long SInt32Array1[2]; - long SInt32Array2[2]; - long SInt32Array3[2]; - long nBytesRemains = dwOutLength; // Number of bytes remaining - long nWordsRemains; // Number of words remaining -// unsigned char * pbSaveOutBuffer; // Copy of output buffer (actually not used) - unsigned long dwBitBuff; - unsigned long dwStopBit; - unsigned long dwBit; - unsigned long ebx; - unsigned long esi; - long nTableValue; - long nOneWord; - long var_1C; - long var_2C; - int nLength; - int nIndex; - int nValue; - int i, chnl; - - // If less than 2 bytes remain, don't decompress anything -// pbSaveOutBuffer = pbOutBuffer; - out.pb = pbOutBuffer; - if(nBytesRemains < 2) - return 2; - - Wcmp.b[1] = (unsigned char)(nCmpLevel - 1); - Wcmp.b[0] = (unsigned char)0; - - *out.pw++ = BSWAP_INT16_SIGNED(Wcmp.w); - if((out.pb - pbOutBuffer + (nChannels * 2)) > nBytesRemains) - return (int)(out.pb - pbOutBuffer + (nChannels * 2)); - - SInt32Array1[0] = SInt32Array1[1] = 0x2C; - - for(i = 0; i < nChannels; i++) - { - nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++); - *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord); - SInt32Array2[i] = nOneWord; - } - - // Weird. But it's there - nLength = dwInLength; - if(nLength < 0) // mov eax, dwInLength; cdq; sub eax, edx; - nLength++; - - nLength = (nLength / 2) - (int)(out.pb - pbOutBuffer); - nLength = (nLength < 0) ? 0 : nLength; - - nIndex = nChannels - 1; // edi - nWordsRemains = dwInLength / 2; // eax - - // ebx - nChannels - // ecx - pwOutPos - for(chnl = nChannels; chnl < nWordsRemains; chnl++) - { - // 1500F030 - if((out.pb - pbOutBuffer + 2) > nBytesRemains) - return (int)(out.pb - pbOutBuffer + 2); - - // Switch index - if(nChannels == 2) - nIndex = (nIndex == 0) ? 1 : 0; - - // Load one word from the input stream - nOneWord = BSWAP_INT16_SIGNED(*pwInBuffer++); // ecx - nOneWord - SInt32Array3[nIndex] = nOneWord; - - // esi - SInt32Array2[nIndex] - // eax - nValue - nValue = nOneWord - SInt32Array2[nIndex]; - nValue = (nValue < 0) ? ((nValue ^ 0xFFFFFFFF) + 1) : nValue; - - ebx = (nOneWord >= SInt32Array2[nIndex]) ? 0 : 0x40; - - // esi - SInt32Array2[nIndex] - // edx - step_table[SInt32Array2[nIndex]] - // edi - (step_table[SInt32Array1[nIndex]] >> nCmpLevel) - nTableValue = step_table[SInt32Array1[nIndex]]; - dwStopBit = (unsigned long)nCmpLevel; - - // edi - nIndex; - if(nValue < (nTableValue >> nCmpLevel)) - { - if(SInt32Array1[nIndex] != 0) - SInt32Array1[nIndex]--; - *out.pb++ = 0x80; - } - else - { - while(nValue > nTableValue * 2) - { - if(SInt32Array1[nIndex] >= 0x58 || nLength == 0) - break; - - SInt32Array1[nIndex] += 8; - if(SInt32Array1[nIndex] > 0x58) - SInt32Array1[nIndex] = 0x58; - - nTableValue = step_table[SInt32Array1[nIndex]]; - *out.pb++ = 0x81; - nLength--; - } - - var_2C = nTableValue >> Wcmp.b[1]; - dwBitBuff = 0; - - esi = (1 << (dwStopBit - 2)); - dwStopBit = (esi <= 0x20) ? esi : 0x20; - - for(var_1C = 0, dwBit = 1; ; dwBit <<= 1) - { -// esi = var_1C + nTableValue; - if((var_1C + nTableValue) <= nValue) - { - var_1C += nTableValue; - dwBitBuff |= dwBit; - } - if(dwBit == dwStopBit) - break; - - nTableValue >>= 1; - } - - nValue = SInt32Array2[nIndex]; - if(ebx != 0) - { - nValue -= (var_1C + var_2C); - if(nValue < -32768) - nValue = -32768; - } - else - { - nValue += (var_1C + var_2C); - if(nValue > 32767) - nValue = 32767; - } - - SInt32Array2[nIndex] = nValue; - *out.pb++ = (unsigned char)(dwBitBuff | ebx); - nTableValue = Table1503F120[dwBitBuff & 0x1F]; - SInt32Array1[nIndex] = SInt32Array1[nIndex] + nTableValue; - if(SInt32Array1[nIndex] < 0) - SInt32Array1[nIndex] = 0; - else if(SInt32Array1[nIndex] > 0x58) - SInt32Array1[nIndex] = 0x58; - } - } - - return (int)(out.pb - pbOutBuffer); -} - -//---------------------------------------------------------------------------- -// DecompressADPCM - -// 1500F230 -int DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels) -{ - BYTE_AND_WORD_PTR out; // Output buffer - BYTE_AND_WORD_PTR in; - unsigned char * pbInBufferEnd = (pbInBuffer + dwInLength); - long SInt32Array1[2]; - long SInt32Array2[2]; - long nOneWord; - int nIndex; - int i; - - SInt32Array1[0] = SInt32Array1[1] = 0x2C; - out.pb = pbOutBuffer; - in.pb = pbInBuffer; - in.pw++; - - // Fill the Uint32Array2 array by channel values. - for(i = 0; i < nChannels; i++) - { - nOneWord = BSWAP_INT16_SIGNED(*in.pw++); - SInt32Array2[i] = nOneWord; - if(dwOutLength < 2) - return (int)(out.pb - pbOutBuffer); - - *out.pw++ = BSWAP_INT16_SIGNED((short)nOneWord); - dwOutLength -= sizeof(short); - } - - // Get the initial index - nIndex = nChannels - 1; - - // Perform the decompression - while(in.pb < pbInBufferEnd) - { - unsigned char nOneByte = *in.pb++; - - // Switch index - if(nChannels == 2) - nIndex = (nIndex == 0) ? 1 : 0; - - // 1500F2A2: Get one byte from input buffer - if(nOneByte & 0x80) - { - switch(nOneByte & 0x7F) - { - case 0: // 1500F315 - if(SInt32Array1[nIndex] != 0) - SInt32Array1[nIndex]--; - - if(dwOutLength < 2) - return (int)(out.pb - pbOutBuffer); - - *out.pw++ = BSWAP_INT16_SIGNED((unsigned short)SInt32Array2[nIndex]); - dwOutLength -= sizeof(unsigned short); - break; - - case 1: // 1500F2E8 - SInt32Array1[nIndex] += 8; - if(SInt32Array1[nIndex] > 0x58) - SInt32Array1[nIndex] = 0x58; - - if(nChannels == 2) - nIndex = (nIndex == 0) ? 1 : 0; - break; - - case 2: // 1500F41E - break; - - default: // 1500F2C4 - SInt32Array1[nIndex] -= 8; - if(SInt32Array1[nIndex] < 0) - SInt32Array1[nIndex] = 0; - - if(nChannels == 2) - nIndex = (nIndex == 0) ? 1 : 0; - break; - } - } - else - { - // 1500F349 - long temp1 = step_table[SInt32Array1[nIndex]]; // EDI - long temp2 = temp1 >> pbInBuffer[1]; // ESI - long temp3 = SInt32Array2[nIndex]; // ECX - - if(nOneByte & 0x01) // EBX = nOneByte - temp2 += (temp1 >> 0); - - if(nOneByte & 0x02) - temp2 += (temp1 >> 1); - - if(nOneByte & 0x04) - temp2 += (temp1 >> 2); - - if(nOneByte & 0x08) - temp2 += (temp1 >> 3); - - if(nOneByte & 0x10) - temp2 += (temp1 >> 4); - - if(nOneByte & 0x20) - temp2 += (temp1 >> 5); - - if(nOneByte & 0x40) - { - temp3 = temp3 - temp2; - if(temp3 <= -32768) - temp3 = -32768; - } - else - { - temp3 = temp3 + temp2; - if(temp3 >= 32767) - temp3 = 32767; - } - - SInt32Array2[nIndex] = temp3; - if(dwOutLength < 2) - break; - - // Store the output 16-bit value - *out.pw++ = BSWAP_INT16_SIGNED((short)SInt32Array2[nIndex]); - dwOutLength -= 2; - - SInt32Array1[nIndex] += Table1503F120[nOneByte & 0x1F]; - - if(SInt32Array1[nIndex] < 0) - SInt32Array1[nIndex] = 0; - else if(SInt32Array1[nIndex] > 0x58) - SInt32Array1[nIndex] = 0x58; - } - } - return (int)(out.pb - pbOutBuffer); -} diff --git a/dep/StormLib/src/adpcm/adpcm.h b/dep/StormLib/src/adpcm/adpcm.h deleted file mode 100644 index beb96159720..00000000000 --- a/dep/StormLib/src/adpcm/adpcm.h +++ /dev/null @@ -1,22 +0,0 @@ -/*****************************************************************************/ -/* adpcm.h Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Header file for adpcm decompress functions */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 31.03.03 1.00 Lad The first version of adpcm.h */ -/*****************************************************************************/ - -#ifndef __ADPCM_H__ -#define __ADPCM_H__ - -//----------------------------------------------------------------------------- -// Functions - -#include "../StormPort.h" - -int CompressADPCM (unsigned char * pbOutBuffer, int dwOutLength, short * pwInBuffer, int dwInLength, int nCmpType, int nChannels); -int DecompressADPCM(unsigned char * pbOutBuffer, int dwOutLength, unsigned char * pbInBuffer, int dwInLength, int nChannels); - -#endif // __ADPCM_H__ diff --git a/dep/StormLib/src/bzip2/blocksort.c b/dep/StormLib/src/bzip2/blocksort.c deleted file mode 100644 index bd2dec157fa..00000000000 --- a/dep/StormLib/src/bzip2/blocksort.c +++ /dev/null @@ -1,1094 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Block sorting machinery ---*/ -/*--- blocksort.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------*/ -/*--- Fallback O(N log(N)^2) sorting ---*/ -/*--- algorithm, for repetitive blocks ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -void fallbackSimpleSort ( UInt32* fmap, - UInt32* eclass, - Int32 lo, - Int32 hi ) -{ - Int32 i, j, tmp; - UInt32 ec_tmp; - - if (lo == hi) return; - - if (hi - lo > 3) { - for ( i = hi-4; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) - fmap[j-4] = fmap[j]; - fmap[j-4] = tmp; - } - } - - for ( i = hi-1; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) - fmap[j-1] = fmap[j]; - fmap[j-1] = tmp; - } -} - - -/*---------------------------------------------*/ -#define fswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define fvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - fswap(fmap[yyp1], fmap[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - - -#define fmin(a,b) ((a) < (b)) ? (a) : (b) - -#define fpush(lz,hz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - sp++; } - -#define fpop(lz,hz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; } - -#define FALLBACK_QSORT_SMALL_THRESH 10 -#define FALLBACK_QSORT_STACK_SIZE 100 - - -static -void fallbackQSort3 ( UInt32* fmap, - UInt32* eclass, - Int32 loSt, - Int32 hiSt ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m; - Int32 sp, lo, hi; - UInt32 med, r, r3; - Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; - Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; - - r = 0; - - sp = 0; - fpush ( loSt, hiSt ); - - while (sp > 0) { - - AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); - - fpop ( lo, hi ); - if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { - fallbackSimpleSort ( fmap, eclass, lo, hi ); - continue; - } - - /* Random partitioning. Median of 3 sometimes fails to - avoid bad cases. Median of 9 seems to help but - looks rather expensive. This too seems to work but - is cheaper. Guidance for the magic constants - 7621 and 32768 is taken from Sedgewick's algorithms - book, chapter 35. - */ - r = ((r * 7621) + 1) % 32768; - r3 = r % 3; - if (r3 == 0) med = eclass[fmap[lo]]; else - if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else - med = eclass[fmap[hi]]; - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (1) { - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unLo]] - (Int32)med; - if (n == 0) { - fswap(fmap[unLo], fmap[ltLo]); - ltLo++; unLo++; - continue; - }; - if (n > 0) break; - unLo++; - } - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unHi]] - (Int32)med; - if (n == 0) { - fswap(fmap[unHi], fmap[gtHi]); - gtHi--; unHi--; - continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); - - if (gtHi < ltLo) continue; - - n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); - m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - if (n - lo > hi - m) { - fpush ( lo, n ); - fpush ( m, hi ); - } else { - fpush ( m, hi ); - fpush ( lo, n ); - } - } -} - -#undef fmin -#undef fpush -#undef fpop -#undef fswap -#undef fvswap -#undef FALLBACK_QSORT_SMALL_THRESH -#undef FALLBACK_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - eclass exists for [0 .. nblock-1] - ((UChar*)eclass) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)eclass) [0 .. nblock-1] holds block - All other areas of eclass destroyed - fmap [0 .. nblock-1] holds sorted order - bhtab [ 0 .. 2+(nblock/32) ] destroyed -*/ - -#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) -#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) -#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) -#define WORD_BH(zz) bhtab[(zz) >> 5] -#define UNALIGNED_BH(zz) ((zz) & 0x01f) - -static -void fallbackSort ( UInt32* fmap, - UInt32* eclass, - UInt32* bhtab, - Int32 nblock, - Int32 verb ) -{ - Int32 ftab[257]; - Int32 ftabCopy[256]; - Int32 H, i, j, k, l, r, cc, cc1; - Int32 nNotDone; - Int32 nBhtab; - UChar* eclass8 = (UChar*)eclass; - - /*-- - Initial 1-char radix sort to generate - initial fmap and initial BH bits. - --*/ - if (verb >= 4) - VPrintf0 ( " bucket sorting ...\n" ); - for (i = 0; i < 257; i++) ftab[i] = 0; - for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; - for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; - for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; - - for (i = 0; i < nblock; i++) { - j = eclass8[i]; - k = ftab[j] - 1; - ftab[j] = k; - fmap[k] = i; - } - - nBhtab = 2 + (nblock / 32); - for (i = 0; i < nBhtab; i++) bhtab[i] = 0; - for (i = 0; i < 256; i++) SET_BH(ftab[i]); - - /*-- - Inductively refine the buckets. Kind-of an - "exponential radix sort" (!), inspired by the - Manber-Myers suffix array construction algorithm. - --*/ - - /*-- set sentinel bits for block-end detection --*/ - for (i = 0; i < 32; i++) { - SET_BH(nblock + 2*i); - CLEAR_BH(nblock + 2*i + 1); - } - - /*-- the log(N) loop --*/ - H = 1; - while (1) { - - if (verb >= 4) - VPrintf1 ( " depth %6d has ", H ); - - j = 0; - for (i = 0; i < nblock; i++) { - if (ISSET_BH(i)) j = i; - k = fmap[i] - H; if (k < 0) k += nblock; - eclass[k] = j; - } - - nNotDone = 0; - r = -1; - while (1) { - - /*-- find the next non-singleton bucket --*/ - k = r + 1; - while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (ISSET_BH(k)) { - while (WORD_BH(k) == 0xffffffff) k += 32; - while (ISSET_BH(k)) k++; - } - l = k - 1; - if (l >= nblock) break; - while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (!ISSET_BH(k)) { - while (WORD_BH(k) == 0x00000000) k += 32; - while (!ISSET_BH(k)) k++; - } - r = k - 1; - if (r >= nblock) break; - - /*-- now [l, r] bracket current bucket --*/ - if (r > l) { - nNotDone += (r - l + 1); - fallbackQSort3 ( fmap, eclass, l, r ); - - /*-- scan bucket and generate header bits-- */ - cc = -1; - for (i = l; i <= r; i++) { - cc1 = eclass[fmap[i]]; - if (cc != cc1) { SET_BH(i); cc = cc1; }; - } - } - } - - if (verb >= 4) - VPrintf1 ( "%6d unresolved strings\n", nNotDone ); - - H *= 2; - if (H > nblock || nNotDone == 0) break; - } - - /*-- - Reconstruct the original block in - eclass8 [0 .. nblock-1], since the - previous phase destroyed it. - --*/ - if (verb >= 4) - VPrintf0 ( " reconstructing block ...\n" ); - j = 0; - for (i = 0; i < nblock; i++) { - while (ftabCopy[j] == 0) j++; - ftabCopy[j]--; - eclass8[fmap[i]] = (UChar)j; - } - AssertH ( j < 256, 1005 ); -} - -#undef SET_BH -#undef CLEAR_BH -#undef ISSET_BH -#undef WORD_BH -#undef UNALIGNED_BH - - -/*---------------------------------------------*/ -/*--- The main, O(N^2 log(N)) sorting ---*/ -/*--- algorithm. Faster for "normal" ---*/ -/*--- non-repetitive blocks. ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -Bool mainGtU ( UInt32 i1, - UInt32 i2, - UChar* block, - UInt16* quadrant, - UInt32 nblock, - Int32* budget ) -{ - Int32 k; - UChar c1, c2; - UInt16 s1, s2; - - AssertD ( i1 != i2, "mainGtU" ); - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 9 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 10 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 11 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 12 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - - k = nblock + 8; - - do { - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - - if (i1 >= nblock) i1 -= nblock; - if (i2 >= nblock) i2 -= nblock; - - k -= 8; - (*budget)--; - } - while (k >= 0); - - return False; -} - - -/*---------------------------------------------*/ -/*-- - Knuth's increments seem to work better - than Incerpi-Sedgewick here. Possibly - because the number of elems to sort is - usually small, typically <= 20. ---*/ -static -Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, - 9841, 29524, 88573, 265720, - 797161, 2391484 }; - -static -void mainSimpleSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 lo, - Int32 hi, - Int32 d, - Int32* budget ) -{ - Int32 i, j, h, bigN, hp; - UInt32 v; - - bigN = hi - lo + 1; - if (bigN < 2) return; - - hp = 0; - while (incs[hp] < bigN) hp++; - hp--; - - for (; hp >= 0; hp--) { - h = incs[hp]; - - i = lo + h; - while (True) { - - /*-- copy 1 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 2 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 3 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - if (*budget < 0) return; - } - } -} - - -/*---------------------------------------------*/ -/*-- - The following is an implementation of - an elegant 3-way quicksort for strings, - described in a paper "Fast Algorithms for - Sorting and Searching Strings", by Robert - Sedgewick and Jon L. Bentley. ---*/ - -#define mswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define mvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - mswap(ptr[yyp1], ptr[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - -static -__inline__ -UChar mmed3 ( UChar a, UChar b, UChar c ) -{ - UChar t; - if (a > b) { t = a; a = b; b = t; }; - if (b > c) { - b = c; - if (a > b) b = a; - } - return b; -} - -#define mmin(a,b) ((a) < (b)) ? (a) : (b) - -#define mpush(lz,hz,dz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - stackD [sp] = dz; \ - sp++; } - -#define mpop(lz,hz,dz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; \ - dz = stackD [sp]; } - - -#define mnextsize(az) (nextHi[az]-nextLo[az]) - -#define mnextswap(az,bz) \ - { Int32 tz; \ - tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ - tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ - tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } - - -#define MAIN_QSORT_SMALL_THRESH 20 -#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) -#define MAIN_QSORT_STACK_SIZE 100 - -static -void mainQSort3 ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 loSt, - Int32 hiSt, - Int32 dSt, - Int32* budget ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m, med; - Int32 sp, lo, hi, d; - - Int32 stackLo[MAIN_QSORT_STACK_SIZE]; - Int32 stackHi[MAIN_QSORT_STACK_SIZE]; - Int32 stackD [MAIN_QSORT_STACK_SIZE]; - - Int32 nextLo[3]; - Int32 nextHi[3]; - Int32 nextD [3]; - - sp = 0; - mpush ( loSt, hiSt, dSt ); - - while (sp > 0) { - - AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); - - mpop ( lo, hi, d ); - if (hi - lo < MAIN_QSORT_SMALL_THRESH || - d > MAIN_QSORT_DEPTH_THRESH) { - mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); - if (*budget < 0) return; - continue; - } - - med = (Int32) - mmed3 ( block[ptr[ lo ]+d], - block[ptr[ hi ]+d], - block[ptr[ (lo+hi)>>1 ]+d] ); - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (True) { - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unLo]+d]) - med; - if (n == 0) { - mswap(ptr[unLo], ptr[ltLo]); - ltLo++; unLo++; continue; - }; - if (n > 0) break; - unLo++; - } - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unHi]+d]) - med; - if (n == 0) { - mswap(ptr[unHi], ptr[gtHi]); - gtHi--; unHi--; continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "mainQSort3(2)" ); - - if (gtHi < ltLo) { - mpush(lo, hi, d+1 ); - continue; - } - - n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); - m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; - nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; - nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; - - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - - AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); - AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); - - mpush (nextLo[0], nextHi[0], nextD[0]); - mpush (nextLo[1], nextHi[1], nextD[1]); - mpush (nextLo[2], nextHi[2], nextD[2]); - } -} - -#undef mswap -#undef mvswap -#undef mpush -#undef mpop -#undef mmin -#undef mnextsize -#undef mnextswap -#undef MAIN_QSORT_SMALL_THRESH -#undef MAIN_QSORT_DEPTH_THRESH -#undef MAIN_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > N_OVERSHOOT - block32 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)block32) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)block32) [0 .. nblock-1] holds block - All other areas of block32 destroyed - ftab [0 .. 65536 ] destroyed - ptr [0 .. nblock-1] holds sorted order - if (*budget < 0), sorting was abandoned -*/ - -#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) -#define SETMASK (1 << 21) -#define CLEARMASK (~(SETMASK)) - -static -void mainSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - UInt32* ftab, - Int32 nblock, - Int32 verb, - Int32* budget ) -{ - Int32 i, j, k, ss, sb; - Int32 runningOrder[256]; - Bool bigDone[256]; - Int32 copyStart[256]; - Int32 copyEnd [256]; - UChar c1; - Int32 numQSorted; - UInt16 s; - if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); - - /*-- set up the 2-byte frequency table --*/ - for (i = 65536; i >= 0; i--) ftab[i] = 0; - - j = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - quadrant[i-1] = 0; - j = (j >> 8) | ( ((UInt16)block[i-1]) << 8); - ftab[j]++; - quadrant[i-2] = 0; - j = (j >> 8) | ( ((UInt16)block[i-2]) << 8); - ftab[j]++; - quadrant[i-3] = 0; - j = (j >> 8) | ( ((UInt16)block[i-3]) << 8); - ftab[j]++; - } - for (; i >= 0; i--) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - } - - /*-- (emphasises close relationship of block & quadrant) --*/ - for (i = 0; i < BZ_N_OVERSHOOT; i++) { - block [nblock+i] = block[i]; - quadrant[nblock+i] = 0; - } - - if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); - - /*-- Complete the initial radix sort --*/ - for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; - - s = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - s = (s >> 8) | (block[i-1] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-1; - s = (s >> 8) | (block[i-2] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-2; - s = (s >> 8) | (block[i-3] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-3; - } - for (; i >= 0; i--) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - } - - /*-- - Now ftab contains the first loc of every small bucket. - Calculate the running order, from smallest to largest - big bucket. - --*/ - for (i = 0; i <= 255; i++) { - bigDone [i] = False; - runningOrder[i] = i; - } - - { - Int32 vv; - Int32 h = 1; - do h = 3 * h + 1; while (h <= 256); - do { - h = h / 3; - for (i = h; i <= 255; i++) { - vv = runningOrder[i]; - j = i; - while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) { - runningOrder[j] = runningOrder[j-h]; - j = j - h; - if (j <= (h - 1)) goto zero; - } - zero: - runningOrder[j] = vv; - } - } while (h != 1); - } - - /*-- - The main sorting loop. - --*/ - - numQSorted = 0; - - for (i = 0; i <= 255; i++) { - - /*-- - Process big buckets, starting with the least full. - Basically this is a 3-step process in which we call - mainQSort3 to sort the small buckets [ss, j], but - also make a big effort to avoid the calls if we can. - --*/ - ss = runningOrder[i]; - - /*-- - Step 1: - Complete the big bucket [ss] by quicksorting - any unsorted small buckets [ss, j], for j != ss. - Hopefully previous pointer-scanning phases have already - completed many of the small buckets [ss, j], so - we don't have to sort them at all. - --*/ - for (j = 0; j <= 255; j++) { - if (j != ss) { - sb = (ss << 8) + j; - if ( ! (ftab[sb] & SETMASK) ) { - Int32 lo = ftab[sb] & CLEARMASK; - Int32 hi = (ftab[sb+1] & CLEARMASK) - 1; - if (hi > lo) { - if (verb >= 4) - VPrintf4 ( " qsort [0x%x, 0x%x] " - "done %d this %d\n", - ss, j, numQSorted, hi - lo + 1 ); - mainQSort3 ( - ptr, block, quadrant, nblock, - lo, hi, BZ_N_RADIX, budget - ); - numQSorted += (hi - lo + 1); - if (*budget < 0) return; - } - } - ftab[sb] |= SETMASK; - } - } - - AssertH ( !bigDone[ss], 1006 ); - - /*-- - Step 2: - Now scan this big bucket [ss] so as to synthesise the - sorted order for small buckets [t, ss] for all t, - including, magically, the bucket [ss,ss] too. - This will avoid doing Real Work in subsequent Step 1's. - --*/ - { - for (j = 0; j <= 255; j++) { - copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; - copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; - } - for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyStart[c1]++ ] = k; - } - for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyEnd[c1]-- ] = k; - } - } - - AssertH ( (copyStart[ss]-1 == copyEnd[ss]) - || - /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. - Necessity for this case is demonstrated by compressing - a sequence of approximately 48.5 million of character - 251; 1.0.0/1.0.1 will then die here. */ - (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), - 1007 ) - - for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK; - - /*-- - Step 3: - The [ss] big bucket is now done. Record this fact, - and update the quadrant descriptors. Remember to - update quadrants in the overshoot area too, if - necessary. The "if (i < 255)" test merely skips - this updating for the last bucket processed, since - updating for the last bucket is pointless. - - The quadrant array provides a way to incrementally - cache sort orderings, as they appear, so as to - make subsequent comparisons in fullGtU() complete - faster. For repetitive blocks this makes a big - difference (but not big enough to be able to avoid - the fallback sorting mechanism, exponential radix sort). - - The precise meaning is: at all times: - - for 0 <= i < nblock and 0 <= j <= nblock - - if block[i] != block[j], - - then the relative values of quadrant[i] and - quadrant[j] are meaningless. - - else { - if quadrant[i] < quadrant[j] - then the string starting at i lexicographically - precedes the string starting at j - - else if quadrant[i] > quadrant[j] - then the string starting at j lexicographically - precedes the string starting at i - - else - the relative ordering of the strings starting - at i and j has not yet been determined. - } - --*/ - bigDone[ss] = True; - - if (i < 255) { - Int32 bbStart = ftab[ss << 8] & CLEARMASK; - Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; - Int32 shifts = 0; - - while ((bbSize >> shifts) > 65534) shifts++; - - for (j = bbSize-1; j >= 0; j--) { - Int32 a2update = ptr[bbStart + j]; - UInt16 qVal = (UInt16)(j >> shifts); - quadrant[a2update] = qVal; - if (a2update < BZ_N_OVERSHOOT) - quadrant[a2update + nblock] = qVal; - } - AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); - } - - } - - if (verb >= 4) - VPrintf3 ( " %d pointers, %d sorted, %d scanned\n", - nblock, numQSorted, nblock - numQSorted ); -} - -#undef BIGFREQ -#undef SETMASK -#undef CLEARMASK - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)arr2) [0 .. nblock-1] holds block - arr1 exists for [0 .. nblock-1] - - Post: - ((UChar*)arr2) [0 .. nblock-1] holds block - All other areas of block destroyed - ftab [ 0 .. 65536 ] destroyed - arr1 [0 .. nblock-1] holds sorted order -*/ -void BZ2_blockSort ( EState* s ) -{ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt32* ftab = s->ftab; - Int32 nblock = s->nblock; - Int32 verb = s->verbosity; - Int32 wfact = s->workFactor; - UInt16* quadrant; - Int32 budget; - Int32 budgetInit; - Int32 i; - - if (nblock < 10000) { - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } else { - /* Calculate the location for quadrant, remembering to get - the alignment right. Assumes that &(block[0]) is at least - 2-byte aligned -- this should be ok since block is really - the first section of arr2. - */ - i = nblock+BZ_N_OVERSHOOT; - if (i & 1) i++; - quadrant = (UInt16*)(&(block[i])); - - /* (wfact-1) / 3 puts the default-factor-30 - transition point at very roughly the same place as - with v0.1 and v0.9.0. - Not that it particularly matters any more, since the - resulting compressed stream is now the same regardless - of whether or not we use the main sort or fallback sort. - */ - if (wfact < 1 ) wfact = 1; - if (wfact > 100) wfact = 100; - budgetInit = nblock * ((wfact-1) / 3); - budget = budgetInit; - - mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget ); - if (verb >= 3) - VPrintf3 ( " %d work, %d block, ratio %5.2f\n", - budgetInit - budget, - nblock, - (float)(budgetInit - budget) / - (float)(nblock==0 ? 1 : nblock) ); - if (budget < 0) { - if (verb >= 2) - VPrintf0 ( " too repetitive; using fallback" - " sorting algorithm\n" ); - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } - } - - s->origPtr = -1; - for (i = 0; i < s->nblock; i++) - if (ptr[i] == 0) - { s->origPtr = i; break; }; - - AssertH( s->origPtr != -1, 1003 ); -} - - -/*-------------------------------------------------------------*/ -/*--- end blocksort.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/bzlib.c b/dep/StormLib/src/bzip2/bzlib.c deleted file mode 100644 index b98f3e586bc..00000000000 --- a/dep/StormLib/src/bzip2/bzlib.c +++ /dev/null @@ -1,1573 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Library top-level functions. ---*/ -/*--- bzlib.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). - fixed bzWrite/bzRead to ignore zero-length requests. - fixed bzread to correctly handle read requests after EOF. - wrong parameter order in call to bzDecompressInit in - bzBuffToBuffDecompress. Fixed. -*/ - -#define _CRT_SECURE_NO_WARNINGS -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Compression stuff ---*/ -/*---------------------------------------------------*/ - - -/*---------------------------------------------------*/ -#ifndef BZ_NO_STDIO -void BZ2_bz__AssertH__fail ( int errcode ) -{ - fprintf(stderr, - "\n\nbzip2/libbzip2: internal error number %d.\n" - "This is a bug in bzip2/libbzip2, %s.\n" - "Please report it to me at: jseward@bzip.org. If this happened\n" - "when you were using some program which uses libbzip2 as a\n" - "component, you should also report this bug to the author(s)\n" - "of that program. Please make an effort to report this bug;\n" - "timely and accurate bug reports eventually lead to higher\n" - "quality software. Thanks. Julian Seward, 10 December 2007.\n\n", - errcode, - BZ2_bzlibVersion() - ); - - if (errcode == 1007) { - fprintf(stderr, - "\n*** A special note about internal error number 1007 ***\n" - "\n" - "Experience suggests that a common cause of i.e. 1007\n" - "is unreliable memory or other hardware. The 1007 assertion\n" - "just happens to cross-check the results of huge numbers of\n" - "memory reads/writes, and so acts (unintendedly) as a stress\n" - "test of your memory system.\n" - "\n" - "I suggest the following: try compressing the file again,\n" - "possibly monitoring progress in detail with the -vv flag.\n" - "\n" - "* If the error cannot be reproduced, and/or happens at different\n" - " points in compression, you may have a flaky memory system.\n" - " Try a memory-test program. I have used Memtest86\n" - " (www.memtest86.com). At the time of writing it is free (GPLd).\n" - " Memtest86 tests memory much more thorougly than your BIOSs\n" - " power-on test, and may find failures that the BIOS doesn't.\n" - "\n" - "* If the error can be repeatably reproduced, this is a bug in\n" - " bzip2, and I would very much like to hear about it. Please\n" - " let me know, and, ideally, save a copy of the file causing the\n" - " problem -- without which I will be unable to investigate it.\n" - "\n" - ); - } - - exit(3); -} -#endif - - -/*---------------------------------------------------*/ -static -int bz_config_ok ( void ) -{ - if (sizeof(int) != 4) return 0; - if (sizeof(short) != 2) return 0; - if (sizeof(char) != 1) return 0; - return 1; -} - - -/*---------------------------------------------------*/ -static -void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) -{ - void* v = malloc ( items * size ); - return v; -} - -static -void default_bzfree ( void* opaque, void* addr ) -{ - if (addr != NULL) free ( addr ); -} - - -/*---------------------------------------------------*/ -static -void prepare_new_block ( EState* s ) -{ - Int32 i; - s->nblock = 0; - s->numZ = 0; - s->state_out_pos = 0; - BZ_INITIALISE_CRC ( s->blockCRC ); - for (i = 0; i < 256; i++) s->inUse[i] = False; - s->blockNo++; -} - - -/*---------------------------------------------------*/ -static -void init_RL ( EState* s ) -{ - s->state_in_ch = 256; - s->state_in_len = 0; -} - - -static -Bool isempty_RL ( EState* s ) -{ - if (s->state_in_ch < 256 && s->state_in_len > 0) - return False; else - return True; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressInit) - ( bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 n; - EState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL || - blockSize100k < 1 || blockSize100k > 9 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(EState) ); - if (s == NULL) return BZ_MEM_ERROR; - s->strm = strm; - - s->arr1 = NULL; - s->arr2 = NULL; - s->ftab = NULL; - - n = 100000 * blockSize100k; - s->arr1 = BZALLOC( n * sizeof(UInt32) ); - s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) ); - s->ftab = BZALLOC( 65537 * sizeof(UInt32) ); - - if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) { - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - if (s != NULL) BZFREE(s); - return BZ_MEM_ERROR; - } - - s->blockNo = 0; - s->state = BZ_S_INPUT; - s->mode = BZ_M_RUNNING; - s->combinedCRC = 0; - s->blockSize100k = blockSize100k; - s->nblockMAX = 100000 * blockSize100k - 19; - s->verbosity = verbosity; - s->workFactor = workFactor; - - s->block = (UChar*)s->arr2; - s->mtfv = (UInt16*)s->arr1; - s->zbits = NULL; - s->ptr = (UInt32*)s->arr1; - - strm->state = s; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - init_RL ( s ); - prepare_new_block ( s ); - return BZ_OK; -} - - -/*---------------------------------------------------*/ -static -void add_pair_to_block ( EState* s ) -{ - Int32 i; - UChar ch = (UChar)(s->state_in_ch); - for (i = 0; i < s->state_in_len; i++) { - BZ_UPDATE_CRC( s->blockCRC, ch ); - } - s->inUse[s->state_in_ch] = True; - switch (s->state_in_len) { - case 1: - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 2: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 3: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - default: - s->inUse[s->state_in_len-4] = True; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = ((UChar)(s->state_in_len-4)); - s->nblock++; - break; - } -} - - -/*---------------------------------------------------*/ -static -void flush_RL ( EState* s ) -{ - if (s->state_in_ch < 256) add_pair_to_block ( s ); - init_RL ( s ); -} - - -/*---------------------------------------------------*/ -#define ADD_CHAR_TO_BLOCK(zs,zchh0) \ -{ \ - UInt32 zchh = (UInt32)(zchh0); \ - /*-- fast track the common case --*/ \ - if (zchh != zs->state_in_ch && \ - zs->state_in_len == 1) { \ - UChar ch = (UChar)(zs->state_in_ch); \ - BZ_UPDATE_CRC( zs->blockCRC, ch ); \ - zs->inUse[zs->state_in_ch] = True; \ - zs->block[zs->nblock] = (UChar)ch; \ - zs->nblock++; \ - zs->state_in_ch = zchh; \ - } \ - else \ - /*-- general, uncommon cases --*/ \ - if (zchh != zs->state_in_ch || \ - zs->state_in_len == 255) { \ - if (zs->state_in_ch < 256) \ - add_pair_to_block ( zs ); \ - zs->state_in_ch = zchh; \ - zs->state_in_len = 1; \ - } else { \ - zs->state_in_len++; \ - } \ -} - - -/*---------------------------------------------------*/ -static -Bool copy_input_until_stop ( EState* s ) -{ - Bool progress_in = False; - - if (s->mode == BZ_M_RUNNING) { - - /*-- fast track the common case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - } - - } else { - - /*-- general, uncommon case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - /*-- flush/finish end? --*/ - if (s->avail_in_expect == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - s->avail_in_expect--; - } - } - return progress_in; -} - - -/*---------------------------------------------------*/ -static -Bool copy_output_until_stop ( EState* s ) -{ - Bool progress_out = False; - - while (True) { - - /*-- no output space? --*/ - if (s->strm->avail_out == 0) break; - - /*-- block done? --*/ - if (s->state_out_pos >= s->numZ) break; - - progress_out = True; - *(s->strm->next_out) = s->zbits[s->state_out_pos]; - s->state_out_pos++; - s->strm->avail_out--; - s->strm->next_out++; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - return progress_out; -} - - -/*---------------------------------------------------*/ -static -Bool handle_compress ( bz_stream* strm ) -{ - Bool progress_in = False; - Bool progress_out = False; - EState* s = strm->state; - - while (True) { - - if (s->state == BZ_S_OUTPUT) { - progress_out |= copy_output_until_stop ( s ); - if (s->state_out_pos < s->numZ) break; - if (s->mode == BZ_M_FINISHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - prepare_new_block ( s ); - s->state = BZ_S_INPUT; - if (s->mode == BZ_M_FLUSHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - } - - if (s->state == BZ_S_INPUT) { - progress_in |= copy_input_until_stop ( s ); - if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { - flush_RL ( s ); - BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) ); - s->state = BZ_S_OUTPUT; - } - else - if (s->nblock >= s->nblockMAX) { - BZ2_compressBlock ( s, False ); - s->state = BZ_S_OUTPUT; - } - else - if (s->strm->avail_in == 0) { - break; - } - } - - } - - return progress_in || progress_out; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) -{ - Bool progress; - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - preswitch: - switch (s->mode) { - - case BZ_M_IDLE: - return BZ_SEQUENCE_ERROR; - - case BZ_M_RUNNING: - if (action == BZ_RUN) { - progress = handle_compress ( strm ); - return progress ? BZ_RUN_OK : BZ_PARAM_ERROR; - } - else - if (action == BZ_FLUSH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FLUSHING; - goto preswitch; - } - else - if (action == BZ_FINISH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FINISHING; - goto preswitch; - } - else - return BZ_PARAM_ERROR; - - case BZ_M_FLUSHING: - if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FLUSH_OK; - s->mode = BZ_M_RUNNING; - return BZ_RUN_OK; - - case BZ_M_FINISHING: - if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (!progress) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FINISH_OK; - s->mode = BZ_M_IDLE; - return BZ_STREAM_END; - } - return BZ_OK; /*--not reached--*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm ) -{ - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - BZFREE(strm->state); - - strm->state = NULL; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/*--- Decompression stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressInit) - ( bz_stream* strm, - int verbosity, - int small ) -{ - DState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL) return BZ_PARAM_ERROR; - if (small != 0 && small != 1) return BZ_PARAM_ERROR; - if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; - - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(DState) ); - if (s == NULL) return BZ_MEM_ERROR; - s->strm = strm; - strm->state = s; - s->state = BZ_X_MAGIC_1; - s->bsLive = 0; - s->bsBuff = 0; - s->calculatedCombinedCRC = 0; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - s->smallDecompress = (Bool)small; - s->ll4 = NULL; - s->ll16 = NULL; - s->tt = NULL; - s->currBlockNo = 0; - s->verbosity = verbosity; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_FAST ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - /* restore */ - UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC; - UChar c_state_out_ch = s->state_out_ch; - Int32 c_state_out_len = s->state_out_len; - Int32 c_nblock_used = s->nblock_used; - Int32 c_k0 = s->k0; - UInt32* c_tt = s->tt; - UInt32 c_tPos = s->tPos; - char* cs_next_out = s->strm->next_out; - unsigned int cs_avail_out = s->strm->avail_out; - Int32 ro_blockSize100k = s->blockSize100k; - /* end restore */ - - UInt32 avail_out_INIT = cs_avail_out; - Int32 s_save_nblockPP = s->save_nblock+1; - unsigned int total_out_lo32_old; - - while (True) { - - /* try to finish existing run */ - if (c_state_out_len > 0) { - while (True) { - if (cs_avail_out == 0) goto return_notr; - if (c_state_out_len == 1) break; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - c_state_out_len--; - cs_next_out++; - cs_avail_out--; - } - s_state_out_len_eq_one: - { - if (cs_avail_out == 0) { - c_state_out_len = 1; goto return_notr; - }; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - cs_next_out++; - cs_avail_out--; - } - } - /* Only caused by corrupt data stream? */ - if (c_nblock_used > s_save_nblockPP) - return True; - - /* can a new run be started? */ - if (c_nblock_used == s_save_nblockPP) { - c_state_out_len = 0; goto return_notr; - }; - c_state_out_ch = c_k0; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (k1 != c_k0) { - c_k0 = k1; goto s_state_out_len_eq_one; - }; - if (c_nblock_used == s_save_nblockPP) - goto s_state_out_len_eq_one; - - c_state_out_len = 2; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - c_state_out_len = 3; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - BZ_GET_FAST_C(k1); c_nblock_used++; - c_state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST_C(c_k0); c_nblock_used++; - } - - return_notr: - total_out_lo32_old = s->strm->total_out_lo32; - s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out); - if (s->strm->total_out_lo32 < total_out_lo32_old) - s->strm->total_out_hi32++; - - /* save */ - s->calculatedBlockCRC = c_calculatedBlockCRC; - s->state_out_ch = c_state_out_ch; - s->state_out_len = c_state_out_len; - s->nblock_used = c_nblock_used; - s->k0 = c_k0; - s->tt = c_tt; - s->tPos = c_tPos; - s->strm->next_out = cs_next_out; - s->strm->avail_out = cs_avail_out; - /* end save */ - } - return False; -} - - - -/*---------------------------------------------------*/ -__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) -{ - Int32 nb, na, mid; - nb = 0; - na = 256; - do { - mid = (nb + na) >> 1; - if (indx >= cftab[mid]) nb = mid; else na = mid; - } - while (na - nb != 1); - return nb; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_SMALL ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) -{ - Bool corrupt; - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - while (True) { - if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; - if (s->state == BZ_X_OUTPUT) { - if (s->smallDecompress) - corrupt = unRLE_obuf_to_output_SMALL ( s ); else - corrupt = unRLE_obuf_to_output_FAST ( s ); - if (corrupt) return BZ_DATA_ERROR; - if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { - BZ_FINALISE_CRC ( s->calculatedBlockCRC ); - if (s->verbosity >= 3) - VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, - s->calculatedBlockCRC ); - if (s->verbosity >= 2) VPrintf0 ( "]" ); - if (s->calculatedBlockCRC != s->storedBlockCRC) - return BZ_DATA_ERROR; - s->calculatedCombinedCRC - = (s->calculatedCombinedCRC << 1) | - (s->calculatedCombinedCRC >> 31); - s->calculatedCombinedCRC ^= s->calculatedBlockCRC; - s->state = BZ_X_BLKHDR_1; - } else { - return BZ_OK; - } - } - if (s->state >= BZ_X_MAGIC_1) { - Int32 r = BZ2_decompress ( s ); - if (r == BZ_STREAM_END) { - if (s->verbosity >= 3) - VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x", - s->storedCombinedCRC, s->calculatedCombinedCRC ); - if (s->calculatedCombinedCRC != s->storedCombinedCRC) - return BZ_DATA_ERROR; - return r; - } - if (s->state != BZ_X_OUTPUT) return r; - } - } - - AssertH ( 0, 6001 ); - - return 0; /*NOTREACHED*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) -{ - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->tt != NULL) BZFREE(s->tt); - if (s->ll16 != NULL) BZFREE(s->ll16); - if (s->ll4 != NULL) BZFREE(s->ll4); - - BZFREE(strm->state); - strm->state = NULL; - - return BZ_OK; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ -/*--- File I/O stuff ---*/ -/*---------------------------------------------------*/ - -#define BZ_SETERR(eee) \ -{ \ - if (bzerror != NULL) *bzerror = eee; \ - if (bzf != NULL) bzf->lastErr = eee; \ -} - -typedef - struct { - FILE* handle; - Char buf[BZ_MAX_UNUSED]; - Int32 bufN; - Bool writing; - bz_stream strm; - Int32 lastErr; - Bool initialisedOk; - } - bzFile; - - -/*---------------------------------------------*/ -static Bool myfeof ( FILE* f ) -{ - Int32 c = fgetc ( f ); - if (c == EOF) return True; - ungetc ( c, f ); - return False; -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzWriteOpen) - ( int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 ret; - bzFile* bzf = NULL; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (blockSize100k < 1 || blockSize100k > 9) || - (workFactor < 0 || workFactor > 250) || - (verbosity < 0 || verbosity > 4)) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - bzf->initialisedOk = False; - bzf->bufN = 0; - bzf->handle = f; - bzf->writing = True; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - if (workFactor == 0) workFactor = 30; - ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = 0; - bzf->initialisedOk = True; - return bzf; -} - - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWrite) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return; }; - - bzf->strm.avail_in = len; - bzf->strm.next_in = buf; - - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN ); - if (ret != BZ_RUN_OK) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (bzf->strm.avail_in == 0) - { BZ_SETERR(BZ_OK); return; }; - } -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWriteClose) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out ) -{ - BZ2_bzWriteClose64 ( bzerror, b, abandon, - nbytes_in, NULL, nbytes_out, NULL ); -} - - -void BZ_API(BZ2_bzWriteClose64) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0; - if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0; - if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0; - if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0; - - if ((!abandon) && bzf->lastErr == BZ_OK) { - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH ); - if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (ret == BZ_STREAM_END) break; - } - } - - if ( !abandon && !ferror ( bzf->handle ) ) { - fflush ( bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (nbytes_in_lo32 != NULL) - *nbytes_in_lo32 = bzf->strm.total_in_lo32; - if (nbytes_in_hi32 != NULL) - *nbytes_in_hi32 = bzf->strm.total_in_hi32; - if (nbytes_out_lo32 != NULL) - *nbytes_out_lo32 = bzf->strm.total_out_lo32; - if (nbytes_out_hi32 != NULL) - *nbytes_out_hi32 = bzf->strm.total_out_hi32; - - BZ_SETERR(BZ_OK); - BZ2_bzCompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzReadOpen) - ( int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused ) -{ - bzFile* bzf = NULL; - int ret; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (small != 0 && small != 1) || - (verbosity < 0 || verbosity > 4) || - (unused == NULL && nUnused != 0) || - (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - - bzf->initialisedOk = False; - bzf->handle = f; - bzf->bufN = 0; - bzf->writing = False; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - while (nUnused > 0) { - bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; - unused = ((void*)( 1 + ((UChar*)(unused)) )); - nUnused--; - } - - ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - - bzf->initialisedOk = True; - return bzf; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) -{ - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - - if (bzf->initialisedOk) - (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzRead) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return 0; }; - - bzf->strm.avail_out = len; - bzf->strm.next_out = buf; - - while (True) { - - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - - if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) { - n = fread ( bzf->buf, sizeof(UChar), - BZ_MAX_UNUSED, bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - bzf->bufN = n; - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - } - - ret = BZ2_bzDecompress ( &(bzf->strm) ); - - if (ret != BZ_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return 0; }; - - if (ret == BZ_OK && myfeof(bzf->handle) && - bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) - { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; - - if (ret == BZ_STREAM_END) - { BZ_SETERR(BZ_STREAM_END); - return len - bzf->strm.avail_out; }; - if (bzf->strm.avail_out == 0) - { BZ_SETERR(BZ_OK); return len; }; - - } - - return 0; /*not reached*/ -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadGetUnused) - ( int* bzerror, - BZFILE* b, - void** unused, - int* nUnused ) -{ - bzFile* bzf = (bzFile*)b; - if (bzf == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (bzf->lastErr != BZ_STREAM_END) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (unused == NULL || nUnused == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - - BZ_SETERR(BZ_OK); - *nUnused = bzf->strm.avail_in; - *unused = bzf->strm.next_in; -} -#endif - - -/*---------------------------------------------------*/ -/*--- Misc convenience stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffCompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - blockSize100k < 1 || blockSize100k > 9 || - verbosity < 0 || verbosity > 4 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzCompressInit ( &strm, blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzCompress ( &strm, BZ_FINISH ); - if (ret == BZ_FINISH_OK) goto output_overflow; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzCompressEnd ( &strm ); - return BZ_OK; - - output_overflow: - BZ2_bzCompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - - errhandler: - BZ2_bzCompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffDecompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - (small != 0 && small != 1) || - verbosity < 0 || verbosity > 4) - return BZ_PARAM_ERROR; - - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzDecompressInit ( &strm, verbosity, small ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzDecompress ( &strm ); - if (ret == BZ_OK) goto output_overflow_or_eof; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzDecompressEnd ( &strm ); - return BZ_OK; - - output_overflow_or_eof: - if (strm.avail_out > 0) { - BZ2_bzDecompressEnd ( &strm ); - return BZ_UNEXPECTED_EOF; - } else { - BZ2_bzDecompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - }; - - errhandler: - BZ2_bzDecompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -/*-- - return version like "0.9.5d, 4-Sept-1999". ---*/ -const char * BZ_API(BZ2_bzlibVersion)(void) -{ - return BZ_VERSION; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ - -#if defined(_WIN32) || defined(OS2) || defined(MSDOS) -# include <fcntl.h> -# include <io.h> -# define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY) -#else -# define SET_BINARY_MODE(file) -#endif -static -BZFILE * bzopen_or_bzdopen - ( const char *path, /* no use when bzdopen */ - int fd, /* no use when bzdopen */ - const char *mode, - int open_mode) /* bzopen: 0, bzdopen:1 */ -{ - int bzerr; - char unused[BZ_MAX_UNUSED]; - int blockSize100k = 9; - int writing = 0; - char mode2[10] = ""; - FILE *fp = NULL; - BZFILE *bzfp = NULL; - int verbosity = 0; - int workFactor = 30; - int smallMode = 0; - int nUnused = 0; - - if (mode == NULL) return NULL; - while (*mode) { - switch (*mode) { - case 'r': - writing = 0; break; - case 'w': - writing = 1; break; - case 's': - smallMode = 1; break; - default: - if (isdigit((int)(*mode))) { - blockSize100k = *mode-BZ_HDR_0; - } - } - mode++; - } - strcat(mode2, writing ? "w" : "r" ); - strcat(mode2,"b"); /* binary mode */ - - if (open_mode==0) { - if (path==NULL || strcmp(path,"")==0) { - fp = (writing ? stdout : stdin); - SET_BINARY_MODE(fp); - } else { - fp = fopen(path,mode2); - } - } else { -#ifdef BZ_STRICT_ANSI - fp = NULL; -#else - fp = _fdopen(fd,mode2); -#endif - } - if (fp == NULL) return NULL; - - if (writing) { - /* Guard against total chaos and anarchy -- JRS */ - if (blockSize100k < 1) blockSize100k = 1; - if (blockSize100k > 9) blockSize100k = 9; - bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k, - verbosity,workFactor); - } else { - bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode, - unused,nUnused); - } - if (bzfp == NULL) { - if (fp != stdin && fp != stdout) fclose(fp); - return NULL; - } - return bzfp; -} - - -/*---------------------------------------------------*/ -/*-- - open file for read or write. - ex) bzopen("file","w9") - case path="" or NULL => use stdin or stdout. ---*/ -BZFILE * BZ_API(BZ2_bzopen) - ( const char *path, - const char *mode ) -{ - return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0); -} - - -/*---------------------------------------------------*/ -BZFILE * BZ_API(BZ2_bzdopen) - ( int fd, - const char *mode ) -{ - return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) -{ - int bzerr, nread; - if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0; - nread = BZ2_bzRead(&bzerr,b,buf,len); - if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) { - return nread; - } else { - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) -{ - int bzerr; - - BZ2_bzWrite(&bzerr,b,buf,len); - if(bzerr == BZ_OK){ - return len; - }else{ - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzflush) (BZFILE *b) -{ - /* do nothing now... */ - return 0; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzclose) (BZFILE* b) -{ - int bzerr; - FILE *fp; - - if (b==NULL) {return;} - fp = ((bzFile *)b)->handle; - if(((bzFile*)b)->writing){ - BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL); - if(bzerr != BZ_OK){ - BZ2_bzWriteClose(NULL,b,1,NULL,NULL); - } - }else{ - BZ2_bzReadClose(&bzerr,b); - } - if(fp!=stdin && fp!=stdout){ - fclose(fp); - } -} - - -/*---------------------------------------------------*/ -/*-- - return last error code ---*/ -static const char *bzerrorstrings[] = { - "OK" - ,"SEQUENCE_ERROR" - ,"PARAM_ERROR" - ,"MEM_ERROR" - ,"DATA_ERROR" - ,"DATA_ERROR_MAGIC" - ,"IO_ERROR" - ,"UNEXPECTED_EOF" - ,"OUTBUFF_FULL" - ,"CONFIG_ERROR" - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ -}; - - -const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) -{ - int err = ((bzFile *)b)->lastErr; - - if(err>0) err = 0; - *errnum = err; - return bzerrorstrings[err*-1]; -} -#endif - - -/*-------------------------------------------------------------*/ -/*--- end bzlib.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/bzlib.h b/dep/StormLib/src/bzip2/bzlib.h deleted file mode 100644 index c5b75d6d8ff..00000000000 --- a/dep/StormLib/src/bzip2/bzlib.h +++ /dev/null @@ -1,282 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Public header file for the library. ---*/ -/*--- bzlib.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_H -#define _BZLIB_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define BZ_RUN 0 -#define BZ_FLUSH 1 -#define BZ_FINISH 2 - -#define BZ_OK 0 -#define BZ_RUN_OK 1 -#define BZ_FLUSH_OK 2 -#define BZ_FINISH_OK 3 -#define BZ_STREAM_END 4 -#define BZ_SEQUENCE_ERROR (-1) -#define BZ_PARAM_ERROR (-2) -#define BZ_MEM_ERROR (-3) -#define BZ_DATA_ERROR (-4) -#define BZ_DATA_ERROR_MAGIC (-5) -#define BZ_IO_ERROR (-6) -#define BZ_UNEXPECTED_EOF (-7) -#define BZ_OUTBUFF_FULL (-8) -#define BZ_CONFIG_ERROR (-9) - -typedef - struct { - char *next_in; - unsigned int avail_in; - unsigned int total_in_lo32; - unsigned int total_in_hi32; - - char *next_out; - unsigned int avail_out; - unsigned int total_out_lo32; - unsigned int total_out_hi32; - - void *state; - - void *(*bzalloc)(void *,int,int); - void (*bzfree)(void *,void *); - void *opaque; - } - bz_stream; - - -#ifndef BZ_IMPORT -#define BZ_EXPORT -#endif - -#ifndef BZ_NO_STDIO -/* Need a definitition for FILE */ -#include <stdio.h> -#endif - -#ifdef _WIN32 -# include <windows.h> -# ifdef small - /* windows.h define small to char */ -# undef small -# endif -# ifdef BZ_EXPORT -# define BZ_API(func) WINAPI func -# define BZ_EXTERN extern -# else - /* import windows dll dynamically */ -# define BZ_API(func) (WINAPI * func) -# define BZ_EXTERN -# endif -#else -# define BZ_API(func) func -# define BZ_EXTERN extern -#endif - - -/*-- Core (low-level) library functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( - bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompress) ( - bz_stream* strm, - int action - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( - bz_stream *strm, - int verbosity, - int small - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( - bz_stream *strm - ); - - - -/*-- High(er) level library functions --*/ - -#ifndef BZ_NO_STDIO -#define BZ_MAX_UNUSED 5000 - -typedef void BZFILE; - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( - int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( - int* bzerror, - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( - int* bzerror, - BZFILE* b, - void** unused, - int* nUnused - ); - -BZ_EXTERN int BZ_API(BZ2_bzRead) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( - int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN void BZ_API(BZ2_bzWrite) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 - ); -#endif - - -/*-- Utility functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity - ); - - -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ - -BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( - void - ); - -#ifndef BZ_NO_STDIO -BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( - const char *path, - const char *mode - ); - -BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( - int fd, - const char *mode - ); - -BZ_EXTERN int BZ_API(BZ2_bzread) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzwrite) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzflush) ( - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzclose) ( - BZFILE* b - ); - -BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( - BZFILE *b, - int *errnum - ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif - -/*-------------------------------------------------------------*/ -/*--- end bzlib.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/bzlib_private.h b/dep/StormLib/src/bzip2/bzlib_private.h deleted file mode 100644 index 23427879b18..00000000000 --- a/dep/StormLib/src/bzip2/bzlib_private.h +++ /dev/null @@ -1,509 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Private header file for the library. ---*/ -/*--- bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_PRIVATE_H -#define _BZLIB_PRIVATE_H - -#include <stdlib.h> - -#ifndef BZ_NO_STDIO -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#endif - -#include "bzlib.h" - - - -/*-- General stuff. --*/ - -#define BZ_VERSION "1.0.5, 10-Dec-2007" - -typedef char Char; -typedef unsigned char Bool; -typedef unsigned char UChar; -typedef int Int32; -typedef unsigned int UInt32; -typedef short Int16; -typedef unsigned short UInt16; - -#define True ((Bool)1) -#define False ((Bool)0) - -#ifndef __GNUC__ -#define __inline__ /* */ -#endif - -#ifndef BZ_NO_STDIO - -extern void BZ2_bz__AssertH__fail ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } - -#if BZ_DEBUG -#define AssertD(cond,msg) \ - { if (!(cond)) { \ - fprintf ( stderr, \ - "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\ - exit(1); \ - }} -#else -#define AssertD(cond,msg) /* */ -#endif - -#define VPrintf0(zf) \ - fprintf(stderr,zf) -#define VPrintf1(zf,za1) \ - fprintf(stderr,zf,za1) -#define VPrintf2(zf,za1,za2) \ - fprintf(stderr,zf,za1,za2) -#define VPrintf3(zf,za1,za2,za3) \ - fprintf(stderr,zf,za1,za2,za3) -#define VPrintf4(zf,za1,za2,za3,za4) \ - fprintf(stderr,zf,za1,za2,za3,za4) -#define VPrintf5(zf,za1,za2,za3,za4,za5) \ - fprintf(stderr,zf,za1,za2,za3,za4,za5) - -#else - -extern void bz_internal_error ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) bz_internal_error ( errcode ); } -#define AssertD(cond,msg) do { } while (0) -#define VPrintf0(zf) do { } while (0) -#define VPrintf1(zf,za1) do { } while (0) -#define VPrintf2(zf,za1,za2) do { } while (0) -#define VPrintf3(zf,za1,za2,za3) do { } while (0) -#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0) -#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0) - -#endif - - -#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) -#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) - - -/*-- Header bytes. --*/ - -#define BZ_HDR_B 0x42 /* 'B' */ -#define BZ_HDR_Z 0x5a /* 'Z' */ -#define BZ_HDR_h 0x68 /* 'h' */ -#define BZ_HDR_0 0x30 /* '0' */ - -/*-- Constants for the back end. --*/ - -#define BZ_MAX_ALPHA_SIZE 258 -#define BZ_MAX_CODE_LEN 23 - -#define BZ_RUNA 0 -#define BZ_RUNB 1 - -#define BZ_N_GROUPS 6 -#define BZ_G_SIZE 50 -#define BZ_N_ITERS 4 - -#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) - - - -/*-- Stuff for randomising repetitive blocks. --*/ - -extern Int32 BZ2_rNums[512]; - -#define BZ_RAND_DECLS \ - Int32 rNToGo; \ - Int32 rTPos \ - -#define BZ_RAND_INIT_MASK \ - s->rNToGo = 0; \ - s->rTPos = 0 \ - -#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) - -#define BZ_RAND_UPD_MASK \ - if (s->rNToGo == 0) { \ - s->rNToGo = BZ2_rNums[s->rTPos]; \ - s->rTPos++; \ - if (s->rTPos == 512) s->rTPos = 0; \ - } \ - s->rNToGo--; - - - -/*-- Stuff for doing CRCs. --*/ - -extern UInt32 BZ2_crc32Table[256]; - -#define BZ_INITIALISE_CRC(crcVar) \ -{ \ - crcVar = 0xffffffffL; \ -} - -#define BZ_FINALISE_CRC(crcVar) \ -{ \ - crcVar = ~(crcVar); \ -} - -#define BZ_UPDATE_CRC(crcVar,cha) \ -{ \ - crcVar = (crcVar << 8) ^ \ - BZ2_crc32Table[(crcVar >> 24) ^ \ - ((UChar)cha)]; \ -} - - - -/*-- States and modes for compression. --*/ - -#define BZ_M_IDLE 1 -#define BZ_M_RUNNING 2 -#define BZ_M_FLUSHING 3 -#define BZ_M_FINISHING 4 - -#define BZ_S_OUTPUT 1 -#define BZ_S_INPUT 2 - -#define BZ_N_RADIX 2 -#define BZ_N_QSORT 12 -#define BZ_N_SHELL 18 -#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) - - - - -/*-- Structure holding all the compression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* mode this stream is in, and whether inputting */ - /* or outputting data */ - Int32 mode; - Int32 state; - - /* remembers avail_in when flush/finish requested */ - UInt32 avail_in_expect; - - /* for doing the block sorting */ - UInt32* arr1; - UInt32* arr2; - UInt32* ftab; - Int32 origPtr; - - /* aliases for arr1 and arr2 */ - UInt32* ptr; - UChar* block; - UInt16* mtfv; - UChar* zbits; - - /* for deciding when to use the fallback sorting algorithm */ - Int32 workFactor; - - /* run-length-encoding of the input */ - UInt32 state_in_ch; - Int32 state_in_len; - BZ_RAND_DECLS; - - /* input and output limits and current posns */ - Int32 nblock; - Int32 nblockMAX; - Int32 numZ; - Int32 state_out_pos; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - UChar unseqToSeq[256]; - - /* the buffer for bit stream creation */ - UInt32 bsBuff; - Int32 bsLive; - - /* block and combined CRCs */ - UInt32 blockCRC; - UInt32 combinedCRC; - - /* misc administratium */ - Int32 verbosity; - Int32 blockNo; - Int32 blockSize100k; - - /* stuff for coding the MTF values */ - Int32 nMTF; - Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - /* second dimension: only 3 needed; 4 makes index calculations faster */ - UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; - - } - EState; - - - -/*-- externs for compression. --*/ - -extern void -BZ2_blockSort ( EState* ); - -extern void -BZ2_compressBlock ( EState*, Bool ); - -extern void -BZ2_bsInitWrite ( EState* ); - -extern void -BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); - -extern void -BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); - - - -/*-- states for decompression. --*/ - -#define BZ_X_IDLE 1 -#define BZ_X_OUTPUT 2 - -#define BZ_X_MAGIC_1 10 -#define BZ_X_MAGIC_2 11 -#define BZ_X_MAGIC_3 12 -#define BZ_X_MAGIC_4 13 -#define BZ_X_BLKHDR_1 14 -#define BZ_X_BLKHDR_2 15 -#define BZ_X_BLKHDR_3 16 -#define BZ_X_BLKHDR_4 17 -#define BZ_X_BLKHDR_5 18 -#define BZ_X_BLKHDR_6 19 -#define BZ_X_BCRC_1 20 -#define BZ_X_BCRC_2 21 -#define BZ_X_BCRC_3 22 -#define BZ_X_BCRC_4 23 -#define BZ_X_RANDBIT 24 -#define BZ_X_ORIGPTR_1 25 -#define BZ_X_ORIGPTR_2 26 -#define BZ_X_ORIGPTR_3 27 -#define BZ_X_MAPPING_1 28 -#define BZ_X_MAPPING_2 29 -#define BZ_X_SELECTOR_1 30 -#define BZ_X_SELECTOR_2 31 -#define BZ_X_SELECTOR_3 32 -#define BZ_X_CODING_1 33 -#define BZ_X_CODING_2 34 -#define BZ_X_CODING_3 35 -#define BZ_X_MTF_1 36 -#define BZ_X_MTF_2 37 -#define BZ_X_MTF_3 38 -#define BZ_X_MTF_4 39 -#define BZ_X_MTF_5 40 -#define BZ_X_MTF_6 41 -#define BZ_X_ENDHDR_2 42 -#define BZ_X_ENDHDR_3 43 -#define BZ_X_ENDHDR_4 44 -#define BZ_X_ENDHDR_5 45 -#define BZ_X_ENDHDR_6 46 -#define BZ_X_CCRC_1 47 -#define BZ_X_CCRC_2 48 -#define BZ_X_CCRC_3 49 -#define BZ_X_CCRC_4 50 - - - -/*-- Constants for the fast MTF decoder. --*/ - -#define MTFA_SIZE 4096 -#define MTFL_SIZE 16 - - - -/*-- Structure holding all the decompression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* state indicator for this stream */ - Int32 state; - - /* for doing the final run-length decoding */ - UChar state_out_ch; - Int32 state_out_len; - Bool blockRandomised; - BZ_RAND_DECLS; - - /* the buffer for bit stream reading */ - UInt32 bsBuff; - Int32 bsLive; - - /* misc administratium */ - Int32 blockSize100k; - Bool smallDecompress; - Int32 currBlockNo; - Int32 verbosity; - - /* for undoing the Burrows-Wheeler transform */ - Int32 origPtr; - UInt32 tPos; - Int32 k0; - Int32 unzftab[256]; - Int32 nblock_used; - Int32 cftab[257]; - Int32 cftabCopy[257]; - - /* for undoing the Burrows-Wheeler transform (FAST) */ - UInt32 *tt; - - /* for undoing the Burrows-Wheeler transform (SMALL) */ - UInt16 *ll16; - UChar *ll4; - - /* stored and calculated CRCs */ - UInt32 storedBlockCRC; - UInt32 storedCombinedCRC; - UInt32 calculatedBlockCRC; - UInt32 calculatedCombinedCRC; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - Bool inUse16[16]; - UChar seqToUnseq[256]; - - /* for decoding the MTF values */ - UChar mtfa [MTFA_SIZE]; - Int32 mtfbase[256 / MTFL_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - - Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 minLens[BZ_N_GROUPS]; - - /* save area for scalars in the main decompress code */ - Int32 save_i; - Int32 save_j; - Int32 save_t; - Int32 save_alphaSize; - Int32 save_nGroups; - Int32 save_nSelectors; - Int32 save_EOB; - Int32 save_groupNo; - Int32 save_groupPos; - Int32 save_nextSym; - Int32 save_nblockMAX; - Int32 save_nblock; - Int32 save_es; - Int32 save_N; - Int32 save_curr; - Int32 save_zt; - Int32 save_zn; - Int32 save_zvec; - Int32 save_zj; - Int32 save_gSel; - Int32 save_gMinlen; - Int32* save_gLimit; - Int32* save_gBase; - Int32* save_gPerm; - - } - DState; - - - -/*-- Macros for decompression. --*/ - -#define BZ_GET_FAST(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - s->tPos = s->tt[s->tPos]; \ - cccc = (UChar)(s->tPos & 0xff); \ - s->tPos >>= 8; - -#define BZ_GET_FAST_C(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \ - c_tPos = c_tt[c_tPos]; \ - cccc = (UChar)(c_tPos & 0xff); \ - c_tPos >>= 8; - -#define SET_LL4(i,n) \ - { if (((i) & 0x1) == 0) \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \ - } - -#define GET_LL4(i) \ - ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF) - -#define SET_LL(i,n) \ - { s->ll16[i] = (UInt16)(n & 0x0000ffff); \ - SET_LL4(i, n >> 16); \ - } - -#define GET_LL(i) \ - (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) - -#define BZ_GET_SMALL(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ - s->tPos = GET_LL(s->tPos); - - -/*-- externs for decompression. --*/ - -extern Int32 -BZ2_indexIntoF ( Int32, Int32* ); - -extern Int32 -BZ2_decompress ( DState* ); - -extern void -BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, - Int32, Int32, Int32 ); - - -#endif - - -/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ - -#ifdef BZ_NO_STDIO -#ifndef NULL -#define NULL 0 -#endif -#endif - - -/*-------------------------------------------------------------*/ -/*--- end bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/compress.c b/dep/StormLib/src/bzip2/compress.c deleted file mode 100644 index 8c80a079700..00000000000 --- a/dep/StormLib/src/bzip2/compress.c +++ /dev/null @@ -1,672 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Compression machinery (not incl block sorting) ---*/ -/*--- compress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- changed setting of nGroups in sendMTFValues() - so as to do a bit better on small files -*/ - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Bit stream I/O ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -void BZ2_bsInitWrite ( EState* s ) -{ - s->bsLive = 0; - s->bsBuff = 0; -} - - -/*---------------------------------------------------*/ -static -void bsFinishWrite ( EState* s ) -{ - while (s->bsLive > 0) { - s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); - s->numZ++; - s->bsBuff <<= 8; - s->bsLive -= 8; - } -} - - -/*---------------------------------------------------*/ -#define bsNEEDW(nz) \ -{ \ - while (s->bsLive >= 8) { \ - s->zbits[s->numZ] \ - = (UChar)(s->bsBuff >> 24); \ - s->numZ++; \ - s->bsBuff <<= 8; \ - s->bsLive -= 8; \ - } \ -} - - -/*---------------------------------------------------*/ -static -__inline__ -void bsW ( EState* s, Int32 n, UInt32 v ) -{ - bsNEEDW ( n ); - s->bsBuff |= (v << (32 - s->bsLive - n)); - s->bsLive += n; -} - - -/*---------------------------------------------------*/ -static -void bsPutUInt32 ( EState* s, UInt32 u ) -{ - bsW ( s, 8, (u >> 24) & 0xffL ); - bsW ( s, 8, (u >> 16) & 0xffL ); - bsW ( s, 8, (u >> 8) & 0xffL ); - bsW ( s, 8, u & 0xffL ); -} - - -/*---------------------------------------------------*/ -static -void bsPutUChar ( EState* s, UChar c ) -{ - bsW( s, 8, (UInt32)c ); -} - - -/*---------------------------------------------------*/ -/*--- The back end proper ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -static -void makeMaps_e ( EState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->unseqToSeq[i] = s->nInUse; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -static -void generateMTFValues ( EState* s ) -{ - UChar yy[256]; - Int32 i, j; - Int32 zPend; - Int32 wr; - Int32 EOB; - - /* - After sorting (eg, here), - s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, - and - ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] - holds the original block data. - - The first thing to do is generate the MTF values, - and put them in - ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. - Because there are strictly fewer or equal MTF values - than block values, ptr values in this area are overwritten - with MTF values only when they are no longer needed. - - The final compressed bitstream is generated into the - area starting at - (UChar*) (&((UChar*)s->arr2)[s->nblock]) - - These storage aliases are set up in bzCompressInit(), - except for the last one, which is arranged in - compressBlock(). - */ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt16* mtfv = s->mtfv; - - makeMaps_e ( s ); - EOB = s->nInUse+1; - - for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; - - wr = 0; - zPend = 0; - for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; - - for (i = 0; i < s->nblock; i++) { - UChar ll_i; - AssertD ( wr <= i, "generateMTFValues(1)" ); - j = ptr[i]-1; if (j < 0) j += s->nblock; - ll_i = s->unseqToSeq[block[j]]; - AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); - - if (yy[0] == ll_i) { - zPend++; - } else { - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - { - register UChar rtmp; - register UChar* ryy_j; - register UChar rll_i; - rtmp = yy[1]; - yy[1] = yy[0]; - ryy_j = &(yy[1]); - rll_i = ll_i; - while ( rll_i != rtmp ) { - register UChar rtmp2; - ryy_j++; - rtmp2 = rtmp; - rtmp = *ryy_j; - *ryy_j = rtmp2; - }; - yy[0] = rtmp; - j = ryy_j - &(yy[0]); - mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; - } - - } - } - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - - mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; - - s->nMTF = wr; -} - - -/*---------------------------------------------------*/ -#define BZ_LESSER_ICOST 0 -#define BZ_GREATER_ICOST 15 - -static -void sendMTFValues ( EState* s ) -{ - Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; - Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; - Int32 nGroups, nBytes; - - /*-- - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - is a global since the decoder also needs it. - - Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - are also globals only used in this proc. - Made global to keep stack frame size small. - --*/ - - - UInt16 cost[BZ_N_GROUPS]; - Int32 fave[BZ_N_GROUPS]; - - UInt16* mtfv = s->mtfv; - - if (s->verbosity >= 3) - VPrintf3( " %d in block, %d after MTF & 1-2 coding, " - "%d+2 syms in use\n", - s->nblock, s->nMTF, s->nInUse ); - - alphaSize = s->nInUse+2; - for (t = 0; t < BZ_N_GROUPS; t++) - for (v = 0; v < alphaSize; v++) - s->len[t][v] = BZ_GREATER_ICOST; - - /*--- Decide how many coding tables to use ---*/ - AssertH ( s->nMTF > 0, 3001 ); - if (s->nMTF < 200) nGroups = 2; else - if (s->nMTF < 600) nGroups = 3; else - if (s->nMTF < 1200) nGroups = 4; else - if (s->nMTF < 2400) nGroups = 5; else - nGroups = 6; - - /*--- Generate an initial set of coding tables ---*/ - { - Int32 nPart, remF, tFreq, aFreq; - - nPart = nGroups; - remF = s->nMTF; - gs = 0; - while (nPart > 0) { - tFreq = remF / nPart; - ge = gs-1; - aFreq = 0; - while (aFreq < tFreq && ge < alphaSize-1) { - ge++; - aFreq += s->mtfFreq[ge]; - } - - if (ge > gs - && nPart != nGroups && nPart != 1 - && ((nGroups-nPart) % 2 == 1)) { - aFreq -= s->mtfFreq[ge]; - ge--; - } - - if (s->verbosity >= 3) - VPrintf5( " initial group %d, [%d .. %d], " - "has %d syms (%4.1f%%)\n", - nPart, gs, ge, aFreq, - (100.0 * (float)aFreq) / (float)(s->nMTF) ); - - for (v = 0; v < alphaSize; v++) - if (v >= gs && v <= ge) - s->len[nPart-1][v] = BZ_LESSER_ICOST; else - s->len[nPart-1][v] = BZ_GREATER_ICOST; - - nPart--; - gs = ge+1; - remF -= aFreq; - } - } - - /*--- - Iterate up to BZ_N_ITERS times to improve the tables. - ---*/ - for (iter = 0; iter < BZ_N_ITERS; iter++) { - - for (t = 0; t < nGroups; t++) fave[t] = 0; - - for (t = 0; t < nGroups; t++) - for (v = 0; v < alphaSize; v++) - s->rfreq[t][v] = 0; - - /*--- - Set up an auxiliary length table which is used to fast-track - the common case (nGroups == 6). - ---*/ - if (nGroups == 6) { - for (v = 0; v < alphaSize; v++) { - s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; - s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; - s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; - } - } - - nSelectors = 0; - totc = 0; - gs = 0; - while (True) { - - /*--- Set group start & end marks. --*/ - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - - /*-- - Calculate the cost of this group as coded - by each of the coding tables. - --*/ - for (t = 0; t < nGroups; t++) cost[t] = 0; - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - register UInt32 cost01, cost23, cost45; - register UInt16 icv; - cost01 = cost23 = cost45 = 0; - -# define BZ_ITER(nn) \ - icv = mtfv[gs+(nn)]; \ - cost01 += s->len_pack[icv][0]; \ - cost23 += s->len_pack[icv][1]; \ - cost45 += s->len_pack[icv][2]; \ - - BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); - BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); - BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); - BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); - BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); - BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); - BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); - BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); - BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); - BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); - -# undef BZ_ITER - - cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; - cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; - cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - UInt16 icv = mtfv[i]; - for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; - } - } - - /*-- - Find the coding table which is best for this group, - and record its identity in the selector table. - --*/ - bc = 999999999; bt = -1; - for (t = 0; t < nGroups; t++) - if (cost[t] < bc) { bc = cost[t]; bt = t; }; - totc += bc; - fave[bt]++; - s->selector[nSelectors] = bt; - nSelectors++; - - /*-- - Increment the symbol frequencies for the selected table. - --*/ - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - -# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ - - BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); - BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); - BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); - BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); - BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); - BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); - BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); - BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); - BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); - BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); - -# undef BZ_ITUR - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) - s->rfreq[bt][ mtfv[i] ]++; - } - - gs = ge+1; - } - if (s->verbosity >= 3) { - VPrintf2 ( " pass %d: size is %d, grp uses are ", - iter+1, totc/8 ); - for (t = 0; t < nGroups; t++) - VPrintf1 ( "%d ", fave[t] ); - VPrintf0 ( "\n" ); - } - - /*-- - Recompute the tables based on the accumulated frequencies. - --*/ - /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See - comment in huffman.c for details. */ - for (t = 0; t < nGroups; t++) - BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), - alphaSize, 17 /*20*/ ); - } - - - AssertH( nGroups < 8, 3002 ); - AssertH( nSelectors < 32768 && - nSelectors <= (2 + (900000 / BZ_G_SIZE)), - 3003 ); - - - /*--- Compute MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; - for (i = 0; i < nGroups; i++) pos[i] = i; - for (i = 0; i < nSelectors; i++) { - ll_i = s->selector[i]; - j = 0; - tmp = pos[j]; - while ( ll_i != tmp ) { - j++; - tmp2 = tmp; - tmp = pos[j]; - pos[j] = tmp2; - }; - pos[0] = tmp; - s->selectorMtf[i] = j; - } - }; - - /*--- Assign actual codes for the tables. --*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); - AssertH ( !(minLen < 1), 3005 ); - BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), - minLen, maxLen, alphaSize ); - } - - /*--- Transmit the mapping table. ---*/ - { - Bool inUse16[16]; - for (i = 0; i < 16; i++) { - inUse16[i] = False; - for (j = 0; j < 16; j++) - if (s->inUse[i * 16 + j]) inUse16[i] = True; - } - - nBytes = s->numZ; - for (i = 0; i < 16; i++) - if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); - - for (i = 0; i < 16; i++) - if (inUse16[i]) - for (j = 0; j < 16; j++) { - if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); - } - - if (s->verbosity >= 3) - VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); - } - - /*--- Now the selectors. ---*/ - nBytes = s->numZ; - bsW ( s, 3, nGroups ); - bsW ( s, 15, nSelectors ); - for (i = 0; i < nSelectors; i++) { - for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); - bsW(s,1,0); - } - if (s->verbosity >= 3) - VPrintf1( "selectors %d, ", s->numZ-nBytes ); - - /*--- Now the coding tables. ---*/ - nBytes = s->numZ; - - for (t = 0; t < nGroups; t++) { - Int32 curr = s->len[t][0]; - bsW ( s, 5, curr ); - for (i = 0; i < alphaSize; i++) { - while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; - while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; - bsW ( s, 1, 0 ); - } - } - - if (s->verbosity >= 3) - VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); - - /*--- And finally, the block data proper ---*/ - nBytes = s->numZ; - selCtr = 0; - gs = 0; - while (True) { - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - AssertH ( s->selector[selCtr] < nGroups, 3006 ); - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - UInt16 mtfv_i; - UChar* s_len_sel_selCtr - = &(s->len[s->selector[selCtr]][0]); - Int32* s_code_sel_selCtr - = &(s->code[s->selector[selCtr]][0]); - -# define BZ_ITAH(nn) \ - mtfv_i = mtfv[gs+(nn)]; \ - bsW ( s, \ - s_len_sel_selCtr[mtfv_i], \ - s_code_sel_selCtr[mtfv_i] ) - - BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); - BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); - BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); - BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); - BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); - BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); - BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); - BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); - BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); - BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); - -# undef BZ_ITAH - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - bsW ( s, - s->len [s->selector[selCtr]] [mtfv[i]], - s->code [s->selector[selCtr]] [mtfv[i]] ); - } - } - - - gs = ge+1; - selCtr++; - } - AssertH( selCtr == nSelectors, 3007 ); - - if (s->verbosity >= 3) - VPrintf1( "codes %d\n", s->numZ-nBytes ); -} - - -/*---------------------------------------------------*/ -void BZ2_compressBlock ( EState* s, Bool is_last_block ) -{ - if (s->nblock > 0) { - - BZ_FINALISE_CRC ( s->blockCRC ); - s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); - s->combinedCRC ^= s->blockCRC; - if (s->blockNo > 1) s->numZ = 0; - - if (s->verbosity >= 2) - VPrintf4( " block %d: crc = 0x%08x, " - "combined CRC = 0x%08x, size = %d\n", - s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); - - BZ2_blockSort ( s ); - } - - s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); - - /*-- If this is the first block, create the stream header. --*/ - if (s->blockNo == 1) { - BZ2_bsInitWrite ( s ); - bsPutUChar ( s, BZ_HDR_B ); - bsPutUChar ( s, BZ_HDR_Z ); - bsPutUChar ( s, BZ_HDR_h ); - bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); - } - - if (s->nblock > 0) { - - bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); - bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); - bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); - - /*-- Now the block's CRC, so it is in a known place. --*/ - bsPutUInt32 ( s, s->blockCRC ); - - /*-- - Now a single bit indicating (non-)randomisation. - As of version 0.9.5, we use a better sorting algorithm - which makes randomisation unnecessary. So always set - the randomised bit to 'no'. Of course, the decoder - still needs to be able to handle randomised blocks - so as to maintain backwards compatibility with - older versions of bzip2. - --*/ - bsW(s,1,0); - - bsW ( s, 24, s->origPtr ); - generateMTFValues ( s ); - sendMTFValues ( s ); - } - - - /*-- If this is the last block, add the stream trailer. --*/ - if (is_last_block) { - - bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); - bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); - bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); - bsPutUInt32 ( s, s->combinedCRC ); - if (s->verbosity >= 2) - VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); - bsFinishWrite ( s ); - } -} - - -/*-------------------------------------------------------------*/ -/*--- end compress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/crctable.c b/dep/StormLib/src/bzip2/crctable.c deleted file mode 100644 index 215687b2c05..00000000000 --- a/dep/StormLib/src/bzip2/crctable.c +++ /dev/null @@ -1,104 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for doing CRCs ---*/ -/*--- crctable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*-- - I think this is an implementation of the AUTODIN-II, - Ethernet & FDDI 32-bit CRC standard. Vaguely derived - from code by Rob Warnock, in Section 51 of the - comp.compression FAQ. ---*/ - -UInt32 BZ2_crc32Table[256] = { - - /*-- Ugly, innit? --*/ - - 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, - 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, - 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, - 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, - 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, - 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, - 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, - 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, - 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, - 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, - 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, - 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, - 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, - 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, - 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, - 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, - 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, - 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, - 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, - 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, - 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, - 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, - 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, - 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, - 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, - 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, - 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, - 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, - 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, - 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, - 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, - 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, - 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, - 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, - 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, - 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, - 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, - 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, - 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, - 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, - 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, - 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, - 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, - 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, - 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, - 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, - 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, - 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, - 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, - 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, - 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, - 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, - 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, - 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, - 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, - 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, - 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, - 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, - 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, - 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, - 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, - 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, - 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, - 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L -}; - - -/*-------------------------------------------------------------*/ -/*--- end crctable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/decompress.c b/dep/StormLib/src/bzip2/decompress.c deleted file mode 100644 index bba5e0fa36d..00000000000 --- a/dep/StormLib/src/bzip2/decompress.c +++ /dev/null @@ -1,626 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Decompression machinery ---*/ -/*--- decompress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -static -void makeMaps_d ( DState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->seqToUnseq[s->nInUse] = i; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -#define RETURN(rrr) \ - { retVal = rrr; goto save_state_and_return; }; - -#define GET_BITS(lll,vvv,nnn) \ - case lll: s->state = lll; \ - while (True) { \ - if (s->bsLive >= nnn) { \ - UInt32 v; \ - v = (s->bsBuff >> \ - (s->bsLive-nnn)) & ((1 << nnn)-1); \ - s->bsLive -= nnn; \ - vvv = v; \ - break; \ - } \ - if (s->strm->avail_in == 0) RETURN(BZ_OK); \ - s->bsBuff \ - = (s->bsBuff << 8) | \ - ((UInt32) \ - (*((UChar*)(s->strm->next_in)))); \ - s->bsLive += 8; \ - s->strm->next_in++; \ - s->strm->avail_in--; \ - s->strm->total_in_lo32++; \ - if (s->strm->total_in_lo32 == 0) \ - s->strm->total_in_hi32++; \ - } - -#define GET_UCHAR(lll,uuu) \ - GET_BITS(lll,uuu,8) - -#define GET_BIT(lll,uuu) \ - GET_BITS(lll,uuu,1) - -/*---------------------------------------------------*/ -#define GET_MTF_VAL(label1,label2,lval) \ -{ \ - if (groupPos == 0) { \ - groupNo++; \ - if (groupNo >= nSelectors) \ - RETURN(BZ_DATA_ERROR); \ - groupPos = BZ_G_SIZE; \ - gSel = s->selector[groupNo]; \ - gMinlen = s->minLens[gSel]; \ - gLimit = &(s->limit[gSel][0]); \ - gPerm = &(s->perm[gSel][0]); \ - gBase = &(s->base[gSel][0]); \ - } \ - groupPos--; \ - zn = gMinlen; \ - GET_BITS(label1, zvec, zn); \ - while (1) { \ - if (zn > 20 /* the longest code */) \ - RETURN(BZ_DATA_ERROR); \ - if (zvec <= gLimit[zn]) break; \ - zn++; \ - GET_BIT(label2, zj); \ - zvec = (zvec << 1) | zj; \ - }; \ - if (zvec - gBase[zn] < 0 \ - || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ - RETURN(BZ_DATA_ERROR); \ - lval = gPerm[zvec - gBase[zn]]; \ -} - - -/*---------------------------------------------------*/ -Int32 BZ2_decompress ( DState* s ) -{ - UChar uc; - Int32 retVal; - Int32 minLen, maxLen; - bz_stream* strm = s->strm; - - /* stuff that needs to be saved/restored */ - Int32 i; - Int32 j; - Int32 t; - Int32 alphaSize; - Int32 nGroups; - Int32 nSelectors; - Int32 EOB; - Int32 groupNo; - Int32 groupPos; - Int32 nextSym; - Int32 nblockMAX; - Int32 nblock; - Int32 es; - Int32 N; - Int32 curr; - Int32 zt; - Int32 zn; - Int32 zvec; - Int32 zj; - Int32 gSel; - Int32 gMinlen; - Int32* gLimit; - Int32* gBase; - Int32* gPerm; - - if (s->state == BZ_X_MAGIC_1) { - /*initialise the save area*/ - s->save_i = 0; - s->save_j = 0; - s->save_t = 0; - s->save_alphaSize = 0; - s->save_nGroups = 0; - s->save_nSelectors = 0; - s->save_EOB = 0; - s->save_groupNo = 0; - s->save_groupPos = 0; - s->save_nextSym = 0; - s->save_nblockMAX = 0; - s->save_nblock = 0; - s->save_es = 0; - s->save_N = 0; - s->save_curr = 0; - s->save_zt = 0; - s->save_zn = 0; - s->save_zvec = 0; - s->save_zj = 0; - s->save_gSel = 0; - s->save_gMinlen = 0; - s->save_gLimit = NULL; - s->save_gBase = NULL; - s->save_gPerm = NULL; - } - - /*restore from the save area*/ - i = s->save_i; - j = s->save_j; - t = s->save_t; - alphaSize = s->save_alphaSize; - nGroups = s->save_nGroups; - nSelectors = s->save_nSelectors; - EOB = s->save_EOB; - groupNo = s->save_groupNo; - groupPos = s->save_groupPos; - nextSym = s->save_nextSym; - nblockMAX = s->save_nblockMAX; - nblock = s->save_nblock; - es = s->save_es; - N = s->save_N; - curr = s->save_curr; - zt = s->save_zt; - zn = s->save_zn; - zvec = s->save_zvec; - zj = s->save_zj; - gSel = s->save_gSel; - gMinlen = s->save_gMinlen; - gLimit = s->save_gLimit; - gBase = s->save_gBase; - gPerm = s->save_gPerm; - - retVal = BZ_OK; - - switch (s->state) { - - GET_UCHAR(BZ_X_MAGIC_1, uc); - if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_2, uc); - if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_3, uc) - if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) - if (s->blockSize100k < (BZ_HDR_0 + 1) || - s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC); - s->blockSize100k -= BZ_HDR_0; - - if (s->smallDecompress) { - s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); - s->ll4 = BZALLOC( - ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) - ); - if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); - } else { - s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); - if (s->tt == NULL) RETURN(BZ_MEM_ERROR); - } - - GET_UCHAR(BZ_X_BLKHDR_1, uc); - - if (uc == 0x17) goto endhdr_2; - if (uc != 0x31) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_2, uc); - if (uc != 0x41) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_3, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_4, uc); - if (uc != 0x26) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_5, uc); - if (uc != 0x53) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_6, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - - s->currBlockNo++; - if (s->verbosity >= 2) - VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); - - s->storedBlockCRC = 0; - GET_UCHAR(BZ_X_BCRC_1, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_2, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_3, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_4, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - - GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); - - s->origPtr = 0; - GET_UCHAR(BZ_X_ORIGPTR_1, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_2, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_3, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - - if (s->origPtr < 0) - RETURN(BZ_DATA_ERROR); - if (s->origPtr > 10 + 100000*s->blockSize100k) - RETURN(BZ_DATA_ERROR); - - /*--- Receive the mapping table ---*/ - for (i = 0; i < 16; i++) { - GET_BIT(BZ_X_MAPPING_1, uc); - if (uc == 1) - s->inUse16[i] = True; else - s->inUse16[i] = False; - } - - for (i = 0; i < 256; i++) s->inUse[i] = False; - - for (i = 0; i < 16; i++) - if (s->inUse16[i]) - for (j = 0; j < 16; j++) { - GET_BIT(BZ_X_MAPPING_2, uc); - if (uc == 1) s->inUse[i * 16 + j] = True; - } - makeMaps_d ( s ); - if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); - alphaSize = s->nInUse+2; - - /*--- Now the selectors ---*/ - GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); - if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); - GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); - if (nSelectors < 1) RETURN(BZ_DATA_ERROR); - for (i = 0; i < nSelectors; i++) { - j = 0; - while (True) { - GET_BIT(BZ_X_SELECTOR_3, uc); - if (uc == 0) break; - j++; - if (j >= nGroups) RETURN(BZ_DATA_ERROR); - } - s->selectorMtf[i] = j; - } - - /*--- Undo the MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], tmp, v; - for (v = 0; v < nGroups; v++) pos[v] = v; - - for (i = 0; i < nSelectors; i++) { - v = s->selectorMtf[i]; - tmp = pos[v]; - while (v > 0) { pos[v] = pos[v-1]; v--; } - pos[0] = tmp; - s->selector[i] = tmp; - } - } - - /*--- Now the coding tables ---*/ - for (t = 0; t < nGroups; t++) { - GET_BITS(BZ_X_CODING_1, curr, 5); - for (i = 0; i < alphaSize; i++) { - while (True) { - if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); - GET_BIT(BZ_X_CODING_2, uc); - if (uc == 0) break; - GET_BIT(BZ_X_CODING_3, uc); - if (uc == 0) curr++; else curr--; - } - s->len[t][i] = curr; - } - } - - /*--- Create the Huffman decoding tables ---*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - BZ2_hbCreateDecodeTables ( - &(s->limit[t][0]), - &(s->base[t][0]), - &(s->perm[t][0]), - &(s->len[t][0]), - minLen, maxLen, alphaSize - ); - s->minLens[t] = minLen; - } - - /*--- Now the MTF values ---*/ - - EOB = s->nInUse+1; - nblockMAX = 100000 * s->blockSize100k; - groupNo = -1; - groupPos = 0; - - for (i = 0; i <= 255; i++) s->unzftab[i] = 0; - - /*-- MTF init --*/ - { - Int32 ii, jj, kk; - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - /*-- end MTF init --*/ - - nblock = 0; - GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); - - while (True) { - - if (nextSym == EOB) break; - - if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { - - es = -1; - N = 1; - do { - if (nextSym == BZ_RUNA) es = es + (0+1) * N; else - if (nextSym == BZ_RUNB) es = es + (1+1) * N; - N = N * 2; - GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); - } - while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); - - es++; - uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; - s->unzftab[uc] += es; - - if (s->smallDecompress) - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->ll16[nblock] = (UInt16)uc; - nblock++; - es--; - } - else - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->tt[nblock] = (UInt32)uc; - nblock++; - es--; - }; - - continue; - - } else { - - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - - /*-- uc = MTF ( nextSym-1 ) --*/ - { - Int32 ii, jj, kk, pp, lno, off; - UInt32 nn; - nn = (UInt32)(nextSym - 1); - - if (nn < MTFL_SIZE) { - /* avoid general-case expense */ - pp = s->mtfbase[0]; - uc = s->mtfa[pp+nn]; - while (nn > 3) { - Int32 z = pp+nn; - s->mtfa[(z) ] = s->mtfa[(z)-1]; - s->mtfa[(z)-1] = s->mtfa[(z)-2]; - s->mtfa[(z)-2] = s->mtfa[(z)-3]; - s->mtfa[(z)-3] = s->mtfa[(z)-4]; - nn -= 4; - } - while (nn > 0) { - s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; - }; - s->mtfa[pp] = uc; - } else { - /* general case */ - lno = nn / MTFL_SIZE; - off = nn % MTFL_SIZE; - pp = s->mtfbase[lno] + off; - uc = s->mtfa[pp]; - while (pp > s->mtfbase[lno]) { - s->mtfa[pp] = s->mtfa[pp-1]; pp--; - }; - s->mtfbase[lno]++; - while (lno > 0) { - s->mtfbase[lno]--; - s->mtfa[s->mtfbase[lno]] - = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; - lno--; - } - s->mtfbase[0]--; - s->mtfa[s->mtfbase[0]] = uc; - if (s->mtfbase[0] == 0) { - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - } - } - /*-- end uc = MTF ( nextSym-1 ) --*/ - - s->unzftab[s->seqToUnseq[uc]]++; - if (s->smallDecompress) - s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else - s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); - nblock++; - - GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); - continue; - } - } - - /* Now we know what nblock is, we can do a better sanity - check on s->origPtr. - */ - if (s->origPtr < 0 || s->origPtr >= nblock) - RETURN(BZ_DATA_ERROR); - - /*-- Set up cftab to facilitate generation of T^(-1) --*/ - s->cftab[0] = 0; - for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; - for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; - for (i = 0; i <= 256; i++) { - if (s->cftab[i] < 0 || s->cftab[i] > nblock) { - /* s->cftab[i] can legitimately be == nblock */ - RETURN(BZ_DATA_ERROR); - } - } - - s->state_out_len = 0; - s->state_out_ch = 0; - BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); - s->state = BZ_X_OUTPUT; - if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); - - if (s->smallDecompress) { - - /*-- Make a copy of cftab, used in generation of T --*/ - for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; - - /*-- compute the T vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->ll16[i]); - SET_LL(i, s->cftabCopy[uc]); - s->cftabCopy[uc]++; - } - - /*-- Compute T^(-1) by pointer reversal on T --*/ - i = s->origPtr; - j = GET_LL(i); - do { - Int32 tmp = GET_LL(j); - SET_LL(j, i); - i = j; - j = tmp; - } - while (i != s->origPtr); - - s->tPos = s->origPtr; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_SMALL(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } else { - - /*-- compute the T^(-1) vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->tt[i] & 0xff); - s->tt[s->cftab[uc]] |= (i << 8); - s->cftab[uc]++; - } - - s->tPos = s->tt[s->origPtr] >> 8; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_FAST(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_FAST(s->k0); s->nblock_used++; - } - - } - - RETURN(BZ_OK); - - - - endhdr_2: - - GET_UCHAR(BZ_X_ENDHDR_2, uc); - if (uc != 0x72) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_3, uc); - if (uc != 0x45) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_4, uc); - if (uc != 0x38) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_5, uc); - if (uc != 0x50) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_6, uc); - if (uc != 0x90) RETURN(BZ_DATA_ERROR); - - s->storedCombinedCRC = 0; - GET_UCHAR(BZ_X_CCRC_1, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_2, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_3, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_4, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - - s->state = BZ_X_IDLE; - RETURN(BZ_STREAM_END); - - default: AssertH ( False, 4001 ); - } - - AssertH ( False, 4002 ); - - save_state_and_return: - - s->save_i = i; - s->save_j = j; - s->save_t = t; - s->save_alphaSize = alphaSize; - s->save_nGroups = nGroups; - s->save_nSelectors = nSelectors; - s->save_EOB = EOB; - s->save_groupNo = groupNo; - s->save_groupPos = groupPos; - s->save_nextSym = nextSym; - s->save_nblockMAX = nblockMAX; - s->save_nblock = nblock; - s->save_es = es; - s->save_N = N; - s->save_curr = curr; - s->save_zt = zt; - s->save_zn = zn; - s->save_zvec = zvec; - s->save_zj = zj; - s->save_gSel = gSel; - s->save_gMinlen = gMinlen; - s->save_gLimit = gLimit; - s->save_gBase = gBase; - s->save_gPerm = gPerm; - - return retVal; -} - - -/*-------------------------------------------------------------*/ -/*--- end decompress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/huffman.c b/dep/StormLib/src/bzip2/huffman.c deleted file mode 100644 index 87e79e38af0..00000000000 --- a/dep/StormLib/src/bzip2/huffman.c +++ /dev/null @@ -1,205 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Huffman coding low-level stuff ---*/ -/*--- huffman.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------------*/ -#define WEIGHTOF(zz0) ((zz0) & 0xffffff00) -#define DEPTHOF(zz1) ((zz1) & 0x000000ff) -#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) - -#define ADDWEIGHTS(zw1,zw2) \ - (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ - (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) - -#define UPHEAP(z) \ -{ \ - Int32 zz, tmp; \ - zz = z; tmp = heap[zz]; \ - while (weight[tmp] < weight[heap[zz >> 1]]) { \ - heap[zz] = heap[zz >> 1]; \ - zz >>= 1; \ - } \ - heap[zz] = tmp; \ -} - -#define DOWNHEAP(z) \ -{ \ - Int32 zz, yy, tmp; \ - zz = z; tmp = heap[zz]; \ - while (True) { \ - yy = zz << 1; \ - if (yy > nHeap) break; \ - if (yy < nHeap && \ - weight[heap[yy+1]] < weight[heap[yy]]) \ - yy++; \ - if (weight[tmp] < weight[heap[yy]]) break; \ - heap[zz] = heap[yy]; \ - zz = yy; \ - } \ - heap[zz] = tmp; \ -} - - -/*---------------------------------------------------*/ -void BZ2_hbMakeCodeLengths ( UChar *len, - Int32 *freq, - Int32 alphaSize, - Int32 maxLen ) -{ - /*-- - Nodes and heap entries run from 1. Entry 0 - for both the heap and nodes is a sentinel. - --*/ - Int32 nNodes, nHeap, n1, n2, i, j, k; - Bool tooLong; - - Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; - Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; - Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; - - for (i = 0; i < alphaSize; i++) - weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; - - while (True) { - - nNodes = alphaSize; - nHeap = 0; - - heap[0] = 0; - weight[0] = 0; - parent[0] = -2; - - for (i = 1; i <= alphaSize; i++) { - parent[i] = -1; - nHeap++; - heap[nHeap] = i; - UPHEAP(nHeap); - } - - AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); - - while (nHeap > 1) { - n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - nNodes++; - parent[n1] = parent[n2] = nNodes; - weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); - parent[nNodes] = -1; - nHeap++; - heap[nHeap] = nNodes; - UPHEAP(nHeap); - } - - AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); - - tooLong = False; - for (i = 1; i <= alphaSize; i++) { - j = 0; - k = i; - while (parent[k] >= 0) { k = parent[k]; j++; } - len[i-1] = j; - if (j > maxLen) tooLong = True; - } - - if (! tooLong) break; - - /* 17 Oct 04: keep-going condition for the following loop used - to be 'i < alphaSize', which missed the last element, - theoretically leading to the possibility of the compressor - looping. However, this count-scaling step is only needed if - one of the generated Huffman code words is longer than - maxLen, which up to and including version 1.0.2 was 20 bits, - which is extremely unlikely. In version 1.0.3 maxLen was - changed to 17 bits, which has minimal effect on compression - ratio, but does mean this scaling step is used from time to - time, enough to verify that it works. - - This means that bzip2-1.0.3 and later will only produce - Huffman codes with a maximum length of 17 bits. However, in - order to preserve backwards compatibility with bitstreams - produced by versions pre-1.0.3, the decompressor must still - handle lengths of up to 20. */ - - for (i = 1; i <= alphaSize; i++) { - j = weight[i] >> 8; - j = 1 + (j / 2); - weight[i] = j << 8; - } - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbAssignCodes ( Int32 *code, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 n, vec, i; - - vec = 0; - for (n = minLen; n <= maxLen; n++) { - for (i = 0; i < alphaSize; i++) - if (length[i] == n) { code[i] = vec; vec++; }; - vec <<= 1; - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbCreateDecodeTables ( Int32 *limit, - Int32 *base, - Int32 *perm, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 pp, i, j, vec; - - pp = 0; - for (i = minLen; i <= maxLen; i++) - for (j = 0; j < alphaSize; j++) - if (length[j] == i) { perm[pp] = j; pp++; }; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0; - for (i = 0; i < alphaSize; i++) base[length[i]+1]++; - - for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1]; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0; - vec = 0; - - for (i = minLen; i <= maxLen; i++) { - vec += (base[i+1] - base[i]); - limit[i] = vec-1; - vec <<= 1; - } - for (i = minLen + 1; i <= maxLen; i++) - base[i] = ((limit[i-1] + 1) << 1) - base[i]; -} - - -/*-------------------------------------------------------------*/ -/*--- end huffman.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/bzip2/randtable.c b/dep/StormLib/src/bzip2/randtable.c deleted file mode 100644 index 068b76367bc..00000000000 --- a/dep/StormLib/src/bzip2/randtable.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for randomising repetitive blocks ---*/ -/*--- randtable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.5 of 10 December 2007 - Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------*/ -Int32 BZ2_rNums[512] = { - 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, - 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, - 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, - 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, - 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, - 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, - 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, - 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, - 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, - 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, - 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, - 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, - 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, - 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, - 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, - 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, - 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, - 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, - 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, - 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, - 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, - 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, - 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, - 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, - 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, - 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, - 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, - 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, - 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, - 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, - 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, - 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, - 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, - 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, - 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, - 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, - 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, - 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, - 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, - 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, - 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, - 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, - 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, - 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, - 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, - 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, - 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, - 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, - 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, - 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, - 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, - 936, 638 -}; - - -/*-------------------------------------------------------------*/ -/*--- end randtable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/dep/StormLib/src/huffman/huff.cpp b/dep/StormLib/src/huffman/huff.cpp deleted file mode 100644 index 66a46b3fa55..00000000000 --- a/dep/StormLib/src/huffman/huff.cpp +++ /dev/null @@ -1,1303 +0,0 @@ -/*****************************************************************************/ -/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */ -/*---------------------------------------------------------------------------*/ -/* This module contains Huffmann (de)compression methods */ -/* */ -/* Authors : Ladislav Zezula (ladik@zezula.net) */ -/* ShadowFlare (BlakFlare@hotmail.com) */ -/* */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */ -/* 03.05.03 1.00 Lad Added compression methods */ -/* 19.11.03 1.01 Dan Big endian handling */ -/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ -/*****************************************************************************/ - -#include <assert.h> -#include <string.h> - -#include "huff.h" - -// Special for Mac - we have to know if normal pointer greater or less -// than 0x80000000. This variable is used in the PTR_VALID and PTR_INVALID -// macros -static long mul = 1; - -#define PTR_VALID(ptr) (((LONG_PTR)(ptr) * mul) > 0) -#define PTR_INVALID(ptr) (((LONG_PTR)(ptr) * mul) < 0) -#define PTR_INVALID_OR_NULL(ptr) (((LONG_PTR)(ptr) * mul) <= 0) - - -//----------------------------------------------------------------------------- -// Methods of the THTreeItem struct - -// 1501DB70 -THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast) -{ - if(pLast == NULL) - pLast = this + 1; - return pLast; -} - -// Gets previous Huffman tree item (?) -THTreeItem * THTreeItem::GetPrevItem(LONG_PTR value) -{ - if(PTR_INVALID(prev)) - return PTR_NOT(prev); - - if(value == -1 || PTR_INVALID(value)) - value = (LONG_PTR)(this - next->prev); - return prev + value; - -// OLD VERSION -// if(PTR_INT(value) < 0) -// value = PTR_INT((item - item->next->prev)); -// return (THTreeItem *)((char *)prev + value); -} - -// 1500F5E0 -void THTreeItem::ClearItemLinks() -{ - next = prev = NULL; -} - -// 1500BC90 -void THTreeItem::RemoveItem() -{ - THTreeItem * pTemp; // EDX - - if(next != NULL) - { - pTemp = prev; - - if(PTR_INVALID_OR_NULL(pTemp)) - pTemp = PTR_NOT(pTemp); - else - pTemp += (this - next->prev); - - pTemp->next = next; - next->prev = prev; - next = prev = NULL; - } -} - -/* -// OLD VERSION : Removes item from the tree (?) -static void RemoveItem(THTreeItem * item) -{ - THTreeItem * next = item->next; // ESI - THTreeItem * prev = item->prev; // EDX - - if(next == NULL) - return; - - if(PTR_INT(prev) < 0) - prev = PTR_NOT(prev); - else - // ??? usually item == next->prev, so what is it ? - prev = (THTreeItem *)((unsigned char *)prev + (unsigned long)((unsigned char *)item - (unsigned char *)(next->prev))); - - // Remove HTree item from the chain - prev->next = next; // Sets the 'first' pointer - next->prev = item->prev; - - // Invalidate pointers - item->next = NULL; - item->prev = NULL; -} -*/ - -//----------------------------------------------------------------------------- -// TOutputStream functions - -void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits) -{ - dwBitBuff |= (dwBuff << nBits); - nBits += nPutBits; - - // Flush completed bytes - while(nBits >= 8) - { - if(cbOutSize != 0) - { - *pbOutPos++ = (unsigned char)dwBitBuff; - cbOutSize--; - } - - dwBitBuff >>= 8; - nBits -= 8; - } -} - -//----------------------------------------------------------------------------- -// TInputStream functions - -// Gets one bit from input stream -unsigned long TInputStream::GetBit() -{ - unsigned long dwOneBit = 0; - - // Ensure that the input stream is reloaded, if there are no bits left - if(BitCount == 0) - { - // Refill the bit buffer - BitBuffer = *pbInBuffer++; - BitCount = 8; - } - - // Copy the bit from bit buffer to the variable - dwOneBit = (BitBuffer & 0x01); - BitBuffer >>= 1; - BitCount--; - - return dwOneBit; -} - -// Gets 7 bits from the stream. DOES NOT remove the bits from input stream -unsigned long TInputStream::Get7Bits() -{ - unsigned long dwReloadByte = 0; - - // If there is not enough bits to get the value, - // we have to add 8 more bits from the input buffer - if(BitCount < 7) - { - dwReloadByte = *pbInBuffer++; - BitBuffer |= dwReloadByte << BitCount; - BitCount += 8; - } - - // Return the first available 7 bits. DO NOT remove them from the input stream - return (BitBuffer & 0x7F); -} - -// Gets the whole byte from the input stream. -unsigned long TInputStream::Get8Bits() -{ - unsigned long dwReloadByte = 0; - unsigned long dwOneByte = 0; - - // If there is not enough bits to get the value, - // we have to add 8 more bits from the input buffer - if(BitCount < 8) - { - dwReloadByte = *pbInBuffer++; - BitBuffer |= dwReloadByte << BitCount; - BitCount += 8; - } - - // Return the lowest 8 its - dwOneByte = (BitBuffer & 0xFF); - BitBuffer >>= 8; - BitCount -= 8; - return dwOneByte; -} - -void TInputStream::SkipBits(unsigned int dwBitsToSkip) -{ - unsigned long dwReloadByte = 0; - - // If there is not enough bits in the buffer, - // we have to add 8 more bits from the input buffer - if(BitCount < dwBitsToSkip) - { - dwReloadByte = *pbInBuffer++; - BitBuffer |= dwReloadByte << BitCount; - BitCount += 8; - } - - // Skip the remaining bits - BitBuffer >>= dwBitsToSkip; - BitCount -= dwBitsToSkip; -} - -//----------------------------------------------------------------------------- -// Functions for huffmann tree items - -// Inserts item into the tree (?) -static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long nWhere, THTreeItem * item2) -{ - THTreeItem * next = item->next; // EDI - next to the first item - THTreeItem * prev = item->prev; // ESI - prev to the first item - THTreeItem * prev2; // Pointer to previous item - LONG_PTR next2; // Pointer to the next item - - // The same code like in RemoveItem(item); - if(next != 0) // If the first item already has next one - { - if(PTR_INVALID(prev)) - prev = PTR_NOT(prev); - else - prev += (item - next->prev); - - // 150083C1 - // Remove the item from the tree - prev->next = next; - next->prev = prev; - - // Invalidate 'prev' and 'next' pointer - item->next = 0; - item->prev = 0; - } - - if(item2 == NULL) // EDX - If the second item is not entered, - item2 = PTR_PTR(&itemPtr[1]); // take the first tree item - - switch(nWhere) - { - case SWITCH_ITEMS : // Switch the two items - item->next = item2->next; // item2->next (Pointer to pointer to first) - item->prev = item2->next->prev; - item2->next->prev = item; - item2->next = item; // Set the first item - return; - - case INSERT_ITEM: // Insert as the last item - item->next = item2; // Set next item (or pointer to pointer to first item) - item->prev = item2->prev; // Set prev item (or last item in the tree) - - next2 = PTR_INT(itemPtr[0]);// Usually NULL - prev2 = item2->prev; // Prev item to the second (or last tree item) - - if(PTR_INVALID(prev2)) - { - if(prev != NULL) - { - prev2 = PTR_NOT(prev); - if(prev2 != NULL) - { - prev2->next = item; - item2->prev = item; // Next after last item - } - } - return; - } - - if(PTR_INVALID(next2)) - next2 = (LONG_PTR)(item2 - item2->next->prev); -// next2 = (THTreeItem *)(unsigned long)((unsigned char *)item2 - (unsigned char *)(item2->next->prev)); - -// prev2 = (THTreeItem *)((char *)prev2 + (unsigned long)next2);// ??? - prev2 += next2; - prev2->next = item; - item2->prev = item; // Set the next/last item - return; - - default: - return; - } -} - -//----------------------------------------------------------------------------- -// THuffmannTree class functions - -THuffmannTree::THuffmannTree() -{ - // We have to check if the "this" pointer is less than zero - if((LONG_PTR)this < 0) - mul = -1; -} - -void THuffmannTree::InitTree(bool bCompression) -{ - THTreeItem * pItem; - unsigned int nCount; - - // Clear links for all the items in the tree - for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--) - pItem->ClearItemLinks(); - - pItem3050 = NULL; - pItem3054 = PTR_PTR(&pItem3054); - pItem3058 = PTR_NOT(pItem3054); - - pItem305C = NULL; - pFirst = PTR_PTR(&pFirst); - pLast = PTR_NOT(pFirst); - - offs0004 = 1; - nItems = 0; - - // Clear all TQDecompress items. Do this only if preparing for decompression - if(bCompression == false) - { - for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++) - qd3474[nCount].offs00 = 0; - } -} - -// Builds Huffman tree. Called with the first 8 bits loaded from input stream -void THuffmannTree::BuildTree(unsigned int nCmpType) -{ - unsigned long maxByte; // [ESP+10] - The greatest character found in table - THTreeItem ** itemPtr; // [ESP+14] - Pointer to Huffman tree item pointer array - unsigned char * byteArray; // [ESP+1C] - Pointer to unsigned char in Table1502A630 - THTreeItem * child1; - unsigned long i; // egcs in linux doesn't like multiple for loops without an explicit i - - // Loop while pointer has a valid value - while(PTR_VALID(pLast)) // ESI - Last entry - { - THTreeItem * temp; // EAX - - if(pLast->next != NULL) // ESI->next - pLast->RemoveItem(); - // EDI = &offs3054 - pItem3058 = PTR_PTR(&pItem3054); // [EDI+4] - pLast->prev = pItem3058; // EAX - - temp = PTR_PTR(&pItem3054)->GetPrevItem(PTR_INT(&pItem3050)); - - temp->next = pLast; - pItem3054 = pLast; - } - - // Clear all pointers in HTree item array - memset(items306C, 0, sizeof(items306C)); - - maxByte = 0; // Greatest character found init to zero. - itemPtr = (THTreeItem **)&items306C; // Pointer to current entry in HTree item pointer array - - // Ensure we have low 8 bits only - nCmpType &= 0xFF; - byteArray = Table1502A630 + nCmpType * 258; // EDI also - - for(i = 0; i < 0x100; i++, itemPtr++) - { - THTreeItem * item = pItem3058; // Item to be created - THTreeItem * pItem3 = pItem3058; - unsigned char oneByte = byteArray[i]; - - // Skip all the bytes which are zero. - if(byteArray[i] == 0) - continue; - - // If not valid pointer, take the first available item in the array - if(PTR_INVALID_OR_NULL(item)) - item = &items0008[nItems++]; - - // Insert this item as the top of the tree - InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL); - - item->parent = NULL; // Invalidate child and parent - item->child = NULL; - *itemPtr = item; // Store pointer into pointer array - - item->dcmpByte = i; // Store counter - item->byteValue = oneByte; // Store byte value - if(oneByte >= maxByte) - { - maxByte = oneByte; - continue; - } - - // Find the first item which has byte value greater than current one byte - if(PTR_VALID(pItem3 = pLast)) // EDI - Pointer to the last item - { - // 15006AF7 - if(pItem3 != NULL) - { - do // 15006AFB - { - if(pItem3->byteValue >= oneByte) - goto _15006B09; - pItem3 = pItem3->prev; - } - while(PTR_VALID(pItem3)); - } - } - pItem3 = NULL; - - // 15006B09 - _15006B09: - if(item->next != NULL) - item->RemoveItem(); - - // 15006B15 - if(pItem3 == NULL) - pItem3 = PTR_PTR(&pFirst); - - // 15006B1F - item->next = pItem3->next; - item->prev = pItem3->next->prev; - pItem3->next->prev = item; - pItem3->next = item; - } - - // 15006B4A - for(; i < 0x102; i++) - { - THTreeItem ** itemPtr = &items306C[i]; // EDI - - // 15006B59 - THTreeItem * item = pItem3058; // ESI - if(PTR_INVALID_OR_NULL(item)) - item = &items0008[nItems++]; - - InsertItem(&pItem305C, item, INSERT_ITEM, NULL); - - // 15006B89 - item->dcmpByte = i; - item->byteValue = 1; - item->parent = NULL; - item->child = NULL; - *itemPtr++ = item; - } - - // 15006BAA - if(PTR_VALID(child1 = pLast)) // EDI - last item (first child to item - { - THTreeItem * child2; // EBP - THTreeItem * item; // ESI - - // 15006BB8 - while(PTR_VALID(child2 = child1->prev)) - { - if(PTR_INVALID_OR_NULL(item = pItem3058)) - item = &items0008[nItems++]; - - // 15006BE3 - InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL); - - // 15006BF3 - item->parent = NULL; - item->child = NULL; - - //EDX = child2->byteValue + child1->byteValue; - //EAX = child1->byteValue; - //ECX = maxByte; // The greatest character (0xFF usually) - - item->byteValue = child1->byteValue + child2->byteValue; // 0x02 - item->child = child1; // Prev item in the - child1->parent = item; - child2->parent = item; - - // EAX = item->byteValue; - if(item->byteValue >= maxByte) - maxByte = item->byteValue; - else - { - THTreeItem * pItem2 = child2->prev; // EDI - - // 15006C2D - while(PTR_VALID(pItem2)) - { - if(pItem2->byteValue >= item->byteValue) - goto _15006C3B; - pItem2 = pItem2->prev; - } - pItem2 = NULL; - - _15006C3B: - if(item->next != 0) - { - THTreeItem * temp4 = item->GetPrevItem(-1); - - temp4->next = item->next; // The first item changed - item->next->prev = item->prev; // First->prev changed to negative value - item->next = NULL; - item->prev = NULL; - } - - // 15006C62 - if(pItem2 == NULL) - pItem2 = PTR_PTR(&pFirst); - - item->next = pItem2->next; // Set item with 0x100 byte value - item->prev = pItem2->next->prev; // Set item with 0x17 byte value - pItem2->next->prev = item; // Changed prev of item with - pItem2->next = item; - } - - // 15006C7B - if(PTR_INVALID_OR_NULL(child1 = child2->prev)) - break; - } - } - // 15006C88 - offs0004 = 1; -} -/* -// Modifies Huffman tree. Adds new item and changes -void THuffmannTree::ModifyTree(unsigned long dwIndex) -{ - THTreeItem * pItem1 = pItem3058; // ESI - THTreeItem * pSaveLast = (PTR_INT(pLast) <= 0) ? NULL : pLast; // EBX - THTreeItem * temp; // EAX - - // Prepare the first item to insert to the tree - if(PTR_INT(pItem1) <= 0) - pItem1 = &items0008[nItems++]; - - // If item has any next item, remove it from the chain - if(pItem1->next != NULL) - { - THTreeItem * temp = pItem1->GetPrevItem(-1); // EAX - - temp->next = pItem1->next; - pItem1->next->prev = pItem1->prev; - pItem1->next = NULL; - pItem1->prev = NULL; - } - - pItem1->next = PTR_PTR(&pFirst); - pItem1->prev = pLast; - temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C)); - - // 150068E9 - temp->next = pItem1; - pLast = pItem1; - - pItem1->parent = NULL; - pItem1->child = NULL; - - // 150068F6 - pItem1->dcmpByte = pSaveLast->dcmpByte; // Copy item index - pItem1->byteValue = pSaveLast->byteValue; // Copy item byte value - pItem1->parent = pSaveLast; // Set parent to last item - items306C[pSaveLast->dcmpByte] = pItem1; // Insert item into item pointer array - - // Prepare the second item to insert into the tree - if(PTR_INT((pItem1 = pItem3058)) <= 0) - pItem1 = &items0008[nItems++]; - - // 1500692E - if(pItem1->next != NULL) - { - temp = pItem1->GetPrevItem(-1); // EAX - - temp->next = pItem1->next; - pItem1->next->prev = pItem1->prev; - pItem1->next = NULL; - pItem1->prev = NULL; - } - // 1500694C - pItem1->next = PTR_PTR(&pFirst); - pItem1->prev = pLast; - temp = pItem1->next->GetPrevItem(PTR_INT(pItem305C)); - - // 15006968 - temp->next = pItem1; - pLast = pItem1; - - // 1500696E - pItem1->child = NULL; - pItem1->dcmpByte = dwIndex; - pItem1->byteValue = 0; - pItem1->parent = pSaveLast; - pSaveLast->child = pItem1; - items306C[dwIndex] = pItem1; - - do - { - THTreeItem * pItem2 = pItem1; - THTreeItem * pItem3; - unsigned long byteValue; - - // 15006993 - byteValue = ++pItem1->byteValue; - - // Pass through all previous which have its value greater than byteValue - while(PTR_INT((pItem3 = pItem2->prev)) > 0) // EBX - { - if(pItem3->byteValue >= byteValue) - goto _150069AE; - - pItem2 = pItem2->prev; - } - // 150069AC - pItem3 = NULL; - - _150069AE: - if(pItem2 == pItem1) - continue; - - // 150069B2 - // Switch pItem2 with item - InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1); - InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3); - - // 150069D0 - // Switch parents of pItem1 and pItem2 - temp = pItem2->parent->child; - if(pItem1 == pItem1->parent->child) - pItem1->parent->child = pItem2; - - if(pItem2 == temp) - pItem2->parent->child = pItem1; - - // 150069ED - // Switch parents of pItem1 and pItem3 - temp = pItem1->parent; - pItem1 ->parent = pItem2->parent; - pItem2->parent = temp; - offs0004++; - } - while(PTR_INT((pItem1 = pItem1->parent)) > 0); -} - -void THuffmannTree::UninitTree() -{ - while(PTR_INT(pLast) > 0) - { - pItem = pItem305C->Call1501DB70(pLast); - pItem->RemoveItem(); - } - - for(pItem = pFirst; PTR_INT(pItem3058) > 0; pItem = pItem3058) - pItem->RemoveItem(); - PTR_PTR(&pItem3054)->RemoveItem(); - - for(pItem = items0008 + 0x203, nCount = 0x203; nCount != 0; nCount--) - { - pItem--; - pItem->RemoveItem(); - pItem->RemoveItem(); - } -} -*/ - -THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue) -{ - THTreeItem * pItem1 = pItem3058; // EDX - THTreeItem * pItem2; // EAX - THTreeItem * pNext; - THTreeItem * pPrev; - THTreeItem ** ppItem; - - if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL) - { - if((pItem2 = &items0008[nItems++]) != NULL) - pItem1 = pItem2; - else - pItem1 = pFirst; - } - else - pItem1 = pItem2; - - pNext = pItem1->next; - if(pNext != NULL) - { - pPrev = pItem1->prev; - if(PTR_INVALID_OR_NULL(pPrev)) - pPrev = PTR_NOT(pPrev); - else - pPrev += (pItem1 - pItem1->next->prev); - - pPrev->next = pNext; - pNext->prev = pPrev; - pItem1->next = NULL; - pItem1->prev = NULL; - } - - ppItem = &pFirst; // esi - if(nValue > 1) - { - // ecx = pFirst->next; - pItem1->next = *ppItem; - pItem1->prev = (*ppItem)->prev; - - (*ppItem)->prev = pItem2; - *ppItem = pItem1; - - pItem2->parent = NULL; - pItem2->child = NULL; - } - else - { - pItem1->next = (THTreeItem *)ppItem; - pItem1->prev = ppItem[1]; - // edi = pItem305C; - pPrev = ppItem[1]; // ecx - if(PTR_INVALID_OR_NULL(pPrev)) - { - pPrev = PTR_NOT(pPrev); - pPrev->next = pItem1; - pPrev->prev = pItem2; - - pItem2->parent = NULL; - pItem2->child = NULL; - } - else - { - if(PTR_INVALID(pItem305C)) - pPrev += (THTreeItem *)ppItem - (*ppItem)->prev; - else - pPrev += PTR_INT(pItem305C); - - pPrev->next = pItem1; - ppItem[1] = pItem2; - pItem2->parent = NULL; - pItem2->child = NULL; - } - } - return pItem2; -} - -void THuffmannTree::Call1500E820(THTreeItem * pItem) -{ - THTreeItem * pItem1; // edi - THTreeItem * pItem2 = NULL; // eax - THTreeItem * pItem3; // edx - THTreeItem * pPrev; // ebx - - for(; pItem != NULL; pItem = pItem->parent) - { - pItem->byteValue++; - - for(pItem1 = pItem; ; pItem1 = pPrev) - { - pPrev = pItem1->prev; - if(PTR_INVALID_OR_NULL(pPrev)) - { - pPrev = NULL; - break; - } - - if(pPrev->byteValue >= pItem->byteValue) - break; - } - - if(pItem1 == pItem) - continue; - - if(pItem1->next != NULL) - { - pItem2 = pItem1->GetPrevItem(-1); - pItem2->next = pItem1->next; - pItem1->next->prev = pItem1->prev; - pItem1->next = NULL; - pItem1->prev = NULL; - } - - pItem2 = pItem->next; - pItem1->next = pItem2; - pItem1->prev = pItem2->prev; - pItem2->prev = pItem1; - pItem->next = pItem1; - if((pItem2 = pItem1) != NULL) - { - pItem2 = pItem->GetPrevItem(-1); - pItem2->next = pItem->next; - pItem->next->prev = pItem->prev; - pItem->next = NULL; - pItem->prev = NULL; - } - - if(pPrev == NULL) - pPrev = PTR_PTR(&pFirst); - - pItem2 = pPrev->next; - pItem->next = pItem2; - pItem->prev = pItem2->prev; - pItem2->prev = pItem; - pPrev->next = pItem; - - pItem3 = pItem1->parent->child; - pItem2 = pItem->parent; - if(pItem2->child == pItem) - pItem2->child = pItem1; - if(pItem3 == pItem1) - pItem1->parent->child = pItem; - - pItem2 = pItem->parent; - pItem->parent = pItem1->parent; - pItem1->parent = pItem2; - offs0004++; - } -} - -// 1500E920 -unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType) -{ - THTreeItem * pItem1; - THTreeItem * pItem2; - THTreeItem * pItem3; - THTreeItem * pTemp; - unsigned long dwBitBuff; - unsigned int nBits; - unsigned int nBit; - - BuildTree(nCmpType); - bIsCmp0 = (nCmpType == 0); - - // Store the compression type into output buffer - os->dwBitBuff |= (nCmpType << os->nBits); - os->nBits += 8; - - // Flush completed bytes - while(os->nBits >= 8) - { - if(os->cbOutSize != 0) - { - *os->pbOutPos++ = (unsigned char)os->dwBitBuff; - os->cbOutSize--; - } - - os->dwBitBuff >>= 8; - os->nBits -= 8; - } - - for(; nInLength != 0; nInLength--) - { - unsigned char bOneByte = *pbInBuffer++; - - if((pItem1 = items306C[bOneByte]) == NULL) - { - pItem2 = items306C[0x101]; // ecx - pItem3 = pItem2->parent; // eax - dwBitBuff = 0; - nBits = 0; - - for(; pItem3 != NULL; pItem3 = pItem3->parent) - { - nBit = (pItem3->child != pItem2) ? 1 : 0; - dwBitBuff = (dwBitBuff << 1) | nBit; - nBits++; - pItem2 = pItem3; - } - os->PutBits(dwBitBuff, nBits); - - // Store the loaded byte into output stream - os->dwBitBuff |= (bOneByte << os->nBits); - os->nBits += 8; - - // Flush the whole byte(s) - while(os->nBits >= 8) - { - if(os->cbOutSize != 0) - { - *os->pbOutPos++ = (unsigned char)os->dwBitBuff; - os->cbOutSize--; - } - os->dwBitBuff >>= 8; - os->nBits -= 8; - } - - pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast; - pItem2 = Call1500E740(1); - pItem2->dcmpByte = pItem1->dcmpByte; - pItem2->byteValue = pItem1->byteValue; - pItem2->parent = pItem1; - items306C[pItem2->dcmpByte] = pItem2; - - pItem2 = Call1500E740(1); - pItem2->dcmpByte = bOneByte; - pItem2->byteValue = 0; - pItem2->parent = pItem1; - items306C[pItem2->dcmpByte] = pItem2; - pItem1->child = pItem2; - - Call1500E820(pItem2); - - if(bIsCmp0 != 0) - { - Call1500E820(items306C[bOneByte]); - continue; - } - - for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent) - { - pItem1->byteValue++; - pItem2 = pItem1; - - for(;;) - { - pItem3 = pItem2->prev; - if(PTR_INVALID_OR_NULL(pItem3)) - { - pItem3 = NULL; - break; - } - if(pItem3->byteValue >= pItem1->byteValue) - break; - pItem2 = pItem3; - } - - if(pItem2 != pItem1) - { - InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1); - InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3); - - pItem3 = pItem2->parent->child; - if(pItem1->parent->child == pItem1) - pItem1->parent->child = pItem2; - - if(pItem3 == pItem2) - pItem2->parent->child = pItem1; - - pTemp = pItem1->parent; - pItem1->parent = pItem2->parent; - pItem2->parent = pTemp; - offs0004++; - } - } - } -// 1500EB62 - else - { - dwBitBuff = 0; - nBits = 0; - for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent) - { - nBit = (pItem2->child != pItem1) ? 1 : 0; - dwBitBuff = (dwBitBuff << 1) | nBit; - nBits++; - pItem1 = pItem2; - } - os->PutBits(dwBitBuff, nBits); - } - -// 1500EB98 - if(bIsCmp0 != 0) - Call1500E820(items306C[bOneByte]); // 1500EB9D -// 1500EBAF - } // for(; nInLength != 0; nInLength--) - -// 1500EBB8 - pItem1 = items306C[0x100]; - dwBitBuff = 0; - nBits = 0; - for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent) - { - nBit = (pItem2->child != pItem1) ? 1 : 0; - dwBitBuff = (dwBitBuff << 1) | nBit; - nBits++; - pItem1 = pItem2; - } - -// 1500EBE6 - os->PutBits(dwBitBuff, nBits); - -// 1500EBEF - // Flush the remaining bits - while(os->nBits != 0) - { - if(os->cbOutSize != 0) - { - *os->pbOutPos++ = (unsigned char)os->dwBitBuff; - os->cbOutSize--; - } - os->dwBitBuff >>= 8; - os->nBits -= ((os->nBits > 8) ? 8 : os->nBits); - } - - return (unsigned int)(os->pbOutPos - os->pbOutBuffer); -} - -// Decompression using Huffman tree (1500E450) -unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is) -{ - TQDecompress * qd; - THTreeItem * pItem1; - THTreeItem * pItem2; - unsigned char * pbOutPos = pbOutBuffer; - unsigned long nBitCount; - unsigned int nDcmpByte = 0; - unsigned int n8Bits; // 8 bits loaded from input stream - unsigned int n7Bits; // 7 bits loaded from input stream - bool bHasQdEntry; - - // Test the output length. Must not be NULL. - if(dwOutLength == 0) - return 0; - - // Get the compression type from the input stream - n8Bits = is->Get8Bits(); - - // Build the Huffman tree - BuildTree(n8Bits); - bIsCmp0 = (n8Bits == 0) ? 1 : 0; - - for(;;) - { - // Security check: If we are at the end of the input buffer, - // it means that the data is corrupt - if(is->BitCount == 0 && is->pbInBuffer >= is->pbInBufferEnd) - return 0; - - // Get 7 bits from input stream - n7Bits = is->Get7Bits(); - - // Try to use quick decompression. Check TQDecompress array for corresponding item. - // If found, ise the result byte instead. - qd = &qd3474[n7Bits]; - - // If there is a quick-pass possible (ebx) - bHasQdEntry = (qd->offs00 >= offs0004) ? true : false; - - // If we can use quick decompress, use it. - if(bHasQdEntry) - { - if(qd->nBits > 7) - { - is->SkipBits(7); - pItem1 = qd->pItem; - goto _1500E549; - } - is->SkipBits(qd->nBits); - nDcmpByte = qd->dcmpByte; - } - else - { - pItem1 = pFirst->next->prev; - if(PTR_INVALID_OR_NULL(pItem1)) - pItem1 = NULL; -_1500E549: - nBitCount = 0; - pItem2 = NULL; - - do - { - if(pItem1 == NULL) - return 0; - - pItem1 = pItem1->child; // Move down by one level - if(is->GetBit()) // If current bit is set, move to previous - pItem1 = pItem1->prev; - - if(++nBitCount == 7) // If we are at 7th bit, save current HTree item. - pItem2 = pItem1; - } - while(pItem1->child != NULL); // Walk until tree has no deeper level - - if(bHasQdEntry == false) - { - if(nBitCount > 7) - { - qd->offs00 = offs0004; - qd->nBits = nBitCount; - qd->pItem = pItem2; - } - else - { - unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount)); - unsigned long nAdd = (1 << nBitCount); - - for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd) - { - qd->offs00 = offs0004; - qd->nBits = nBitCount; - qd->dcmpByte = pItem1->dcmpByte; - } - } - } - nDcmpByte = pItem1->dcmpByte; - } - - if(nDcmpByte == 0x101) // Huffman tree needs to be modified - { - n8Bits = is->Get8Bits(); - pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast; - - pItem2 = Call1500E740(1); - pItem2->parent = pItem1; - pItem2->dcmpByte = pItem1->dcmpByte; - pItem2->byteValue = pItem1->byteValue; - items306C[pItem2->dcmpByte] = pItem2; - - pItem2 = Call1500E740(1); - pItem2->parent = pItem1; - pItem2->dcmpByte = n8Bits; - pItem2->byteValue = 0; - items306C[pItem2->dcmpByte] = pItem2; - - pItem1->child = pItem2; - Call1500E820(pItem2); - if(bIsCmp0 == 0) - Call1500E820(items306C[n8Bits]); - - nDcmpByte = n8Bits; - } - - if(nDcmpByte == 0x100) - break; - - *pbOutPos++ = (unsigned char)nDcmpByte; - if(--dwOutLength == 0) - break; - - if(bIsCmp0) - Call1500E820(items306C[nDcmpByte]); - } - - return (unsigned int)(pbOutPos - pbOutBuffer); -} - - -// Table for (de)compression. Every compression type has 258 entries -unsigned char THuffmannTree::Table1502A630[] = -{ - // Data for compression type 0x00 - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, - - // Data for compression type 0x01 - 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, - 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, - 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, - 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, - 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, - 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, - 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, - 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, - 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, - 0x00, 0x00, - - // Data for compression type 0x02 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, - 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, - 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, - 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x03 - 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, - 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, - 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, - 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, - 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, - 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, - 0x00, 0x00, - - // Data for compression type 0x04 - 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x05 - 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, - 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, - 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, - 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x06 - 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x07 - 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x08 - 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, - 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, - 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 -}; diff --git a/dep/StormLib/src/huffman/huff.h b/dep/StormLib/src/huffman/huff.h deleted file mode 100644 index 83e9b2cdad0..00000000000 --- a/dep/StormLib/src/huffman/huff.h +++ /dev/null @@ -1,142 +0,0 @@ -/*****************************************************************************/ -/* huffman.h Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Description : */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.xx 1.00 Lad The first version of huffman.h */ -/* 03.05.03 2.00 Lad Added compression */ -/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ -/*****************************************************************************/ - -#ifndef __HUFFMAN_H__ -#define __HUFFMAN_H__ - -#include "../StormPort.h" - -//----------------------------------------------------------------------------- -// Defines - -#define INSERT_ITEM 1 -#define SWITCH_ITEMS 2 // Switch the item1 and item2 - -#define PTR_NOT(ptr) (THTreeItem *)(~(DWORD_PTR)(ptr)) -#define PTR_PTR(ptr) ((THTreeItem *)(ptr)) -#define PTR_INT(ptr) (INT_PTR)(ptr) - -#ifndef NULL -#define NULL 0 -#endif - -//----------------------------------------------------------------------------- -// Structures and classes - -// Input stream for Huffmann decompression -class TInputStream -{ - public: - - unsigned long GetBit(); - unsigned long Get7Bits(); - unsigned long Get8Bits(); - void SkipBits(unsigned int BitCount); - - unsigned char * pbInBuffer; // Input data - unsigned char * pbInBufferEnd; // End of the input buffer - unsigned long BitBuffer; // Input bit buffer - unsigned int BitCount; // Number of bits remaining in 'dwBitBuff' -}; - -// Output stream for Huffmann compression -class TOutputStream -{ - public: - - void PutBits(unsigned long dwBuff, unsigned int nPutBits); - - unsigned char * pbOutBuffer; // 00 : Output buffer - unsigned long cbOutSize; // 04 : Size of output buffer - unsigned char * pbOutPos; // 08 : Current output position - unsigned long dwBitBuff; // 0C : Bit buffer - unsigned long nBits; // 10 : Number of bits in the bit buffer -}; - -// Huffmann tree item (?) -struct THTreeItem -{ - THTreeItem * Call1501DB70(THTreeItem * pLast); - THTreeItem * GetPrevItem(LONG_PTR value); - void ClearItemLinks(); - void RemoveItem(); - - THTreeItem * next; // 00 - Pointer to next THTreeItem - THTreeItem * prev; // 04 - Pointer to prev THTreeItem (< 0 if none) - unsigned long dcmpByte; // 08 - Index of this item in item pointer array, decompressed byte value - unsigned long byteValue; // 0C - Some byte value - THTreeItem * parent; // 10 - Pointer to parent THTreeItem (NULL if none) - THTreeItem * child; // 14 - Pointer to child THTreeItem - int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive -}; - -// Structure used for quick decompress. The 'bitCount' contains number of bits -// and byte value contains result decompressed byte value. -// After each walk through Huffman tree are filled all entries which are -// multiplies of number of bits loaded from input stream. These entries -// contain number of bits and result value. At the next 7 bits is tested this -// structure first. If corresponding entry found, decompression routine will -// not walk through Huffman tree and directly stores output byte to output stream. -struct TQDecompress -{ - unsigned long offs00; // 00 - 1 if resolved - unsigned long nBits; // 04 - Bit count - union - { - unsigned long dcmpByte; // 08 - Byte value for decompress (if bitCount <= 7) - THTreeItem * pItem; // 08 - THTreeItem (if number of bits is greater than 7 - }; -}; - -// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert -// for the decompression, I do not know actually if the class is really a Hufmann -// tree. If someone knows the decompression details, please let me know -class THuffmannTree -{ - public: - - THuffmannTree(); - void InitTree(bool bCompression); - void BuildTree(unsigned int nCmpType); -// void ModifyTree(unsigned long dwIndex); -// void UninitTree(); - -// void Call15007010(Bit32 dwInLength, THTreeItem * item); - THTreeItem * Call1500E740(unsigned int nValue); - void Call1500E820(THTreeItem * pItem); - unsigned int DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType); - unsigned int DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is); - - unsigned long bIsCmp0; // 0000 - 1 if compression type 0 - unsigned long offs0004; // 0004 - Some flag - THTreeItem items0008[0x203]; // 0008 - HTree items - - //- Sometimes used as HTree item ----------- - THTreeItem * pItem3050; // 3050 - Always NULL (?) - THTreeItem * pItem3054; // 3054 - Pointer to Huffman tree item - THTreeItem * pItem3058; // 3058 - Pointer to Huffman tree item (< 0 if invalid) - - //- Sometimes used as HTree item ----------- - THTreeItem * pItem305C; // 305C - Usually NULL - THTreeItem * pFirst; // 3060 - Pointer to top (first) Huffman tree item - THTreeItem * pLast; // 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) - unsigned long nItems; // 3068 - Number of used HTree items - - //------------------------------------------- - THTreeItem * items306C[0x102]; // 306C - THTreeItem pointer array - TQDecompress qd3474[0x80]; // 3474 - Array for quick decompression - int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive - - static unsigned char Table1502A630[];// Some table -}; - -#endif // __HUFFMAN_H__ diff --git a/dep/StormLib/src/huffman/huff_patch.cpp b/dep/StormLib/src/huffman/huff_patch.cpp deleted file mode 100644 index 6176a9b1f77..00000000000 --- a/dep/StormLib/src/huffman/huff_patch.cpp +++ /dev/null @@ -1,1120 +0,0 @@ -/*****************************************************************************/ -/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */ -/*---------------------------------------------------------------------------*/ -/* This module contains Huffmann (de)compression methods */ -/* */ -/* Authors : Ladislav Zezula (ladik@zezula.net) */ -/* ShadowFlare (BlakFlare@hotmail.com) */ -/* */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */ -/* 03.05.03 1.00 Lad Added compression methods */ -/* 19.11.03 1.01 Dan Big endian handling */ -/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ -/*****************************************************************************/ - -#include <assert.h> -#include <string.h> - -#include "huff.h" - -THTreeItem * gcpFirst, * gpFirst, * gcpItem3054, * gpItem3054; - -#define PTR_VALID(ptr) ((ptr) != gcpFirst && (ptr) != gcpItem3054) -#define PTR_INVALID(ptr) (!PTR_VALID(ptr)) -#define PTR_INVALID_OR_NULL(ptr) (0 == (ptr) || PTR_INVALID(ptr)) - -//----------------------------------------------------------------------------- -// Methods of the THTreeItem struct - -// 1501DB70 -THTreeItem * THTreeItem::Call1501DB70(THTreeItem * pLast) -{ - if(pLast == NULL) - pLast = this + 1; - return pLast; -} - -// Gets previous Huffman tree item (?) -THTreeItem * THTreeItem::GetPrevItem(SIntPtr value) -{ - if(PTR_INVALID(prev)) - return PTR_NOT(prev); - - if(value == -1 || PTR_INVALID((THTreeItem *) value)) - value = (SIntPtr)(this - next->prev); - return prev + value; -} - -// 1500F5E0 -void THTreeItem::ClearItemLinks() -{ - next = prev = NULL; -} - -// 1500BC90 -void THTreeItem::RemoveItem() -{ - THTreeItem * pTemp; // EDX - - if(next != NULL) - { - pTemp = prev; - - if(PTR_INVALID(pTemp)) - pTemp = PTR_NOT(pTemp); - else - pTemp += (this - next->prev); - - pTemp->next = next; - next->prev = prev; - next = prev = NULL; - } -} - -//----------------------------------------------------------------------------- -// TOutputStream functions - -void TOutputStream::PutBits(unsigned long dwBuff, unsigned int nPutBits) -{ - dwBitBuff |= (dwBuff << nBits); - nBits += nPutBits; - - // Flush completed bytes - while(nBits >= 8) - { - if(cbOutSize != 0) - { - *pbOutPos++ = (unsigned char)dwBitBuff; - cbOutSize--; - } - - dwBitBuff >>= 8; - nBits -= 8; - } -} - -//----------------------------------------------------------------------------- -// TInputStream functions - -// Gets one bit from input stream -unsigned long TInputStream::GetBit() -{ - unsigned long dwOneBit = 0; - - // Ensure that the input stream is reloaded, if there are no bits left - if(BitCount == 0) - { - // Refill the bit buffer - BitBuffer = *pbInBuffer++; - BitCount = 8; - } - - // Copy the bit from bit buffer to the variable - dwOneBit = (BitBuffer & 0x01); - BitBuffer >>= 1; - BitCount--; - - return dwOneBit; -} - -// Gets 7 bits from the stream. DOES NOT remove the bits from input stream -unsigned long TInputStream::Get7Bits() -{ - unsigned long dwReloadByte = 0; - - // If there is not enough bits to get the value, - // we have to add 8 more bits from the input buffer - if(BitCount < 7) - { - dwReloadByte = *pbInBuffer++; - BitBuffer |= dwReloadByte << BitCount; - BitCount += 8; - } - - // Return the first available 7 bits. DO NOT remove them from the input stream - return (BitBuffer & 0x7F); -} - -// Gets the whole byte from the input stream. -unsigned long TInputStream::Get8Bits() -{ - unsigned long dwReloadByte = 0; - unsigned long dwOneByte = 0; - - // If there is not enough bits to get the value, - // we have to add 8 more bits from the input buffer - if(BitCount < 8) - { - dwReloadByte = *pbInBuffer++; - BitBuffer |= dwReloadByte << BitCount; - BitCount += 8; - } - - // Return the lowest 8 its - dwOneByte = (BitBuffer & 0xFF); - BitBuffer >>= 8; - BitCount -= 8; - return dwOneByte; -} - -void TInputStream::SkipBits(unsigned int dwBitsToSkip) -{ - unsigned long dwReloadByte = 0; - - // If there is not enough bits in the buffer, - // we have to add 8 more bits from the input buffer - if(BitCount < dwBitsToSkip) - { - dwReloadByte = *pbInBuffer++; - BitBuffer |= dwReloadByte << BitCount; - BitCount += 8; - } - - // Skip the remaining bits - BitBuffer >>= dwBitsToSkip; - BitCount -= dwBitsToSkip; -} - -//----------------------------------------------------------------------------- -// Functions for huffmann tree items - -// Inserts item into the tree (?) -static void InsertItem(THTreeItem ** itemPtr, THTreeItem * item, unsigned long where, THTreeItem * item2) -{ - THTreeItem * next = item->next; // EDI - next to the first item - THTreeItem * prev = item->prev; // ESI - prev to the first item - THTreeItem * prev2; // Pointer to previous item - THTreeItem * next2; // Pointer to the next item - - // The same code like in RemoveItem(item); - if(next != 0) // If the first item already has next one - { - if(PTR_INVALID(prev)) - prev = PTR_NOT(prev); - else - prev += (item - next->prev); - - // 150083C1 - // Remove the item from the tree - prev->next = next; - next->prev = prev; - - // Invalidate 'prev' and 'next' pointer - item->next = 0; - item->prev = 0; - } - - if(item2 == NULL) // EDX - If the second item is not entered, - item2 = PTR_PTR(&itemPtr[1]); // take the first tree item - - switch(where) - { - case SWITCH_ITEMS : // Switch the two items - item->next = item2->next; // item2->next (Pointer to pointer to first) - item->prev = item2->next->prev; - item2->next->prev = item; - item2->next = item; // Set the first item - return; - - case INSERT_ITEM: // Insert as the last item - item->next = item2; // Set next item (or pointer to pointer to first item) - item->prev = item2->prev; // Set prev item (or last item in the tree) - - next2 = itemPtr[0];// Usually NULL - prev2 = item2->prev; // Prev item to the second (or last tree item) - - if(PTR_INVALID(prev2)) - { - prev2 = PTR_NOT(prev); - - prev2->next = item; - item2->prev = item; // Next after last item - return; - } - - if(PTR_INVALID(next2)) - next2 = (THTreeItem *)(item2 - item2->next->prev); - - prev2 += (long) next2; - prev2->next = item; - item2->prev = item; // Set the next/last item - return; - - default: - return; - } -} - -//----------------------------------------------------------------------------- -// THuffmannTree class functions - -THuffmannTree::THuffmannTree() -{ -} - -void THuffmannTree::InitTree(bool bCompression) -{ - THTreeItem * pItem; - unsigned int nCount; - - // Clear links for all the items in the tree - for(pItem = items0008, nCount = 0x203; nCount != 0; pItem++, nCount--) - pItem->ClearItemLinks(); - - gcpItem3054 = (THTreeItem *) &gcpItem3054; - pItem3050 = NULL; - pItem3054 = PTR_PTR(&pItem3054); - pItem3058 = gcpItem3054; - gpItem3054 = pItem3054; - - gcpFirst = (THTreeItem *) &gcpFirst; - pItem305C = NULL; - pFirst = PTR_PTR(&pFirst); - pLast = gcpFirst; - gpFirst = pFirst; - - offs0004 = 1; - nItems = 0; - - // Clear all TQDecompress items. Do this only if preparing for decompression - if(bCompression == false) - { - for(nCount = 0; nCount < sizeof(qd3474) / sizeof(TQDecompress); nCount++) - qd3474[nCount].offs00 = 0; - } -} - -// Builds Huffman tree. Called with the first 8 bits loaded from input stream -void THuffmannTree::BuildTree(unsigned int nCmpType) -{ - unsigned long maxByte; // [ESP+10] - The greatest character found in table - THTreeItem ** itemPtr; // [ESP+14] - Pointer to Huffman tree item pointer array - unsigned char * byteArray; // [ESP+1C] - Pointer to unsigned char in Table1502A630 - THTreeItem * child1; - unsigned long i; // egcs in linux doesn't like multiple for loops without an explicit i - - // Loop while pointer has a valid value - while(PTR_VALID(pLast)) // ESI - Last entry - { - THTreeItem * temp; // EAX - - if(pLast->next != NULL) // ESI->next - pLast->RemoveItem(); - // EDI = &offs3054 - pItem3058 = PTR_PTR(&pItem3054); // [EDI+4] - pLast->prev = pItem3058; // EAX - - temp = PTR_PTR(&pItem3054)->GetPrevItem((SIntPtr)(&pItem3050)); - - temp->next = pLast; - pItem3054 = pLast; - } - - // Clear all pointers in HTree item array - memset(items306C, 0, sizeof(items306C)); - - maxByte = 0; // Greatest character found init to zero. - itemPtr = (THTreeItem **)&items306C; // Pointer to current entry in HTree item pointer array - - // Ensure we have low 8 bits only - nCmpType &= 0xFF; - byteArray = Table1502A630 + nCmpType * 258; // EDI also - - for(i = 0; i < 0x100; i++, itemPtr++) - { - THTreeItem * item = pItem3058; // Item to be created - THTreeItem * pItem3 = pItem3058; - unsigned char oneByte = byteArray[i]; - - // Skip all the bytes which are zero. - if(byteArray[i] == 0) - continue; - - // If not valid pointer, take the first available item in the array - if(PTR_INVALID_OR_NULL(item)) - item = &items0008[nItems++]; - - // Insert this item as the top of the tree - InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL); - - item->parent = NULL; // Invalidate child and parent - item->child = NULL; - *itemPtr = item; // Store pointer into pointer array - - item->dcmpByte = i; // Store counter - item->byteValue = oneByte; // Store byte value - if(oneByte >= maxByte) - { - maxByte = oneByte; - continue; - } - - // Find the first item which has byte value greater than current one byte - if(PTR_VALID(pItem3 = pLast)) // EDI - Pointer to the last item - { - // 15006AF7 - if(pItem3 != NULL) - { - do // 15006AFB - { - if(pItem3->byteValue >= oneByte) - goto _15006B09; - pItem3 = pItem3->prev; - } - while(PTR_VALID(pItem3)); - } - } - pItem3 = NULL; - - // 15006B09 - _15006B09: - if(item->next != NULL) - item->RemoveItem(); - - // 15006B15 - if(pItem3 == NULL) - pItem3 = PTR_PTR(&pFirst); - - // 15006B1F - item->next = pItem3->next; - item->prev = pItem3->next->prev; - pItem3->next->prev = item; - pItem3->next = item; - } - - // 15006B4A - for(; i < 0x102; i++) - { - THTreeItem ** itemPtr = &items306C[i]; // EDI - - // 15006B59 - THTreeItem * item = pItem3058; // ESI - if(PTR_INVALID_OR_NULL(item)) - item = &items0008[nItems++]; - - InsertItem(&pItem305C, item, INSERT_ITEM, NULL); - - // 15006B89 - item->dcmpByte = i; - item->byteValue = 1; - item->parent = NULL; - item->child = NULL; - *itemPtr++ = item; - } - - // 15006BAA - if(PTR_VALID(child1 = pLast)) // EDI - last item (first child to item - { - THTreeItem * child2; // EBP - THTreeItem * item; // ESI - - // 15006BB8 - while(PTR_VALID(child2 = child1->prev)) - { - if(PTR_INVALID_OR_NULL(item = pItem3058)) - item = &items0008[nItems++]; - - // 15006BE3 - InsertItem(&pItem305C, item, SWITCH_ITEMS, NULL); - - // 15006BF3 - item->parent = NULL; - item->child = NULL; - - //EDX = child2->byteValue + child1->byteValue; - //EAX = child1->byteValue; - //ECX = maxByte; // The greatest character (0xFF usually) - - item->byteValue = child1->byteValue + child2->byteValue; // 0x02 - item->child = child1; // Prev item in the - child1->parent = item; - child2->parent = item; - - // EAX = item->byteValue; - if(item->byteValue >= maxByte) - maxByte = item->byteValue; - else - { - THTreeItem * pItem2 = child2->prev; // EDI - - // 15006C2D - while(PTR_VALID(pItem2)) - { - if(pItem2->byteValue >= item->byteValue) - goto _15006C3B; - pItem2 = pItem2->prev; - } - pItem2 = NULL; - - _15006C3B: - if(item->next != 0) - { - THTreeItem * temp4 = item->GetPrevItem(-1); - - temp4->next = item->next; // The first item changed - item->next->prev = item->prev; // First->prev changed to negative value - item->next = NULL; - item->prev = NULL; - } - - // 15006C62 - if(pItem2 == NULL) - pItem2 = PTR_PTR(&pFirst); - - item->next = pItem2->next; // Set item with 0x100 byte value - item->prev = pItem2->next->prev; // Set item with 0x17 byte value - pItem2->next->prev = item; // Changed prev of item with - pItem2->next = item; - } - - // 15006C7B - if(PTR_INVALID_OR_NULL(child1 = child2->prev)) - break; - } - } - // 15006C88 - offs0004 = 1; -} - -THTreeItem * THuffmannTree::Call1500E740(unsigned int nValue) -{ - THTreeItem * pItem1 = pItem3058; // EDX - THTreeItem * pItem2; // EAX - THTreeItem * pNext; - THTreeItem * pPrev; - THTreeItem ** ppItem; - - if(PTR_INVALID_OR_NULL(pItem1) || (pItem2 = pItem1) == NULL) - { - if((pItem2 = &items0008[nItems++]) != NULL) - pItem1 = pItem2; - else - pItem1 = pFirst; - } - else - pItem1 = pItem2; - - pNext = pItem1->next; - if(pNext != NULL) - { - pPrev = pItem1->prev; - if(PTR_INVALID(pPrev)) - pPrev = PTR_NOT(pPrev); - else - pPrev += (pItem1 - pItem1->next->prev); - - pPrev->next = pNext; - pNext->prev = pPrev; - pItem1->next = NULL; - pItem1->prev = NULL; - } - - ppItem = &pFirst; // esi - if(nValue > 1) - { - // ecx = pFirst->next; - pItem1->next = *ppItem; - pItem1->prev = (*ppItem)->prev; - - (*ppItem)->prev = pItem2; - *ppItem = pItem1; - - pItem2->parent = NULL; - pItem2->child = NULL; - } - else - { - pItem1->next = (THTreeItem *)ppItem; - pItem1->prev = ppItem[1]; - // edi = pItem305C; - pPrev = ppItem[1]; // ecx - if(PTR_INVALID(pPrev)) - { - pPrev = PTR_NOT(pPrev); - pPrev->next = pItem1; - pPrev->prev = pItem2; - - pItem2->parent = NULL; - pItem2->child = NULL; - } - else - { - if(PTR_INVALID(pItem305C)) - pPrev += (THTreeItem *)ppItem - (*ppItem)->prev; - else - pPrev += (long)pItem305C; - - pPrev->next = pItem1; - ppItem[1] = pItem2; - pItem2->parent = NULL; - pItem2->child = NULL; - } - } - return pItem2; -} - -void THuffmannTree::Call1500E820(THTreeItem * pItem) -{ - THTreeItem * pItem1; // edi - THTreeItem * pItem2 = NULL; // eax - THTreeItem * pItem3; // edx - THTreeItem * pPrev; // ebx - - for(; pItem != NULL; pItem = pItem->parent) - { - pItem->byteValue++; - - for(pItem1 = pItem; ; pItem1 = pPrev) - { - pPrev = pItem1->prev; - if(PTR_INVALID_OR_NULL(pPrev)) - { - pPrev = NULL; - break; - } - - if(pPrev->byteValue >= pItem->byteValue) - break; - } - - if(pItem1 == pItem) - continue; - - if(pItem1->next != NULL) - { - pItem2 = pItem1->GetPrevItem(-1); - pItem2->next = pItem1->next; - pItem1->next->prev = pItem1->prev; - pItem1->next = NULL; - pItem1->prev = NULL; - } - - pItem2 = pItem->next; - pItem1->next = pItem2; - pItem1->prev = pItem2->prev; - pItem2->prev = pItem1; - pItem->next = pItem1; - if((pItem2 = pItem1) != NULL) - { - pItem2 = pItem->GetPrevItem(-1); - pItem2->next = pItem->next; - pItem->next->prev = pItem->prev; - pItem->next = NULL; - pItem->prev = NULL; - } - - if(pPrev == NULL) - pPrev = PTR_PTR(&pFirst); - - pItem2 = pPrev->next; - pItem->next = pItem2; - pItem->prev = pItem2->prev; - pItem2->prev = pItem; - pPrev->next = pItem; - - pItem3 = pItem1->parent->child; - pItem2 = pItem->parent; - if(pItem2->child == pItem) - pItem2->child = pItem1; - if(pItem3 == pItem1) - pItem1->parent->child = pItem; - - pItem2 = pItem->parent; - pItem->parent = pItem1->parent; - pItem1->parent = pItem2; - offs0004++; - } -} - -// 1500E920 -unsigned int THuffmannTree::DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType) -{ - THTreeItem * pItem1; - THTreeItem * pItem2; - THTreeItem * pItem3; - THTreeItem * pTemp; - unsigned long dwBitBuff; - unsigned int nBits; - unsigned int nBit; - - BuildTree(nCmpType); - bIsCmp0 = (nCmpType == 0); - - // Store the compression type into output buffer - os->dwBitBuff |= (nCmpType << os->nBits); - os->nBits += 8; - - // Flush completed bytes - while(os->nBits >= 8) - { - if(os->cbOutSize != 0) - { - *os->pbOutPos++ = (unsigned char)os->dwBitBuff; - os->cbOutSize--; - } - - os->dwBitBuff >>= 8; - os->nBits -= 8; - } - - for(; nInLength != 0; nInLength--) - { - unsigned char bOneByte = *pbInBuffer++; - - if((pItem1 = items306C[bOneByte]) == NULL) - { - pItem2 = items306C[0x101]; // ecx - pItem3 = pItem2->parent; // eax - dwBitBuff = 0; - nBits = 0; - - for(; pItem3 != NULL; pItem3 = pItem3->parent) - { - nBit = (pItem3->child != pItem2) ? 1 : 0; - dwBitBuff = (dwBitBuff << 1) | nBit; - nBits++; - pItem2 = pItem3; - } - os->PutBits(dwBitBuff, nBits); - - // Store the loaded byte into output stream - os->dwBitBuff |= (bOneByte << os->nBits); - os->nBits += 8; - - // Flush the whole byte(s) - while(os->nBits >= 8) - { - if(os->cbOutSize != 0) - { - *os->pbOutPos++ = (unsigned char)os->dwBitBuff; - os->cbOutSize--; - } - os->dwBitBuff >>= 8; - os->nBits -= 8; - } - - pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast; - pItem2 = Call1500E740(1); - pItem2->dcmpByte = pItem1->dcmpByte; - pItem2->byteValue = pItem1->byteValue; - pItem2->parent = pItem1; - items306C[pItem2->dcmpByte] = pItem2; - - pItem2 = Call1500E740(1); - pItem2->dcmpByte = bOneByte; - pItem2->byteValue = 0; - pItem2->parent = pItem1; - items306C[pItem2->dcmpByte] = pItem2; - pItem1->child = pItem2; - - Call1500E820(pItem2); - - if(bIsCmp0 != 0) - { - Call1500E820(items306C[bOneByte]); - continue; - } - - for(pItem1 = items306C[bOneByte]; pItem1 != NULL; pItem1 = pItem1->parent) - { - pItem1->byteValue++; - pItem2 = pItem1; - - for(;;) - { - pItem3 = pItem2->prev; - if(PTR_INVALID_OR_NULL(pItem3)) - { - pItem3 = NULL; - break; - } - if(pItem3->byteValue >= pItem1->byteValue) - break; - pItem2 = pItem3; - } - - if(pItem2 != pItem1) - { - InsertItem(&pItem305C, pItem2, SWITCH_ITEMS, pItem1); - InsertItem(&pItem305C, pItem1, SWITCH_ITEMS, pItem3); - - pItem3 = pItem2->parent->child; - if(pItem1->parent->child == pItem1) - pItem1->parent->child = pItem2; - - if(pItem3 == pItem2) - pItem2->parent->child = pItem1; - - pTemp = pItem1->parent; - pItem1->parent = pItem2->parent; - pItem2->parent = pTemp; - offs0004++; - } - } - } -// 1500EB62 - else - { - dwBitBuff = 0; - nBits = 0; - for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent) - { - nBit = (pItem2->child != pItem1) ? 1 : 0; - dwBitBuff = (dwBitBuff << 1) | nBit; - nBits++; - pItem1 = pItem2; - } - os->PutBits(dwBitBuff, nBits); - } - -// 1500EB98 - if(bIsCmp0 != 0) - Call1500E820(items306C[bOneByte]); // 1500EB9D -// 1500EBAF - } // for(; nInLength != 0; nInLength--) - -// 1500EBB8 - pItem1 = items306C[0x100]; - dwBitBuff = 0; - nBits = 0; - for(pItem2 = pItem1->parent; pItem2 != NULL; pItem2 = pItem2->parent) - { - nBit = (pItem2->child != pItem1) ? 1 : 0; - dwBitBuff = (dwBitBuff << 1) | nBit; - nBits++; - pItem1 = pItem2; - } - -// 1500EBE6 - os->PutBits(dwBitBuff, nBits); - -// 1500EBEF - // Flush the remaining bits - while(os->nBits != 0) - { - if(os->cbOutSize != 0) - { - *os->pbOutPos++ = (unsigned char)os->dwBitBuff; - os->cbOutSize--; - } - os->dwBitBuff >>= 8; - os->nBits -= ((os->nBits > 8) ? 8 : os->nBits); - } - - return (unsigned int)(os->pbOutPos - os->pbOutBuffer); -} - -// Decompression using Huffman tree (1500E450) -unsigned int THuffmannTree::DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is) -{ - TQDecompress * qd; - THTreeItem * pItem1; - THTreeItem * pItem2; - unsigned char * pbOutPos = pbOutBuffer; - unsigned long nBitCount; - unsigned int nDcmpByte = 0; - unsigned int n8Bits; // 8 bits loaded from input stream - unsigned int n7Bits; // 7 bits loaded from input stream - bool bHasQdEntry; - - // Test the output length. Must not be NULL. - if(dwOutLength == 0) - return 0; - - // Get the compression type from the input stream - n8Bits = is->Get8Bits(); - - // Build the Huffman tree - BuildTree(n8Bits); - bIsCmp0 = (n8Bits == 0) ? 1 : 0; - - for(;;) - { - // Security check: If we are at the end of the input buffer, - // it means that the data are corrupt. - if(is->pbInBuffer > is->pbInBufferEnd) - return 0; - - // Get 7 bits from input stream - n7Bits = is->Get7Bits(); - - // Try to use quick decompression. Check TQDecompress array for corresponding item. - // If found, ise the result byte instead. - qd = &qd3474[n7Bits]; - - // If there is a quick-pass possible (ebx) - bHasQdEntry = (qd->offs00 >= offs0004) ? true : false; - - // If we can use quick decompress, use it. - if(bHasQdEntry) - { - if(qd->nBits > 7) - { - is->SkipBits(7); - pItem1 = qd->pItem; - goto _1500E549; - } - is->SkipBits(qd->nBits); - nDcmpByte = qd->dcmpByte; - } - else - { - pItem1 = pFirst->next->prev; - if(PTR_INVALID_OR_NULL(pItem1)) - pItem1 = NULL; -_1500E549: - nBitCount = 0; - pItem2 = NULL; - - do - { - pItem1 = pItem1->child; // Move down by one level - if(is->GetBit()) // If current bit is set, move to previous - pItem1 = pItem1->prev; - - if(++nBitCount == 7) // If we are at 7th bit, save current HTree item. - pItem2 = pItem1; - } - while(pItem1->child != NULL); // Walk until tree has no deeper level - - if(bHasQdEntry == false) - { - if(nBitCount > 7) - { - qd->offs00 = offs0004; - qd->nBits = nBitCount; - qd->pItem = pItem2; - } - else - { - unsigned long nIndex = n7Bits & (0xFFFFFFFF >> (32 - nBitCount)); - unsigned long nAdd = (1 << nBitCount); - - for(qd = &qd3474[nIndex]; nIndex <= 0x7F; nIndex += nAdd, qd += nAdd) - { - qd->offs00 = offs0004; - qd->nBits = nBitCount; - qd->dcmpByte = pItem1->dcmpByte; - } - } - } - nDcmpByte = pItem1->dcmpByte; - } - - if(nDcmpByte == 0x101) // Huffman tree needs to be modified - { - n8Bits = is->Get8Bits(); - pItem1 = (PTR_INVALID_OR_NULL(pLast)) ? NULL : pLast; - - pItem2 = Call1500E740(1); - pItem2->parent = pItem1; - pItem2->dcmpByte = pItem1->dcmpByte; - pItem2->byteValue = pItem1->byteValue; - items306C[pItem2->dcmpByte] = pItem2; - - pItem2 = Call1500E740(1); - pItem2->parent = pItem1; - pItem2->dcmpByte = n8Bits; - pItem2->byteValue = 0; - items306C[pItem2->dcmpByte] = pItem2; - - pItem1->child = pItem2; - Call1500E820(pItem2); - if(bIsCmp0 == 0) - Call1500E820(items306C[n8Bits]); - - nDcmpByte = n8Bits; - } - - if(nDcmpByte == 0x100) - break; - - *pbOutPos++ = (unsigned char)nDcmpByte; - if(--dwOutLength == 0) - break; - - if(bIsCmp0) - Call1500E820(items306C[nDcmpByte]); - } - - return (unsigned int)(pbOutPos - pbOutBuffer); -} - - -// Table for (de)compression. Every compression type has 258 entries -unsigned char THuffmannTree::Table1502A630[] = -{ - // Data for compression type 0x00 - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, - - // Data for compression type 0x01 - 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, - 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, - 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, - 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, - 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, - 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, - 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, - 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, - 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, - 0x00, 0x00, - - // Data for compression type 0x02 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, - 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, - 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, - 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x03 - 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, - 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, - 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, - 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, - 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, - 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, - 0x00, 0x00, - - // Data for compression type 0x04 - 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x05 - 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, - 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, - 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, - 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x06 - 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x07 - 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - // Data for compression type 0x08 - 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, - 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, - 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 -}; diff --git a/dep/StormLib/src/huffman/huff_patch.h b/dep/StormLib/src/huffman/huff_patch.h deleted file mode 100644 index c1c03e67860..00000000000 --- a/dep/StormLib/src/huffman/huff_patch.h +++ /dev/null @@ -1,145 +0,0 @@ -/*****************************************************************************/ -/* huffman.h Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Description : */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.xx 1.00 Lad The first version of huffman.h */ -/* 03.05.03 2.00 Lad Added compression */ -/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ -/*****************************************************************************/ - -#ifndef __HUFFMAN_H__ -#define __HUFFMAN_H__ - -#include <stdint.h> - -#define SIntPtr intptr_t - -//----------------------------------------------------------------------------- -// Defines - -#define INSERT_ITEM 1 -#define SWITCH_ITEMS 2 // Switch the item1 and item2 - -#define PTR_NOT(ptr) ((ptr) == gcpFirst ? gpFirst : gpItem3054) -#define PTR_PTR(ptr) ((THTreeItem *)(ptr)) - -#ifndef NULL -#define NULL 0 -#endif - -//----------------------------------------------------------------------------- -// Structures and classes - -// Input stream for Huffmann decompression -class TInputStream -{ - public: - - unsigned long GetBit(); - unsigned long Get7Bits(); - unsigned long Get8Bits(); - void SkipBits(unsigned int BitCount); - - unsigned char * pbInBuffer; // Input data - unsigned char * pbInBufferEnd; // End of the input buffer - unsigned long BitBuffer; // Input bit buffer - unsigned int BitCount; // Number of bits remaining in 'dwBitBuff' -}; - -// Output stream for Huffmann compression -class TOutputStream -{ - public: - - void PutBits(unsigned long dwBuff, unsigned int nPutBits); - - unsigned char * pbOutBuffer; // 00 : Output buffer - unsigned long cbOutSize; // 04 : Size of output buffer - unsigned char * pbOutPos; // 08 : Current output position - unsigned long dwBitBuff; // 0C : Bit buffer - unsigned long nBits; // 10 : Number of bits in the bit buffer -}; - -// Huffmann tree item (?) -struct THTreeItem -{ - public: - - THTreeItem * Call1501DB70(THTreeItem * pLast); - THTreeItem * GetPrevItem(SIntPtr value); - void ClearItemLinks(); - void RemoveItem(); - - THTreeItem * next; // 00 - Pointer to next THTreeItem - THTreeItem * prev; // 04 - Pointer to prev THTreeItem (< 0 if none) - unsigned long dcmpByte; // 08 - Index of this item in item pointer array, decompressed byte value - unsigned long byteValue; // 0C - Some byte value - THTreeItem * parent; // 10 - Pointer to parent THTreeItem (NULL if none) - THTreeItem * child; // 14 - Pointer to child THTreeItem - int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive -}; - -// Structure used for quick decompress. The 'bitCount' contains number of bits -// and byte value contains result decompressed byte value. -// After each walk through Huffman tree are filled all entries which are -// multiplies of number of bits loaded from input stream. These entries -// contain number of bits and result value. At the next 7 bits is tested this -// structure first. If corresponding entry found, decompression routine will -// not walk through Huffman tree and directly stores output byte to output stream. -struct TQDecompress -{ - unsigned long offs00; // 00 - 1 if resolved - unsigned long nBits; // 04 - Bit count - union - { - unsigned long dcmpByte; // 08 - Byte value for decompress (if bitCount <= 7) - THTreeItem * pItem; // 08 - THTreeItem (if number of bits is greater than 7 - }; -}; - -// Structure for Huffman tree (Size 0x3674 bytes). Because I'm not expert -// for the decompression, I do not know actually if the class is really a Hufmann -// tree. If someone knows the decompression details, please let me know -class THuffmannTree -{ - public: - - THuffmannTree(); - void InitTree(bool bCompression); - void BuildTree(unsigned int nCmpType); -// void ModifyTree(unsigned long dwIndex); -// void UninitTree(); - -// void Call15007010(Bit32 dwInLength, THTreeItem * item); - THTreeItem * Call1500E740(unsigned int nValue); - void Call1500E820(THTreeItem * pItem); - unsigned int DoCompression(TOutputStream * os, unsigned char * pbInBuffer, int nInLength, int nCmpType); - unsigned int DoDecompression(unsigned char * pbOutBuffer, unsigned int dwOutLength, TInputStream * is); - - unsigned long bIsCmp0; // 0000 - 1 if compression type 0 - unsigned long offs0004; // 0004 - Some flag - THTreeItem items0008[0x203]; // 0008 - HTree items - - //- Sometimes used as HTree item ----------- - THTreeItem * pItem3050; // 3050 - Always NULL (?) - THTreeItem * pItem3054; // 3054 - Pointer to Huffman tree item - THTreeItem * pItem3058; // 3058 - Pointer to Huffman tree item (< 0 if invalid) - - //- Sometimes used as HTree item ----------- - THTreeItem * pItem305C; // 305C - Usually NULL - THTreeItem * pFirst; // 3060 - Pointer to top (first) Huffman tree item - THTreeItem * pLast; // 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) - unsigned long nItems; // 3068 - Number of used HTree items - - //------------------------------------------- - THTreeItem * items306C[0x102]; // 306C - THTreeItem pointer array - TQDecompress qd3474[0x80]; // 3474 - Array for quick decompression - int addressMultiplier; // -1 if object on negative address (>0x80000000), +1 if positive - - static unsigned char Table1502A630[];// Some table -}; - -#endif // __HUFFMAN_H__ diff --git a/dep/StormLib/src/jenkins/lookup.h b/dep/StormLib/src/jenkins/lookup.h deleted file mode 100644 index 54ccc979ca6..00000000000 --- a/dep/StormLib/src/jenkins/lookup.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __LOOKUP3_H__ -#define __LOOKUP3_H__ - -#ifdef WIN32 -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -#else -#include <stdint.h> /* defines uint32_t etc */ -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -uint32_t hashlittle(const void *key, size_t length, uint32_t initval); -void hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb); - -#ifdef __cplusplus -} -#endif - -#endif // __LOOKUP3_H__ diff --git a/dep/StormLib/src/jenkins/lookup3.c b/dep/StormLib/src/jenkins/lookup3.c deleted file mode 100644 index 6af56b481ad..00000000000 --- a/dep/StormLib/src/jenkins/lookup3.c +++ /dev/null @@ -1,1003 +0,0 @@ -/* -------------------------------------------------------------------------------- -lookup3.c, by Bob Jenkins, May 2006, Public Domain. - -These are functions for producing 32-bit hashes for hash table lookup. -hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() -are externally useful functions. Routines to test the hash are included -if SELF_TEST is defined. You can use this free for any purpose. It's in -the public domain. It has no warranty. - -You probably want to use hashlittle(). hashlittle() and hashbig() -hash byte arrays. hashlittle() is is faster than hashbig() on -little-endian machines. Intel and AMD are little-endian machines. -On second thought, you probably want hashlittle2(), which is identical to -hashlittle() except it returns two 32-bit hashes for the price of one. -You could implement hashbig2() if you wanted but I haven't bothered here. - -If you want to find a hash of, say, exactly 7 integers, do - a = i1; b = i2; c = i3; - mix(a,b,c); - a += i4; b += i5; c += i6; - mix(a,b,c); - a += i7; - final(a,b,c); -then use c as the hash value. If you have a variable length array of -4-byte integers to hash, use hashword(). If you have a byte array (like -a character string), use hashlittle(). If you have several byte arrays, or -a mix of things, see the comments above hashlittle(). - -Why is this so big? I read 12 bytes at a time into 3 4-byte integers, -then mix those integers. This is fast (you can do a lot more thorough -mixing with 12*3 instructions on 3 integers than you can with 3 instructions -on 1 byte), but shoehorning those bytes into integers efficiently is messy. -------------------------------------------------------------------------------- -*/ -//#define SELF_TEST 1 - -#include <stdio.h> /* defines printf for tests */ -#include <time.h> /* defines time_t for timings in the test */ - -#ifdef linux -#include <sys/param.h> /* attempt to define endianness */ -#include <endian.h> /* attempt to define endianness */ -#endif - -#include "lookup.h" - -/* - * My best guess at if you are big-endian or little-endian. This may - * need adjustment. - */ -#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ - __BYTE_ORDER == __LITTLE_ENDIAN) || \ - (defined(i386) || defined(__i386__) || defined(__i486__) || \ - defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 -#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ - __BYTE_ORDER == __BIG_ENDIAN) || \ - (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 -#else -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 0 -#endif - -#define hashsize(n) ((uint32_t)1<<(n)) -#define hashmask(n) (hashsize(n)-1) -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -/* -------------------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. - -This is reversible, so any information in (a,b,c) before mix() is -still in (a,b,c) after mix(). - -If four pairs of (a,b,c) inputs are run through mix(), or through -mix() in reverse, there are at least 32 bits of the output that -are sometimes the same for one pair and different for another pair. -This was tested for: -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that -satisfy this are - 4 6 8 16 19 4 - 9 15 3 18 27 15 - 14 9 3 7 17 3 -Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing -for "differ" defined as + with a one-bit base and a two-bit delta. I -used http://burtleburtle.net/bob/hash/avalanche.html to choose -the operations, constants, and arrangements of the variables. - -This does not achieve avalanche. There are input bits of (a,b,c) -that fail to affect some output bits of (a,b,c), especially of a. The -most thoroughly mixed value is c, but it doesn't really even achieve -avalanche in c. - -This allows some parallelism. Read-after-writes are good at doubling -the number of bits affected, so the goal of mixing pulls in the opposite -direction as the goal of parallelism. I did what I could. Rotates -seem to cost as much as shifts on every machine I could lay my hands -on, and rotates are much kinder to the top and bottom bits, so I used -rotates. -------------------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/* -------------------------------------------------------------------------------- -final -- final mixing of 3 32-bit values (a,b,c) into c - -Pairs of (a,b,c) values differing in only a few bits will usually -produce values of c that look totally different. This was tested for -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -These constants passed: - 14 11 25 16 4 14 24 - 12 14 25 16 4 14 24 -and these came close: - 4 8 15 26 3 22 24 - 10 8 15 26 3 22 24 - 11 8 15 26 3 22 24 -------------------------------------------------------------------------------- -*/ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - -/* --------------------------------------------------------------------- - This works on all machines. To be useful, it requires - -- that the key be an array of uint32_t's, and - -- that the length be the number of uint32_t's in the key - - The function hashword() is identical to hashlittle() on little-endian - machines, and identical to hashbig() on big-endian machines, - except that the length has to be measured in uint32_ts rather than in - bytes. hashlittle() is more complicated than hashword() only because - hashlittle() has to dance around fitting the key bytes into registers. --------------------------------------------------------------------- -*/ -uint32_t hashword( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t initval) /* the previous hash, or an arbitrary value */ -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; - - /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } - - /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } - /*------------------------------------------------------ report the result */ - return c; -} - - -/* --------------------------------------------------------------------- -hashword2() -- same as hashword(), but take two seeds and return two -32-bit values. pc and pb must both be nonnull, and *pc and *pb must -both be initialized with seeds. If you pass in (*pb)==0, the output -(*pc) will be the same as the return value from hashword(). --------------------------------------------------------------------- -*/ -void hashword2 ( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t *pc, /* IN: seed OUT: primary hash value */ -uint32_t *pb) /* IN: more seed OUT: secondary hash value */ -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; - c += *pb; - - /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } - - /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } - /*------------------------------------------------------ report the result */ - *pc=c; *pb=b; -} - - -/* -------------------------------------------------------------------------------- -hashlittle() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - length : the length of the key, counting by bytes - initval : can be any 4-byte value -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Two keys differing by one or two bits will have -totally different hash values. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (uint8_t **)k, do it like this: - for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h); - -By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this -code any way you wish, private, educational, or commercial. It's free. - -Use for hash table lookup, or anything where one collision in 2^^32 is -acceptable. Do NOT use for cryptographic purposes. -------------------------------------------------------------------------------- -*/ - -uint32_t hashlittle( const void *key, size_t length, uint32_t initval) -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : return c; - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - - -/* - * hashlittle2: return 2 32-bit hash values - * - * This is identical to hashlittle(), except it returns two 32-bit hash - * values instead of just one. This is good enough for hash table - * lookup with 2^^64 buckets, or if you want a second hash if you're not - * happy with the first, or if you want a probably-unique 64-bit ID for - * the key. *pc is better mixed than *pb, so use *pc first. If you want - * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". - */ -void hashlittle2( - const void *key, /* the key to hash */ - size_t length, /* length of the key */ - uint32_t *pc, /* IN: primary initval, OUT: primary hash */ - uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; - c += *pb; - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - } - - final(a,b,c); - *pc=c; *pb=b; -} - - - -/* - * hashbig(): - * This is the same as hashword() on big-endian machines. It is different - * from hashlittle() on all machines. hashbig() takes advantage of - * big-endian byte ordering. - */ -uint32_t hashbig( const void *key, size_t length, uint32_t initval) -{ - uint32_t a,b,c; - union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; - - u.ptr = key; - if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]<<8" actually reads beyond the end of the string, but - * then shifts out the part it's not allowed to read. Because the - * string is aligned, the illegal read is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; - case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; - case 5 : b+=k[1]&0xff000000; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff00; break; - case 2 : a+=k[0]&0xffff0000; break; - case 1 : a+=k[0]&0xff000000; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ - case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ - case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ - case 1 : a+=((uint32_t)k8[0])<<24; break; - case 0 : return c; - } - -#endif /* !VALGRIND */ - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += ((uint32_t)k[0])<<24; - a += ((uint32_t)k[1])<<16; - a += ((uint32_t)k[2])<<8; - a += ((uint32_t)k[3]); - b += ((uint32_t)k[4])<<24; - b += ((uint32_t)k[5])<<16; - b += ((uint32_t)k[6])<<8; - b += ((uint32_t)k[7]); - c += ((uint32_t)k[8])<<24; - c += ((uint32_t)k[9])<<16; - c += ((uint32_t)k[10])<<8; - c += ((uint32_t)k[11]); - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[11]; - case 11: c+=((uint32_t)k[10])<<8; - case 10: c+=((uint32_t)k[9])<<16; - case 9 : c+=((uint32_t)k[8])<<24; - case 8 : b+=k[7]; - case 7 : b+=((uint32_t)k[6])<<8; - case 6 : b+=((uint32_t)k[5])<<16; - case 5 : b+=((uint32_t)k[4])<<24; - case 4 : a+=k[3]; - case 3 : a+=((uint32_t)k[2])<<8; - case 2 : a+=((uint32_t)k[1])<<16; - case 1 : a+=((uint32_t)k[0])<<24; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - - -#ifdef SELF_TEST - -/* used for timings */ -void driver1() -{ - uint8_t buf[256]; - uint32_t i; - uint32_t h=0; - time_t a,z; - - time(&a); - for (i=0; i<256; ++i) buf[i] = 'x'; - for (i=0; i<1; ++i) - { - h = hashlittle(&buf[0],1,h); - } - time(&z); - if (z-a > 0) printf("time %d %.8x\n", z-a, h); -} - -/* check that every input bit changes every output bit half the time */ -#define HASHSTATE 1 -#define HASHLEN 1 -#define MAXPAIR 60 -#define MAXLEN 70 -void driver2() -{ - uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; - uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; - uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; - uint32_t x[HASHSTATE],y[HASHSTATE]; - uint32_t hlen; - - printf("No more than %d trials should ever be needed \n",MAXPAIR/2); - for (hlen=0; hlen < MAXLEN; ++hlen) - { - z=0; - for (i=0; i<hlen; ++i) /*----------------------- for each input byte, */ - { - for (j=0; j<8; ++j) /*------------------------ for each input bit, */ - { - for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */ - { - for (l=0; l<HASHSTATE; ++l) - e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0); - - /*---- check that every output bit is affected by that input bit */ - for (k=0; k<MAXPAIR; k+=2) - { - uint32_t finished=1; - /* keys have one bit different */ - for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8_t)0;} - /* have a and b be two keys differing in only one bit */ - a[i] ^= (k<<j); - a[i] ^= (k>>(8-j)); - c[0] = hashlittle(a, hlen, m); - b[i] ^= ((k+1)<<j); - b[i] ^= ((k+1)>>(8-j)); - d[0] = hashlittle(b, hlen, m); - /* check every bit is 1, 0, set, and not set at least once */ - for (l=0; l<HASHSTATE; ++l) - { - e[l] &= (c[l]^d[l]); - f[l] &= ~(c[l]^d[l]); - g[l] &= c[l]; - h[l] &= ~c[l]; - x[l] &= d[l]; - y[l] &= ~d[l]; - if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0; - } - if (finished) break; - } - if (k>z) z=k; - if (k==MAXPAIR) - { - printf("Some bit didn't change: "); - printf("%.8x %.8x %.8x %.8x %.8x %.8x ", - e[0],f[0],g[0],h[0],x[0],y[0]); - printf("i %d j %d m %d len %d\n", i, j, m, hlen); - } - if (z==MAXPAIR) goto done; - } - } - } - done: - if (z < MAXPAIR) - { - printf("Mix success %2d bytes %2d initvals ",i,m); - printf("required %d trials\n", z/2); - } - } - printf("\n"); -} - -/* Check for reading beyond the end of the buffer and alignment problems */ -void driver3() -{ - uint8_t buf[MAXLEN+20], *b; - uint32_t len; - uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; - uint32_t h; - uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; - uint32_t i; - uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; - uint32_t j; - uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; - uint32_t ref,x,y; - uint8_t *p; - - printf("Endianness. These lines should all be the same (for values filled in):\n"); - printf("%.8x %.8x %.8x\n", - hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13), - hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13), - hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13)); - p = q; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qq[1]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqq[2]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqqq[3]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - printf("\n"); - - /* check that hashlittle2 and hashlittle produce the same results */ - i=47; j=0; - hashlittle2(q, sizeof(q), &i, &j); - if (hashlittle(q, sizeof(q), 47) != i) - printf("hashlittle2 and hashlittle mismatch\n"); - - /* check that hashword2 and hashword produce the same results */ - len = 0xdeadbeef; - i=47, j=0; - hashword2(&len, 1, &i, &j); - if (hashword(&len, 1, 47) != i) - printf("hashword2 and hashword mismatch %x %x\n", - i, hashword(&len, 1, 47)); - - /* check hashlittle doesn't read before or after the ends of the string */ - for (h=0, b=buf+1; h<8; ++h, ++b) - { - for (i=0; i<MAXLEN; ++i) - { - len = i; - for (j=0; j<i; ++j) *(b+j)=0; - - /* these should all be equal */ - ref = hashlittle(b, len, (uint32_t)1); - *(b+i)=(uint8_t)~0; - *(b-1)=(uint8_t)~0; - x = hashlittle(b, len, (uint32_t)1); - y = hashlittle(b, len, (uint32_t)1); - if ((ref != x) || (ref != y)) - { - printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y, - h, i); - } - } - } -} - -/* check for problems with nulls */ - void driver4() -{ - uint8_t buf[1]; - uint32_t h,i,state[HASHSTATE]; - - - buf[0] = ~0; - for (i=0; i<HASHSTATE; ++i) state[i] = 1; - printf("These should all be different\n"); - for (i=0, h=0; i<8; ++i) - { - h = hashlittle(buf, 0, h); - printf("%2ld 0-byte strings, hash is %.8x\n", i, h); - } -} - -void driver5() -{ - uint32_t b,c; - b=0, c=0, hashlittle2("", 0, &c, &b); - printf("hash is %.8lx %.8lx\n", c, b); /* deadbeef deadbeef */ - b=0xdeadbeef, c=0, hashlittle2("", 0, &c, &b); - printf("hash is %.8lx %.8lx\n", c, b); /* bd5b7dde deadbeef */ - b=0xdeadbeef, c=0xdeadbeef, hashlittle2("", 0, &c, &b); - printf("hash is %.8lx %.8lx\n", c, b); /* 9c093ccd bd5b7dde */ - b=0, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b); - printf("hash is %.8lx %.8lx\n", c, b); /* 17770551 ce7226e6 */ - b=1, c=0, hashlittle2("Four score and seven years ago", 30, &c, &b); - printf("hash is %.8lx %.8lx\n", c, b); /* e3607cae bd371de4 */ - b=0, c=1, hashlittle2("Four score and seven years ago", 30, &c, &b); - printf("hash is %.8lx %.8lx\n", c, b); /* cd628161 6cbea4b3 */ - c = hashlittle("Four score and seven years ago", 30, 0); - printf("hash is %.8lx\n", c); /* 17770551 */ - c = hashlittle("Four score and seven years ago", 30, 1); - printf("hash is %.8lx\n", c); /* cd628161 */ -} - - -int main() -{ - driver1(); /* test that the key is hashed: used for timings */ - driver2(); /* test that whole key is hashed thoroughly */ - driver3(); /* test that nothing but the key is hashed */ - driver4(); /* test hashing multiple buffers (all buffers are null) */ - driver5(); /* test the hash against known vectors */ - return 1; -} - -#endif /* SELF_TEST */ diff --git a/dep/StormLib/src/libtomcrypt/src/hashes/hash_memory.c b/dep/StormLib/src/libtomcrypt/src/hashes/hash_memory.c deleted file mode 100644 index 1daf0bffa1b..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/hashes/hash_memory.c +++ /dev/null @@ -1,69 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file hash_memory.c - Hash memory helper, Tom St Denis -*/ - -/** - Hash a block of memory and store the digest. - @param hash The index of the hash you wish to use - @param in The data you wish to hash - @param inlen The length of the data to hash (octets) - @param out [out] Where to store the digest - @param outlen [in/out] Max size and resulting size of the digest - @return CRYPT_OK if successful -*/ -int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) -{ - hash_state *md; - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - if ((err = hash_is_valid(hash)) != CRYPT_OK) { - return err; - } - - if (*outlen < hash_descriptor[hash].hashsize) { - *outlen = hash_descriptor[hash].hashsize; - return CRYPT_BUFFER_OVERFLOW; - } - - md = XMALLOC(sizeof(hash_state)); - if (md == NULL) { - return CRYPT_MEM; - } - - if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) { - goto LBL_ERR; - } - err = hash_descriptor[hash].done(md, out); - *outlen = hash_descriptor[hash].hashsize; -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(md, sizeof(hash_state)); -#endif - XFREE(md); - - return err; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/hashes/md5.c b/dep/StormLib/src/libtomcrypt/src/hashes/md5.c deleted file mode 100644 index 4cbd000c0d4..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/hashes/md5.c +++ /dev/null @@ -1,368 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - - -/** - @file md5.c - LTC_MD5 hash function by Tom St Denis -*/ - -#ifdef LTC_MD5 - -const struct ltc_hash_descriptor md5_desc = -{ - "md5", - 3, - 16, - 64, - - /* OID */ - { 1, 2, 840, 113549, 2, 5, }, - 6, - - &md5_init, - &md5_process, - &md5_done, - &md5_test, - NULL -}; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define G(x,y,z) (y ^ (z & (y ^ x))) -#define H(x,y,z) (x^y^z) -#define I(x,y,z) (y^(x|(~z))) - -#ifdef LTC_SMALL_CODE - -#define FF(a,b,c,d,M,s,t) \ - a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b; - -#define GG(a,b,c,d,M,s,t) \ - a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b; - -#define HH(a,b,c,d,M,s,t) \ - a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b; - -#define II(a,b,c,d,M,s,t) \ - a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; - -static const unsigned char Worder[64] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, - 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, - 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, - 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 -}; - -static const unsigned char Rorder[64] = { - 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, - 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, - 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, - 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21 -}; - -static const ulong32 Korder[64] = { -0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, -0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL, -0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, -0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL, -0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL, -0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, -0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL, -0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL -}; - -#else - -#define FF(a,b,c,d,M,s,t) \ - a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define GG(a,b,c,d,M,s,t) \ - a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define HH(a,b,c,d,M,s,t) \ - a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define II(a,b,c,d,M,s,t) \ - a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; - - -#endif - -#ifdef LTC_CLEAN_STACK -static int _md5_compress(hash_state *md, unsigned char *buf) -#else -static int md5_compress(hash_state *md, unsigned char *buf) -#endif -{ - ulong32 i, W[16], a, b, c, d; -#ifdef LTC_SMALL_CODE - ulong32 t; -#endif - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD32L(W[i], buf + (4*i)); - } - - /* copy state */ - a = md->md5.state[0]; - b = md->md5.state[1]; - c = md->md5.state[2]; - d = md->md5.state[3]; - -#ifdef LTC_SMALL_CODE - for (i = 0; i < 16; ++i) { - FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); - t = d; d = c; c = b; b = a; a = t; - } - - for (; i < 32; ++i) { - GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); - t = d; d = c; c = b; b = a; a = t; - } - - for (; i < 48; ++i) { - HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); - t = d; d = c; c = b; b = a; a = t; - } - - for (; i < 64; ++i) { - II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); - t = d; d = c; c = b; b = a; a = t; - } - -#else - FF(a,b,c,d,W[0],7,0xd76aa478UL) - FF(d,a,b,c,W[1],12,0xe8c7b756UL) - FF(c,d,a,b,W[2],17,0x242070dbUL) - FF(b,c,d,a,W[3],22,0xc1bdceeeUL) - FF(a,b,c,d,W[4],7,0xf57c0fafUL) - FF(d,a,b,c,W[5],12,0x4787c62aUL) - FF(c,d,a,b,W[6],17,0xa8304613UL) - FF(b,c,d,a,W[7],22,0xfd469501UL) - FF(a,b,c,d,W[8],7,0x698098d8UL) - FF(d,a,b,c,W[9],12,0x8b44f7afUL) - FF(c,d,a,b,W[10],17,0xffff5bb1UL) - FF(b,c,d,a,W[11],22,0x895cd7beUL) - FF(a,b,c,d,W[12],7,0x6b901122UL) - FF(d,a,b,c,W[13],12,0xfd987193UL) - FF(c,d,a,b,W[14],17,0xa679438eUL) - FF(b,c,d,a,W[15],22,0x49b40821UL) - GG(a,b,c,d,W[1],5,0xf61e2562UL) - GG(d,a,b,c,W[6],9,0xc040b340UL) - GG(c,d,a,b,W[11],14,0x265e5a51UL) - GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) - GG(a,b,c,d,W[5],5,0xd62f105dUL) - GG(d,a,b,c,W[10],9,0x02441453UL) - GG(c,d,a,b,W[15],14,0xd8a1e681UL) - GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) - GG(a,b,c,d,W[9],5,0x21e1cde6UL) - GG(d,a,b,c,W[14],9,0xc33707d6UL) - GG(c,d,a,b,W[3],14,0xf4d50d87UL) - GG(b,c,d,a,W[8],20,0x455a14edUL) - GG(a,b,c,d,W[13],5,0xa9e3e905UL) - GG(d,a,b,c,W[2],9,0xfcefa3f8UL) - GG(c,d,a,b,W[7],14,0x676f02d9UL) - GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) - HH(a,b,c,d,W[5],4,0xfffa3942UL) - HH(d,a,b,c,W[8],11,0x8771f681UL) - HH(c,d,a,b,W[11],16,0x6d9d6122UL) - HH(b,c,d,a,W[14],23,0xfde5380cUL) - HH(a,b,c,d,W[1],4,0xa4beea44UL) - HH(d,a,b,c,W[4],11,0x4bdecfa9UL) - HH(c,d,a,b,W[7],16,0xf6bb4b60UL) - HH(b,c,d,a,W[10],23,0xbebfbc70UL) - HH(a,b,c,d,W[13],4,0x289b7ec6UL) - HH(d,a,b,c,W[0],11,0xeaa127faUL) - HH(c,d,a,b,W[3],16,0xd4ef3085UL) - HH(b,c,d,a,W[6],23,0x04881d05UL) - HH(a,b,c,d,W[9],4,0xd9d4d039UL) - HH(d,a,b,c,W[12],11,0xe6db99e5UL) - HH(c,d,a,b,W[15],16,0x1fa27cf8UL) - HH(b,c,d,a,W[2],23,0xc4ac5665UL) - II(a,b,c,d,W[0],6,0xf4292244UL) - II(d,a,b,c,W[7],10,0x432aff97UL) - II(c,d,a,b,W[14],15,0xab9423a7UL) - II(b,c,d,a,W[5],21,0xfc93a039UL) - II(a,b,c,d,W[12],6,0x655b59c3UL) - II(d,a,b,c,W[3],10,0x8f0ccc92UL) - II(c,d,a,b,W[10],15,0xffeff47dUL) - II(b,c,d,a,W[1],21,0x85845dd1UL) - II(a,b,c,d,W[8],6,0x6fa87e4fUL) - II(d,a,b,c,W[15],10,0xfe2ce6e0UL) - II(c,d,a,b,W[6],15,0xa3014314UL) - II(b,c,d,a,W[13],21,0x4e0811a1UL) - II(a,b,c,d,W[4],6,0xf7537e82UL) - II(d,a,b,c,W[11],10,0xbd3af235UL) - II(c,d,a,b,W[2],15,0x2ad7d2bbUL) - II(b,c,d,a,W[9],21,0xeb86d391UL) -#endif - - md->md5.state[0] = md->md5.state[0] + a; - md->md5.state[1] = md->md5.state[1] + b; - md->md5.state[2] = md->md5.state[2] + c; - md->md5.state[3] = md->md5.state[3] + d; - - return CRYPT_OK; -} - -#ifdef LTC_CLEAN_STACK -static int md5_compress(hash_state *md, unsigned char *buf) -{ - int err; - err = _md5_compress(md, buf); - burn_stack(sizeof(ulong32) * 21); - return err; -} -#endif - -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int md5_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - md->md5.state[0] = 0x67452301UL; - md->md5.state[1] = 0xefcdab89UL; - md->md5.state[2] = 0x98badcfeUL; - md->md5.state[3] = 0x10325476UL; - md->md5.curlen = 0; - md->md5.length = 0; - return CRYPT_OK; -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return CRYPT_OK if successful -*/ -HASH_PROCESS(md5_process, md5_compress, md5, 64) - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (16 bytes) - @return CRYPT_OK if successful -*/ -int md5_done(hash_state * md, unsigned char *out) -{ - int i; - - LTC_ARGCHK(md != NULL); - LTC_ARGCHK(out != NULL); - - if (md->md5.curlen >= sizeof(md->md5.buf)) { - return CRYPT_INVALID_ARG; - } - - - /* increase the length of the message */ - md->md5.length += md->md5.curlen * 8; - - /* append the '1' bit */ - md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->md5.curlen > 56) { - while (md->md5.curlen < 64) { - md->md5.buf[md->md5.curlen++] = (unsigned char)0; - } - md5_compress(md, md->md5.buf); - md->md5.curlen = 0; - } - - /* pad upto 56 bytes of zeroes */ - while (md->md5.curlen < 56) { - md->md5.buf[md->md5.curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64L(md->md5.length, md->md5.buf+56); - md5_compress(md, md->md5.buf); - - /* copy output */ - for (i = 0; i < 4; i++) { - STORE32L(md->md5.state[i], out+(4*i)); - } -#ifdef LTC_CLEAN_STACK - zeromem(md, sizeof(hash_state)); -#endif - return CRYPT_OK; -} - -/** - Self-test the hash - @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled -*/ -int md5_test(void) -{ - #ifndef LTC_TEST - return CRYPT_NOP; - #else - static const struct { - char *msg; - unsigned char hash[16]; - } tests[] = { - { "", - { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, - 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, - { "a", - {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, - 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, - { "abc", - { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, - 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, - { "message digest", - { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, - 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, - { "abcdefghijklmnopqrstuvwxyz", - { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, - 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, - 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, - { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", - { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, - 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, - { NULL, { 0 } } - }; - - int i; - unsigned char tmp[16]; - hash_state md; - - for (i = 0; tests[i].msg != NULL; i++) { - md5_init(&md); - md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); - md5_done(&md, tmp); - if (XMEMCMP(tmp, tests[i].hash, 16) != 0) { - return CRYPT_FAIL_TESTVECTOR; - } - } - return CRYPT_OK; - #endif -} - -#endif - - - -/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ -/* $Revision: 1.10 $ */ -/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/hashes/sha1.c b/dep/StormLib/src/libtomcrypt/src/hashes/sha1.c deleted file mode 100644 index 409d0954241..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/hashes/sha1.c +++ /dev/null @@ -1,288 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file sha1.c - LTC_SHA1 code by Tom St Denis -*/ - - -#ifdef LTC_SHA1 - -const struct ltc_hash_descriptor sha1_desc = -{ - "sha1", - 2, - 20, - 64, - - /* OID */ - { 1, 3, 14, 3, 2, 26, }, - 6, - - &sha1_init, - &sha1_process, - &sha1_done, - &sha1_test, - NULL -}; - -#define F0(x,y,z) (z ^ (x & (y ^ z))) -#define F1(x,y,z) (x ^ y ^ z) -#define F2(x,y,z) ((x & y) | (z & (x | y))) -#define F3(x,y,z) (x ^ y ^ z) - -#ifdef LTC_CLEAN_STACK -static int _sha1_compress(hash_state *md, unsigned char *buf) -#else -static int sha1_compress(hash_state *md, unsigned char *buf) -#endif -{ - ulong32 a,b,c,d,e,W[80],i; -#ifdef LTC_SMALL_CODE - ulong32 t; -#endif - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD32H(W[i], buf + (4*i)); - } - - /* copy state */ - a = md->sha1.state[0]; - b = md->sha1.state[1]; - c = md->sha1.state[2]; - d = md->sha1.state[3]; - e = md->sha1.state[4]; - - /* expand it */ - for (i = 16; i < 80; i++) { - W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); - } - - /* compress */ - /* round one */ - #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); - #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); - #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); - #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); - -#ifdef LTC_SMALL_CODE - - for (i = 0; i < 20; ) { - FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; - } - - for (; i < 40; ) { - FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; - } - - for (; i < 60; ) { - FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; - } - - for (; i < 80; ) { - FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; - } - -#else - - for (i = 0; i < 20; ) { - FF0(a,b,c,d,e,i++); - FF0(e,a,b,c,d,i++); - FF0(d,e,a,b,c,i++); - FF0(c,d,e,a,b,i++); - FF0(b,c,d,e,a,i++); - } - - /* round two */ - for (; i < 40; ) { - FF1(a,b,c,d,e,i++); - FF1(e,a,b,c,d,i++); - FF1(d,e,a,b,c,i++); - FF1(c,d,e,a,b,i++); - FF1(b,c,d,e,a,i++); - } - - /* round three */ - for (; i < 60; ) { - FF2(a,b,c,d,e,i++); - FF2(e,a,b,c,d,i++); - FF2(d,e,a,b,c,i++); - FF2(c,d,e,a,b,i++); - FF2(b,c,d,e,a,i++); - } - - /* round four */ - for (; i < 80; ) { - FF3(a,b,c,d,e,i++); - FF3(e,a,b,c,d,i++); - FF3(d,e,a,b,c,i++); - FF3(c,d,e,a,b,i++); - FF3(b,c,d,e,a,i++); - } -#endif - - #undef FF0 - #undef FF1 - #undef FF2 - #undef FF3 - - /* store */ - md->sha1.state[0] = md->sha1.state[0] + a; - md->sha1.state[1] = md->sha1.state[1] + b; - md->sha1.state[2] = md->sha1.state[2] + c; - md->sha1.state[3] = md->sha1.state[3] + d; - md->sha1.state[4] = md->sha1.state[4] + e; - - return CRYPT_OK; -} - -#ifdef LTC_CLEAN_STACK -static int sha1_compress(hash_state *md, unsigned char *buf) -{ - int err; - err = _sha1_compress(md, buf); - burn_stack(sizeof(ulong32) * 87); - return err; -} -#endif - -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int sha1_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - md->sha1.state[0] = 0x67452301UL; - md->sha1.state[1] = 0xefcdab89UL; - md->sha1.state[2] = 0x98badcfeUL; - md->sha1.state[3] = 0x10325476UL; - md->sha1.state[4] = 0xc3d2e1f0UL; - md->sha1.curlen = 0; - md->sha1.length = 0; - return CRYPT_OK; -} - -/** - Process a block of memory though the hash - @param md The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return CRYPT_OK if successful -*/ -HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) - -/** - Terminate the hash to get the digest - @param md The hash state - @param out [out] The destination of the hash (20 bytes) - @return CRYPT_OK if successful -*/ -int sha1_done(hash_state * md, unsigned char *out) -{ - int i; - - LTC_ARGCHK(md != NULL); - LTC_ARGCHK(out != NULL); - - if (md->sha1.curlen >= sizeof(md->sha1.buf)) { - return CRYPT_INVALID_ARG; - } - - /* increase the length of the message */ - md->sha1.length += md->sha1.curlen * 8; - - /* append the '1' bit */ - md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->sha1.curlen > 56) { - while (md->sha1.curlen < 64) { - md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; - } - sha1_compress(md, md->sha1.buf); - md->sha1.curlen = 0; - } - - /* pad upto 56 bytes of zeroes */ - while (md->sha1.curlen < 56) { - md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64H(md->sha1.length, md->sha1.buf+56); - sha1_compress(md, md->sha1.buf); - - /* copy output */ - for (i = 0; i < 5; i++) { - STORE32H(md->sha1.state[i], out+(4*i)); - } -#ifdef LTC_CLEAN_STACK - zeromem(md, sizeof(hash_state)); -#endif - return CRYPT_OK; -} - -/** - Self-test the hash - @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled -*/ -int sha1_test(void) -{ - #ifndef LTC_TEST - return CRYPT_NOP; - #else - static const struct { - char *msg; - unsigned char hash[20]; - } tests[] = { - { "abc", - { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, - 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, - 0x9c, 0xd0, 0xd8, 0x9d } - }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, - 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, - 0xE5, 0x46, 0x70, 0xF1 } - } - }; - - int i; - unsigned char tmp[20]; - hash_state md; - - for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { - sha1_init(&md); - sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); - sha1_done(&md, tmp); - if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { - return CRYPT_FAIL_TESTVECTOR; - } - } - return CRYPT_OK; - #endif -} - -#endif - - - -/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ -/* $Revision: 1.10 $ */ -/* $Date: 2007/05/12 14:25:28 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt.h deleted file mode 100644 index 74cdff47549..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef TOMCRYPT_H_ -#define TOMCRYPT_H_ -#include <assert.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <time.h> -#include <ctype.h> -#include <limits.h> - -/* use configuration data */ -#include "tomcrypt_custom.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* version */ -#define CRYPT 0x0117 -#define SCRYPT "1.17" - -/* max size of either a cipher/hash block or symmetric key [largest of the two] */ -#define MAXBLOCKSIZE 128 - -/* descriptor table size */ -#define TAB_SIZE 32 - -/* error codes [will be expanded in future releases] */ -enum { - CRYPT_OK=0, /* Result OK */ - CRYPT_ERROR, /* Generic Error */ - CRYPT_NOP, /* Not a failure but no operation was performed */ - - CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ - CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ - CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ - - CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ - CRYPT_INVALID_PACKET, /* Invalid input packet given */ - - CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ - CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ - - CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ - CRYPT_INVALID_HASH, /* Invalid hash specified */ - CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ - - CRYPT_MEM, /* Out of memory */ - - CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ - CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ - - CRYPT_INVALID_ARG, /* Generic invalid argument */ - CRYPT_FILE_NOTFOUND, /* File Not Found */ - - CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ - CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ - CRYPT_PK_DUP, /* Duplicate key already in key ring */ - CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ - CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ - - CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ - CRYPT_PK_INVALID_PADDING /* Invalid padding on input */ -}; - -#include "tomcrypt_cfg.h" -#include "tomcrypt_macros.h" -#include "tomcrypt_cipher.h" -#include "tomcrypt_hash.h" -#include "tomcrypt_mac.h" -#include "tomcrypt_prng.h" -#include "tomcrypt_pk.h" -#include "tomcrypt_math.h" -#include "tomcrypt_misc.h" -#include "tomcrypt_argchk.h" -#include "tomcrypt_pkcs.h" - -#ifdef __cplusplus - } -#endif - -#endif /* TOMCRYPT_H_ */ - - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt.h,v $ */ -/* $Revision: 1.21 $ */ -/* $Date: 2006/12/16 19:34:05 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h deleted file mode 100644 index cfc93ad7ea6..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_argchk.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Defines the LTC_ARGCHK macro used within the library */ -/* ARGTYPE is defined in mycrypt_cfg.h */ -#if ARGTYPE == 0 - -#include <signal.h> - -/* this is the default LibTomCrypt macro */ -void crypt_argchk(char *v, char *s, int d); -#define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } -#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) - -#elif ARGTYPE == 1 - -/* fatal type of error */ -#define LTC_ARGCHK(x) assert((x)) -#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) - -#elif ARGTYPE == 2 - -#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); } -#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) - -#elif ARGTYPE == 3 - -#define LTC_ARGCHK(x) -#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) - -#elif ARGTYPE == 4 - -#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG; -#define LTC_ARGCHKVD(x) if (!(x)) return; - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_argchk.h,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/08/27 20:50:21 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h deleted file mode 100644 index 7feae6e8bdc..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cfg.h +++ /dev/null @@ -1,136 +0,0 @@ -/* This is the build config file. - * - * With this you can setup what to inlcude/exclude automatically during any build. Just comment - * out the line that #define's the word for the thing you want to remove. phew! - */ - -#ifndef TOMCRYPT_CFG_H -#define TOMCRYPT_CFG_H - -#if defined(_WIN32) || defined(_MSC_VER) -#define LTC_CALL __cdecl -#else -#ifndef LTC_CALL - #define LTC_CALL -#endif -#endif - -#ifndef LTC_EXPORT -#define LTC_EXPORT -#endif - -/* certain platforms use macros for these, making the prototypes broken */ -#ifndef LTC_NO_PROTOTYPES - -/* you can change how memory allocation works ... */ -LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); -LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n); -LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s); -LTC_EXPORT void LTC_CALL XFREE(void *p); - -LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); - - -/* change the clock function too */ -LTC_EXPORT clock_t LTC_CALL XCLOCK(void); - -/* various other functions */ -LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n); -LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n); -LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n); - -LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); - -#endif - -/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */ -#ifndef ARGTYPE - #define ARGTYPE 0 -#endif - -/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code - * - * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes. - * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** - * use the portable [slower] macros. - */ - -/* detect x86-32 machines somewhat */ -#if !defined(__STRICT_ANSI__) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__)))) - #define ENDIAN_LITTLE - #define ENDIAN_32BITWORD - #define LTC_FAST - #define LTC_FAST_TYPE unsigned long -#endif - -/* detects MIPS R5900 processors (PS2) */ -#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) - #define ENDIAN_LITTLE - #define ENDIAN_64BITWORD -#endif - -/* detect amd64 */ -#if !defined(__STRICT_ANSI__) && defined(__x86_64__) - #define ENDIAN_LITTLE - #define ENDIAN_64BITWORD - #define LTC_FAST - #define LTC_FAST_TYPE unsigned long -#endif - -/* detect PPC32 */ -#if !defined(__STRICT_ANSI__) && defined(LTC_PPC32) - #define ENDIAN_BIG - #define ENDIAN_32BITWORD - #define LTC_FAST - #define LTC_FAST_TYPE unsigned long -#endif - -/* detect sparc and sparc64 */ -#if defined(__sparc__) - #define ENDIAN_BIG - #if defined(__arch64__) - #define ENDIAN_64BITWORD - #else - #define ENDIAN_32BITWORD - #endif -#endif - - -#ifdef LTC_NO_FAST - #ifdef LTC_FAST - #undef LTC_FAST - #endif -#endif - -/* No asm is a quick way to disable anything "not portable" */ -#ifdef LTC_NO_ASM - #undef ENDIAN_LITTLE - #undef ENDIAN_BIG - #undef ENDIAN_32BITWORD - #undef ENDIAN_64BITWORD - #undef LTC_FAST - #undef LTC_FAST_TYPE - #define LTC_NO_ROLC - #define LTC_NO_BSWAP -#endif - -/* #define ENDIAN_LITTLE */ -/* #define ENDIAN_BIG */ - -/* #define ENDIAN_32BITWORD */ -/* #define ENDIAN_64BITWORD */ - -#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) - #error You must specify a word size as well as endianess in tomcrypt_cfg.h -#endif - -#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) - #define ENDIAN_NEUTRAL -#endif - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cfg.h,v $ */ -/* $Revision: 1.19 $ */ -/* $Date: 2006/12/04 02:19:48 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h deleted file mode 100644 index bd740bf4a0c..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_cipher.h +++ /dev/null @@ -1,891 +0,0 @@ -/* ---- SYMMETRIC KEY STUFF ----- - * - * We put each of the ciphers scheduled keys in their own structs then we put all of - * the key formats in one union. This makes the function prototypes easier to use. - */ -#ifdef LTC_BLOWFISH -struct blowfish_key { - ulong32 S[4][256]; - ulong32 K[18]; -}; -#endif - -#ifdef LTC_RC5 -struct rc5_key { - int rounds; - ulong32 K[50]; -}; -#endif - -#ifdef LTC_RC6 -struct rc6_key { - ulong32 K[44]; -}; -#endif - -#ifdef LTC_SAFERP -struct saferp_key { - unsigned char K[33][16]; - long rounds; -}; -#endif - -#ifdef LTC_RIJNDAEL -struct rijndael_key { - ulong32 eK[60], dK[60]; - int Nr; -}; -#endif - -#ifdef LTC_KSEED -struct kseed_key { - ulong32 K[32], dK[32]; -}; -#endif - -#ifdef LTC_KASUMI -struct kasumi_key { - ulong32 KLi1[8], KLi2[8], - KOi1[8], KOi2[8], KOi3[8], - KIi1[8], KIi2[8], KIi3[8]; -}; -#endif - -#ifdef LTC_XTEA -struct xtea_key { - unsigned long A[32], B[32]; -}; -#endif - -#ifdef LTC_TWOFISH -#ifndef LTC_TWOFISH_SMALL - struct twofish_key { - ulong32 S[4][256], K[40]; - }; -#else - struct twofish_key { - ulong32 K[40]; - unsigned char S[32], start; - }; -#endif -#endif - -#ifdef LTC_SAFER -#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6 -#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10 -#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8 -#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10 -#define LTC_SAFER_MAX_NOF_ROUNDS 13 -#define LTC_SAFER_BLOCK_LEN 8 -#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS)) -typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN]; -typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN]; -struct safer_key { safer_key_t key; }; -#endif - -#ifdef LTC_RC2 -struct rc2_key { unsigned xkey[64]; }; -#endif - -#ifdef LTC_DES -struct des_key { - ulong32 ek[32], dk[32]; -}; - -struct des3_key { - ulong32 ek[3][32], dk[3][32]; -}; -#endif - -#ifdef LTC_CAST5 -struct cast5_key { - ulong32 K[32], keylen; -}; -#endif - -#ifdef LTC_NOEKEON -struct noekeon_key { - ulong32 K[4], dK[4]; -}; -#endif - -#ifdef LTC_SKIPJACK -struct skipjack_key { - unsigned char key[10]; -}; -#endif - -#ifdef LTC_KHAZAD -struct khazad_key { - ulong64 roundKeyEnc[8 + 1]; - ulong64 roundKeyDec[8 + 1]; -}; -#endif - -#ifdef LTC_ANUBIS -struct anubis_key { - int keyBits; - int R; - ulong32 roundKeyEnc[18 + 1][4]; - ulong32 roundKeyDec[18 + 1][4]; -}; -#endif - -#ifdef LTC_MULTI2 -struct multi2_key { - int N; - ulong32 uk[8]; -}; -#endif - -typedef union Symmetric_key { -#ifdef LTC_DES - struct des_key des; - struct des3_key des3; -#endif -#ifdef LTC_RC2 - struct rc2_key rc2; -#endif -#ifdef LTC_SAFER - struct safer_key safer; -#endif -#ifdef LTC_TWOFISH - struct twofish_key twofish; -#endif -#ifdef LTC_BLOWFISH - struct blowfish_key blowfish; -#endif -#ifdef LTC_RC5 - struct rc5_key rc5; -#endif -#ifdef LTC_RC6 - struct rc6_key rc6; -#endif -#ifdef LTC_SAFERP - struct saferp_key saferp; -#endif -#ifdef LTC_RIJNDAEL - struct rijndael_key rijndael; -#endif -#ifdef LTC_XTEA - struct xtea_key xtea; -#endif -#ifdef LTC_CAST5 - struct cast5_key cast5; -#endif -#ifdef LTC_NOEKEON - struct noekeon_key noekeon; -#endif -#ifdef LTC_SKIPJACK - struct skipjack_key skipjack; -#endif -#ifdef LTC_KHAZAD - struct khazad_key khazad; -#endif -#ifdef LTC_ANUBIS - struct anubis_key anubis; -#endif -#ifdef LTC_KSEED - struct kseed_key kseed; -#endif -#ifdef LTC_KASUMI - struct kasumi_key kasumi; -#endif -#ifdef LTC_MULTI2 - struct multi2_key multi2; -#endif - void *data; -} symmetric_key; - -#ifdef LTC_ECB_MODE -/** A block cipher ECB structure */ -typedef struct { - /** The index of the cipher chosen */ - int cipher, - /** The block size of the given cipher */ - blocklen; - /** The scheduled key */ - symmetric_key key; -} symmetric_ECB; -#endif - -#ifdef LTC_CFB_MODE -/** A block cipher CFB structure */ -typedef struct { - /** The index of the cipher chosen */ - int cipher, - /** The block size of the given cipher */ - blocklen, - /** The padding offset */ - padlen; - /** The current IV */ - unsigned char IV[MAXBLOCKSIZE], - /** The pad used to encrypt/decrypt */ - pad[MAXBLOCKSIZE]; - /** The scheduled key */ - symmetric_key key; -} symmetric_CFB; -#endif - -#ifdef LTC_OFB_MODE -/** A block cipher OFB structure */ -typedef struct { - /** The index of the cipher chosen */ - int cipher, - /** The block size of the given cipher */ - blocklen, - /** The padding offset */ - padlen; - /** The current IV */ - unsigned char IV[MAXBLOCKSIZE]; - /** The scheduled key */ - symmetric_key key; -} symmetric_OFB; -#endif - -#ifdef LTC_CBC_MODE -/** A block cipher CBC structure */ -typedef struct { - /** The index of the cipher chosen */ - int cipher, - /** The block size of the given cipher */ - blocklen; - /** The current IV */ - unsigned char IV[MAXBLOCKSIZE]; - /** The scheduled key */ - symmetric_key key; -} symmetric_CBC; -#endif - - -#ifdef LTC_CTR_MODE -/** A block cipher CTR structure */ -typedef struct { - /** The index of the cipher chosen */ - int cipher, - /** The block size of the given cipher */ - blocklen, - /** The padding offset */ - padlen, - /** The mode (endianess) of the CTR, 0==little, 1==big */ - mode, - /** counter width */ - ctrlen; - - /** The counter */ - unsigned char ctr[MAXBLOCKSIZE], - /** The pad used to encrypt/decrypt */ - pad[MAXBLOCKSIZE]; - /** The scheduled key */ - symmetric_key key; -} symmetric_CTR; -#endif - - -#ifdef LTC_LRW_MODE -/** A LRW structure */ -typedef struct { - /** The index of the cipher chosen (must be a 128-bit block cipher) */ - int cipher; - - /** The current IV */ - unsigned char IV[16], - - /** the tweak key */ - tweak[16], - - /** The current pad, it's the product of the first 15 bytes against the tweak key */ - pad[16]; - - /** The scheduled symmetric key */ - symmetric_key key; - -#ifdef LRW_TABLES - /** The pre-computed multiplication table */ - unsigned char PC[16][256][16]; -#endif -} symmetric_LRW; -#endif - -#ifdef LTC_F8_MODE -/** A block cipher F8 structure */ -typedef struct { - /** The index of the cipher chosen */ - int cipher, - /** The block size of the given cipher */ - blocklen, - /** The padding offset */ - padlen; - /** The current IV */ - unsigned char IV[MAXBLOCKSIZE], - MIV[MAXBLOCKSIZE]; - /** Current block count */ - ulong32 blockcnt; - /** The scheduled key */ - symmetric_key key; -} symmetric_F8; -#endif - - -/** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ -extern struct ltc_cipher_descriptor { - /** name of cipher */ - char *name; - /** internal ID */ - unsigned char ID; - /** min keysize (octets) */ - int min_key_length, - /** max keysize (octets) */ - max_key_length, - /** block size (octets) */ - block_length, - /** default number of rounds */ - default_rounds; - /** Setup the cipher - @param key The input symmetric key - @param keylen The length of the input key (octets) - @param num_rounds The requested number of rounds (0==default) - @param skey [out] The destination of the scheduled key - @return CRYPT_OK if successful - */ - int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); - /** Encrypt a block - @param pt The plaintext - @param ct [out] The ciphertext - @param skey The scheduled key - @return CRYPT_OK if successful - */ - int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); - /** Decrypt a block - @param ct The ciphertext - @param pt [out] The plaintext - @param skey The scheduled key - @return CRYPT_OK if successful - */ - int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); - /** Test the block cipher - @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled - */ - int (*test)(void); - - /** Terminate the context - @param skey The scheduled key - */ - void (*done)(symmetric_key *skey); - - /** Determine a key size - @param keysize [in/out] The size of the key desired and the suggested size - @return CRYPT_OK if successful - */ - int (*keysize)(int *keysize); - -/** Accelerators **/ - /** Accelerated ECB encryption - @param pt Plaintext - @param ct Ciphertext - @param blocks The number of complete blocks to process - @param skey The scheduled key context - @return CRYPT_OK if successful - */ - int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); - - /** Accelerated ECB decryption - @param pt Plaintext - @param ct Ciphertext - @param blocks The number of complete blocks to process - @param skey The scheduled key context - @return CRYPT_OK if successful - */ - int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); - - /** Accelerated CBC encryption - @param pt Plaintext - @param ct Ciphertext - @param blocks The number of complete blocks to process - @param IV The initial value (input/output) - @param skey The scheduled key context - @return CRYPT_OK if successful - */ - int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); - - /** Accelerated CBC decryption - @param pt Plaintext - @param ct Ciphertext - @param blocks The number of complete blocks to process - @param IV The initial value (input/output) - @param skey The scheduled key context - @return CRYPT_OK if successful - */ - int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); - - /** Accelerated CTR encryption - @param pt Plaintext - @param ct Ciphertext - @param blocks The number of complete blocks to process - @param IV The initial value (input/output) - @param mode little or big endian counter (mode=0 or mode=1) - @param skey The scheduled key context - @return CRYPT_OK if successful - */ - int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); - - /** Accelerated LRW - @param pt Plaintext - @param ct Ciphertext - @param blocks The number of complete blocks to process - @param IV The initial value (input/output) - @param tweak The LRW tweak - @param skey The scheduled key context - @return CRYPT_OK if successful - */ - int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); - - /** Accelerated LRW - @param ct Ciphertext - @param pt Plaintext - @param blocks The number of complete blocks to process - @param IV The initial value (input/output) - @param tweak The LRW tweak - @param skey The scheduled key context - @return CRYPT_OK if successful - */ - int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); - - /** Accelerated CCM packet (one-shot) - @param key The secret key to use - @param keylen The length of the secret key (octets) - @param uskey A previously scheduled key [optional can be NULL] - @param nonce The session nonce [use once] - @param noncelen The length of the nonce - @param header The header for the session - @param headerlen The length of the header (octets) - @param pt [out] The plaintext - @param ptlen The length of the plaintext (octets) - @param ct [out] The ciphertext - @param tag [out] The destination tag - @param taglen [in/out] The max size and resulting size of the authentication tag - @param direction Encrypt or Decrypt direction (0 or 1) - @return CRYPT_OK if successful - */ - int (*accel_ccm_memory)( - const unsigned char *key, unsigned long keylen, - symmetric_key *uskey, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen, - unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen, - int direction); - - /** Accelerated GCM packet (one shot) - @param key The secret key - @param keylen The length of the secret key - @param IV The initial vector - @param IVlen The length of the initial vector - @param adata The additional authentication data (header) - @param adatalen The length of the adata - @param pt The plaintext - @param ptlen The length of the plaintext (ciphertext length is the same) - @param ct The ciphertext - @param tag [out] The MAC tag - @param taglen [in/out] The MAC tag length - @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) - @return CRYPT_OK on success - */ - int (*accel_gcm_memory)( - const unsigned char *key, unsigned long keylen, - const unsigned char *IV, unsigned long IVlen, - const unsigned char *adata, unsigned long adatalen, - unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen, - int direction); - - /** Accelerated one shot LTC_OMAC - @param key The secret key - @param keylen The key length (octets) - @param in The message - @param inlen Length of message (octets) - @param out [out] Destination for tag - @param outlen [in/out] Initial and final size of out - @return CRYPT_OK on success - */ - int (*omac_memory)( - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); - - /** Accelerated one shot XCBC - @param key The secret key - @param keylen The key length (octets) - @param in The message - @param inlen Length of message (octets) - @param out [out] Destination for tag - @param outlen [in/out] Initial and final size of out - @return CRYPT_OK on success - */ - int (*xcbc_memory)( - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); - - /** Accelerated one shot F9 - @param key The secret key - @param keylen The key length (octets) - @param in The message - @param inlen Length of message (octets) - @param out [out] Destination for tag - @param outlen [in/out] Initial and final size of out - @return CRYPT_OK on success - @remark Requires manual padding - */ - int (*f9_memory)( - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -} cipher_descriptor[]; - -#ifdef LTC_BLOWFISH -int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int blowfish_test(void); -void blowfish_done(symmetric_key *skey); -int blowfish_keysize(int *keysize); -extern const struct ltc_cipher_descriptor blowfish_desc; -#endif - -#ifdef LTC_RC5 -int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int rc5_test(void); -void rc5_done(symmetric_key *skey); -int rc5_keysize(int *keysize); -extern const struct ltc_cipher_descriptor rc5_desc; -#endif - -#ifdef LTC_RC6 -int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int rc6_test(void); -void rc6_done(symmetric_key *skey); -int rc6_keysize(int *keysize); -extern const struct ltc_cipher_descriptor rc6_desc; -#endif - -#ifdef LTC_RC2 -int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int rc2_test(void); -void rc2_done(symmetric_key *skey); -int rc2_keysize(int *keysize); -extern const struct ltc_cipher_descriptor rc2_desc; -#endif - -#ifdef LTC_SAFERP -int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int saferp_test(void); -void saferp_done(symmetric_key *skey); -int saferp_keysize(int *keysize); -extern const struct ltc_cipher_descriptor saferp_desc; -#endif - -#ifdef LTC_SAFER -int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); -int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); -int safer_k64_test(void); -int safer_sk64_test(void); -int safer_sk128_test(void); -void safer_done(symmetric_key *skey); -int safer_64_keysize(int *keysize); -int safer_128_keysize(int *keysize); -extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; -#endif - -#ifdef LTC_RIJNDAEL - -/* make aes an alias */ -#define aes_setup rijndael_setup -#define aes_ecb_encrypt rijndael_ecb_encrypt -#define aes_ecb_decrypt rijndael_ecb_decrypt -#define aes_test rijndael_test -#define aes_done rijndael_done -#define aes_keysize rijndael_keysize - -#define aes_enc_setup rijndael_enc_setup -#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt -#define aes_enc_keysize rijndael_enc_keysize - -int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int rijndael_test(void); -void rijndael_done(symmetric_key *skey); -int rijndael_keysize(int *keysize); -int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -void rijndael_enc_done(symmetric_key *skey); -int rijndael_enc_keysize(int *keysize); -extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; -extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; -#endif - -#ifdef LTC_XTEA -int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int xtea_test(void); -void xtea_done(symmetric_key *skey); -int xtea_keysize(int *keysize); -extern const struct ltc_cipher_descriptor xtea_desc; -#endif - -#ifdef LTC_TWOFISH -int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int twofish_test(void); -void twofish_done(symmetric_key *skey); -int twofish_keysize(int *keysize); -extern const struct ltc_cipher_descriptor twofish_desc; -#endif - -#ifdef LTC_DES -int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int des_test(void); -void des_done(symmetric_key *skey); -int des_keysize(int *keysize); -int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int des3_test(void); -void des3_done(symmetric_key *skey); -int des3_keysize(int *keysize); -extern const struct ltc_cipher_descriptor des_desc, des3_desc; -#endif - -#ifdef LTC_CAST5 -int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int cast5_test(void); -void cast5_done(symmetric_key *skey); -int cast5_keysize(int *keysize); -extern const struct ltc_cipher_descriptor cast5_desc; -#endif - -#ifdef LTC_NOEKEON -int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int noekeon_test(void); -void noekeon_done(symmetric_key *skey); -int noekeon_keysize(int *keysize); -extern const struct ltc_cipher_descriptor noekeon_desc; -#endif - -#ifdef LTC_SKIPJACK -int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int skipjack_test(void); -void skipjack_done(symmetric_key *skey); -int skipjack_keysize(int *keysize); -extern const struct ltc_cipher_descriptor skipjack_desc; -#endif - -#ifdef LTC_KHAZAD -int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int khazad_test(void); -void khazad_done(symmetric_key *skey); -int khazad_keysize(int *keysize); -extern const struct ltc_cipher_descriptor khazad_desc; -#endif - -#ifdef LTC_ANUBIS -int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int anubis_test(void); -void anubis_done(symmetric_key *skey); -int anubis_keysize(int *keysize); -extern const struct ltc_cipher_descriptor anubis_desc; -#endif - -#ifdef LTC_KSEED -int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int kseed_test(void); -void kseed_done(symmetric_key *skey); -int kseed_keysize(int *keysize); -extern const struct ltc_cipher_descriptor kseed_desc; -#endif - -#ifdef LTC_KASUMI -int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int kasumi_test(void); -void kasumi_done(symmetric_key *skey); -int kasumi_keysize(int *keysize); -extern const struct ltc_cipher_descriptor kasumi_desc; -#endif - - -#ifdef LTC_MULTI2 -int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int multi2_test(void); -void multi2_done(symmetric_key *skey); -int multi2_keysize(int *keysize); -extern const struct ltc_cipher_descriptor multi2_desc; -#endif - -#ifdef LTC_ECB_MODE -int ecb_start(int cipher, const unsigned char *key, - int keylen, int num_rounds, symmetric_ECB *ecb); -int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb); -int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb); -int ecb_done(symmetric_ECB *ecb); -#endif - -#ifdef LTC_CFB_MODE -int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, - int keylen, int num_rounds, symmetric_CFB *cfb); -int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); -int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); -int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb); -int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb); -int cfb_done(symmetric_CFB *cfb); -#endif - -#ifdef LTC_OFB_MODE -int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, - int keylen, int num_rounds, symmetric_OFB *ofb); -int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); -int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); -int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb); -int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb); -int ofb_done(symmetric_OFB *ofb); -#endif - -#ifdef LTC_CBC_MODE -int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, - int keylen, int num_rounds, symmetric_CBC *cbc); -int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc); -int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc); -int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc); -int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc); -int cbc_done(symmetric_CBC *cbc); -#endif - -#ifdef LTC_CTR_MODE - -#define CTR_COUNTER_LITTLE_ENDIAN 0x0000 -#define CTR_COUNTER_BIG_ENDIAN 0x1000 -#define LTC_CTR_RFC3686 0x2000 - -int ctr_start( int cipher, - const unsigned char *IV, - const unsigned char *key, int keylen, - int num_rounds, int ctr_mode, - symmetric_CTR *ctr); -int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); -int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); -int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr); -int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr); -int ctr_done(symmetric_CTR *ctr); -int ctr_test(void); -#endif - -#ifdef LTC_LRW_MODE - -#define LRW_ENCRYPT 0 -#define LRW_DECRYPT 1 - -int lrw_start( int cipher, - const unsigned char *IV, - const unsigned char *key, int keylen, - const unsigned char *tweak, - int num_rounds, - symmetric_LRW *lrw); -int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw); -int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw); -int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw); -int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw); -int lrw_done(symmetric_LRW *lrw); -int lrw_test(void); - -/* don't call */ -int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw); -#endif - -#ifdef LTC_F8_MODE -int f8_start( int cipher, const unsigned char *IV, - const unsigned char *key, int keylen, - const unsigned char *salt_key, int skeylen, - int num_rounds, symmetric_F8 *f8); -int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); -int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); -int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); -int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); -int f8_done(symmetric_F8 *f8); -int f8_test_mode(void); -#endif - -#ifdef LTC_XTS_MODE -typedef struct { - symmetric_key key1, key2; - int cipher; -} symmetric_xts; - -int xts_start( int cipher, - const unsigned char *key1, - const unsigned char *key2, - unsigned long keylen, - int num_rounds, - symmetric_xts *xts); - -int xts_encrypt( - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - const unsigned char *tweak, - symmetric_xts *xts); -int xts_decrypt( - const unsigned char *ct, unsigned long ptlen, - unsigned char *pt, - const unsigned char *tweak, - symmetric_xts *xts); - -void xts_done(symmetric_xts *xts); -int xts_test(void); -void xts_mult_x(unsigned char *I); -#endif - -int find_cipher(const char *name); -int find_cipher_any(const char *name, int blocklen, int keylen); -int find_cipher_id(unsigned char ID); -int register_cipher(const struct ltc_cipher_descriptor *cipher); -int unregister_cipher(const struct ltc_cipher_descriptor *cipher); -int cipher_is_valid(int idx); - -LTC_MUTEX_PROTO(ltc_cipher_mutex) - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cipher.h,v $ */ -/* $Revision: 1.54 $ */ -/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h deleted file mode 100644 index 88ec8f984ab..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_custom.h +++ /dev/null @@ -1,424 +0,0 @@ -#ifndef TOMCRYPT_CUSTOM_H_ -#define TOMCRYPT_CUSTOM_H_ - -#define LTC_NO_CIPHERS -#define LTC_NO_HASHES -#define LTC_NO_MACS -#define LTC_NO_PRNGS -#define LTC_NO_CURVES -#define LTC_NO_MODES -#define LTC_NO_PKCS -#define LTC_NO_ROLC - -#define LTC_SOURCE -#define LTC_SHA1 -#define LTC_MD5 -#define LTC_DER -#define LTC_RC4 - -#define USE_LTM -#define LTM_DESC - -/* macros for various libc functions you can change for embedded targets */ -#ifndef XMALLOC - #ifdef malloc - #define LTC_NO_PROTOTYPES - #endif -#define XMALLOC LibTomMalloc -#endif -#ifndef XREALLOC - #ifdef realloc - #define LTC_NO_PROTOTYPES - #endif -#define XREALLOC LibTomRealloc -#endif -#ifndef XCALLOC - #ifdef calloc - #define LTC_NO_PROTOTYPES - #endif -#define XCALLOC LibTomCalloc -#endif -#ifndef XFREE - #ifdef free - #define LTC_NO_PROTOTYPES - #endif -#define XFREE LibTomFree -#endif - -#ifndef XMEMSET - #ifdef memset - #define LTC_NO_PROTOTYPES - #endif -#define XMEMSET memset -#endif -#ifndef XMEMCPY - #ifdef memcpy - #define LTC_NO_PROTOTYPES - #endif -#define XMEMCPY memcpy -#endif -#ifndef XMEMCMP - #ifdef memcmp - #define LTC_NO_PROTOTYPES - #endif -#define XMEMCMP memcmp -#endif -#ifndef XSTRCMP - #ifdef strcmp - #define LTC_NO_PROTOTYPES - #endif -#define XSTRCMP strcmp -#endif - -#ifndef XCLOCK -#define XCLOCK LibTomClock -#endif -#ifndef XCLOCKS_PER_SEC -#define XCLOCKS_PER_SEC CLOCKS_PER_SEC -#endif - -#ifndef XQSORT - #ifdef qsort - #define LTC_NO_PROTOTYPES - #endif -#define XQSORT LibTomQsort -#endif - -/* Easy button? */ -#ifdef LTC_EASY - #define LTC_NO_CIPHERS - #define LTC_RIJNDAEL - #define LTC_BLOWFISH - #define LTC_DES - #define LTC_CAST5 - - #define LTC_NO_MODES - #define LTC_ECB_MODE - #define LTC_CBC_MODE - #define LTC_CTR_MODE - - #define LTC_NO_HASHES - #define LTC_SHA1 - #define LTC_SHA512 - #define LTC_SHA384 - #define LTC_SHA256 - #define LTC_SHA224 - - #define LTC_NO_MACS - #define LTC_HMAC - #define LTC_OMAC - #define LTC_CCM_MODE - - #define LTC_NO_PRNGS - #define LTC_SPRNG - #define LTC_YARROW - #define LTC_DEVRANDOM - #define TRY_URANDOM_FIRST - - #define LTC_NO_PK - #define LTC_MRSA - #define LTC_MECC -#endif - -/* Use small code where possible */ -/* #define LTC_SMALL_CODE */ - -/* Enable self-test test vector checking */ -#ifndef LTC_NO_TEST - #define LTC_TEST -#endif - -/* clean the stack of functions which put private information on stack */ -/* #define LTC_CLEAN_STACK */ - -/* disable all file related functions */ -/* #define LTC_NO_FILE */ - -/* disable all forms of ASM */ -/* #define LTC_NO_ASM */ - -/* disable FAST mode */ -/* #define LTC_NO_FAST */ - -/* disable BSWAP on x86 */ -/* #define LTC_NO_BSWAP */ - -/* ---> Symmetric Block Ciphers <--- */ -#ifndef LTC_NO_CIPHERS - -#define LTC_BLOWFISH -#define LTC_RC2 -#define LTC_RC5 -#define LTC_RC6 -#define LTC_SAFERP -#define LTC_RIJNDAEL -#define LTC_XTEA -/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format - * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ -#define LTC_TWOFISH -#ifndef LTC_NO_TABLES - #define LTC_TWOFISH_TABLES - /* #define LTC_TWOFISH_ALL_TABLES */ -#else - #define LTC_TWOFISH_SMALL -#endif -/* #define LTC_TWOFISH_SMALL */ -/* LTC_DES includes EDE triple-LTC_DES */ -#define LTC_DES -#define LTC_CAST5 -#define LTC_NOEKEON -#define LTC_SKIPJACK -#define LTC_SAFER -#define LTC_KHAZAD -#define LTC_ANUBIS -#define LTC_ANUBIS_TWEAK -#define LTC_KSEED -#define LTC_KASUMI - -#endif /* LTC_NO_CIPHERS */ - - -/* ---> Block Cipher Modes of Operation <--- */ -#ifndef LTC_NO_MODES - -#define LTC_CFB_MODE -#define LTC_OFB_MODE -#define LTC_ECB_MODE -#define LTC_CBC_MODE -#define LTC_CTR_MODE - -/* F8 chaining mode */ -#define LTC_F8_MODE - -/* LRW mode */ -#define LTC_LRW_MODE -#ifndef LTC_NO_TABLES - /* like GCM mode this will enable 16 8x128 tables [64KB] that make - * seeking very fast. - */ - #define LRW_TABLES -#endif - -/* XTS mode */ -#define LTC_XTS_MODE - -#endif /* LTC_NO_MODES */ - -/* ---> One-Way Hash Functions <--- */ -#ifndef LTC_NO_HASHES - -#define LTC_CHC_HASH -#define LTC_WHIRLPOOL -#define LTC_SHA512 -#define LTC_SHA384 -#define LTC_SHA256 -#define LTC_SHA224 -#define LTC_TIGER -#define LTC_SHA1 -#define LTC_MD5 -#define LTC_MD4 -#define LTC_MD2 -#define LTC_RIPEMD128 -#define LTC_RIPEMD160 -#define LTC_RIPEMD256 -#define LTC_RIPEMD320 - -#endif /* LTC_NO_HASHES */ - -/* ---> MAC functions <--- */ -#ifndef LTC_NO_MACS - -#define LTC_HMAC -#define LTC_OMAC -#define LTC_PMAC -#define LTC_XCBC -#define LTC_F9_MODE -#define LTC_PELICAN - -#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) - #error Pelican-MAC requires LTC_RIJNDAEL -#endif - -/* ---> Encrypt + Authenticate Modes <--- */ - -#define LTC_EAX_MODE -#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) - #error LTC_EAX_MODE requires CTR and LTC_OMAC mode -#endif - -#define LTC_OCB_MODE -#define LTC_CCM_MODE -#define LTC_GCM_MODE - -/* Use 64KiB tables */ -#ifndef LTC_NO_TABLES - #define LTC_GCM_TABLES -#endif - -/* USE SSE2? requires GCC works on x86_32 and x86_64*/ -#ifdef LTC_GCM_TABLES -/* #define LTC_GCM_TABLES_SSE2 */ -#endif - -#endif /* LTC_NO_MACS */ - -/* Various tidbits of modern neatoness */ -#define LTC_BASE64 - -/* --> Pseudo Random Number Generators <--- */ -#ifndef LTC_NO_PRNGS - -/* Yarrow */ -#define LTC_YARROW -/* which descriptor of AES to use? */ -/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ -#define LTC_YARROW_AES 0 - -#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) - #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! -#endif - -/* a PRNG that simply reads from an available system source */ -#define LTC_SPRNG - -/* The LTC_RC4 stream cipher */ -#define LTC_RC4 - -/* Fortuna PRNG */ -#define LTC_FORTUNA -/* reseed every N calls to the read function */ -#define LTC_FORTUNA_WD 10 -/* number of pools (4..32) can save a bit of ram by lowering the count */ -#define LTC_FORTUNA_POOLS 32 - -/* Greg's LTC_SOBER128 PRNG ;-0 */ -#define LTC_SOBER128 - -/* the *nix style /dev/random device */ -#define LTC_DEVRANDOM -/* try /dev/urandom before trying /dev/random */ -#define TRY_URANDOM_FIRST - -#endif /* LTC_NO_PRNGS */ - -/* ---> math provider? <--- */ -#ifndef LTC_NO_MATH - -/* LibTomMath */ -#define LTM_LTC_DESC - -/* TomsFastMath */ -//#define TFM_LTC_DESC - -#endif /* LTC_NO_MATH */ - -/* ---> Public Key Crypto <--- */ -#ifndef LTC_NO_PK - -/* Include RSA support */ -#define LTC_MRSA - -/* Include Katja (a Rabin variant like RSA) */ -/* #define MKAT */ - -/* Digital Signature Algorithm */ -#define LTC_MDSA - -/* ECC */ -#define LTC_MECC - -/* use Shamir's trick for point mul (speeds up signature verification) */ -#define LTC_ECC_SHAMIR - -#if defined(TFM_LTC_DESC) && defined(LTC_MECC) - #define LTC_MECC_ACCEL -#endif - -/* do we want fixed point ECC */ -/* #define LTC_MECC_FP */ - -/* Timing Resistant? */ -/* #define LTC_ECC_TIMING_RESISTANT */ - -#endif /* LTC_NO_PK */ - -/* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */ -#ifndef LTC_NO_PKCS - -#define LTC_PKCS_1 -#define LTC_PKCS_5 - -/* Include ASN.1 DER (required by DSA/RSA) */ -#define LTC_DER - -#endif /* LTC_NO_PKCS */ - -/* cleanup */ - -#ifdef LTC_MECC -/* Supported ECC Key Sizes */ -#ifndef LTC_NO_CURVES - #define ECC112 - #define ECC128 - #define ECC160 - #define ECC192 - #define ECC224 - #define ECC256 - #define ECC384 - #define ECC521 -#endif -#endif - -#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA) - /* Include the MPI functionality? (required by the PK algorithms) */ - #define MPI -#endif - -#ifdef LTC_MRSA - #define LTC_PKCS_1 -#endif - -#if defined(LTC_DER) && !defined(MPI) - #error ASN.1 DER requires MPI functionality -#endif - -#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER) - #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled -#endif - -/* THREAD management */ -#ifdef LTC_PTHREAD - -#include <pthread.h> - -#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; -#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; -#define LTC_MUTEX_TYPE(x) pthread_mutex_t x; -#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL); -#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x); -#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x); - -#else - -/* default no functions */ -#define LTC_MUTEX_GLOBAL(x) -#define LTC_MUTEX_PROTO(x) -#define LTC_MUTEX_TYPE(x) -#define LTC_MUTEX_INIT(x) -#define LTC_MUTEX_LOCK(x) -#define LTC_MUTEX_UNLOCK(x) - -#endif - -/* Debuggers */ - -/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */ -/* #define LTC_VALGRIND */ - -#endif - - - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */ -/* $Revision: 1.73 $ */ -/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h deleted file mode 100644 index 18553ebf9da..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_hash.h +++ /dev/null @@ -1,378 +0,0 @@ -/* ---- HASH FUNCTIONS ---- */ -#ifdef LTC_SHA512 -struct sha512_state { - ulong64 length, state[8]; - unsigned long curlen; - unsigned char buf[128]; -}; -#endif - -#ifdef LTC_SHA256 -struct sha256_state { - ulong64 length; - ulong32 state[8], curlen; - unsigned char buf[64]; -}; -#endif - -#ifdef LTC_SHA1 -struct sha1_state { - ulong64 length; - ulong32 state[5], curlen; - unsigned char buf[64]; -}; -#endif - -#ifdef LTC_MD5 -struct md5_state { - ulong64 length; - ulong32 state[4], curlen; - unsigned char buf[64]; -}; -#endif - -#ifdef LTC_MD4 -struct md4_state { - ulong64 length; - ulong32 state[4], curlen; - unsigned char buf[64]; -}; -#endif - -#ifdef LTC_TIGER -struct tiger_state { - ulong64 state[3], length; - unsigned long curlen; - unsigned char buf[64]; -}; -#endif - -#ifdef LTC_MD2 -struct md2_state { - unsigned char chksum[16], X[48], buf[16]; - unsigned long curlen; -}; -#endif - -#ifdef LTC_RIPEMD128 -struct rmd128_state { - ulong64 length; - unsigned char buf[64]; - ulong32 curlen, state[4]; -}; -#endif - -#ifdef LTC_RIPEMD160 -struct rmd160_state { - ulong64 length; - unsigned char buf[64]; - ulong32 curlen, state[5]; -}; -#endif - -#ifdef LTC_RIPEMD256 -struct rmd256_state { - ulong64 length; - unsigned char buf[64]; - ulong32 curlen, state[8]; -}; -#endif - -#ifdef LTC_RIPEMD320 -struct rmd320_state { - ulong64 length; - unsigned char buf[64]; - ulong32 curlen, state[10]; -}; -#endif - -#ifdef LTC_WHIRLPOOL -struct whirlpool_state { - ulong64 length, state[8]; - unsigned char buf[64]; - ulong32 curlen; -}; -#endif - -#ifdef LTC_CHC_HASH -struct chc_state { - ulong64 length; - unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; - ulong32 curlen; -}; -#endif - -typedef union Hash_state { -#ifdef LTC_CHC_HASH - struct chc_state chc; -#endif -#ifdef LTC_WHIRLPOOL - struct whirlpool_state whirlpool; -#endif -#ifdef LTC_SHA512 - struct sha512_state sha512; -#endif -#ifdef LTC_SHA256 - struct sha256_state sha256; -#endif -#ifdef LTC_SHA1 - struct sha1_state sha1; -#endif -#ifdef LTC_MD5 - struct md5_state md5; -#endif -#ifdef LTC_MD4 - struct md4_state md4; -#endif -#ifdef LTC_MD2 - struct md2_state md2; -#endif -#ifdef LTC_TIGER - struct tiger_state tiger; -#endif -#ifdef LTC_RIPEMD128 - struct rmd128_state rmd128; -#endif -#ifdef LTC_RIPEMD160 - struct rmd160_state rmd160; -#endif -#ifdef LTC_RIPEMD256 - struct rmd256_state rmd256; -#endif -#ifdef LTC_RIPEMD320 - struct rmd320_state rmd320; -#endif - void *data; -} hash_state; - -/** hash descriptor */ -extern struct ltc_hash_descriptor { - /** name of hash */ - char *name; - /** internal ID */ - unsigned char ID; - /** Size of digest in octets */ - unsigned long hashsize; - /** Input block size in octets */ - unsigned long blocksize; - /** ASN.1 OID */ - unsigned long OID[16]; - /** Length of DER encoding */ - unsigned long OIDlen; - - /** Init a hash state - @param hash The hash to initialize - @return CRYPT_OK if successful - */ - int (*init)(hash_state *hash); - /** Process a block of data - @param hash The hash state - @param in The data to hash - @param inlen The length of the data (octets) - @return CRYPT_OK if successful - */ - int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen); - /** Produce the digest and store it - @param hash The hash state - @param out [out] The destination of the digest - @return CRYPT_OK if successful - */ - int (*done)(hash_state *hash, unsigned char *out); - /** Self-test - @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled - */ - int (*test)(void); - - /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */ - int (*hmac_block)(const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); - -} hash_descriptor[]; - -#ifdef LTC_CHC_HASH -int chc_register(int cipher); -int chc_init(hash_state * md); -int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int chc_done(hash_state * md, unsigned char *hash); -int chc_test(void); -extern const struct ltc_hash_descriptor chc_desc; -#endif - -#ifdef LTC_WHIRLPOOL -int whirlpool_init(hash_state * md); -int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int whirlpool_done(hash_state * md, unsigned char *hash); -int whirlpool_test(void); -extern const struct ltc_hash_descriptor whirlpool_desc; -#endif - -#ifdef LTC_SHA512 -int sha512_init(hash_state * md); -int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int sha512_done(hash_state * md, unsigned char *hash); -int sha512_test(void); -extern const struct ltc_hash_descriptor sha512_desc; -#endif - -#ifdef LTC_SHA384 -#ifndef LTC_SHA512 - #error LTC_SHA512 is required for LTC_SHA384 -#endif -int sha384_init(hash_state * md); -#define sha384_process sha512_process -int sha384_done(hash_state * md, unsigned char *hash); -int sha384_test(void); -extern const struct ltc_hash_descriptor sha384_desc; -#endif - -#ifdef LTC_SHA256 -int sha256_init(hash_state * md); -int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int sha256_done(hash_state * md, unsigned char *hash); -int sha256_test(void); -extern const struct ltc_hash_descriptor sha256_desc; - -#ifdef LTC_SHA224 -#ifndef LTC_SHA256 - #error LTC_SHA256 is required for LTC_SHA224 -#endif -int sha224_init(hash_state * md); -#define sha224_process sha256_process -int sha224_done(hash_state * md, unsigned char *hash); -int sha224_test(void); -extern const struct ltc_hash_descriptor sha224_desc; -#endif -#endif - -#ifdef LTC_SHA1 -int sha1_init(hash_state * md); -int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int sha1_done(hash_state * md, unsigned char *hash); -int sha1_test(void); -extern const struct ltc_hash_descriptor sha1_desc; -#endif - -#ifdef LTC_MD5 -int md5_init(hash_state * md); -int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int md5_done(hash_state * md, unsigned char *hash); -int md5_test(void); -extern const struct ltc_hash_descriptor md5_desc; -#endif - -#ifdef LTC_MD4 -int md4_init(hash_state * md); -int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int md4_done(hash_state * md, unsigned char *hash); -int md4_test(void); -extern const struct ltc_hash_descriptor md4_desc; -#endif - -#ifdef LTC_MD2 -int md2_init(hash_state * md); -int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int md2_done(hash_state * md, unsigned char *hash); -int md2_test(void); -extern const struct ltc_hash_descriptor md2_desc; -#endif - -#ifdef LTC_TIGER -int tiger_init(hash_state * md); -int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int tiger_done(hash_state * md, unsigned char *hash); -int tiger_test(void); -extern const struct ltc_hash_descriptor tiger_desc; -#endif - -#ifdef LTC_RIPEMD128 -int rmd128_init(hash_state * md); -int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int rmd128_done(hash_state * md, unsigned char *hash); -int rmd128_test(void); -extern const struct ltc_hash_descriptor rmd128_desc; -#endif - -#ifdef LTC_RIPEMD160 -int rmd160_init(hash_state * md); -int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int rmd160_done(hash_state * md, unsigned char *hash); -int rmd160_test(void); -extern const struct ltc_hash_descriptor rmd160_desc; -#endif - -#ifdef LTC_RIPEMD256 -int rmd256_init(hash_state * md); -int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int rmd256_done(hash_state * md, unsigned char *hash); -int rmd256_test(void); -extern const struct ltc_hash_descriptor rmd256_desc; -#endif - -#ifdef LTC_RIPEMD320 -int rmd320_init(hash_state * md); -int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int rmd320_done(hash_state * md, unsigned char *hash); -int rmd320_test(void); -extern const struct ltc_hash_descriptor rmd320_desc; -#endif - - -int find_hash(const char *name); -int find_hash_id(unsigned char ID); -int find_hash_oid(const unsigned long *ID, unsigned long IDlen); -int find_hash_any(const char *name, int digestlen); -int register_hash(const struct ltc_hash_descriptor *hash); -int unregister_hash(const struct ltc_hash_descriptor *hash); -int hash_is_valid(int idx); - -LTC_MUTEX_PROTO(ltc_hash_mutex) - -int hash_memory(int hash, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); -int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen); -int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen); - -/* a simple macro for making hash "process" functions */ -#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ -int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ -{ \ - unsigned long n; \ - int err; \ - LTC_ARGCHK(md != NULL); \ - LTC_ARGCHK(in != NULL); \ - if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ - return CRYPT_INVALID_ARG; \ - } \ - while (inlen > 0) { \ - if (md-> state_var .curlen == 0 && inlen >= block_size) { \ - if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ - return err; \ - } \ - md-> state_var .length += block_size * 8; \ - in += block_size; \ - inlen -= block_size; \ - } else { \ - n = MIN(inlen, (block_size - md-> state_var .curlen)); \ - memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ - md-> state_var .curlen += n; \ - in += n; \ - inlen -= n; \ - if (md-> state_var .curlen == block_size) { \ - if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ - return err; \ - } \ - md-> state_var .length += 8*block_size; \ - md-> state_var .curlen = 0; \ - } \ - } \ - } \ - return CRYPT_OK; \ -} - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */ -/* $Revision: 1.22 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h deleted file mode 100644 index 7ad9516bd29..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_mac.h +++ /dev/null @@ -1,384 +0,0 @@ -#ifdef LTC_HMAC -typedef struct Hmac_state { - hash_state md; - int hash; - hash_state hashstate; - unsigned char *key; -} hmac_state; - -int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); -int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); -int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); -int hmac_test(void); -int hmac_memory(int hash, - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int hmac_memory_multi(int hash, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); -int hmac_file(int hash, const char *fname, const unsigned char *key, - unsigned long keylen, - unsigned char *dst, unsigned long *dstlen); -#endif - -#ifdef LTC_OMAC - -typedef struct { - int cipher_idx, - buflen, - blklen; - unsigned char block[MAXBLOCKSIZE], - prev[MAXBLOCKSIZE], - Lu[2][MAXBLOCKSIZE]; - symmetric_key key; -} omac_state; - -int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); -int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen); -int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen); -int omac_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int omac_memory_multi(int cipher, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); -int omac_file(int cipher, - const unsigned char *key, unsigned long keylen, - const char *filename, - unsigned char *out, unsigned long *outlen); -int omac_test(void); -#endif /* LTC_OMAC */ - -#ifdef LTC_PMAC - -typedef struct { - unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ - Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ - Lr[MAXBLOCKSIZE], /* L * x^-1 */ - block[MAXBLOCKSIZE], /* currently accumulated block */ - checksum[MAXBLOCKSIZE]; /* current checksum */ - - symmetric_key key; /* scheduled key for cipher */ - unsigned long block_index; /* index # for current block */ - int cipher_idx, /* cipher idx */ - block_len, /* length of block */ - buflen; /* number of bytes in the buffer */ -} pmac_state; - -int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); -int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen); -int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen); - -int pmac_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *msg, unsigned long msglen, - unsigned char *out, unsigned long *outlen); - -int pmac_memory_multi(int cipher, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); - -int pmac_file(int cipher, - const unsigned char *key, unsigned long keylen, - const char *filename, - unsigned char *out, unsigned long *outlen); - -int pmac_test(void); - -/* internal functions */ -int pmac_ntz(unsigned long x); -void pmac_shift_xor(pmac_state *pmac); - -#endif /* PMAC */ - -#ifdef LTC_EAX_MODE - -#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) - #error LTC_EAX_MODE requires LTC_OMAC and CTR -#endif - -typedef struct { - unsigned char N[MAXBLOCKSIZE]; - symmetric_CTR ctr; - omac_state headeromac, ctomac; -} eax_state; - -int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen); - -int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); -int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); -int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); -int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); - -int eax_encrypt_authenticate_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int eax_decrypt_verify_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - unsigned char *tag, unsigned long taglen, - int *stat); - - int eax_test(void); -#endif /* EAX MODE */ - -#ifdef LTC_OCB_MODE -typedef struct { - unsigned char L[MAXBLOCKSIZE], /* L value */ - Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ - Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ - Lr[MAXBLOCKSIZE], /* L * x^-1 */ - R[MAXBLOCKSIZE], /* R value */ - checksum[MAXBLOCKSIZE]; /* current checksum */ - - symmetric_key key; /* scheduled key for cipher */ - unsigned long block_index; /* index # for current block */ - int cipher, /* cipher idx */ - block_len; /* length of block */ -} ocb_state; - -int ocb_init(ocb_state *ocb, int cipher, - const unsigned char *key, unsigned long keylen, const unsigned char *nonce); - -int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); -int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); - -int ocb_done_encrypt(ocb_state *ocb, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int ocb_done_decrypt(ocb_state *ocb, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, int *stat); - -int ocb_encrypt_authenticate_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int ocb_decrypt_verify_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, - int *stat); - -int ocb_test(void); - -/* internal functions */ -void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); -int ocb_ntz(unsigned long x); -int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); - -#endif /* LTC_OCB_MODE */ - -#ifdef LTC_CCM_MODE - -#define CCM_ENCRYPT 0 -#define CCM_DECRYPT 1 - -int ccm_memory(int cipher, - const unsigned char *key, unsigned long keylen, - symmetric_key *uskey, - const unsigned char *nonce, unsigned long noncelen, - const unsigned char *header, unsigned long headerlen, - unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen, - int direction); - -int ccm_test(void); - -#endif /* LTC_CCM_MODE */ - -#if defined(LRW_MODE) || defined(LTC_GCM_MODE) -void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); -#endif - - -/* table shared between GCM and LRW */ -#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) -extern const unsigned char gcm_shift_table[]; -#endif - -#ifdef LTC_GCM_MODE - -#define GCM_ENCRYPT 0 -#define GCM_DECRYPT 1 - -#define LTC_GCM_MODE_IV 0 -#define LTC_GCM_MODE_AAD 1 -#define LTC_GCM_MODE_TEXT 2 - -typedef struct { - symmetric_key K; - unsigned char H[16], /* multiplier */ - X[16], /* accumulator */ - Y[16], /* counter */ - Y_0[16], /* initial counter */ - buf[16]; /* buffer for stuff */ - - int cipher, /* which cipher */ - ivmode, /* Which mode is the IV in? */ - mode, /* mode the GCM code is in */ - buflen; /* length of data in buf */ - - ulong64 totlen, /* 64-bit counter used for IV and AAD */ - pttotlen; /* 64-bit counter for the PT */ - -#ifdef LTC_GCM_TABLES - unsigned char PC[16][256][16] /* 16 tables of 8x128 */ -#ifdef LTC_GCM_TABLES_SSE2 -__attribute__ ((aligned (16))) -#endif -; -#endif -} gcm_state; - -void gcm_mult_h(gcm_state *gcm, unsigned char *I); - -int gcm_init(gcm_state *gcm, int cipher, - const unsigned char *key, int keylen); - -int gcm_reset(gcm_state *gcm); - -int gcm_add_iv(gcm_state *gcm, - const unsigned char *IV, unsigned long IVlen); - -int gcm_add_aad(gcm_state *gcm, - const unsigned char *adata, unsigned long adatalen); - -int gcm_process(gcm_state *gcm, - unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - int direction); - -int gcm_done(gcm_state *gcm, - unsigned char *tag, unsigned long *taglen); - -int gcm_memory( int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *IV, unsigned long IVlen, - const unsigned char *adata, unsigned long adatalen, - unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen, - int direction); -int gcm_test(void); - -#endif /* LTC_GCM_MODE */ - -#ifdef LTC_PELICAN - -typedef struct pelican_state -{ - symmetric_key K; - unsigned char state[16]; - int buflen; -} pelican_state; - -int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); -int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); -int pelican_done(pelican_state *pelmac, unsigned char *out); -int pelican_test(void); - -int pelican_memory(const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out); - -#endif - -#ifdef LTC_XCBC - -/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */ -#define LTC_XCBC_PURE 0x8000UL - -typedef struct { - unsigned char K[3][MAXBLOCKSIZE], - IV[MAXBLOCKSIZE]; - - symmetric_key key; - - int cipher, - buflen, - blocksize; -} xcbc_state; - -int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen); -int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen); -int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen); -int xcbc_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int xcbc_memory_multi(int cipher, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); -int xcbc_file(int cipher, - const unsigned char *key, unsigned long keylen, - const char *filename, - unsigned char *out, unsigned long *outlen); -int xcbc_test(void); - -#endif - -#ifdef LTC_F9_MODE - -typedef struct { - unsigned char akey[MAXBLOCKSIZE], - ACC[MAXBLOCKSIZE], - IV[MAXBLOCKSIZE]; - - symmetric_key key; - - int cipher, - buflen, - keylen, - blocksize; -} f9_state; - -int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen); -int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen); -int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen); -int f9_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int f9_memory_multi(int cipher, - const unsigned char *key, unsigned long keylen, - unsigned char *out, unsigned long *outlen, - const unsigned char *in, unsigned long inlen, ...); -int f9_file(int cipher, - const unsigned char *key, unsigned long keylen, - const char *filename, - unsigned char *out, unsigned long *outlen); -int f9_test(void); - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */ -/* $Revision: 1.23 $ */ -/* $Date: 2007/05/12 14:37:41 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h deleted file mode 100644 index 53bda9bb4ba..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_macros.h +++ /dev/null @@ -1,424 +0,0 @@ -/* fix for MSVC ...evil! */ -#ifdef _MSC_VER - #define CONST64(n) n ## ui64 - typedef unsigned __int64 ulong64; -#else - #define CONST64(n) n ## ULL - typedef unsigned long long ulong64; -#endif - -/* this is the "32-bit at least" data type - * Re-define it to suit your platform but it must be at least 32-bits - */ -#if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__)) - typedef unsigned ulong32; -#else - typedef unsigned long ulong32; -#endif - -/* ---- HELPER MACROS ---- */ -#ifdef ENDIAN_NEUTRAL - -#define STORE32L(x, y) \ - { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - -#define LOAD32L(x, y) \ - { x = ((unsigned long)((y)[3] & 255)<<24) | \ - ((unsigned long)((y)[2] & 255)<<16) | \ - ((unsigned long)((y)[1] & 255)<<8) | \ - ((unsigned long)((y)[0] & 255)); } - -#define STORE64L(x, y) \ - { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ - (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ - (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - -#define LOAD64L(x, y) \ - { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ - (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ - (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ - (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } - -#define STORE32H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ - (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } - -#define LOAD32H(x, y) \ - { x = ((unsigned long)((y)[0] & 255)<<24) | \ - ((unsigned long)((y)[1] & 255)<<16) | \ - ((unsigned long)((y)[2] & 255)<<8) | \ - ((unsigned long)((y)[3] & 255)); } - -#define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } - -#define LOAD64H(x, y) \ - { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ - (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ - (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ - (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } - -#endif /* ENDIAN_NEUTRAL */ - -#ifdef ENDIAN_LITTLE - -#if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__)))) - -#define STORE32H(x, y) \ -asm __volatile__ ( \ - "bswapl %0 \n\t" \ - "movl %0,(%1)\n\t" \ - "bswapl %0 \n\t" \ - ::"r"(x), "r"(y)); - -#define LOAD32H(x, y) \ -asm __volatile__ ( \ - "movl (%1),%0\n\t" \ - "bswapl %0\n\t" \ - :"=r"(x): "r"(y)); - -#else - -#define STORE32H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ - (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } - -#define LOAD32H(x, y) \ - { x = ((unsigned long)((y)[0] & 255)<<24) | \ - ((unsigned long)((y)[1] & 255)<<16) | \ - ((unsigned long)((y)[2] & 255)<<8) | \ - ((unsigned long)((y)[3] & 255)); } - -#endif - - -/* x86_64 processor */ -#if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) - -#define STORE64H(x, y) \ -asm __volatile__ ( \ - "bswapq %0 \n\t" \ - "movq %0,(%1)\n\t" \ - "bswapq %0 \n\t" \ - ::"r"(x), "r"(y)); - -#define LOAD64H(x, y) \ -asm __volatile__ ( \ - "movq (%1),%0\n\t" \ - "bswapq %0\n\t" \ - :"=r"(x): "r"(y)); - -#else - -#define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } - -#define LOAD64H(x, y) \ - { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ - (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ - (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ - (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } - -#endif - -#ifdef ENDIAN_32BITWORD - -#define STORE32L(x, y) \ - { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } - -#define LOAD32L(x, y) \ - XMEMCPY(&(x), y, 4); - -#define STORE64L(x, y) \ - { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ - (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ - (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - -#define LOAD64L(x, y) \ - { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ - (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ - (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ - (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } - -#else /* 64-bit words then */ - -#define STORE32L(x, y) \ - { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } - -#define LOAD32L(x, y) \ - { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } - -#define STORE64L(x, y) \ - { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } - -#define LOAD64L(x, y) \ - { XMEMCPY(&(x), y, 8); } - -#endif /* ENDIAN_64BITWORD */ - -#endif /* ENDIAN_LITTLE */ - -#ifdef ENDIAN_BIG -#define STORE32L(x, y) \ - { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - -#define LOAD32L(x, y) \ - { x = ((unsigned long)((y)[3] & 255)<<24) | \ - ((unsigned long)((y)[2] & 255)<<16) | \ - ((unsigned long)((y)[1] & 255)<<8) | \ - ((unsigned long)((y)[0] & 255)); } - -#define STORE64L(x, y) \ - { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ - (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ - (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - -#define LOAD64L(x, y) \ - { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ - (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ - (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ - (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } - -#ifdef ENDIAN_32BITWORD - -#define STORE32H(x, y) \ - { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } - -#define LOAD32H(x, y) \ - XMEMCPY(&(x), y, 4); - -#define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } - -#define LOAD64H(x, y) \ - { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ - (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ - (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ - (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } - -#else /* 64-bit words then */ - -#define STORE32H(x, y) \ - { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } - -#define LOAD32H(x, y) \ - { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } - -#define STORE64H(x, y) \ - { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } - -#define LOAD64H(x, y) \ - { XMEMCPY(&(x), y, 8); } - -#endif /* ENDIAN_64BITWORD */ -#endif /* ENDIAN_BIG */ - -#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ - ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) - - -/* 32-bit Rotates */ -#if defined(_MSC_VER) - -/* instrinsic rotate */ -#include <stdlib.h> -#pragma intrinsic(_lrotr,_lrotl) -#define ROR(x,n) _lrotr(x,n) -#define ROL(x,n) _lrotl(x,n) -#define RORc(x,n) _lrotr(x,n) -#define ROLc(x,n) _lrotl(x,n) - -#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM) - -static inline unsigned ROL(unsigned word, int i) -{ - asm ("roll %%cl,%0" - :"=r" (word) - :"0" (word),"c" (i)); - return word; -} - -static inline unsigned ROR(unsigned word, int i) -{ - asm ("rorl %%cl,%0" - :"=r" (word) - :"0" (word),"c" (i)); - return word; -} - -#ifndef LTC_NO_ROLC - -static inline unsigned ROLc(unsigned word, const int i) -{ - asm ("roll %2,%0" - :"=r" (word) - :"0" (word),"I" (i)); - return word; -} - -static inline unsigned RORc(unsigned word, const int i) -{ - asm ("rorl %2,%0" - :"=r" (word) - :"0" (word),"I" (i)); - return word; -} - -#else - -#define ROLc ROL -#define RORc ROR - -#endif - -#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32) - -static inline unsigned ROL(unsigned word, int i) -{ - asm ("rotlw %0,%0,%2" - :"=r" (word) - :"0" (word),"r" (i)); - return word; -} - -static inline unsigned ROR(unsigned word, int i) -{ - asm ("rotlw %0,%0,%2" - :"=r" (word) - :"0" (word),"r" (32-i)); - return word; -} - -#ifndef LTC_NO_ROLC - -static inline unsigned ROLc(unsigned word, const int i) -{ - asm ("rotlwi %0,%0,%2" - :"=r" (word) - :"0" (word),"I" (i)); - return word; -} - -static inline unsigned RORc(unsigned word, const int i) -{ - asm ("rotrwi %0,%0,%2" - :"=r" (word) - :"0" (word),"I" (i)); - return word; -} - -#else - -#define ROLc ROL -#define RORc ROR - -#endif - - -#else - -/* rotates the hard way */ -#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) - -#endif - - -/* 64-bit Rotates */ -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM) - -static inline unsigned long ROL64(unsigned long word, int i) -{ - asm("rolq %%cl,%0" - :"=r" (word) - :"0" (word),"c" (i)); - return word; -} - -static inline unsigned long ROR64(unsigned long word, int i) -{ - asm("rorq %%cl,%0" - :"=r" (word) - :"0" (word),"c" (i)); - return word; -} - -#ifndef LTC_NO_ROLC - -static inline unsigned long ROL64c(unsigned long word, const int i) -{ - asm("rolq %2,%0" - :"=r" (word) - :"0" (word),"J" (i)); - return word; -} - -static inline unsigned long ROR64c(unsigned long word, const int i) -{ - asm("rorq %2,%0" - :"=r" (word) - :"0" (word),"J" (i)); - return word; -} - -#else /* LTC_NO_ROLC */ - -#define ROL64c ROL64 -#define ROR64c ROR64 - -#endif - -#else /* Not x86_64 */ - -#define ROL64(x, y) \ - ( (((x)<<((ulong64)(y)&63)) | \ - (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) - -#define ROR64(x, y) \ - ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ - ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) - -#define ROL64c(x, y) \ - ( (((x)<<((ulong64)(y)&63)) | \ - (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) - -#define ROR64c(x, y) \ - ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ - ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) - -#endif - -#ifndef MAX - #define MAX(x, y) ( ((x)>(y))?(x):(y) ) -#endif - -#ifndef MIN - #define MIN(x, y) ( ((x)<(y))?(x):(y) ) -#endif - -/* extract a byte portably */ -#ifdef _MSC_VER - #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) -#else - #define byte(x, n) (((x) >> (8 * (n))) & 255) -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_macros.h,v $ */ -/* $Revision: 1.15 $ */ -/* $Date: 2006/11/29 23:43:57 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h deleted file mode 100644 index a05d7fff942..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_math.h +++ /dev/null @@ -1,500 +0,0 @@ -/** math functions **/ - -#define LTC_MP_LT -1 -#define LTC_MP_EQ 0 -#define LTC_MP_GT 1 - -#define LTC_MP_NO 0 -#define LTC_MP_YES 1 - -#ifndef LTC_MECC - typedef void ecc_point; -#endif - -#ifndef LTC_MRSA - typedef void rsa_key; -#endif - -/** math descriptor */ -typedef struct { - /** Name of the math provider */ - char *name; - - /** Bits per digit, amount of bits must fit in an unsigned long */ - int bits_per_digit; - -/* ---- init/deinit functions ---- */ - - /** initialize a bignum - @param a The number to initialize - @return CRYPT_OK on success - */ - int (*init)(void **a); - - /** init copy - @param dst The number to initialize and write to - @param src The number to copy from - @return CRYPT_OK on success - */ - int (*init_copy)(void **dst, void *src); - - /** deinit - @param a The number to free - @return CRYPT_OK on success - */ - void (*deinit)(void *a); - -/* ---- data movement ---- */ - - /** negate - @param src The number to negate - @param dst The destination - @return CRYPT_OK on success - */ - int (*neg)(void *src, void *dst); - - /** copy - @param src The number to copy from - @param dst The number to write to - @return CRYPT_OK on success - */ - int (*copy)(void *src, void *dst); - -/* ---- trivial low level functions ---- */ - - /** set small constant - @param a Number to write to - @param n Source upto bits_per_digit (actually meant for very small constants) - @return CRYPT_OK on succcess - */ - int (*set_int)(void *a, unsigned long n); - - /** get small constant - @param a Number to read, only fetches upto bits_per_digit from the number - @return The lower bits_per_digit of the integer (unsigned) - */ - unsigned long (*get_int)(void *a); - - /** get digit n - @param a The number to read from - @param n The number of the digit to fetch - @return The bits_per_digit sized n'th digit of a - */ - unsigned long (*get_digit)(void *a, int n); - - /** Get the number of digits that represent the number - @param a The number to count - @return The number of digits used to represent the number - */ - int (*get_digit_count)(void *a); - - /** compare two integers - @param a The left side integer - @param b The right side integer - @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) - */ - int (*compare)(void *a, void *b); - - /** compare against int - @param a The left side integer - @param b The right side integer (upto bits_per_digit) - @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) - */ - int (*compare_d)(void *a, unsigned long n); - - /** Count the number of bits used to represent the integer - @param a The integer to count - @return The number of bits required to represent the integer - */ - int (*count_bits)(void * a); - - /** Count the number of LSB bits which are zero - @param a The integer to count - @return The number of contiguous zero LSB bits - */ - int (*count_lsb_bits)(void *a); - - /** Compute a power of two - @param a The integer to store the power in - @param n The power of two you want to store (a = 2^n) - @return CRYPT_OK on success - */ - int (*twoexpt)(void *a , int n); - -/* ---- radix conversions ---- */ - - /** read ascii string - @param a The integer to store into - @param str The string to read - @param radix The radix the integer has been represented in (2-64) - @return CRYPT_OK on success - */ - int (*read_radix)(void *a, const char *str, int radix); - - /** write number to string - @param a The integer to store - @param str The destination for the string - @param radix The radix the integer is to be represented in (2-64) - @return CRYPT_OK on success - */ - int (*write_radix)(void *a, char *str, int radix); - - /** get size as unsigned char string - @param a The integer to get the size (when stored in array of octets) - @return The length of the integer - */ - unsigned long (*unsigned_size)(void *a); - - /** store an integer as an array of octets - @param src The integer to store - @param dst The buffer to store the integer in - @return CRYPT_OK on success - */ - int (*unsigned_write)(void *src, unsigned char *dst); - - /** read an array of octets and store as integer - @param dst The integer to load - @param src The array of octets - @param len The number of octets - @return CRYPT_OK on success - */ - int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len); - -/* ---- basic math ---- */ - - /** add two integers - @param a The first source integer - @param b The second source integer - @param c The destination of "a + b" - @return CRYPT_OK on success - */ - int (*add)(void *a, void *b, void *c); - - - /** add two integers - @param a The first source integer - @param b The second source integer (single digit of upto bits_per_digit in length) - @param c The destination of "a + b" - @return CRYPT_OK on success - */ - int (*addi)(void *a, unsigned long b, void *c); - - /** subtract two integers - @param a The first source integer - @param b The second source integer - @param c The destination of "a - b" - @return CRYPT_OK on success - */ - int (*sub)(void *a, void *b, void *c); - - /** subtract two integers - @param a The first source integer - @param b The second source integer (single digit of upto bits_per_digit in length) - @param c The destination of "a - b" - @return CRYPT_OK on success - */ - int (*subi)(void *a, unsigned long b, void *c); - - /** multiply two integers - @param a The first source integer - @param b The second source integer (single digit of upto bits_per_digit in length) - @param c The destination of "a * b" - @return CRYPT_OK on success - */ - int (*mul)(void *a, void *b, void *c); - - /** multiply two integers - @param a The first source integer - @param b The second source integer (single digit of upto bits_per_digit in length) - @param c The destination of "a * b" - @return CRYPT_OK on success - */ - int (*muli)(void *a, unsigned long b, void *c); - - /** Square an integer - @param a The integer to square - @param b The destination - @return CRYPT_OK on success - */ - int (*sqr)(void *a, void *b); - - /** Divide an integer - @param a The dividend - @param b The divisor - @param c The quotient (can be NULL to signify don't care) - @param d The remainder (can be NULL to signify don't care) - @return CRYPT_OK on success - */ - int (*mpdiv)(void *a, void *b, void *c, void *d); - - /** divide by two - @param a The integer to divide (shift right) - @param b The destination - @return CRYPT_OK on success - */ - int (*div_2)(void *a, void *b); - - /** Get remainder (small value) - @param a The integer to reduce - @param b The modulus (upto bits_per_digit in length) - @param c The destination for the residue - @return CRYPT_OK on success - */ - int (*modi)(void *a, unsigned long b, unsigned long *c); - - /** gcd - @param a The first integer - @param b The second integer - @param c The destination for (a, b) - @return CRYPT_OK on success - */ - int (*gcd)(void *a, void *b, void *c); - - /** lcm - @param a The first integer - @param b The second integer - @param c The destination for [a, b] - @return CRYPT_OK on success - */ - int (*lcm)(void *a, void *b, void *c); - - /** Modular multiplication - @param a The first source - @param b The second source - @param c The modulus - @param d The destination (a*b mod c) - @return CRYPT_OK on success - */ - int (*mulmod)(void *a, void *b, void *c, void *d); - - /** Modular squaring - @param a The first source - @param b The modulus - @param c The destination (a*a mod b) - @return CRYPT_OK on success - */ - int (*sqrmod)(void *a, void *b, void *c); - - /** Modular inversion - @param a The value to invert - @param b The modulus - @param c The destination (1/a mod b) - @return CRYPT_OK on success - */ - int (*invmod)(void *, void *, void *); - -/* ---- reduction ---- */ - - /** setup montgomery - @param a The modulus - @param b The destination for the reduction digit - @return CRYPT_OK on success - */ - int (*montgomery_setup)(void *a, void **b); - - /** get normalization value - @param a The destination for the normalization value - @param b The modulus - @return CRYPT_OK on success - */ - int (*montgomery_normalization)(void *a, void *b); - - /** reduce a number - @param a The number [and dest] to reduce - @param b The modulus - @param c The value "b" from montgomery_setup() - @return CRYPT_OK on success - */ - int (*montgomery_reduce)(void *a, void *b, void *c); - - /** clean up (frees memory) - @param a The value "b" from montgomery_setup() - @return CRYPT_OK on success - */ - void (*montgomery_deinit)(void *a); - -/* ---- exponentiation ---- */ - - /** Modular exponentiation - @param a The base integer - @param b The power (can be negative) integer - @param c The modulus integer - @param d The destination - @return CRYPT_OK on success - */ - int (*exptmod)(void *a, void *b, void *c, void *d); - - /** Primality testing - @param a The integer to test - @param b The destination of the result (FP_YES if prime) - @return CRYPT_OK on success - */ - int (*isprime)(void *a, int *b); - -/* ---- (optional) ecc point math ---- */ - - /** ECC GF(p) point multiplication (from the NIST curves) - @param k The integer to multiply the point by - @param G The point to multiply - @param R The destination for kG - @param modulus The modulus for the field - @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) - @return CRYPT_OK on success - */ - int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); - - /** ECC GF(p) point addition - @param P The first point - @param Q The second point - @param R The destination of P + Q - @param modulus The modulus - @param mp The "b" value from montgomery_setup() - @return CRYPT_OK on success - */ - int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); - - /** ECC GF(p) point double - @param P The first point - @param R The destination of 2P - @param modulus The modulus - @param mp The "b" value from montgomery_setup() - @return CRYPT_OK on success - */ - int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp); - - /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) - @param P The point to map - @param modulus The modulus - @param mp The "b" value from montgomery_setup() - @return CRYPT_OK on success - @remark The mapping can be different but keep in mind a ecc_point only has three - integers (x,y,z) so if you use a different mapping you have to make it fit. - */ - int (*ecc_map)(ecc_point *P, void *modulus, void *mp); - - /** Computes kA*A + kB*B = C using Shamir's Trick - @param A First point to multiply - @param kA What to multiple A by - @param B Second point to multiply - @param kB What to multiple B by - @param C [out] Destination point (can overlap with A or B - @param modulus Modulus for curve - @return CRYPT_OK on success - */ - int (*ecc_mul2add)(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, - void *modulus); - -/* ---- (optional) rsa optimized math (for internal CRT) ---- */ - - /** RSA Key Generation - @param prng An active PRNG state - @param wprng The index of the PRNG desired - @param size The size of the modulus (key size) desired (octets) - @param e The "e" value (public key). e==65537 is a good choice - @param key [out] Destination of a newly created private key pair - @return CRYPT_OK if successful, upon error all allocated ram is freed - */ - int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); - - - /** RSA exponentiation - @param in The octet array representing the base - @param inlen The length of the input - @param out The destination (to be stored in an octet array format) - @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus) - @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA - @param key The RSA key to use - @return CRYPT_OK on success - */ - int (*rsa_me)(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, int which, - rsa_key *key); -} ltc_math_descriptor; - -extern ltc_math_descriptor ltc_mp; - -int ltc_init_multi(void **a, ...); -void ltc_deinit_multi(void *a, ...); - -#ifdef LTM_DESC -extern const ltc_math_descriptor ltm_desc; -#endif - -#ifdef TFM_DESC -extern const ltc_math_descriptor tfm_desc; -#endif - -#ifdef GMP_DESC -extern const ltc_math_descriptor gmp_desc; -#endif - -#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE) - -#define MP_DIGIT_BIT ltc_mp.bits_per_digit - -/* some handy macros */ -#define mp_init(a) ltc_mp.init(a) -#define mp_init_multi ltc_init_multi -#define mp_clear(a) ltc_mp.deinit(a) -#define mp_clear_multi ltc_deinit_multi -#define mp_init_copy(a, b) ltc_mp.init_copy(a, b) - -#define mp_neg(a, b) ltc_mp.neg(a, b) -#define mp_copy(a, b) ltc_mp.copy(a, b) - -#define mp_set(a, b) ltc_mp.set_int(a, b) -#define mp_set_int(a, b) ltc_mp.set_int(a, b) -#define mp_get_int(a) ltc_mp.get_int(a) -#define mp_get_digit(a, n) ltc_mp.get_digit(a, n) -#define mp_get_digit_count(a) ltc_mp.get_digit_count(a) -#define mp_cmp(a, b) ltc_mp.compare(a, b) -#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b) -#define mp_count_bits(a) ltc_mp.count_bits(a) -#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a) -#define mp_2expt(a, b) ltc_mp.twoexpt(a, b) - -#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c) -#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c) -#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) -#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) -#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) - -#define mp_add(a, b, c) ltc_mp.add(a, b, c) -#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c) -#define mp_sub(a, b, c) ltc_mp.sub(a, b, c) -#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c) -#define mp_mul(a, b, c) ltc_mp.mul(a, b, c) -#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) -#define mp_sqr(a, b) ltc_mp.sqr(a, b) -#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) -#define mp_div_2(a, b) ltc_mp.div_2(a, b) -#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) -#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) -#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) -#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) - -#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) -#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) -#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) - -#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) -#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b) -#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c) -#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a) - -#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) -#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c) - -#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO) -#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO) -#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0); - -#define mp_tohex(a, b) mp_toradix(a, b, 16) - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */ -/* $Revision: 1.44 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h deleted file mode 100644 index f5384cacc51..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_misc.h +++ /dev/null @@ -1,23 +0,0 @@ -/* ---- LTC_BASE64 Routines ---- */ -#ifdef LTC_BASE64 -int base64_encode(const unsigned char *in, unsigned long len, - unsigned char *out, unsigned long *outlen); - -int base64_decode(const unsigned char *in, unsigned long len, - unsigned char *out, unsigned long *outlen); -#endif - -/* ---- MEM routines ---- */ -void zeromem(void *dst, size_t len); -void burn_stack(unsigned long len); - -const char *error_to_string(int err); - -extern const char *crypt_build_settings; - -/* ---- HMM ---- */ -int crypt_fsa(void *mp, ...); - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_misc.h,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h deleted file mode 100644 index b5f277a8848..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pk.h +++ /dev/null @@ -1,558 +0,0 @@ -/* ---- NUMBER THEORY ---- */ - -enum { - PK_PUBLIC=0, - PK_PRIVATE=1 -}; - -int rand_prime(void *N, long len, prng_state *prng, int wprng); - -/* ---- RSA ---- */ -#ifdef LTC_MRSA - -/* Min and Max RSA key sizes (in bits) */ -#define MIN_RSA_SIZE 1024 -#define MAX_RSA_SIZE 4096 - -/** RSA LTC_PKCS style key */ -typedef struct Rsa_key { - /** Type of key, PK_PRIVATE or PK_PUBLIC */ - int type; - /** The public exponent */ - void *e; - /** The private exponent */ - void *d; - /** The modulus */ - void *N; - /** The p factor of N */ - void *p; - /** The q factor of N */ - void *q; - /** The 1/q mod p CRT param */ - void *qP; - /** The d mod (p - 1) CRT param */ - void *dP; - /** The d mod (q - 1) CRT param */ - void *dQ; -} rsa_key; - -int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); - -int rsa_exptmod(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, int which, - rsa_key *key); - -void rsa_free(rsa_key *key); - -/* These use LTC_PKCS #1 v2.0 padding */ -#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ - rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_LTC_PKCS_1_OAEP, _key) - -#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \ - rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_LTC_PKCS_1_OAEP, _stat, _key) - -#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \ - rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) - -#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ - rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) - -/* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */ -int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key); - -int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - int hash_idx, int padding, - int *stat, rsa_key *key); - -int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - int padding, - prng_state *prng, int prng_idx, - int hash_idx, unsigned long saltlen, - rsa_key *key); - -int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int padding, - int hash_idx, unsigned long saltlen, - int *stat, rsa_key *key); - -/* LTC_PKCS #1 import/export */ -int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); -int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); - -/* Ladik: Added for verifying Blizzard strong signature verification */ -int rsa_verify_simple(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, - rsa_key *key); - -#endif - -/* ---- Katja ---- */ -#ifdef MKAT - -/* Min and Max KAT key sizes (in bits) */ -#define MIN_KAT_SIZE 1024 -#define MAX_KAT_SIZE 4096 - -/** Katja LTC_PKCS style key */ -typedef struct KAT_key { - /** Type of key, PK_PRIVATE or PK_PUBLIC */ - int type; - /** The private exponent */ - void *d; - /** The modulus */ - void *N; - /** The p factor of N */ - void *p; - /** The q factor of N */ - void *q; - /** The 1/q mod p CRT param */ - void *qP; - /** The d mod (p - 1) CRT param */ - void *dP; - /** The d mod (q - 1) CRT param */ - void *dQ; - /** The pq param */ - void *pq; -} katja_key; - -int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key); - -int katja_exptmod(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, int which, - katja_key *key); - -void katja_free(katja_key *key); - -/* These use LTC_PKCS #1 v2.0 padding */ -int katja_encrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - prng_state *prng, int prng_idx, int hash_idx, katja_key *key); - -int katja_decrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - int hash_idx, int *stat, - katja_key *key); - -/* LTC_PKCS #1 import/export */ -int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); -int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); - -#endif - -/* ---- ECC Routines ---- */ -#ifdef LTC_MECC - -/* size of our temp buffers for exported keys */ -#define ECC_BUF_SIZE 256 - -/* max private key size */ -#define ECC_MAXSIZE 66 - -/** Structure defines a NIST GF(p) curve */ -typedef struct { - /** The size of the curve in octets */ - int size; - - /** name of curve */ - char *name; - - /** The prime that defines the field the curve is in (encoded in hex) */ - char *prime; - - /** The fields B param (hex) */ - char *B; - - /** The order of the curve (hex) */ - char *order; - - /** The x co-ordinate of the base point on the curve (hex) */ - char *Gx; - - /** The y co-ordinate of the base point on the curve (hex) */ - char *Gy; -} ltc_ecc_set_type; - -/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ -typedef struct { - /** The x co-ordinate */ - void *x; - - /** The y co-ordinate */ - void *y; - - /** The z co-ordinate */ - void *z; -} ecc_point; - -/** An ECC key */ -typedef struct { - /** Type of key, PK_PRIVATE or PK_PUBLIC */ - int type; - - /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */ - int idx; - - /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */ - const ltc_ecc_set_type *dp; - - /** The public key */ - ecc_point pubkey; - - /** The private key */ - void *k; -} ecc_key; - -/** the ECC params provided */ -extern const ltc_ecc_set_type ltc_ecc_sets[]; - -int ecc_test(void); -void ecc_sizes(int *low, int *high); -int ecc_get_size(ecc_key *key); - -int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); -int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); -void ecc_free(ecc_key *key); - -int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); -int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); -int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); - -int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); -int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); -int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); - -int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, - unsigned char *out, unsigned long *outlen); - -int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, int hash, - ecc_key *key); - -int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - ecc_key *key); - -int ecc_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, ecc_key *key); - -int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, ecc_key *key); - -/* low level functions */ -ecc_point *ltc_ecc_new_point(void); -void ltc_ecc_del_point(ecc_point *p); -int ltc_ecc_is_valid_idx(int n); - -/* point ops (mp == montgomery digit) */ -#if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC) -/* R = 2P */ -int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); - -/* R = P + Q */ -int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); -#endif - -#if defined(LTC_MECC_FP) -/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ -int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); - -/* functions for saving/loading/freeing/adding to fixed point cache */ -int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); -int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); -void ltc_ecc_fp_free(void); -int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); - -/* lock/unlock all points currently in fixed point cache */ -void ltc_ecc_fp_tablelock(int lock); -#endif - -/* R = kG */ -int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); - -#ifdef LTC_ECC_SHAMIR -/* kA*A + kB*B = C */ -int ltc_ecc_mul2add(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, - void *modulus); - -#ifdef LTC_MECC_FP -/* Shamir's trick with optimized point multiplication using fixed point cache */ -int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, void *modulus); -#endif - -#endif - - -/* map P to affine from projective */ -int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); - -#endif - -#ifdef LTC_MDSA - -/* Max diff between group and modulus size in bytes */ -#define LTC_MDSA_DELTA 512 - -/* Max DSA group size in bytes (default allows 4k-bit groups) */ -#define LTC_MDSA_MAX_GROUP 512 - -/** DSA key structure */ -typedef struct { - /** The key type, PK_PRIVATE or PK_PUBLIC */ - int type; - - /** The order of the sub-group used in octets */ - int qord; - - /** The generator */ - void *g; - - /** The prime used to generate the sub-group */ - void *q; - - /** The large prime that generats the field the contains the sub-group */ - void *p; - - /** The private key */ - void *x; - - /** The public key */ - void *y; -} dsa_key; - -int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); -void dsa_free(dsa_key *key); - -int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, - void *r, void *s, - prng_state *prng, int wprng, dsa_key *key); - -int dsa_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, dsa_key *key); - -int dsa_verify_hash_raw( void *r, void *s, - const unsigned char *hash, unsigned long hashlen, - int *stat, dsa_key *key); - -int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, dsa_key *key); - -int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, int hash, - dsa_key *key); - -int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - dsa_key *key); - -int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); -int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); -int dsa_verify_key(dsa_key *key, int *stat); - -int dsa_shared_secret(void *private_key, void *base, - dsa_key *public_key, - unsigned char *out, unsigned long *outlen); -#endif - -#ifdef LTC_DER -/* DER handling */ - -enum { - LTC_ASN1_EOL, - LTC_ASN1_BOOLEAN, - LTC_ASN1_INTEGER, - LTC_ASN1_SHORT_INTEGER, - LTC_ASN1_BIT_STRING, - LTC_ASN1_OCTET_STRING, - LTC_ASN1_NULL, - LTC_ASN1_OBJECT_IDENTIFIER, - LTC_ASN1_IA5_STRING, - LTC_ASN1_PRINTABLE_STRING, - LTC_ASN1_UTF8_STRING, - LTC_ASN1_UTCTIME, - LTC_ASN1_CHOICE, - LTC_ASN1_SEQUENCE, - LTC_ASN1_SET, - LTC_ASN1_SETOF -}; - -/** A LTC ASN.1 list type */ -typedef struct ltc_asn1_list_ { - /** The LTC ASN.1 enumerated type identifier */ - int type; - /** The data to encode or place for decoding */ - void *data; - /** The size of the input or resulting output */ - unsigned long size; - /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ - int used; - /** prev/next entry in the list */ - struct ltc_asn1_list_ *prev, *next, *child, *parent; -} ltc_asn1_list; - -#define LTC_SET_ASN1(list, index, Type, Data, Size) \ - do { \ - int LTC_MACRO_temp = (index); \ - ltc_asn1_list *LTC_MACRO_list = (list); \ - LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ - LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ - LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ - LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ - } while (0); - -/* SEQUENCE */ -int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, - unsigned char *out, unsigned long *outlen, int type_of); - -#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE) - -int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, - ltc_asn1_list *list, unsigned long outlen, int ordered); - -#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) - -int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, - unsigned long *outlen); - -/* SET */ -#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) -#define der_length_set der_length_sequence -int der_encode_set(ltc_asn1_list *list, unsigned long inlen, - unsigned char *out, unsigned long *outlen); - -int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, - unsigned char *out, unsigned long *outlen); - -/* VA list handy helpers with triplets of <type, size, data> */ -int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); -int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); - -/* FLEXI DECODER handle unknown list decoder */ -int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); -void der_free_sequence_flexi(ltc_asn1_list *list); -void der_sequence_free(ltc_asn1_list *in); - -/* BOOLEAN */ -int der_length_boolean(unsigned long *outlen); -int der_encode_boolean(int in, - unsigned char *out, unsigned long *outlen); -int der_decode_boolean(const unsigned char *in, unsigned long inlen, - int *out); -/* INTEGER */ -int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); -int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); -int der_length_integer(void *num, unsigned long *len); - -/* INTEGER -- handy for 0..2^32-1 values */ -int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); -int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); -int der_length_short_integer(unsigned long num, unsigned long *outlen); - -/* BIT STRING */ -int der_encode_bit_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_decode_bit_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_length_bit_string(unsigned long nbits, unsigned long *outlen); - -/* OCTET STRING */ -int der_encode_octet_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_decode_octet_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_length_octet_string(unsigned long noctets, unsigned long *outlen); - -/* OBJECT IDENTIFIER */ -int der_encode_object_identifier(unsigned long *words, unsigned long nwords, - unsigned char *out, unsigned long *outlen); -int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, - unsigned long *words, unsigned long *outlen); -int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); -unsigned long der_object_identifier_bits(unsigned long x); - -/* IA5 STRING */ -int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); - -int der_ia5_char_encode(int c); -int der_ia5_value_decode(int v); - -/* Printable STRING */ -int der_encode_printable_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_decode_printable_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); -int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); - -int der_printable_char_encode(int c); -int der_printable_value_decode(int v); - -/* UTF-8 */ -#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) -#include <wchar.h> -#else -typedef ulong32 wchar_t; -#endif - -int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen); - -int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, - wchar_t *out, unsigned long *outlen); -unsigned long der_utf8_charsize(const wchar_t c); -int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen); - - -/* CHOICE */ -int der_decode_choice(const unsigned char *in, unsigned long *inlen, - ltc_asn1_list *list, unsigned long outlen); - -/* UTCTime */ -typedef struct { - unsigned YY, /* year */ - MM, /* month */ - DD, /* day */ - hh, /* hour */ - mm, /* minute */ - ss, /* second */ - off_dir, /* timezone offset direction 0 == +, 1 == - */ - off_hh, /* timezone offset hours */ - off_mm; /* timezone offset minutes */ -} ltc_utctime; - -int der_encode_utctime(ltc_utctime *utctime, - unsigned char *out, unsigned long *outlen); - -int der_decode_utctime(const unsigned char *in, unsigned long *inlen, - ltc_utctime *out); - -int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); - - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pk.h,v $ */ -/* $Revision: 1.81 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h deleted file mode 100644 index 84fb82a6229..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_pkcs.h +++ /dev/null @@ -1,89 +0,0 @@ -/* LTC_PKCS Header Info */ - -/* ===> LTC_PKCS #1 -- RSA Cryptography <=== */ -#ifdef LTC_PKCS_1 - -enum ltc_pkcs_1_v1_5_blocks -{ - LTC_LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */ - LTC_LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */ -}; - -enum ltc_pkcs_1_paddings -{ - LTC_LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ - LTC_LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */ - LTC_LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */ -}; - -int pkcs_1_mgf1( int hash_idx, - const unsigned char *seed, unsigned long seedlen, - unsigned char *mask, unsigned long masklen); - -int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); -int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); - -/* *** v1.5 padding */ -int pkcs_1_v1_5_encode(const unsigned char *msg, - unsigned long msglen, - int block_type, - unsigned long modulus_bitlen, - prng_state *prng, - int prng_idx, - unsigned char *out, - unsigned long *outlen); - -int pkcs_1_v1_5_decode(const unsigned char *msg, - unsigned long msglen, - int block_type, - unsigned long modulus_bitlen, - unsigned char *out, - unsigned long *outlen, - int *is_valid); - -/* *** v2.1 padding */ -int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, - const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, prng_state *prng, - int prng_idx, int hash_idx, - unsigned char *out, unsigned long *outlen); - -int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, - const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, int hash_idx, - unsigned char *out, unsigned long *outlen, - int *res); - -int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, - unsigned long saltlen, prng_state *prng, - int prng_idx, int hash_idx, - unsigned long modulus_bitlen, - unsigned char *out, unsigned long *outlen); - -int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, - const unsigned char *sig, unsigned long siglen, - unsigned long saltlen, int hash_idx, - unsigned long modulus_bitlen, int *res); - -#endif /* LTC_PKCS_1 */ - -/* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */ -#ifdef LTC_PKCS_5 - -/* Algorithm #1 (old) */ -int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, - const unsigned char *salt, - int iteration_count, int hash_idx, - unsigned char *out, unsigned long *outlen); - -/* Algorithm #2 (new) */ -int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, - const unsigned char *salt, unsigned long salt_len, - int iteration_count, int hash_idx, - unsigned char *out, unsigned long *outlen); - -#endif /* LTC_PKCS_5 */ - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pkcs.h,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h b/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h deleted file mode 100644 index f3e3e550e88..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/headers/tomcrypt_prng.h +++ /dev/null @@ -1,199 +0,0 @@ -/* ---- PRNG Stuff ---- */ -#ifdef LTC_YARROW -struct yarrow_prng { - int cipher, hash; - unsigned char pool[MAXBLOCKSIZE]; - symmetric_CTR ctr; - LTC_MUTEX_TYPE(prng_lock) -}; -#endif - -#ifdef LTC_RC4 -struct rc4_prng { - int x, y; - unsigned char buf[256]; -}; -#endif - -#ifdef LTC_FORTUNA -struct fortuna_prng { - hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ - - symmetric_key skey; - - unsigned char K[32], /* the current key */ - IV[16]; /* IV for CTR mode */ - - unsigned long pool_idx, /* current pool we will add to */ - pool0_len, /* length of 0'th pool */ - wd; - - ulong64 reset_cnt; /* number of times we have reset */ - LTC_MUTEX_TYPE(prng_lock) -}; -#endif - -#ifdef LTC_SOBER128 -struct sober128_prng { - ulong32 R[17], /* Working storage for the shift register */ - initR[17], /* saved register contents */ - konst, /* key dependent constant */ - sbuf; /* partial word encryption buffer */ - - int nbuf, /* number of part-word stream bits buffered */ - flag, /* first add_entropy call or not? */ - set; /* did we call add_entropy to set key? */ - -}; -#endif - -typedef union Prng_state { - char dummy[1]; -#ifdef LTC_YARROW - struct yarrow_prng yarrow; -#endif -#ifdef LTC_RC4 - struct rc4_prng rc4; -#endif -#ifdef LTC_FORTUNA - struct fortuna_prng fortuna; -#endif -#ifdef LTC_SOBER128 - struct sober128_prng sober128; -#endif -} prng_state; - -/** PRNG descriptor */ -extern struct ltc_prng_descriptor { - /** Name of the PRNG */ - char *name; - /** size in bytes of exported state */ - int export_size; - /** Start a PRNG state - @param prng [out] The state to initialize - @return CRYPT_OK if successful - */ - int (*start)(prng_state *prng); - /** Add entropy to the PRNG - @param in The entropy - @param inlen Length of the entropy (octets)\ - @param prng The PRNG state - @return CRYPT_OK if successful - */ - int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng); - /** Ready a PRNG state to read from - @param prng The PRNG state to ready - @return CRYPT_OK if successful - */ - int (*ready)(prng_state *prng); - /** Read from the PRNG - @param out [out] Where to store the data - @param outlen Length of data desired (octets) - @param prng The PRNG state to read from - @return Number of octets read - */ - unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng); - /** Terminate a PRNG state - @param prng The PRNG state to terminate - @return CRYPT_OK if successful - */ - int (*done)(prng_state *prng); - /** Export a PRNG state - @param out [out] The destination for the state - @param outlen [in/out] The max size and resulting size of the PRNG state - @param prng The PRNG to export - @return CRYPT_OK if successful - */ - int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng); - /** Import a PRNG state - @param in The data to import - @param inlen The length of the data to import (octets) - @param prng The PRNG to initialize/import - @return CRYPT_OK if successful - */ - int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng); - /** Self-test the PRNG - @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled - */ - int (*test)(void); -} prng_descriptor[]; - -#ifdef LTC_YARROW -int yarrow_start(prng_state *prng); -int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); -int yarrow_ready(prng_state *prng); -unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng); -int yarrow_done(prng_state *prng); -int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng); -int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng); -int yarrow_test(void); -extern const struct ltc_prng_descriptor yarrow_desc; -#endif - -#ifdef LTC_FORTUNA -int fortuna_start(prng_state *prng); -int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); -int fortuna_ready(prng_state *prng); -unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng); -int fortuna_done(prng_state *prng); -int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng); -int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng); -int fortuna_test(void); -extern const struct ltc_prng_descriptor fortuna_desc; -#endif - -#ifdef LTC_RC4 -int rc4_start(prng_state *prng); -int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); -int rc4_ready(prng_state *prng); -unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng); -int rc4_done(prng_state *prng); -int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng); -int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng); -int rc4_test(void); -extern const struct ltc_prng_descriptor rc4_desc; -#endif - -#ifdef LTC_SPRNG -int sprng_start(prng_state *prng); -int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); -int sprng_ready(prng_state *prng); -unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng); -int sprng_done(prng_state *prng); -int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); -int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); -int sprng_test(void); -extern const struct ltc_prng_descriptor sprng_desc; -#endif - -#ifdef LTC_SOBER128 -int sober128_start(prng_state *prng); -int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); -int sober128_ready(prng_state *prng); -unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng); -int sober128_done(prng_state *prng); -int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng); -int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng); -int sober128_test(void); -extern const struct ltc_prng_descriptor sober128_desc; -#endif - -int find_prng(const char *name); -int register_prng(const struct ltc_prng_descriptor *prng); -int unregister_prng(const struct ltc_prng_descriptor *prng); -int prng_is_valid(int idx); -LTC_MUTEX_PROTO(ltc_prng_mutex) - -/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this - * might not work on all platforms as planned - */ -unsigned long rng_get_bytes(unsigned char *out, - unsigned long outlen, - void (*callback)(void)); - -int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); - - -/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_prng.h,v $ */ -/* $Revision: 1.9 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/math/ltm_desc.c b/dep/StormLib/src/libtomcrypt/src/math/ltm_desc.c deleted file mode 100644 index 25dc0b32279..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/math/ltm_desc.c +++ /dev/null @@ -1,483 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -#define DESC_DEF_ONLY -#include "../headers/tomcrypt.h" - -#ifdef LTM_DESC - -#include "../../../libtommath/tommath.h" - -static const struct { - int mpi_code, ltc_code; -} mpi_to_ltc_codes[] = { - { MP_OKAY , CRYPT_OK}, - { MP_MEM , CRYPT_MEM}, - { MP_VAL , CRYPT_INVALID_ARG}, -}; - -/** - Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) - @param err The error to convert - @return The equivalent LTC error code or CRYPT_ERROR if none found -*/ -static int mpi_to_ltc_error(int err) -{ - int x; - - for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { - if (err == mpi_to_ltc_codes[x].mpi_code) { - return mpi_to_ltc_codes[x].ltc_code; - } - } - return CRYPT_ERROR; -} - -static int init(void **a) -{ - int err; - - LTC_ARGCHK(a != NULL); - - *a = XCALLOC(1, sizeof(mp_int)); - if (*a == NULL) { - return CRYPT_MEM; - } - - if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) { - XFREE(*a); - } - return err; -} - -static void deinit(void *a) -{ - LTC_ARGCHKVD(a != NULL); - mp_clear(a); - XFREE(a); -} - -static int neg(void *a, void *b) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_neg(a, b)); -} - -static int copy(void *a, void *b) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_copy(a, b)); -} - -static int init_copy(void **a, void *b) -{ - if (init(a) != CRYPT_OK) { - return CRYPT_MEM; - } - return copy(b, *a); -} - -/* ---- trivial ---- */ -static int set_int(void *a, unsigned long b) -{ - LTC_ARGCHK(a != NULL); - return mpi_to_ltc_error(mp_set_int(a, b)); -} - -static unsigned long get_int(void *a) -{ - LTC_ARGCHK(a != NULL); - return mp_get_int(a); -} - -static unsigned long get_digit(void *a, int n) -{ - mp_int *A; - LTC_ARGCHK(a != NULL); - A = a; - return (n >= A->used || n < 0) ? 0 : A->dp[n]; -} - -static int get_digit_count(void *a) -{ - mp_int *A; - LTC_ARGCHK(a != NULL); - A = a; - return A->used; -} - -static int compare(void *a, void *b) -{ - int ret; - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - ret = mp_cmp(a, b); - switch (ret) { - case MP_LT: return LTC_MP_LT; - case MP_EQ: return LTC_MP_EQ; - case MP_GT: return LTC_MP_GT; - } - return 0; -} - -static int compare_d(void *a, unsigned long b) -{ - int ret; - LTC_ARGCHK(a != NULL); - ret = mp_cmp_d(a, b); - switch (ret) { - case MP_LT: return LTC_MP_LT; - case MP_EQ: return LTC_MP_EQ; - case MP_GT: return LTC_MP_GT; - } - return 0; -} - -static int count_bits(void *a) -{ - LTC_ARGCHK(a != NULL); - return mp_count_bits(a); -} - -static int count_lsb_bits(void *a) -{ - LTC_ARGCHK(a != NULL); - return mp_cnt_lsb(a); -} - - -static int twoexpt(void *a, int n) -{ - LTC_ARGCHK(a != NULL); - return mpi_to_ltc_error(mp_2expt(a, n)); -} - -/* ---- conversions ---- */ - -/* read ascii string */ -static int read_radix(void *a, const char *b, int radix) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_read_radix(a, b, radix)); -} - -/* write one */ -static int write_radix(void *a, char *b, int radix) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_toradix(a, b, radix)); -} - -/* get size as unsigned char string */ -static unsigned long unsigned_size(void *a) -{ - LTC_ARGCHK(a != NULL); - return mp_unsigned_bin_size(a); -} - -/* store */ -static int unsigned_write(void *a, unsigned char *b) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_to_unsigned_bin(a, b)); -} - -/* read */ -static int unsigned_read(void *a, unsigned char *b, unsigned long len) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len)); -} - -/* add */ -static int add(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_add(a, b, c)); -} - -static int addi(void *a, unsigned long b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_add_d(a, b, c)); -} - -/* sub */ -static int sub(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_sub(a, b, c)); -} - -static int subi(void *a, unsigned long b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_sub_d(a, b, c)); -} - -/* mul */ -static int mul(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_mul(a, b, c)); -} - -static int muli(void *a, unsigned long b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_mul_d(a, b, c)); -} - -/* sqr */ -static int sqr(void *a, void *b) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_sqr(a, b)); -} - -/* div */ -static int divide(void *a, void *b, void *c, void *d) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_div(a, b, c, d)); -} - -static int div_2(void *a, void *b) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_div_2(a, b)); -} - -/* modi */ -static int modi(void *a, unsigned long b, unsigned long *c) -{ - mp_digit tmp; - int err; - - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(c != NULL); - - if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) { - return err; - } - *c = tmp; - return CRYPT_OK; -} - -/* gcd */ -static int gcd(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_gcd(a, b, c)); -} - -/* lcm */ -static int lcm(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_lcm(a, b, c)); -} - -static int mulmod(void *a, void *b, void *c, void *d) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - LTC_ARGCHK(d != NULL); - return mpi_to_ltc_error(mp_mulmod(a,b,c,d)); -} - -static int sqrmod(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_sqrmod(a,b,c)); -} - -/* invmod */ -static int invmod(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_invmod(a, b, c)); -} - -/* setup */ -static int montgomery_setup(void *a, void **b) -{ - int err; - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - *b = XCALLOC(1, sizeof(mp_digit)); - if (*b == NULL) { - return CRYPT_MEM; - } - if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) { - XFREE(*b); - } - return err; -} - -/* get normalization value */ -static int montgomery_normalization(void *a, void *b) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b)); -} - -/* reduce */ -static int montgomery_reduce(void *a, void *b, void *c) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c))); -} - -/* clean up */ -static void montgomery_deinit(void *a) -{ - XFREE(a); -} - -static int exptmod(void *a, void *b, void *c, void *d) -{ - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - LTC_ARGCHK(c != NULL); - LTC_ARGCHK(d != NULL); - return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); -} - -static int isprime(void *a, int *b) -{ - int err; - LTC_ARGCHK(a != NULL); - LTC_ARGCHK(b != NULL); - err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b)); - *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO; - return err; -} - -const ltc_math_descriptor ltm_desc = { - - "LibTomMath", - (int)DIGIT_BIT, - - &init, - &init_copy, - &deinit, - - &neg, - ©, - - &set_int, - &get_int, - &get_digit, - &get_digit_count, - &compare, - &compare_d, - &count_bits, - &count_lsb_bits, - &twoexpt, - - &read_radix, - &write_radix, - &unsigned_size, - &unsigned_write, - &unsigned_read, - - &add, - &addi, - &sub, - &subi, - &mul, - &muli, - &sqr, - ÷, - &div_2, - &modi, - &gcd, - &lcm, - - &mulmod, - &sqrmod, - &invmod, - - &montgomery_setup, - &montgomery_normalization, - &montgomery_reduce, - &montgomery_deinit, - - &exptmod, - &isprime, - -#ifdef LTC_MECC -#ifdef LTC_MECC_FP - <c_ecc_fp_mulmod, -#else - <c_ecc_mulmod, -#endif - <c_ecc_projective_add_point, - <c_ecc_projective_dbl_point, - <c_ecc_map, -#ifdef LTC_ECC_SHAMIR -#ifdef LTC_MECC_FP - <c_ecc_fp_mul2add, -#else - <c_ecc_mul2add, -#endif /* LTC_MECC_FP */ -#else - NULL, -#endif /* LTC_ECC_SHAMIR */ -#else - NULL, NULL, NULL, NULL, NULL, -#endif /* LTC_MECC */ - -#ifdef LTC_MRSA - &rsa_make_key, - &rsa_exptmod, -#else - NULL, NULL -#endif -}; - - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/math/ltm_desc.c,v $ */ -/* $Revision: 1.31 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/math/multi.c b/dep/StormLib/src/libtomcrypt/src/math/multi.c deleted file mode 100644 index 7d40040a1de..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/math/multi.c +++ /dev/null @@ -1,61 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -#ifdef MPI -#include <stdarg.h> - -int ltc_init_multi(void **a, ...) -{ - void **cur = a; - int np = 0; - va_list args; - - va_start(args, a); - while (cur != NULL) { - if (mp_init(cur) != CRYPT_OK) { - /* failed */ - va_list clean_list; - - va_start(clean_list, a); - cur = a; - while (np--) { - mp_clear(*cur); - cur = va_arg(clean_list, void**); - } - va_end(clean_list); - return CRYPT_MEM; - } - ++np; - cur = va_arg(args, void**); - } - va_end(args); - return CRYPT_OK; -} - -void ltc_deinit_multi(void *a, ...) -{ - void *cur = a; - va_list args; - - va_start(args, a); - while (cur != NULL) { - mp_clear(cur); - cur = va_arg(args, void *); - } - va_end(args); -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/math/multi.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/math/rand_prime.c b/dep/StormLib/src/libtomcrypt/src/math/rand_prime.c deleted file mode 100644 index 913fa95a4a3..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/math/rand_prime.c +++ /dev/null @@ -1,87 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file rand_prime.c - Generate a random prime, Tom St Denis -*/ - -#define USE_BBS 1 - -int rand_prime(void *N, long len, prng_state *prng, int wprng) -{ - int err, res, type; - unsigned char *buf; - - LTC_ARGCHK(N != NULL); - - /* get type */ - if (len < 0) { - type = USE_BBS; - len = -len; - } else { - type = 0; - } - - /* allow sizes between 2 and 512 bytes for a prime size */ - if (len < 2 || len > 512) { - return CRYPT_INVALID_PRIME_SIZE; - } - - /* valid PRNG? Better be! */ - if ((err = prng_is_valid(wprng)) != CRYPT_OK) { - return err; - } - - /* allocate buffer to work with */ - buf = XCALLOC(1, len); - if (buf == NULL) { - return CRYPT_MEM; - } - - do { - /* generate value */ - if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) { - XFREE(buf); - return CRYPT_ERROR_READPRNG; - } - - /* munge bits */ - buf[0] |= 0x80 | 0x40; - buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); - - /* load value */ - if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { - XFREE(buf); - return err; - } - - /* test */ - if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) { - XFREE(buf); - return err; - } - } while (res == LTC_MP_NO); - -#ifdef LTC_CLEAN_STACK - zeromem(buf, len); -#endif - - XFREE(buf); - return CRYPT_OK; -} - - - -/* $Source: /cvs/libtom/libtomcrypt/src/math/rand_prime.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/base64_decode.c b/dep/StormLib/src/libtomcrypt/src/misc/base64_decode.c deleted file mode 100644 index 3d13393a1dc..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/base64_decode.c +++ /dev/null @@ -1,104 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file base64_decode.c - Compliant base64 code donated by Wayne Scott (wscott@bitmover.com) -*/ - - -#ifdef LTC_BASE64 - -static const unsigned char map[256] = { -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, -255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, -255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255 }; - -/** - base64 decode a block of memory - @param in The base64 data to decode - @param inlen The length of the base64 data - @param out [out] The destination of the binary decoded data - @param outlen [in/out] The max size and resulting size of the decoded data - @return CRYPT_OK if successful -*/ -int base64_decode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) -{ - unsigned long t, x, y, z; - unsigned char c; - int g; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - g = 3; - for (x = y = z = t = 0; x < inlen; x++) { - c = map[in[x]&0xFF]; - if (c == 255) continue; - /* the final = symbols are read and used to trim the remaining bytes */ - if (c == 254) { - c = 0; - /* prevent g < 0 which would potentially allow an overflow later */ - if (--g < 0) { - return CRYPT_INVALID_PACKET; - } - } else if (g != 3) { - /* we only allow = to be at the end */ - return CRYPT_INVALID_PACKET; - } - - t = (t<<6)|c; - - if (++y == 4) { - if (z + g > *outlen) { - return CRYPT_BUFFER_OVERFLOW; - } - out[z++] = (unsigned char)((t>>16)&255); - if (g > 1) out[z++] = (unsigned char)((t>>8)&255); - if (g > 2) out[z++] = (unsigned char)(t&255); - y = t = 0; - } - } - if (y != 0) { - return CRYPT_INVALID_PACKET; - } - *outlen = z; - return CRYPT_OK; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_decode.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c deleted file mode 100644 index 537516d80d9..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_argchk.c +++ /dev/null @@ -1,30 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" -#include <signal.h> - -/** - @file crypt_argchk.c - Perform argument checking, Tom St Denis -*/ - -#if (ARGTYPE == 0) -void crypt_argchk(char *v, char *s, int d) -{ - fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n", - v, d, s); - (void)raise(SIGABRT); -} -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_argchk.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c deleted file mode 100644 index fef2d8cca32..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_hash.c +++ /dev/null @@ -1,40 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_find_hash.c - Find a hash, Tom St Denis -*/ - -/** - Find a registered hash by name - @param name The name of the hash to look for - @return >= 0 if found, -1 if not present -*/ -int find_hash(const char *name) -{ - int x; - LTC_ARGCHK(name != NULL); - LTC_MUTEX_LOCK(<c_hash_mutex); - for (x = 0; x < TAB_SIZE; x++) { - if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) { - LTC_MUTEX_UNLOCK(<c_hash_mutex); - return x; - } - } - LTC_MUTEX_UNLOCK(<c_hash_mutex); - return -1; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c deleted file mode 100644 index fafbb0e226f..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_find_prng.c +++ /dev/null @@ -1,41 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_find_prng.c - Find a PRNG, Tom St Denis -*/ - -/** - Find a registered PRNG by name - @param name The name of the PRNG to look for - @return >= 0 if found, -1 if not present -*/ -int find_prng(const char *name) -{ - int x; - LTC_ARGCHK(name != NULL); - LTC_MUTEX_LOCK(<c_prng_mutex); - for (x = 0; x < TAB_SIZE; x++) { - if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) { - LTC_MUTEX_UNLOCK(<c_prng_mutex); - return x; - } - } - LTC_MUTEX_UNLOCK(<c_prng_mutex); - return -1; -} - - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_prng.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c deleted file mode 100644 index 5925fd27302..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_descriptor.c +++ /dev/null @@ -1,27 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_hash_descriptor.c - Stores the hash descriptor table, Tom St Denis -*/ - -struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { -{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL } -}; - -LTC_MUTEX_GLOBAL(ltc_hash_mutex) - - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c,v $ */ -/* $Revision: 1.10 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c deleted file mode 100644 index 8ed5105b56c..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_hash_is_valid.c +++ /dev/null @@ -1,36 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_hash_is_valid.c - Determine if hash is valid, Tom St Denis -*/ - -/* - Test if a hash index is valid - @param idx The index of the hash to search for - @return CRYPT_OK if valid -*/ -int hash_is_valid(int idx) -{ - LTC_MUTEX_LOCK(<c_hash_mutex); - if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) { - LTC_MUTEX_UNLOCK(<c_hash_mutex); - return CRYPT_INVALID_HASH; - } - LTC_MUTEX_UNLOCK(<c_hash_mutex); - return CRYPT_OK; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_libc.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_libc.c deleted file mode 100644 index bcc89f4f94d..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_libc.c +++ /dev/null @@ -1,43 +0,0 @@ -/*****************************************************************************/ -/* crypt_libc.c Copyright (c) Ladislav Zezula 2010 */ -/*---------------------------------------------------------------------------*/ -/* Description: */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 05.05.10 1.00 Lad The first version of crypt_libc.c */ -/*****************************************************************************/ - -// LibTomCrypt header -#include <stdlib.h> -#include "../headers/tomcrypt.h" - -void * LibTomMalloc(size_t n) -{ - return malloc(n); -} - -void * LibTomCalloc(size_t n, size_t s) -{ - return calloc(n, s); -} - -void * LibTomRealloc(void *p, size_t n) -{ - return realloc(p, n); -} - -void LibTomFree(void * p) -{ - free(p); -} - -clock_t LibTomClock(void) -{ - return clock(); -} - -void LibTomQsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)) -{ - qsort(base, nmemb, size, compar); -} diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c deleted file mode 100644 index 91ba9d162d2..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_ltc_mp_descriptor.c +++ /dev/null @@ -1,13 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -ltc_math_descriptor ltc_mp; diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c deleted file mode 100644 index c5b39e0c26f..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_descriptor.c +++ /dev/null @@ -1,26 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_prng_descriptor.c - Stores the PRNG descriptors, Tom St Denis -*/ -struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { -{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } -}; - -LTC_MUTEX_GLOBAL(ltc_prng_mutex) - - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c deleted file mode 100644 index d38fd3a3c9d..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_prng_is_valid.c +++ /dev/null @@ -1,36 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_prng_is_valid.c - Determine if PRNG is valid, Tom St Denis -*/ - -/* - Test if a PRNG index is valid - @param idx The index of the PRNG to search for - @return CRYPT_OK if valid -*/ -int prng_is_valid(int idx) -{ - LTC_MUTEX_LOCK(<c_prng_mutex); - if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) { - LTC_MUTEX_UNLOCK(<c_prng_mutex); - return CRYPT_INVALID_PRNG; - } - LTC_MUTEX_UNLOCK(<c_prng_mutex); - return CRYPT_OK; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c deleted file mode 100644 index 17300915487..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_hash.c +++ /dev/null @@ -1,54 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_register_hash.c - Register a HASH, Tom St Denis -*/ - -/** - Register a hash with the descriptor table - @param hash The hash you wish to register - @return value >= 0 if successfully added (or already present), -1 if unsuccessful -*/ -int register_hash(const struct ltc_hash_descriptor *hash) -{ - int x; - - LTC_ARGCHK(hash != NULL); - - /* is it already registered? */ - LTC_MUTEX_LOCK(<c_hash_mutex); - for (x = 0; x < TAB_SIZE; x++) { - if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { - LTC_MUTEX_UNLOCK(<c_hash_mutex); - return x; - } - } - - /* find a blank spot */ - for (x = 0; x < TAB_SIZE; x++) { - if (hash_descriptor[x].name == NULL) { - XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)); - LTC_MUTEX_UNLOCK(<c_hash_mutex); - return x; - } - } - - /* no spot */ - LTC_MUTEX_UNLOCK(<c_hash_mutex); - return -1; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_hash.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c b/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c deleted file mode 100644 index 29fc9bdf63d..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/crypt_register_prng.c +++ /dev/null @@ -1,54 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file crypt_register_prng.c - Register a PRNG, Tom St Denis -*/ - -/** - Register a PRNG with the descriptor table - @param prng The PRNG you wish to register - @return value >= 0 if successfully added (or already present), -1 if unsuccessful -*/ -int register_prng(const struct ltc_prng_descriptor *prng) -{ - int x; - - LTC_ARGCHK(prng != NULL); - - /* is it already registered? */ - LTC_MUTEX_LOCK(<c_prng_mutex); - for (x = 0; x < TAB_SIZE; x++) { - if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) { - LTC_MUTEX_UNLOCK(<c_prng_mutex); - return x; - } - } - - /* find a blank spot */ - for (x = 0; x < TAB_SIZE; x++) { - if (prng_descriptor[x].name == NULL) { - XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)); - LTC_MUTEX_UNLOCK(<c_prng_mutex); - return x; - } - } - - /* no spot */ - LTC_MUTEX_UNLOCK(<c_prng_mutex); - return -1; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_prng.c,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/misc/zeromem.c b/dep/StormLib/src/libtomcrypt/src/misc/zeromem.c deleted file mode 100644 index faa0efa7842..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/misc/zeromem.c +++ /dev/null @@ -1,34 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file zeromem.c - Zero a block of memory, Tom St Denis -*/ - -/** - Zero a block of memory - @param out The destination of the area to zero - @param outlen The length of the area to zero (octets) -*/ -void zeromem(void *out, size_t outlen) -{ - unsigned char *mem = out; - LTC_ARGCHKVD(out != NULL); - while (outlen-- > 0) { - *mem++ = 0; - } -} - -/* $Source: /cvs/libtom/libtomcrypt/src/misc/zeromem.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c deleted file mode 100644 index e53686750fd..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_bit_string.c +++ /dev/null @@ -1,102 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_bit_string.c - ASN.1 DER, encode a BIT STRING, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Store a BIT STRING - @param in The DER encoded BIT STRING - @param inlen The size of the DER BIT STRING - @param out [out] The array of bits stored (one per char) - @param outlen [in/out] The number of bits stored - @return CRYPT_OK if successful -*/ -int der_decode_bit_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) -{ - unsigned long dlen, blen, x, y; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - /* packet must be at least 4 bytes */ - if (inlen < 4) { - return CRYPT_INVALID_ARG; - } - - /* check for 0x03 */ - if ((in[0]&0x1F) != 0x03) { - return CRYPT_INVALID_PACKET; - } - - /* offset in the data */ - x = 1; - - /* get the length of the data */ - if (in[x] & 0x80) { - /* long format get number of length bytes */ - y = in[x++] & 0x7F; - - /* invalid if 0 or > 2 */ - if (y == 0 || y > 2) { - return CRYPT_INVALID_PACKET; - } - - /* read the data len */ - dlen = 0; - while (y--) { - dlen = (dlen << 8) | (unsigned long)in[x++]; - } - } else { - /* short format */ - dlen = in[x++] & 0x7F; - } - - /* is the data len too long or too short? */ - if ((dlen == 0) || (dlen + x > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* get padding count */ - blen = ((dlen - 1) << 3) - (in[x++] & 7); - - /* too many bits? */ - if (blen > *outlen) { - *outlen = blen; - return CRYPT_BUFFER_OVERFLOW; - } - - /* decode/store the bits */ - for (y = 0; y < blen; y++) { - out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; - if ((y & 7) == 7) { - ++x; - } - } - - /* we done */ - *outlen = blen; - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c deleted file mode 100644 index 617d4e8611d..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_boolean.c +++ /dev/null @@ -1,47 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_boolean.c - ASN.1 DER, decode a BOOLEAN, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Read a BOOLEAN - @param in The destination for the DER encoded BOOLEAN - @param inlen The size of the DER BOOLEAN - @param out [out] The boolean to decode - @return CRYPT_OK if successful -*/ -int der_decode_boolean(const unsigned char *in, unsigned long inlen, - int *out) -{ - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - - if (inlen != 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { - return CRYPT_INVALID_ARG; - } - - *out = (in[2]==0xFF) ? 1 : 0; - - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c,v $ */ -/* $Revision: 1.2 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c deleted file mode 100644 index 44a0891bead..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_choice.c +++ /dev/null @@ -1,182 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_choice.c - ASN.1 DER, decode a CHOICE, Tom St Denis -*/ - -#ifdef LTC_DER - -/** - Decode a CHOICE - @param in The DER encoded input - @param inlen [in/out] The size of the input and resulting size of read type - @param list The list of items to decode - @param outlen The number of items in the list - @return CRYPT_OK on success -*/ -int der_decode_choice(const unsigned char *in, unsigned long *inlen, - ltc_asn1_list *list, unsigned long outlen) -{ - unsigned long size, x, z; - void *data; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(inlen != NULL); - LTC_ARGCHK(list != NULL); - - /* get blk size */ - if (*inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* set all of the "used" flags to zero */ - for (x = 0; x < outlen; x++) { - list[x].used = 0; - } - - /* now scan until we have a winner */ - for (x = 0; x < outlen; x++) { - size = list[x].size; - data = list[x].data; - - switch (list[x].type) { - case LTC_ASN1_INTEGER: - if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { - if (der_length_integer(data, &z) == CRYPT_OK) { - list[x].used = 1; - *inlen = z; - return CRYPT_OK; - } - } - break; - - case LTC_ASN1_SHORT_INTEGER: - if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { - if (der_length_short_integer(size, &z) == CRYPT_OK) { - list[x].used = 1; - *inlen = z; - return CRYPT_OK; - } - } - break; - - case LTC_ASN1_BIT_STRING: - if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) { - if (der_length_bit_string(size, &z) == CRYPT_OK) { - list[x].used = 1; - list[x].size = size; - *inlen = z; - return CRYPT_OK; - } - } - break; - - case LTC_ASN1_OCTET_STRING: - if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { - if (der_length_octet_string(size, &z) == CRYPT_OK) { - list[x].used = 1; - list[x].size = size; - *inlen = z; - return CRYPT_OK; - } - } - break; - - case LTC_ASN1_NULL: - if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { - *inlen = 2; - list[x].used = 1; - return CRYPT_OK; - } - break; - - case LTC_ASN1_OBJECT_IDENTIFIER: - if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { - if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { - list[x].used = 1; - list[x].size = size; - *inlen = z; - return CRYPT_OK; - } - } - break; - - case LTC_ASN1_IA5_STRING: - if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { - if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { - list[x].used = 1; - list[x].size = size; - *inlen = z; - return CRYPT_OK; - } - } - break; - - - case LTC_ASN1_PRINTABLE_STRING: - if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { - if (der_length_printable_string(data, size, &z) == CRYPT_OK) { - list[x].used = 1; - list[x].size = size; - *inlen = z; - return CRYPT_OK; - } - } - break; - - case LTC_ASN1_UTF8_STRING: - if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) { - if (der_length_utf8_string(data, size, &z) == CRYPT_OK) { - list[x].used = 1; - list[x].size = size; - *inlen = z; - return CRYPT_OK; - } - } - break; - - case LTC_ASN1_UTCTIME: - z = *inlen; - if (der_decode_utctime(in, &z, data) == CRYPT_OK) { - list[x].used = 1; - *inlen = z; - return CRYPT_OK; - } - break; - - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: - if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { - if (der_length_sequence(data, size, &z) == CRYPT_OK) { - list[x].used = 1; - *inlen = z; - return CRYPT_OK; - } - } - break; - - default: - return CRYPT_INVALID_ARG; - } - } - - return CRYPT_INVALID_PACKET; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ -/* $Revision: 1.9 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c deleted file mode 100644 index f2e073b8d84..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_ia5_string.c +++ /dev/null @@ -1,96 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_ia5_string.c - ASN.1 DER, encode a IA5 STRING, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Store a IA5 STRING - @param in The DER encoded IA5 STRING - @param inlen The size of the DER IA5 STRING - @param out [out] The array of octets stored (one per char) - @param outlen [in/out] The number of octets stored - @return CRYPT_OK if successful -*/ -int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) -{ - unsigned long x, y, len; - int t; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - /* must have header at least */ - if (inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* check for 0x16 */ - if ((in[0] & 0x1F) != 0x16) { - return CRYPT_INVALID_PACKET; - } - x = 1; - - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; - } - - /* is it too long? */ - if (len > *outlen) { - *outlen = len; - return CRYPT_BUFFER_OVERFLOW; - } - - if (len + x > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* read the data */ - for (y = 0; y < len; y++) { - t = der_ia5_value_decode(in[x++]); - if (t == -1) { - return CRYPT_INVALID_ARG; - } - out[y] = t; - } - - *outlen = y; - - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c deleted file mode 100644 index cca27451963..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_integer.c +++ /dev/null @@ -1,110 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_integer.c - ASN.1 DER, decode an integer, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Read a mp_int integer - @param in The DER encoded data - @param inlen Size of DER encoded data - @param num The first mp_int to decode - @return CRYPT_OK if successful -*/ -int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) -{ - unsigned long x, y, z; - int err; - - LTC_ARGCHK(num != NULL); - LTC_ARGCHK(in != NULL); - - /* min DER INTEGER is 0x02 01 00 == 0 */ - if (inlen < (1 + 1 + 1)) { - return CRYPT_INVALID_PACKET; - } - - /* ok expect 0x02 when we AND with 0001 1111 [1F] */ - x = 0; - if ((in[x++] & 0x1F) != 0x02) { - return CRYPT_INVALID_PACKET; - } - - /* now decode the len stuff */ - z = in[x++]; - - if ((z & 0x80) == 0x00) { - /* short form */ - - /* will it overflow? */ - if (x + z > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* no so read it */ - if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { - return err; - } - } else { - /* long form */ - z &= 0x7F; - - /* will number of length bytes overflow? (or > 4) */ - if (((x + z) > inlen) || (z > 4) || (z == 0)) { - return CRYPT_INVALID_PACKET; - } - - /* now read it in */ - y = 0; - while (z--) { - y = ((unsigned long)(in[x++])) | (y << 8); - } - - /* now will reading y bytes overrun? */ - if ((x + y) > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* no so read it */ - if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { - return err; - } - } - - /* see if it's negative */ - if (in[x] & 0x80) { - void *tmp; - if (mp_init(&tmp) != CRYPT_OK) { - return CRYPT_MEM; - } - - if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { - mp_clear(tmp); - return CRYPT_MEM; - } - mp_clear(tmp); - } - - return CRYPT_OK; - -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c deleted file mode 100644 index e7baae88e0c..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_object_identifier.c +++ /dev/null @@ -1,99 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_object_identifier.c - ASN.1 DER, Decode Object Identifier, Tom St Denis -*/ - -#ifdef LTC_DER -/** - Decode OID data and store the array of integers in words - @param in The OID DER encoded data - @param inlen The length of the OID data - @param words [out] The destination of the OID words - @param outlen [in/out] The number of OID words - @return CRYPT_OK if successful -*/ -int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, - unsigned long *words, unsigned long *outlen) -{ - unsigned long x, y, t, len; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(words != NULL); - LTC_ARGCHK(outlen != NULL); - - /* header is at least 3 bytes */ - if (inlen < 3) { - return CRYPT_INVALID_PACKET; - } - - /* must be room for at least two words */ - if (*outlen < 2) { - return CRYPT_BUFFER_OVERFLOW; - } - - /* decode the packet header */ - x = 0; - if ((in[x++] & 0x1F) != 0x06) { - return CRYPT_INVALID_PACKET; - } - - /* get the length */ - if (in[x] < 128) { - len = in[x++]; - } else { - if (in[x] < 0x81 || in[x] > 0x82) { - return CRYPT_INVALID_PACKET; - } - y = in[x++] & 0x7F; - len = 0; - while (y--) { - len = (len << 8) | (unsigned long)in[x++]; - } - } - - if (len < 1 || (len + x) > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* decode words */ - y = 0; - t = 0; - while (len--) { - t = (t << 7) | (in[x] & 0x7F); - if (!(in[x++] & 0x80)) { - /* store t */ - if (y >= *outlen) { - return CRYPT_BUFFER_OVERFLOW; - } - if (y == 0) { - words[0] = t / 40; - words[1] = t % 40; - y = 2; - } else { - words[y++] = t; - } - t = 0; - } - } - - *outlen = y; - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c deleted file mode 100644 index 523d0baa057..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_octet_string.c +++ /dev/null @@ -1,91 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_octet_string.c - ASN.1 DER, encode a OCTET STRING, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Store a OCTET STRING - @param in The DER encoded OCTET STRING - @param inlen The size of the DER OCTET STRING - @param out [out] The array of octets stored (one per char) - @param outlen [in/out] The number of octets stored - @return CRYPT_OK if successful -*/ -int der_decode_octet_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) -{ - unsigned long x, y, len; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - /* must have header at least */ - if (inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* check for 0x04 */ - if ((in[0] & 0x1F) != 0x04) { - return CRYPT_INVALID_PACKET; - } - x = 1; - - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; - } - - /* is it too long? */ - if (len > *outlen) { - *outlen = len; - return CRYPT_BUFFER_OVERFLOW; - } - - if (len + x > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* read the data */ - for (y = 0; y < len; y++) { - out[y] = in[x++]; - } - - *outlen = y; - - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c deleted file mode 100644 index f8325934395..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_printable_string.c +++ /dev/null @@ -1,96 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_printable_string.c - ASN.1 DER, encode a printable STRING, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Store a printable STRING - @param in The DER encoded printable STRING - @param inlen The size of the DER printable STRING - @param out [out] The array of octets stored (one per char) - @param outlen [in/out] The number of octets stored - @return CRYPT_OK if successful -*/ -int der_decode_printable_string(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) -{ - unsigned long x, y, len; - int t; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - /* must have header at least */ - if (inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* check for 0x13 */ - if ((in[0] & 0x1F) != 0x13) { - return CRYPT_INVALID_PACKET; - } - x = 1; - - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; - } - - /* is it too long? */ - if (len > *outlen) { - *outlen = len; - return CRYPT_BUFFER_OVERFLOW; - } - - if (len + x > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* read the data */ - for (y = 0; y < len; y++) { - t = der_printable_value_decode(in[x++]); - if (t == -1) { - return CRYPT_INVALID_ARG; - } - out[y] = t; - } - - *outlen = y; - - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c deleted file mode 100644 index 9b00f61b09a..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_ex.c +++ /dev/null @@ -1,287 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" -#include <stdarg.h> - - -/** - @file der_decode_sequence_ex.c - ASN.1 DER, decode a SEQUENCE, Tom St Denis -*/ - -#ifdef LTC_DER - -/** - Decode a SEQUENCE - @param in The DER encoded input - @param inlen The size of the input - @param list The list of items to decode - @param outlen The number of items in the list - @param ordered Search an unordeded or ordered list - @return CRYPT_OK on success -*/ -int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, - ltc_asn1_list *list, unsigned long outlen, int ordered) -{ - int err, type; - unsigned long size, x, y, z, i, blksize; - void *data; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(list != NULL); - - /* get blk size */ - if (inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ - x = 0; - if (in[x] != 0x30 && in[x] != 0x31) { - return CRYPT_INVALID_PACKET; - } - ++x; - - if (in[x] < 128) { - blksize = in[x++]; - } else if (in[x] & 0x80) { - if (in[x] < 0x81 || in[x] > 0x83) { - return CRYPT_INVALID_PACKET; - } - y = in[x++] & 0x7F; - - /* would reading the len bytes overrun? */ - if (x + y > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* read len */ - blksize = 0; - while (y--) { - blksize = (blksize << 8) | (unsigned long)in[x++]; - } - } - - /* would this blksize overflow? */ - if (x + blksize > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* mark all as unused */ - for (i = 0; i < outlen; i++) { - list[i].used = 0; - } - - /* ok read data */ - inlen = blksize; - for (i = 0; i < outlen; i++) { - z = 0; - type = list[i].type; - size = list[i].size; - data = list[i].data; - if (!ordered && list[i].used == 1) { continue; } - - if (type == LTC_ASN1_EOL) { - break; - } - - switch (type) { - case LTC_ASN1_BOOLEAN: - z = inlen; - if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = der_length_boolean(&z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_INTEGER: - z = inlen; - if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - if ((err = der_length_integer(data, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_SHORT_INTEGER: - z = inlen; - if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { - goto LBL_ERR; - } - - break; - - case LTC_ASN1_BIT_STRING: - z = inlen; - if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_OCTET_STRING: - z = inlen; - if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_NULL: - if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { - if (!ordered) { continue; } - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - z = 2; - break; - - case LTC_ASN1_OBJECT_IDENTIFIER: - z = inlen; - if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_IA5_STRING: - z = inlen; - if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - - case LTC_ASN1_PRINTABLE_STRING: - z = inlen; - if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_UTF8_STRING: - z = inlen; - if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - list[i].size = size; - if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_UTCTIME: - z = inlen; - if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - break; - - case LTC_ASN1_SET: - z = inlen; - if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: - /* detect if we have the right type */ - if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - - z = inlen; - if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { - goto LBL_ERR; - } - break; - - - case LTC_ASN1_CHOICE: - z = inlen; - if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { - if (!ordered) { continue; } - goto LBL_ERR; - } - break; - - default: - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - x += z; - inlen -= z; - list[i].used = 1; - if (!ordered) { - /* restart the decoder */ - i = -1; - } - } - - for (i = 0; i < outlen; i++) { - if (list[i].used == 0) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - } - err = CRYPT_OK; - -LBL_ERR: - return err; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */ -/* $Revision: 1.16 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c deleted file mode 100644 index 9c648bc89c6..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_flexi.c +++ /dev/null @@ -1,386 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_sequence_flexi.c - ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis -*/ - -#ifdef LTC_DER - -static unsigned long fetch_length(const unsigned char *in, unsigned long inlen) -{ - unsigned long x, y, z; - - y = 0; - - /* skip type and read len */ - if (inlen < 2) { - return 0xFFFFFFFF; - } - ++in; ++y; - - /* read len */ - x = *in++; ++y; - - /* <128 means literal */ - if (x < 128) { - return x+y; - } - x &= 0x7F; /* the lower 7 bits are the length of the length */ - inlen -= 2; - - /* len means len of len! */ - if (x == 0 || x > 4 || x > inlen) { - return 0xFFFFFFFF; - } - - y += x; - z = 0; - while (x--) { - z = (z<<8) | ((unsigned long)*in); - ++in; - } - return z+y; -} - -/** - ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. - @param in The input buffer - @param inlen [in/out] The length of the input buffer and on output the amount of decoded data - @param out [out] A pointer to the linked list - @return CRYPT_OK on success. -*/ -int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) -{ - ltc_asn1_list *l; - unsigned long err, type, len, totlen, x, y; - void *realloc_tmp; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(inlen != NULL); - LTC_ARGCHK(out != NULL); - - l = NULL; - totlen = 0; - - /* scan the input and and get lengths and what not */ - while (*inlen) { - /* read the type byte */ - type = *in; - - /* fetch length */ - len = fetch_length(in, *inlen); - if (len > *inlen) { - err = CRYPT_INVALID_PACKET; - goto error; - } - - /* alloc new link */ - if (l == NULL) { - l = XCALLOC(1, sizeof(*l)); - if (l == NULL) { - err = CRYPT_MEM; - goto error; - } - } else { - l->next = XCALLOC(1, sizeof(*l)); - if (l->next == NULL) { - err = CRYPT_MEM; - goto error; - } - l->next->prev = l; - l = l->next; - } - - /* now switch on type */ - switch (type) { - case 0x01: /* BOOLEAN */ - l->type = LTC_ASN1_BOOLEAN; - l->size = 1; - l->data = XCALLOC(1, sizeof(int)); - - if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_boolean(&len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x02: /* INTEGER */ - /* init field */ - l->type = LTC_ASN1_INTEGER; - l->size = 1; - if ((err = mp_init(&l->data)) != CRYPT_OK) { - goto error; - } - - /* decode field */ - if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) { - goto error; - } - - /* calc length of object */ - if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x03: /* BIT */ - /* init field */ - l->type = LTC_ASN1_BIT_STRING; - l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */ - - if ((l->data = XCALLOC(1, l->size)) == NULL) { - err = CRYPT_MEM; - goto error; - } - - if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x04: /* OCTET */ - - /* init field */ - l->type = LTC_ASN1_OCTET_STRING; - l->size = len; - - if ((l->data = XCALLOC(1, l->size)) == NULL) { - err = CRYPT_MEM; - goto error; - } - - if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x05: /* NULL */ - - /* valid NULL is 0x05 0x00 */ - if (in[0] != 0x05 || in[1] != 0x00) { - err = CRYPT_INVALID_PACKET; - goto error; - } - - /* simple to store ;-) */ - l->type = LTC_ASN1_NULL; - l->data = NULL; - l->size = 0; - len = 2; - - break; - - case 0x06: /* OID */ - - /* init field */ - l->type = LTC_ASN1_OBJECT_IDENTIFIER; - l->size = len; - - if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { - err = CRYPT_MEM; - goto error; - } - - if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) { - goto error; - } - - /* resize it to save a bunch of mem */ - if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) { - /* out of heap but this is not an error */ - break; - } - l->data = realloc_tmp; - break; - - case 0x0C: /* UTF8 */ - - /* init field */ - l->type = LTC_ASN1_UTF8_STRING; - l->size = len; - - if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) { - err = CRYPT_MEM; - goto error; - } - - if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x13: /* PRINTABLE */ - - /* init field */ - l->type = LTC_ASN1_PRINTABLE_STRING; - l->size = len; - - if ((l->data = XCALLOC(1, l->size)) == NULL) { - err = CRYPT_MEM; - goto error; - } - - if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x16: /* IA5 */ - - /* init field */ - l->type = LTC_ASN1_IA5_STRING; - l->size = len; - - if ((l->data = XCALLOC(1, l->size)) == NULL) { - err = CRYPT_MEM; - goto error; - } - - if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x17: /* UTC TIME */ - - /* init field */ - l->type = LTC_ASN1_UTCTIME; - l->size = 1; - - if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { - err = CRYPT_MEM; - goto error; - } - - len = *inlen; - if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) { - goto error; - } - - if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) { - goto error; - } - break; - - case 0x30: /* SEQUENCE */ - case 0x31: /* SET */ - - /* init field */ - l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET; - - /* we have to decode the SEQUENCE header and get it's length */ - - /* move past type */ - ++in; --(*inlen); - - /* read length byte */ - x = *in++; --(*inlen); - - /* smallest SEQUENCE/SET header */ - y = 2; - - /* now if it's > 127 the next bytes are the length of the length */ - if (x > 128) { - x &= 0x7F; - in += x; - *inlen -= x; - - /* update sequence header len */ - y += x; - } - - /* Sequence elements go as child */ - len = len - y; - if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { - goto error; - } - - /* len update */ - totlen += y; - - /* link them up y0 */ - l->child->parent = l; - - break; - default: - /* invalid byte ... this is a soft error */ - /* remove link */ - l = l->prev; - XFREE(l->next); - l->next = NULL; - goto outside; - } - - /* advance pointers */ - totlen += len; - in += len; - *inlen -= len; - } - -outside: - - /* rewind l please */ - while (l->prev != NULL || l->parent != NULL) { - if (l->parent != NULL) { - l = l->parent; - } else { - l = l->prev; - } - } - - /* return */ - *out = l; - *inlen = totlen; - return CRYPT_OK; - -error: - /* free list */ - der_sequence_free(l); - - return err; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c,v $ */ -/* $Revision: 1.26 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c deleted file mode 100644 index ff633df3511..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_sequence_multi.c +++ /dev/null @@ -1,139 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" -#include <stdarg.h> - - -/** - @file der_decode_sequence_multi.c - ASN.1 DER, decode a SEQUENCE, Tom St Denis -*/ - -#ifdef LTC_DER - -/** - Decode a SEQUENCE type using a VA list - @param in Input buffer - @param inlen Length of input in octets - @remark <...> is of the form <type, size, data> (int, unsigned long, void*) - @return CRYPT_OK on success -*/ -int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) -{ - int err, type; - unsigned long size, x; - void *data; - va_list args; - ltc_asn1_list *list; - - LTC_ARGCHK(in != NULL); - - /* get size of output that will be required */ - va_start(args, inlen); - x = 0; - for (;;) { - type = va_arg(args, int); - size = va_arg(args, unsigned long); - data = va_arg(args, void*); - - if (type == LTC_ASN1_EOL) { - break; - } - - switch (type) { - case LTC_ASN1_BOOLEAN: - case LTC_ASN1_INTEGER: - case LTC_ASN1_SHORT_INTEGER: - case LTC_ASN1_BIT_STRING: - case LTC_ASN1_OCTET_STRING: - case LTC_ASN1_NULL: - case LTC_ASN1_OBJECT_IDENTIFIER: - case LTC_ASN1_IA5_STRING: - case LTC_ASN1_PRINTABLE_STRING: - case LTC_ASN1_UTF8_STRING: - case LTC_ASN1_UTCTIME: - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: - case LTC_ASN1_CHOICE: - ++x; - break; - - default: - va_end(args); - return CRYPT_INVALID_ARG; - } - } - va_end(args); - - /* allocate structure for x elements */ - if (x == 0) { - return CRYPT_NOP; - } - - list = XCALLOC(sizeof(*list), x); - if (list == NULL) { - return CRYPT_MEM; - } - - /* fill in the structure */ - va_start(args, inlen); - x = 0; - for (;;) { - type = va_arg(args, int); - size = va_arg(args, unsigned long); - data = va_arg(args, void*); - - if (type == LTC_ASN1_EOL) { - break; - } - - switch (type) { - case LTC_ASN1_BOOLEAN: - case LTC_ASN1_INTEGER: - case LTC_ASN1_SHORT_INTEGER: - case LTC_ASN1_BIT_STRING: - case LTC_ASN1_OCTET_STRING: - case LTC_ASN1_NULL: - case LTC_ASN1_OBJECT_IDENTIFIER: - case LTC_ASN1_IA5_STRING: - case LTC_ASN1_PRINTABLE_STRING: - case LTC_ASN1_UTF8_STRING: - case LTC_ASN1_UTCTIME: - case LTC_ASN1_SEQUENCE: - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: - case LTC_ASN1_CHOICE: - list[x].type = type; - list[x].size = size; - list[x++].data = data; - break; - - default: - va_end(args); - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - } - va_end(args); - - err = der_decode_sequence(in, inlen, list, x); -LBL_ERR: - XFREE(list); - return err; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */ -/* $Revision: 1.13 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c deleted file mode 100644 index 907e4e1c3bb..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_short_integer.c +++ /dev/null @@ -1,68 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_short_integer.c - ASN.1 DER, decode an integer, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Read a short integer - @param in The DER encoded data - @param inlen Size of data - @param num [out] The integer to decode - @return CRYPT_OK if successful -*/ -int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num) -{ - unsigned long len, x, y; - - LTC_ARGCHK(num != NULL); - LTC_ARGCHK(in != NULL); - - /* check length */ - if (inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* check header */ - x = 0; - if ((in[x++] & 0x1F) != 0x02) { - return CRYPT_INVALID_PACKET; - } - - /* get the packet len */ - len = in[x++]; - - if (x + len > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* read number */ - y = 0; - while (len--) { - y = (y<<8) | (unsigned long)in[x++]; - } - *num = y; - - return CRYPT_OK; - -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c deleted file mode 100644 index 7f3f0d76683..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utctime.c +++ /dev/null @@ -1,127 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_utctime.c - ASN.1 DER, decode a UTCTIME, Tom St Denis -*/ - -#ifdef LTC_DER - -static int char_to_int(unsigned char x) -{ - switch (x) { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - } - return 100; -} - -#define DECODE_V(y, max) \ - y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ - if (y >= max) return CRYPT_INVALID_PACKET; \ - x += 2; - -/** - Decodes a UTC time structure in DER format (reads all 6 valid encoding formats) - @param in Input buffer - @param inlen Length of input buffer in octets - @param out [out] Destination of UTC time structure - @return CRYPT_OK if successful -*/ -int der_decode_utctime(const unsigned char *in, unsigned long *inlen, - ltc_utctime *out) -{ - unsigned char buf[32]; - unsigned long x; - int y; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(inlen != NULL); - LTC_ARGCHK(out != NULL); - - /* check header */ - if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* decode the string */ - for (x = 0; x < in[1]; x++) { - y = der_ia5_value_decode(in[x+2]); - if (y == -1) { - return CRYPT_INVALID_PACKET; - } - buf[x] = y; - } - *inlen = 2 + x; - - - /* possible encodings are -YYMMDDhhmmZ -YYMMDDhhmm+hh'mm' -YYMMDDhhmm-hh'mm' -YYMMDDhhmmssZ -YYMMDDhhmmss+hh'mm' -YYMMDDhhmmss-hh'mm' - - So let's do a trivial decode upto [including] mm - */ - - x = 0; - DECODE_V(out->YY, 100); - DECODE_V(out->MM, 13); - DECODE_V(out->DD, 32); - DECODE_V(out->hh, 24); - DECODE_V(out->mm, 60); - - /* clear timezone and seconds info */ - out->off_dir = out->off_hh = out->off_mm = out->ss = 0; - - /* now is it Z, +, - or 0-9 */ - if (buf[x] == 'Z') { - return CRYPT_OK; - } else if (buf[x] == '+' || buf[x] == '-') { - out->off_dir = (buf[x++] == '+') ? 0 : 1; - DECODE_V(out->off_hh, 24); - DECODE_V(out->off_mm, 60); - return CRYPT_OK; - } - - /* decode seconds */ - DECODE_V(out->ss, 60); - - /* now is it Z, +, - */ - if (buf[x] == 'Z') { - return CRYPT_OK; - } else if (buf[x] == '+' || buf[x] == '-') { - out->off_dir = (buf[x++] == '+') ? 0 : 1; - DECODE_V(out->off_hh, 24); - DECODE_V(out->off_mm, 60); - return CRYPT_OK; - } else { - return CRYPT_INVALID_PACKET; - } -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */ -/* $Revision: 1.9 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c deleted file mode 100644 index 898d6cd2a76..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_decode_utf8_string.c +++ /dev/null @@ -1,111 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_decode_utf8_string.c - ASN.1 DER, encode a UTF8 STRING, Tom St Denis -*/ - - -#ifdef LTC_DER - -/** - Store a UTF8 STRING - @param in The DER encoded UTF8 STRING - @param inlen The size of the DER UTF8 STRING - @param out [out] The array of utf8s stored (one per char) - @param outlen [in/out] The number of utf8s stored - @return CRYPT_OK if successful -*/ -int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, - wchar_t *out, unsigned long *outlen) -{ - wchar_t tmp; - unsigned long x, y, z, len; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - /* must have header at least */ - if (inlen < 2) { - return CRYPT_INVALID_PACKET; - } - - /* check for 0x0C */ - if ((in[0] & 0x1F) != 0x0C) { - return CRYPT_INVALID_PACKET; - } - x = 1; - - /* decode the length */ - if (in[x] & 0x80) { - /* valid # of bytes in length are 1,2,3 */ - y = in[x] & 0x7F; - if ((y == 0) || (y > 3) || ((x + y) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* read the length in */ - len = 0; - ++x; - while (y--) { - len = (len << 8) | in[x++]; - } - } else { - len = in[x++] & 0x7F; - } - - if (len + x > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* proceed to decode */ - for (y = 0; x < inlen; ) { - /* get first byte */ - tmp = in[x++]; - - /* count number of bytes */ - for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); - - if (z > 4 || (x + (z - 1) > inlen)) { - return CRYPT_INVALID_PACKET; - } - - /* decode, grab upper bits */ - tmp >>= z; - - /* grab remaining bytes */ - if (z > 1) { --z; } - while (z-- != 0) { - if ((in[x] & 0xC0) != 0x80) { - return CRYPT_INVALID_PACKET; - } - tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); - } - - if (y > *outlen) { - *outlen = y; - return CRYPT_BUFFER_OVERFLOW; - } - out[y++] = tmp; - } - *outlen = y; - - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c deleted file mode 100644 index 2bffa3b6341..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_bit_string.c +++ /dev/null @@ -1,54 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_bit_string.c - ASN.1 DER, get length of BIT STRING, Tom St Denis -*/ - -#ifdef LTC_DER -/** - Gets length of DER encoding of BIT STRING - @param nbits The number of bits in the string to encode - @param outlen [out] The length of the DER encoding for the given string - @return CRYPT_OK if successful -*/ -int der_length_bit_string(unsigned long nbits, unsigned long *outlen) -{ - unsigned long nbytes; - LTC_ARGCHK(outlen != NULL); - - /* get the number of the bytes */ - nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; - - if (nbytes < 128) { - /* 03 LL PP DD DD DD ... */ - *outlen = 2 + nbytes; - } else if (nbytes < 256) { - /* 03 81 LL PP DD DD DD ... */ - *outlen = 3 + nbytes; - } else if (nbytes < 65536) { - /* 03 82 LL LL PP DD DD DD ... */ - *outlen = 4 + nbytes; - } else { - return CRYPT_INVALID_ARG; - } - - return CRYPT_OK; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c deleted file mode 100644 index e34ce5c65d8..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_boolean.c +++ /dev/null @@ -1,35 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_boolean.c - ASN.1 DER, get length of a BOOLEAN, Tom St Denis -*/ - -#ifdef LTC_DER -/** - Gets length of DER encoding of a BOOLEAN - @param outlen [out] The length of the DER encoding - @return CRYPT_OK if successful -*/ -int der_length_boolean(unsigned long *outlen) -{ - LTC_ARGCHK(outlen != NULL); - *outlen = 3; - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c deleted file mode 100644 index 473bc793257..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_ia5_string.c +++ /dev/null @@ -1,194 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_ia5_string.c - ASN.1 DER, get length of IA5 STRING, Tom St Denis -*/ - -#ifdef LTC_DER - -static const struct { - int code, value; -} ia5_table[] = { -{ '\0', 0 }, -{ '\a', 7 }, -{ '\b', 8 }, -{ '\t', 9 }, -{ '\n', 10 }, -{ '\f', 12 }, -{ '\r', 13 }, -{ ' ', 32 }, -{ '!', 33 }, -{ '"', 34 }, -{ '#', 35 }, -{ '$', 36 }, -{ '%', 37 }, -{ '&', 38 }, -{ '\'', 39 }, -{ '(', 40 }, -{ ')', 41 }, -{ '*', 42 }, -{ '+', 43 }, -{ ',', 44 }, -{ '-', 45 }, -{ '.', 46 }, -{ '/', 47 }, -{ '0', 48 }, -{ '1', 49 }, -{ '2', 50 }, -{ '3', 51 }, -{ '4', 52 }, -{ '5', 53 }, -{ '6', 54 }, -{ '7', 55 }, -{ '8', 56 }, -{ '9', 57 }, -{ ':', 58 }, -{ ';', 59 }, -{ '<', 60 }, -{ '=', 61 }, -{ '>', 62 }, -{ '?', 63 }, -{ '@', 64 }, -{ 'A', 65 }, -{ 'B', 66 }, -{ 'C', 67 }, -{ 'D', 68 }, -{ 'E', 69 }, -{ 'F', 70 }, -{ 'G', 71 }, -{ 'H', 72 }, -{ 'I', 73 }, -{ 'J', 74 }, -{ 'K', 75 }, -{ 'L', 76 }, -{ 'M', 77 }, -{ 'N', 78 }, -{ 'O', 79 }, -{ 'P', 80 }, -{ 'Q', 81 }, -{ 'R', 82 }, -{ 'S', 83 }, -{ 'T', 84 }, -{ 'U', 85 }, -{ 'V', 86 }, -{ 'W', 87 }, -{ 'X', 88 }, -{ 'Y', 89 }, -{ 'Z', 90 }, -{ '[', 91 }, -{ '\\', 92 }, -{ ']', 93 }, -{ '^', 94 }, -{ '_', 95 }, -{ '`', 96 }, -{ 'a', 97 }, -{ 'b', 98 }, -{ 'c', 99 }, -{ 'd', 100 }, -{ 'e', 101 }, -{ 'f', 102 }, -{ 'g', 103 }, -{ 'h', 104 }, -{ 'i', 105 }, -{ 'j', 106 }, -{ 'k', 107 }, -{ 'l', 108 }, -{ 'm', 109 }, -{ 'n', 110 }, -{ 'o', 111 }, -{ 'p', 112 }, -{ 'q', 113 }, -{ 'r', 114 }, -{ 's', 115 }, -{ 't', 116 }, -{ 'u', 117 }, -{ 'v', 118 }, -{ 'w', 119 }, -{ 'x', 120 }, -{ 'y', 121 }, -{ 'z', 122 }, -{ '{', 123 }, -{ '|', 124 }, -{ '}', 125 }, -{ '~', 126 } -}; - -int der_ia5_char_encode(int c) -{ - int x; - for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { - if (ia5_table[x].code == c) { - return ia5_table[x].value; - } - } - return -1; -} - -int der_ia5_value_decode(int v) -{ - int x; - for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { - if (ia5_table[x].value == v) { - return ia5_table[x].code; - } - } - return -1; -} - -/** - Gets length of DER encoding of IA5 STRING - @param octets The values you want to encode - @param noctets The number of octets in the string to encode - @param outlen [out] The length of the DER encoding for the given string - @return CRYPT_OK if successful -*/ -int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) -{ - unsigned long x; - - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(octets != NULL); - - /* scan string for validity */ - for (x = 0; x < noctets; x++) { - if (der_ia5_char_encode(octets[x]) == -1) { - return CRYPT_INVALID_ARG; - } - } - - if (noctets < 128) { - /* 16 LL DD DD DD ... */ - *outlen = 2 + noctets; - } else if (noctets < 256) { - /* 16 81 LL DD DD DD ... */ - *outlen = 3 + noctets; - } else if (noctets < 65536UL) { - /* 16 82 LL LL DD DD DD ... */ - *outlen = 4 + noctets; - } else if (noctets < 16777216UL) { - /* 16 83 LL LL LL DD DD DD ... */ - *outlen = 5 + noctets; - } else { - return CRYPT_INVALID_ARG; - } - - return CRYPT_OK; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c deleted file mode 100644 index 540d205f028..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_integer.c +++ /dev/null @@ -1,82 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_integer.c - ASN.1 DER, get length of encoding, Tom St Denis -*/ - - -#ifdef LTC_DER -/** - Gets length of DER encoding of num - @param num The int to get the size of - @param outlen [out] The length of the DER encoding for the given integer - @return CRYPT_OK if successful -*/ -int der_length_integer(void *num, unsigned long *outlen) -{ - unsigned long z, len; - int leading_zero; - - LTC_ARGCHK(num != NULL); - LTC_ARGCHK(outlen != NULL); - - if (mp_cmp_d(num, 0) != LTC_MP_LT) { - /* positive */ - - /* we only need a leading zero if the msb of the first byte is one */ - if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { - leading_zero = 1; - } else { - leading_zero = 0; - } - - /* size for bignum */ - z = len = leading_zero + mp_unsigned_bin_size(num); - } else { - /* it's negative */ - /* find power of 2 that is a multiple of eight and greater than count bits */ - leading_zero = 0; - z = mp_count_bits(num); - z = z + (8 - (z & 7)); - if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; - len = z = z >> 3; - } - - /* now we need a length */ - if (z < 128) { - /* short form */ - ++len; - } else { - /* long form (relies on z != 0), assumes length bytes < 128 */ - ++len; - - while (z) { - ++len; - z >>= 8; - } - } - - /* we need a 0x02 to indicate it's INTEGER */ - ++len; - - /* return length */ - *outlen = len; - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c deleted file mode 100644 index 94c326f7cac..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_object_identifier.c +++ /dev/null @@ -1,89 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_object_identifier.c - ASN.1 DER, get length of Object Identifier, Tom St Denis -*/ - -#ifdef LTC_DER - -unsigned long der_object_identifier_bits(unsigned long x) -{ - unsigned long c; - x &= 0xFFFFFFFF; - c = 0; - while (x) { - ++c; - x >>= 1; - } - return c; -} - - -/** - Gets length of DER encoding of Object Identifier - @param nwords The number of OID words - @param words The actual OID words to get the size of - @param outlen [out] The length of the DER encoding for the given string - @return CRYPT_OK if successful -*/ -int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) -{ - unsigned long y, z, t, wordbuf; - - LTC_ARGCHK(words != NULL); - LTC_ARGCHK(outlen != NULL); - - - /* must be >= 2 words */ - if (nwords < 2) { - return CRYPT_INVALID_ARG; - } - - /* word1 = 0,1,2,3 and word2 0..39 */ - if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) { - return CRYPT_INVALID_ARG; - } - - /* leading word is the first two */ - z = 0; - wordbuf = words[0] * 40 + words[1]; - for (y = 1; y < nwords; y++) { - t = der_object_identifier_bits(wordbuf); - z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); - if (y < nwords - 1) { - /* grab next word */ - wordbuf = words[y+1]; - } - } - - /* now depending on the length our length encoding changes */ - if (z < 128) { - z += 2; - } else if (z < 256) { - z += 3; - } else if (z < 65536UL) { - z += 4; - } else { - return CRYPT_INVALID_ARG; - } - - *outlen = z; - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c deleted file mode 100644 index acd4053c16a..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_octet_string.c +++ /dev/null @@ -1,53 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_octet_string.c - ASN.1 DER, get length of OCTET STRING, Tom St Denis -*/ - -#ifdef LTC_DER -/** - Gets length of DER encoding of OCTET STRING - @param noctets The number of octets in the string to encode - @param outlen [out] The length of the DER encoding for the given string - @return CRYPT_OK if successful -*/ -int der_length_octet_string(unsigned long noctets, unsigned long *outlen) -{ - LTC_ARGCHK(outlen != NULL); - - if (noctets < 128) { - /* 04 LL DD DD DD ... */ - *outlen = 2 + noctets; - } else if (noctets < 256) { - /* 04 81 LL DD DD DD ... */ - *outlen = 3 + noctets; - } else if (noctets < 65536UL) { - /* 04 82 LL LL DD DD DD ... */ - *outlen = 4 + noctets; - } else if (noctets < 16777216UL) { - /* 04 83 LL LL LL DD DD DD ... */ - *outlen = 5 + noctets; - } else { - return CRYPT_INVALID_ARG; - } - - return CRYPT_OK; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c deleted file mode 100644 index ef1ed0ede37..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_printable_string.c +++ /dev/null @@ -1,166 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_printable_string.c - ASN.1 DER, get length of Printable STRING, Tom St Denis -*/ - -#ifdef LTC_DER - -static const struct { - int code, value; -} printable_table[] = { -{ ' ', 32 }, -{ '\'', 39 }, -{ '(', 40 }, -{ ')', 41 }, -{ '+', 43 }, -{ ',', 44 }, -{ '-', 45 }, -{ '.', 46 }, -{ '/', 47 }, -{ '0', 48 }, -{ '1', 49 }, -{ '2', 50 }, -{ '3', 51 }, -{ '4', 52 }, -{ '5', 53 }, -{ '6', 54 }, -{ '7', 55 }, -{ '8', 56 }, -{ '9', 57 }, -{ ':', 58 }, -{ '=', 61 }, -{ '?', 63 }, -{ 'A', 65 }, -{ 'B', 66 }, -{ 'C', 67 }, -{ 'D', 68 }, -{ 'E', 69 }, -{ 'F', 70 }, -{ 'G', 71 }, -{ 'H', 72 }, -{ 'I', 73 }, -{ 'J', 74 }, -{ 'K', 75 }, -{ 'L', 76 }, -{ 'M', 77 }, -{ 'N', 78 }, -{ 'O', 79 }, -{ 'P', 80 }, -{ 'Q', 81 }, -{ 'R', 82 }, -{ 'S', 83 }, -{ 'T', 84 }, -{ 'U', 85 }, -{ 'V', 86 }, -{ 'W', 87 }, -{ 'X', 88 }, -{ 'Y', 89 }, -{ 'Z', 90 }, -{ 'a', 97 }, -{ 'b', 98 }, -{ 'c', 99 }, -{ 'd', 100 }, -{ 'e', 101 }, -{ 'f', 102 }, -{ 'g', 103 }, -{ 'h', 104 }, -{ 'i', 105 }, -{ 'j', 106 }, -{ 'k', 107 }, -{ 'l', 108 }, -{ 'm', 109 }, -{ 'n', 110 }, -{ 'o', 111 }, -{ 'p', 112 }, -{ 'q', 113 }, -{ 'r', 114 }, -{ 's', 115 }, -{ 't', 116 }, -{ 'u', 117 }, -{ 'v', 118 }, -{ 'w', 119 }, -{ 'x', 120 }, -{ 'y', 121 }, -{ 'z', 122 }, -}; - -int der_printable_char_encode(int c) -{ - int x; - for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { - if (printable_table[x].code == c) { - return printable_table[x].value; - } - } - return -1; -} - -int der_printable_value_decode(int v) -{ - int x; - for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { - if (printable_table[x].value == v) { - return printable_table[x].code; - } - } - return -1; -} - -/** - Gets length of DER encoding of Printable STRING - @param octets The values you want to encode - @param noctets The number of octets in the string to encode - @param outlen [out] The length of the DER encoding for the given string - @return CRYPT_OK if successful -*/ -int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) -{ - unsigned long x; - - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(octets != NULL); - - /* scan string for validity */ - for (x = 0; x < noctets; x++) { - if (der_printable_char_encode(octets[x]) == -1) { - return CRYPT_INVALID_ARG; - } - } - - if (noctets < 128) { - /* 16 LL DD DD DD ... */ - *outlen = 2 + noctets; - } else if (noctets < 256) { - /* 16 81 LL DD DD DD ... */ - *outlen = 3 + noctets; - } else if (noctets < 65536UL) { - /* 16 82 LL LL DD DD DD ... */ - *outlen = 4 + noctets; - } else if (noctets < 16777216UL) { - /* 16 83 LL LL LL DD DD DD ... */ - *outlen = 5 + noctets; - } else { - return CRYPT_INVALID_ARG; - } - - return CRYPT_OK; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c deleted file mode 100644 index e75ed7e7eeb..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_sequence.c +++ /dev/null @@ -1,169 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_sequence.c - ASN.1 DER, length a SEQUENCE, Tom St Denis -*/ - -#ifdef LTC_DER - -/** - Get the length of a DER sequence - @param list The sequences of items in the SEQUENCE - @param inlen The number of items - @param outlen [out] The length required in octets to store it - @return CRYPT_OK on success -*/ -int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, - unsigned long *outlen) -{ - int err, type; - unsigned long size, x, y, z, i; - void *data; - - LTC_ARGCHK(list != NULL); - LTC_ARGCHK(outlen != NULL); - - /* get size of output that will be required */ - y = 0; - for (i = 0; i < inlen; i++) { - type = list[i].type; - size = list[i].size; - data = list[i].data; - - if (type == LTC_ASN1_EOL) { - break; - } - - switch (type) { - case LTC_ASN1_BOOLEAN: - if ((err = der_length_boolean(&x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_INTEGER: - if ((err = der_length_integer(data, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_SHORT_INTEGER: - if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_BIT_STRING: - if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_OCTET_STRING: - if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_NULL: - y += 2; - break; - - case LTC_ASN1_OBJECT_IDENTIFIER: - if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_IA5_STRING: - if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_PRINTABLE_STRING: - if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_UTCTIME: - if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_UTF8_STRING: - if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: - if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - y += x; - break; - - - default: - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - } - - /* calc header size */ - z = y; - if (y < 128) { - y += 2; - } else if (y < 256) { - /* 0x30 0x81 LL */ - y += 3; - } else if (y < 65536UL) { - /* 0x30 0x82 LL LL */ - y += 4; - } else if (y < 16777216UL) { - /* 0x30 0x83 LL LL LL */ - y += 5; - } else { - err = CRYPT_INVALID_ARG; - goto LBL_ERR; - } - - /* store size */ - *outlen = y; - err = CRYPT_OK; - -LBL_ERR: - return err; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c,v $ */ -/* $Revision: 1.14 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c deleted file mode 100644 index afa6dd0ee61..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_short_integer.c +++ /dev/null @@ -1,70 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_short_integer.c - ASN.1 DER, get length of encoding, Tom St Denis -*/ - - -#ifdef LTC_DER -/** - Gets length of DER encoding of num - @param num The integer to get the size of - @param outlen [out] The length of the DER encoding for the given integer - @return CRYPT_OK if successful -*/ -int der_length_short_integer(unsigned long num, unsigned long *outlen) -{ - unsigned long z, y, len; - - LTC_ARGCHK(outlen != NULL); - - /* force to 32 bits */ - num &= 0xFFFFFFFFUL; - - /* get the number of bytes */ - z = 0; - y = num; - while (y) { - ++z; - y >>= 8; - } - - /* handle zero */ - if (z == 0) { - z = 1; - } - - /* we need a 0x02 to indicate it's INTEGER */ - len = 1; - - /* length byte */ - ++len; - - /* bytes in value */ - len += z; - - /* see if msb is set */ - len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; - - /* return length */ - *outlen = len; - - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c deleted file mode 100644 index 1296babbadf..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utctime.c +++ /dev/null @@ -1,46 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_utctime.c - ASN.1 DER, get length of UTCTIME, Tom St Denis -*/ - -#ifdef LTC_DER - -/** - Gets length of DER encoding of UTCTIME - @param utctime The UTC time structure to get the size of - @param outlen [out] The length of the DER encoding - @return CRYPT_OK if successful -*/ -int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) -{ - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(utctime != NULL); - - if (utctime->off_hh == 0 && utctime->off_mm == 0) { - /* we encode as YYMMDDhhmmssZ */ - *outlen = 2 + 13; - } else { - /* we encode as YYMMDDhhmmss{+|-}hh'mm' */ - *outlen = 2 + 17; - } - - return CRYPT_OK; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c deleted file mode 100644 index 514db8450ef..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_length_utf8_string.c +++ /dev/null @@ -1,83 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_length_utf8_string.c - ASN.1 DER, get length of UTF8 STRING, Tom St Denis -*/ - -#ifdef LTC_DER - -/** Return the size in bytes of a UTF-8 character - @param c The UTF-8 character to measure - @return The size in bytes -*/ -unsigned long der_utf8_charsize(const wchar_t c) -{ - if (c <= 0x7F) { - return 1; - } else if (c <= 0x7FF) { - return 2; - } else if (c <= 0xFFFF) { - return 3; - } else { - return 4; - } -} - -/** - Gets length of DER encoding of UTF8 STRING - @param in The characters to measure the length of - @param noctets The number of octets in the string to encode - @param outlen [out] The length of the DER encoding for the given string - @return CRYPT_OK if successful -*/ -int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen) -{ - unsigned long x, len; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(outlen != NULL); - - len = 0; - for (x = 0; x < noctets; x++) { - if (in[x] < 0 || in[x] > 0x10FFFF) { - return CRYPT_INVALID_ARG; - } - len += der_utf8_charsize(in[x]); - } - - if (len < 128) { - /* 0C LL DD DD DD ... */ - *outlen = 2 + len; - } else if (len < 256) { - /* 0C 81 LL DD DD DD ... */ - *outlen = 3 + len; - } else if (len < 65536UL) { - /* 0C 82 LL LL DD DD DD ... */ - *outlen = 4 + len; - } else if (len < 16777216UL) { - /* 0C 83 LL LL LL DD DD DD ... */ - *outlen = 5 + len; - } else { - return CRYPT_INVALID_ARG; - } - - return CRYPT_OK; -} - -#endif - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c b/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c deleted file mode 100644 index 4887215397f..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/asn1/der_sequence_free.c +++ /dev/null @@ -1,65 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file der_sequence_free.c - ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis -*/ - -#ifdef LTC_DER - -/** - Free memory allocated by der_decode_sequence_flexi() - @param in The list to free -*/ -void der_sequence_free(ltc_asn1_list *in) -{ - ltc_asn1_list *l; - - /* walk to the start of the chain */ - while (in->prev != NULL || in->parent != NULL) { - if (in->parent != NULL) { - in = in->parent; - } else { - in = in->prev; - } - } - - /* now walk the list and free stuff */ - while (in != NULL) { - /* is there a child? */ - if (in->child) { - /* disconnect */ - in->child->parent = NULL; - der_sequence_free(in->child); - } - - switch (in->type) { - case LTC_ASN1_SET: - case LTC_ASN1_SETOF: - case LTC_ASN1_SEQUENCE: break; - case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; - default : if (in->data != NULL) { XFREE(in->data); } - } - - /* move to next and free current */ - l = in->next; - free(in); - in = l; - } -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:27:24 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c deleted file mode 100644 index 5a1324c4986..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_map.c +++ /dev/null @@ -1,76 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b - * - * All curves taken from NIST recommendation paper of July 1999 - * Available at http://csrc.nist.gov/cryptval/dss.htm - */ -#include "../../headers/tomcrypt.h" - -/** - @file ltc_ecc_map.c - ECC Crypto, Tom St Denis -*/ - -#ifdef LTC_MECC - -/** - Map a projective jacbobian point back to affine space - @param P [in/out] The point to map - @param modulus The modulus of the field the ECC curve is in - @param mp The "b" value from montgomery_setup() - @return CRYPT_OK on success -*/ -int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) -{ - void *t1, *t2; - int err; - - LTC_ARGCHK(P != NULL); - LTC_ARGCHK(modulus != NULL); - LTC_ARGCHK(mp != NULL); - - if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { - return CRYPT_MEM; - } - - /* first map z back to normal */ - if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; } - - /* get 1/z */ - if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; } - - /* get 1/z^2 and 1/z^3 */ - if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } - if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; } - if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; } - - /* multiply against x/y */ - if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; } - if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; } - if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; } - - err = CRYPT_OK; -done: - mp_clear_multi(t1, t2, NULL); - return err; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_map.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ - diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c deleted file mode 100644 index 2c468eaafa1..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c +++ /dev/null @@ -1,207 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b - * - * All curves taken from NIST recommendation paper of July 1999 - * Available at http://csrc.nist.gov/cryptval/dss.htm - */ -#include "../../headers/tomcrypt.h" - -/** - @file ltc_ecc_mul2add.c - ECC Crypto, Shamir's Trick, Tom St Denis -*/ - -#ifdef LTC_MECC - -#ifdef LTC_ECC_SHAMIR - -/** Computes kA*A + kB*B = C using Shamir's Trick - @param A First point to multiply - @param kA What to multiple A by - @param B Second point to multiply - @param kB What to multiple B by - @param C [out] Destination point (can overlap with A or B - @param modulus Modulus for curve - @return CRYPT_OK on success -*/ -int ltc_ecc_mul2add(ecc_point *A, void *kA, - ecc_point *B, void *kB, - ecc_point *C, - void *modulus) -{ - ecc_point *precomp[16]; - unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble; - unsigned char *tA, *tB; - int err, first; - void *mp, *mu; - - /* argchks */ - LTC_ARGCHK(A != NULL); - LTC_ARGCHK(B != NULL); - LTC_ARGCHK(C != NULL); - LTC_ARGCHK(kA != NULL); - LTC_ARGCHK(kB != NULL); - LTC_ARGCHK(modulus != NULL); - - /* allocate memory */ - tA = XCALLOC(1, ECC_BUF_SIZE); - if (tA == NULL) { - return CRYPT_MEM; - } - tB = XCALLOC(1, ECC_BUF_SIZE); - if (tB == NULL) { - XFREE(tA); - return CRYPT_MEM; - } - - /* get sizes */ - lenA = mp_unsigned_bin_size(kA); - lenB = mp_unsigned_bin_size(kB); - len = MAX(lenA, lenB); - - /* sanity check */ - if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) { - err = CRYPT_INVALID_ARG; - goto ERR_T; - } - - /* extract and justify kA */ - mp_to_unsigned_bin(kA, (len - lenA) + tA); - - /* extract and justify kB */ - mp_to_unsigned_bin(kB, (len - lenB) + tB); - - /* allocate the table */ - for (x = 0; x < 16; x++) { - precomp[x] = ltc_ecc_new_point(); - if (precomp[x] == NULL) { - for (y = 0; y < x; ++y) { - ltc_ecc_del_point(precomp[y]); - } - err = CRYPT_MEM; - goto ERR_T; - } - } - - /* init montgomery reduction */ - if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { - goto ERR_P; - } - if ((err = mp_init(&mu)) != CRYPT_OK) { - goto ERR_MP; - } - if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { - goto ERR_MU; - } - - /* copy ones ... */ - if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; } - - if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; } - - /* precomp [i,0](A + B) table */ - if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - - /* precomp [0,i](A + B) table */ - if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - - /* precomp [i,j](A + B) table (i != 0, j != 0) */ - for (x = 1; x < 4; x++) { - for (y = 1; y < 4; y++) { - if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - } - } - - nibble = 3; - first = 1; - bitbufA = tA[0]; - bitbufB = tB[0]; - - /* for every byte of the multiplicands */ - for (x = -1;; ) { - /* grab a nibble */ - if (++nibble == 4) { - ++x; if (x == len) break; - bitbufA = tA[x]; - bitbufB = tB[x]; - nibble = 0; - } - - /* extract two bits from both, shift/update */ - nA = (bitbufA >> 6) & 0x03; - nB = (bitbufB >> 6) & 0x03; - bitbufA = (bitbufA << 2) & 0xFF; - bitbufB = (bitbufB << 2) & 0xFF; - - /* if both zero, if first, continue */ - if ((nA == 0) && (nB == 0) && (first == 1)) { - continue; - } - - /* double twice, only if this isn't the first */ - if (first == 0) { - /* double twice */ - if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - } - - /* if not both zero */ - if ((nA != 0) || (nB != 0)) { - if (first == 1) { - /* if first, copy from table */ - first = 0; - if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; } - if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } - } else { - /* if not first, add from table */ - if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } - } - } - } - - /* reduce to affine */ - err = ltc_ecc_map(C, modulus, mp); - - /* clean up */ -ERR_MU: - mp_clear(mu); -ERR_MP: - mp_montgomery_free(mp); -ERR_P: - for (x = 0; x < 16; x++) { - ltc_ecc_del_point(precomp[x]); - } -ERR_T: -#ifdef LTC_CLEAN_STACK - zeromem(tA, ECC_BUF_SIZE); - zeromem(tB, ECC_BUF_SIZE); -#endif - XFREE(tA); - XFREE(tB); - - return err; -} - -#endif -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c deleted file mode 100644 index f9d0cad832d..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c +++ /dev/null @@ -1,222 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b - * - * All curves taken from NIST recommendation paper of July 1999 - * Available at http://csrc.nist.gov/cryptval/dss.htm - */ -#include "../../headers/tomcrypt.h" - -/** - @file ltc_ecc_mulmod.c - ECC Crypto, Tom St Denis -*/ - -#ifdef LTC_MECC -#ifndef LTC_ECC_TIMING_RESISTANT - -/* size of sliding window, don't change this! */ -#define WINSIZE 4 - -/** - Perform a point multiplication - @param k The scalar to multiply by - @param G The base point - @param R [out] Destination for kG - @param modulus The modulus of the field the ECC curve is in - @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) - @return CRYPT_OK on success -*/ -int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) -{ - ecc_point *tG, *M[8]; - int i, j, err; - void *mu, *mp; - unsigned long buf; - int first, bitbuf, bitcpy, bitcnt, mode, digidx; - - LTC_ARGCHK(k != NULL); - LTC_ARGCHK(G != NULL); - LTC_ARGCHK(R != NULL); - LTC_ARGCHK(modulus != NULL); - - /* init montgomery reduction */ - if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { - return err; - } - if ((err = mp_init(&mu)) != CRYPT_OK) { - mp_montgomery_free(mp); - return err; - } - if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { - mp_montgomery_free(mp); - mp_clear(mu); - return err; - } - - /* alloc ram for window temps */ - for (i = 0; i < 8; i++) { - M[i] = ltc_ecc_new_point(); - if (M[i] == NULL) { - for (j = 0; j < i; j++) { - ltc_ecc_del_point(M[j]); - } - mp_montgomery_free(mp); - mp_clear(mu); - return CRYPT_MEM; - } - } - - /* make a copy of G incase R==G */ - tG = ltc_ecc_new_point(); - if (tG == NULL) { err = CRYPT_MEM; goto done; } - - /* tG = G and convert to montgomery */ - if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { - if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; } - } else { - if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } - if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } - if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } - } - mp_clear(mu); - mu = NULL; - - /* calc the M tab, which holds kG for k==8..15 */ - /* M[0] == 8G */ - if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } - if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } - - /* now find (8+k)G for k=1..7 */ - for (j = 9; j < 16; j++) { - if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; } - } - - /* setup sliding window */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = mp_get_digit_count(k) - 1; - bitcpy = bitbuf = 0; - first = 1; - - /* perform ops */ - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - if (digidx == -1) { - break; - } - buf = mp_get_digit(k, digidx); - bitcnt = (int) ltc_mp.bits_per_digit; - --digidx; - } - - /* grab the next msb from the ltiplicand */ - i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1; - buf <<= 1; - - /* skip leading zero bits */ - if (mode == 0 && i == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we double */ - if (mode == 1 && i == 0) { - if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } - continue; - } - - /* else we add it to the window */ - bitbuf |= (i << (WINSIZE - ++bitcpy)); - mode = 2; - - if (bitcpy == WINSIZE) { - /* if this is the first window we do a simple copy */ - if (first == 1) { - /* R = kG [k = first window] */ - if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; } - first = 0; - } else { - /* normal window */ - /* ok window is filled so double as required and add */ - /* double first */ - for (j = 0; j < WINSIZE; j++) { - if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } - } - - /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ - if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; } - } - /* empty window and reset */ - bitcpy = bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then double/add */ - if (mode == 2 && bitcpy > 0) { - /* double then add */ - for (j = 0; j < bitcpy; j++) { - /* only double if we have had at least one add first */ - if (first == 0) { - if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } - } - - bitbuf <<= 1; - if ((bitbuf & (1 << WINSIZE)) != 0) { - if (first == 1){ - /* first add, so copy */ - if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; } - first = 0; - } else { - /* then add */ - if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; } - } - } - } - } - - /* map R back from projective space */ - if (map) { - err = ltc_ecc_map(R, modulus, mp); - } else { - err = CRYPT_OK; - } -done: - if (mu != NULL) { - mp_clear(mu); - } - mp_montgomery_free(mp); - ltc_ecc_del_point(tG); - for (i = 0; i < 8; i++) { - ltc_ecc_del_point(M[i]); - } - return err; -} - -#endif - -#undef WINSIZE - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c,v $ */ -/* $Revision: 1.26 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c deleted file mode 100644 index f5a4acb4c5a..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_points.c +++ /dev/null @@ -1,60 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b - * - * All curves taken from NIST recommendation paper of July 1999 - * Available at http://csrc.nist.gov/cryptval/dss.htm - */ -#include "../../headers/tomcrypt.h" - -/** - @file ltc_ecc_points.c - ECC Crypto, Tom St Denis -*/ - -#ifdef LTC_MECC - -/** - Allocate a new ECC point - @return A newly allocated point or NULL on error -*/ -ecc_point *ltc_ecc_new_point(void) -{ - ecc_point *p; - p = XCALLOC(1, sizeof(*p)); - if (p == NULL) { - return NULL; - } - if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) { - XFREE(p); - return NULL; - } - return p; -} - -/** Free an ECC point from memory - @param p The point to free -*/ -void ltc_ecc_del_point(ecc_point *p) -{ - /* prevents free'ing null arguments */ - if (p != NULL) { - mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */ - XFREE(p); - } -} - -#endif -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_points.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ - diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c deleted file mode 100644 index b4416fc77de..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c +++ /dev/null @@ -1,196 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b - * - * All curves taken from NIST recommendation paper of July 1999 - * Available at http://csrc.nist.gov/cryptval/dss.htm - */ -#include "../../headers/tomcrypt.h" - -/** - @file ltc_ecc_projective_add_point.c - ECC Crypto, Tom St Denis -*/ - -#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) - -/** - Add two ECC points - @param P The point to add - @param Q The point to add - @param R [out] The destination of the double - @param modulus The modulus of the field the ECC curve is in - @param mp The "b" value from montgomery_setup() - @return CRYPT_OK on success -*/ -int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp) -{ - void *t1, *t2, *x, *y, *z; - int err; - - LTC_ARGCHK(P != NULL); - LTC_ARGCHK(Q != NULL); - LTC_ARGCHK(R != NULL); - LTC_ARGCHK(modulus != NULL); - LTC_ARGCHK(mp != NULL); - - if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) { - return err; - } - - /* should we dbl instead? */ - if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } - - if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) && - (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) && - (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) { - mp_clear_multi(t1, t2, x, y, z, NULL); - return ltc_ecc_projective_dbl_point(P, R, modulus, mp); - } - - if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; } - - /* if Z is one then these are no-operations */ - if (Q->z != NULL) { - /* T1 = Z' * Z' */ - if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - /* X = X * T1 */ - if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } - /* T1 = Z' * T1 */ - if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - /* Y = Y * T1 */ - if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; } - } - - /* T1 = Z*Z */ - if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - /* T2 = X' * T1 */ - if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } - /* T1 = Z * T1 */ - if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - /* T1 = Y' * T1 */ - if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - - /* Y = Y - T1 */ - if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(y, 0) == LTC_MP_LT) { - if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } - } - /* T1 = 2T1 */ - if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; } - if (mp_cmp(t1, modulus) != LTC_MP_LT) { - if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } - } - /* T1 = Y + T1 */ - if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; } - if (mp_cmp(t1, modulus) != LTC_MP_LT) { - if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } - } - /* X = X - T2 */ - if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(x, 0) == LTC_MP_LT) { - if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } - } - /* T2 = 2T2 */ - if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; } - if (mp_cmp(t2, modulus) != LTC_MP_LT) { - if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } - } - /* T2 = X + T2 */ - if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; } - if (mp_cmp(t2, modulus) != LTC_MP_LT) { - if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } - } - - /* if Z' != 1 */ - if (Q->z != NULL) { - /* Z = Z * Z' */ - if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } - } - - /* Z = Z * X */ - if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } - - /* T1 = T1 * X */ - if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - /* X = X * X */ - if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } - /* T2 = T2 * x */ - if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } - /* T1 = T1 * X */ - if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - - /* X = Y*Y */ - if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } - /* X = X - T2 */ - if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(x, 0) == LTC_MP_LT) { - if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } - } - - /* T2 = T2 - X */ - if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(t2, 0) == LTC_MP_LT) { - if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } - } - /* T2 = T2 - X */ - if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(t2, 0) == LTC_MP_LT) { - if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } - } - /* T2 = T2 * Y */ - if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } - /* Y = T2 - T1 */ - if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(y, 0) == LTC_MP_LT) { - if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } - } - /* Y = Y/2 */ - if (mp_isodd(y)) { - if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } - } - if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; } - - if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; } - - err = CRYPT_OK; -done: - mp_clear_multi(t1, t2, x, y, z, NULL); - return err; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c,v $ */ -/* $Revision: 1.16 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ - diff --git a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c b/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c deleted file mode 100644 index b990e0a14aa..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c +++ /dev/null @@ -1,147 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b - * - * All curves taken from NIST recommendation paper of July 1999 - * Available at http://csrc.nist.gov/cryptval/dss.htm - */ -#include "../../headers/tomcrypt.h" - -/** - @file ltc_ecc_projective_dbl_point.c - ECC Crypto, Tom St Denis -*/ - -#if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) - -/** - Double an ECC point - @param P The point to double - @param R [out] The destination of the double - @param modulus The modulus of the field the ECC curve is in - @param mp The "b" value from montgomery_setup() - @return CRYPT_OK on success -*/ -int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp) -{ - void *t1, *t2; - int err; - - LTC_ARGCHK(P != NULL); - LTC_ARGCHK(R != NULL); - LTC_ARGCHK(modulus != NULL); - LTC_ARGCHK(mp != NULL); - - if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { - return err; - } - - if (P != R) { - if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } - } - - /* t1 = Z * Z */ - if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } - /* Z = Y * Z */ - if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; } - /* Z = 2Z */ - if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; } - if (mp_cmp(R->z, modulus) != LTC_MP_LT) { - if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } - } - - /* T2 = X - T1 */ - if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(t2, 0) == LTC_MP_LT) { - if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } - } - /* T1 = X + T1 */ - if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; } - if (mp_cmp(t1, modulus) != LTC_MP_LT) { - if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } - } - /* T2 = T1 * T2 */ - if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } - /* T1 = 2T2 */ - if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; } - if (mp_cmp(t1, modulus) != LTC_MP_LT) { - if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } - } - /* T1 = T1 + T2 */ - if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } - if (mp_cmp(t1, modulus) != LTC_MP_LT) { - if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } - } - - /* Y = 2Y */ - if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; } - if (mp_cmp(R->y, modulus) != LTC_MP_LT) { - if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } - } - /* Y = Y * Y */ - if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } - /* T2 = Y * Y */ - if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } - /* T2 = T2/2 */ - if (mp_isodd(t2)) { - if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } - } - if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; } - /* Y = Y * X */ - if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } - - /* X = T1 * T1 */ - if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; } - /* X = X - Y */ - if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { - if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } - } - /* X = X - Y */ - if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { - if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } - } - - /* Y = Y - X */ - if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { - if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } - } - /* Y = Y * T1 */ - if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; } - if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } - /* Y = Y - T2 */ - if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; } - if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { - if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } - } - - err = CRYPT_OK; -done: - mp_clear_multi(t1, t2, NULL); - return err; -} -#endif -/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */ -/* $Revision: 1.11 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ - diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c deleted file mode 100644 index e8f6418067c..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c +++ /dev/null @@ -1,108 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file pkcs_1_mgf1.c - The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis -*/ - -#ifdef LTC_PKCS_1 - -/** - Perform LTC_PKCS #1 MGF1 (internal) - @param seed The seed for MGF1 - @param seedlen The length of the seed - @param hash_idx The index of the hash desired - @param mask [out] The destination - @param masklen The length of the mask desired - @return CRYPT_OK if successful -*/ -int pkcs_1_mgf1(int hash_idx, - const unsigned char *seed, unsigned long seedlen, - unsigned char *mask, unsigned long masklen) -{ - unsigned long hLen, x; - ulong32 counter; - int err; - hash_state *md; - unsigned char *buf; - - LTC_ARGCHK(seed != NULL); - LTC_ARGCHK(mask != NULL); - - /* ensure valid hash */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - - /* get hash output size */ - hLen = hash_descriptor[hash_idx].hashsize; - - /* allocate memory */ - md = XMALLOC(sizeof(hash_state)); - buf = XMALLOC(hLen); - if (md == NULL || buf == NULL) { - if (md != NULL) { - XFREE(md); - } - if (buf != NULL) { - XFREE(buf); - } - return CRYPT_MEM; - } - - /* start counter */ - counter = 0; - - while (masklen > 0) { - /* handle counter */ - STORE32H(counter, buf); - ++counter; - - /* get hash of seed || counter */ - if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { - goto LBL_ERR; - } - - /* store it */ - for (x = 0; x < hLen && masklen > 0; x++, masklen--) { - *mask++ = buf[x]; - } - } - - err = CRYPT_OK; -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(buf, hLen); - zeromem(md, sizeof(hash_state)); -#endif - - XFREE(buf); - XFREE(md); - - return err; -} - -#endif /* LTC_PKCS_1 */ - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c deleted file mode 100644 index 709ab8a8cd2..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c +++ /dev/null @@ -1,189 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file pkcs_1_oaep_decode.c - OAEP Padding for LTC_PKCS #1, Tom St Denis -*/ - -#ifdef LTC_PKCS_1 - -/** - LTC_PKCS #1 v2.00 OAEP decode - @param msg The encoded data to decode - @param msglen The length of the encoded data (octets) - @param lparam The session or system data (can be NULL) - @param lparamlen The length of the lparam - @param modulus_bitlen The bit length of the RSA modulus - @param hash_idx The index of the hash desired - @param out [out] Destination of decoding - @param outlen [in/out] The max size and resulting size of the decoding - @param res [out] Result of decoding, 1==valid, 0==invalid - @return CRYPT_OK if successful (even if invalid) -*/ -int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, - const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, int hash_idx, - unsigned char *out, unsigned long *outlen, - int *res) -{ - unsigned char *DB, *seed, *mask; - unsigned long hLen, x, y, modulus_len; - int err; - - LTC_ARGCHK(msg != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(res != NULL); - - /* default to invalid packet */ - *res = 0; - - /* test valid hash */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - hLen = hash_descriptor[hash_idx].hashsize; - modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); - - /* test hash/message size */ - if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) { - return CRYPT_PK_INVALID_SIZE; - } - - /* allocate ram for DB/mask/salt of size modulus_len */ - DB = XMALLOC(modulus_len); - mask = XMALLOC(modulus_len); - seed = XMALLOC(hLen); - if (DB == NULL || mask == NULL || seed == NULL) { - if (DB != NULL) { - XFREE(DB); - } - if (mask != NULL) { - XFREE(mask); - } - if (seed != NULL) { - XFREE(seed); - } - return CRYPT_MEM; - } - - /* ok so it's now in the form - - 0x00 || maskedseed || maskedDB - - 1 || hLen || modulus_len - hLen - 1 - - */ - - /* must have leading 0x00 byte */ - if (msg[0] != 0x00) { - err = CRYPT_OK; - goto LBL_ERR; - } - - /* now read the masked seed */ - x = 1; - XMEMCPY(seed, msg + x, hLen); - x += hLen; - - /* now read the masked DB */ - XMEMCPY(DB, msg + x, modulus_len - hLen - 1); - x += modulus_len - hLen - 1; - - /* compute MGF1 of maskedDB (hLen) */ - if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { - goto LBL_ERR; - } - - /* XOR against seed */ - for (y = 0; y < hLen; y++) { - seed[y] ^= mask[y]; - } - - /* compute MGF1 of seed (k - hlen - 1) */ - if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { - goto LBL_ERR; - } - - /* xor against DB */ - for (y = 0; y < (modulus_len - hLen - 1); y++) { - DB[y] ^= mask[y]; - } - - /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ - - /* compute lhash and store it in seed [reuse temps!] */ - x = modulus_len; - if (lparam != NULL) { - if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - } else { - /* can't pass hash_memory a NULL so use DB with zero length */ - if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { - goto LBL_ERR; - } - } - - /* compare the lhash'es */ - if (XMEMCMP(seed, DB, hLen) != 0) { - err = CRYPT_OK; - goto LBL_ERR; - } - - /* now zeroes before a 0x01 */ - for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) { - /* step... */ - } - - /* error out if wasn't 0x01 */ - if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - - /* rest is the message (and skip 0x01) */ - if ((modulus_len - hLen - 1 - ++x) > *outlen) { - *outlen = modulus_len - hLen - 1 - x; - err = CRYPT_BUFFER_OVERFLOW; - goto LBL_ERR; - } - - /* copy message */ - *outlen = modulus_len - hLen - 1 - x; - XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x); - x += modulus_len - hLen - 1; - - /* valid packet */ - *res = 1; - - err = CRYPT_OK; -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(DB, modulus_len); - zeromem(seed, hLen); - zeromem(mask, modulus_len); -#endif - - XFREE(seed); - XFREE(mask); - XFREE(DB); - - return err; -} - -#endif /* LTC_PKCS_1 */ - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c,v $ */ -/* $Revision: 1.13 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c deleted file mode 100644 index c3a7211ef9c..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c +++ /dev/null @@ -1,177 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file pkcs_1_pss_decode.c - LTC_PKCS #1 PSS Signature Padding, Tom St Denis -*/ - -#ifdef LTC_PKCS_1 - -/** - LTC_PKCS #1 v2.00 PSS decode - @param msghash The hash to verify - @param msghashlen The length of the hash (octets) - @param sig The signature data (encoded data) - @param siglen The length of the signature data (octets) - @param saltlen The length of the salt used (octets) - @param hash_idx The index of the hash desired - @param modulus_bitlen The bit length of the RSA modulus - @param res [out] The result of the comparison, 1==valid, 0==invalid - @return CRYPT_OK if successful (even if the comparison failed) -*/ -int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, - const unsigned char *sig, unsigned long siglen, - unsigned long saltlen, int hash_idx, - unsigned long modulus_bitlen, int *res) -{ - unsigned char *DB, *mask, *salt, *hash; - unsigned long x, y, hLen, modulus_len; - int err; - hash_state md; - - LTC_ARGCHK(msghash != NULL); - LTC_ARGCHK(res != NULL); - - /* default to invalid */ - *res = 0; - - /* ensure hash is valid */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - - hLen = hash_descriptor[hash_idx].hashsize; - modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); - - /* check sizes */ - if ((saltlen > modulus_len) || - (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { - return CRYPT_PK_INVALID_SIZE; - } - - /* allocate ram for DB/mask/salt/hash of size modulus_len */ - DB = XMALLOC(modulus_len); - mask = XMALLOC(modulus_len); - salt = XMALLOC(modulus_len); - hash = XMALLOC(modulus_len); - if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { - if (DB != NULL) { - XFREE(DB); - } - if (mask != NULL) { - XFREE(mask); - } - if (salt != NULL) { - XFREE(salt); - } - if (hash != NULL) { - XFREE(hash); - } - return CRYPT_MEM; - } - - /* ensure the 0xBC byte */ - if (sig[siglen-1] != 0xBC) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - - /* copy out the DB */ - x = 0; - XMEMCPY(DB, sig + x, modulus_len - hLen - 1); - x += modulus_len - hLen - 1; - - /* copy out the hash */ - XMEMCPY(hash, sig + x, hLen); - x += hLen; - - /* check the MSB */ - if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - - /* generate mask of length modulus_len - hLen - 1 from hash */ - if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { - goto LBL_ERR; - } - - /* xor against DB */ - for (y = 0; y < (modulus_len - hLen - 1); y++) { - DB[y] ^= mask[y]; - } - - /* now clear the first byte [make sure smaller than modulus] */ - DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); - - /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ - - /* check for zeroes and 0x01 */ - for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) { - if (DB[x] != 0x00) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - } - - /* check for the 0x01 */ - if (DB[x++] != 0x01) { - err = CRYPT_INVALID_PACKET; - goto LBL_ERR; - } - - /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ - if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { - goto LBL_ERR; - } - zeromem(mask, 8); - if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { - goto LBL_ERR; - } - - /* mask == hash means valid signature */ - if (XMEMCMP(mask, hash, hLen) == 0) { - *res = 1; - } - - err = CRYPT_OK; -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(DB, modulus_len); - zeromem(mask, modulus_len); - zeromem(salt, modulus_len); - zeromem(hash, modulus_len); -#endif - - XFREE(hash); - XFREE(salt); - XFREE(mask); - XFREE(DB); - - return err; -} - -#endif /* LTC_PKCS_1 */ - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c,v $ */ -/* $Revision: 1.11 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c b/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c deleted file mode 100644 index 7c3711c17c9..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c +++ /dev/null @@ -1,110 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** @file pkcs_1_v1_5_decode.c - * - * LTC_PKCS #1 v1.5 Padding. (Andreas Lange) - */ - -#ifdef LTC_PKCS_1 - -/** @brief LTC_PKCS #1 v1.5 decode. - * - * @param msg The encoded data to decode - * @param msglen The length of the encoded data (octets) - * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) - * @param modulus_bitlen The bit length of the RSA modulus - * @param out [out] Destination of decoding - * @param outlen [in/out] The max size and resulting size of the decoding - * @param is_valid [out] Boolean whether the padding was valid - * - * @return CRYPT_OK if successful (even if invalid) - */ -int pkcs_1_v1_5_decode(const unsigned char *msg, - unsigned long msglen, - int block_type, - unsigned long modulus_bitlen, - unsigned char *out, - unsigned long *outlen, - int *is_valid) -{ - unsigned long modulus_len, ps_len, i; - int result; - - /* default to invalid packet */ - *is_valid = 0; - - modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); - - /* test message size */ - - if ((msglen > modulus_len) || (modulus_len < 11)) { - return CRYPT_PK_INVALID_SIZE; - } - - /* separate encoded message */ - - if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) { - result = CRYPT_INVALID_PACKET; - goto bail; - } - - if (block_type == LTC_LTC_PKCS_1_EME) { - for (i = 2; i < modulus_len; i++) { - /* separator */ - if (msg[i] == 0x00) { break; } - } - ps_len = i++ - 2; - - if ((i >= modulus_len) || (ps_len < 8)) { - /* There was no octet with hexadecimal value 0x00 to separate ps from m, - * or the length of ps is less than 8 octets. - */ - result = CRYPT_INVALID_PACKET; - goto bail; - } - } else { - for (i = 2; i < modulus_len - 1; i++) { - if (msg[i] != 0xFF) { break; } - } - - /* separator check */ - if (msg[i] != 0) { - /* There was no octet with hexadecimal value 0x00 to separate ps from m. */ - result = CRYPT_INVALID_PACKET; - goto bail; - } - - ps_len = i - 2; - } - - if (*outlen < (msglen - (2 + ps_len + 1))) { - *outlen = msglen - (2 + ps_len + 1); - result = CRYPT_BUFFER_OVERFLOW; - goto bail; - } - - *outlen = (msglen - (2 + ps_len + 1)); - XMEMCPY(out, &msg[2 + ps_len + 1], *outlen); - - /* valid packet */ - *is_valid = 1; - result = CRYPT_OK; -bail: - return result; -} /* pkcs_1_v1_5_decode */ - -#endif /* #ifdef LTC_PKCS_1 */ - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c,v $ */ -/* $Revision: 1.7 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c deleted file mode 100644 index ba44106f2b7..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_exptmod.c +++ /dev/null @@ -1,113 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file rsa_exptmod.c - RSA LTC_PKCS exptmod, Tom St Denis -*/ - -#ifdef LTC_MRSA - -/** - Compute an RSA modular exponentiation - @param in The input data to send into RSA - @param inlen The length of the input (octets) - @param out [out] The destination - @param outlen [in/out] The max size and resulting size of the output - @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC - @param key The RSA key to use - @return CRYPT_OK if successful -*/ -int rsa_exptmod(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, int which, - rsa_key *key) -{ - void *tmp, *tmpa, *tmpb; - unsigned long x; - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); - - /* is the key of the right type for the operation? */ - if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { - return CRYPT_PK_NOT_PRIVATE; - } - - /* must be a private or public operation */ - if (which != PK_PRIVATE && which != PK_PUBLIC) { - return CRYPT_PK_INVALID_TYPE; - } - - /* init and copy into tmp */ - if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } - if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } - - /* sanity check on the input */ - if (mp_cmp(key->N, tmp) == LTC_MP_LT) { - err = CRYPT_PK_INVALID_SIZE; - goto error; - } - - /* are we using the private exponent and is the key optimized? */ - if (which == PK_PRIVATE) { - /* tmpa = tmp^dP mod p */ - if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } - - /* tmpb = tmp^dQ mod q */ - if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } - - /* tmp = (tmpa - tmpb) * qInv (mod p) */ - if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } - if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } - - /* tmp = tmpb + q * tmp */ - if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } - if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } - } else { - /* exptmod it */ - if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } - } - - /* read it back */ - x = (unsigned long)mp_unsigned_bin_size(key->N); - if (x > *outlen) { - *outlen = x; - err = CRYPT_BUFFER_OVERFLOW; - goto error; - } - - /* this should never happen ... */ - if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) { - err = CRYPT_ERROR; - goto error; - } - *outlen = x; - - /* convert it */ - zeromem(out, x); - if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } - - /* clean up and return */ - err = CRYPT_OK; -error: - mp_clear_multi(tmp, tmpa, tmpb, NULL); - return err; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */ -/* $Revision: 1.18 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c deleted file mode 100644 index a10ed5928ce..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_free.c +++ /dev/null @@ -1,34 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file rsa_free.c - Free an RSA key, Tom St Denis -*/ - -#ifdef LTC_MRSA - -/** - Free an RSA key from memory - @param key The RSA key to free -*/ -void rsa_free(rsa_key *key) -{ - LTC_ARGCHKVD(key != NULL); - mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_free.c,v $ */ -/* $Revision: 1.10 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c deleted file mode 100644 index 6254fd7ff86..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_import.c +++ /dev/null @@ -1,143 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file rsa_import.c - Import a LTC_PKCS RSA key, Tom St Denis -*/ - -#ifdef LTC_MRSA - -/** - Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1] - @param in The packet to import from - @param inlen It's length (octets) - @param key [out] Destination for newly imported key - @return CRYPT_OK if successful, upon error allocated memory is freed -*/ -int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) -{ - int err; - void *zero; - unsigned char *tmpbuf; - unsigned long t, x, y, z, tmpoid[16]; - ltc_asn1_list ssl_pubkey_hashoid[2]; - ltc_asn1_list ssl_pubkey[2]; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(ltc_mp.name != NULL); - - /* init key */ - if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { - return err; - } - - /* see if the OpenSSL DER format RSA public key will work */ - tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8); - if (tmpbuf == NULL) { - err = CRYPT_MEM; - goto LBL_ERR; - } - - /* this includes the internal hash ID and optional params (NULL in this case) */ - LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); - LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0); - - /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it - then proceed to convert bit to octet - */ - LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2); - LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8); - - if (der_decode_sequence(in, inlen, - ssl_pubkey, 2UL) == CRYPT_OK) { - - /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */ - for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) { - y = (y << 1) | tmpbuf[x]; - if (++z == 8) { - tmpbuf[t++] = (unsigned char)y; - y = 0; - z = 0; - } - } - - /* now it should be SEQUENCE { INTEGER, INTEGER } */ - if ((err = der_decode_sequence_multi(tmpbuf, t, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - XFREE(tmpbuf); - goto LBL_ERR; - } - XFREE(tmpbuf); - key->type = PK_PUBLIC; - return CRYPT_OK; - } - XFREE(tmpbuf); - - /* not SSL public key, try to match against LTC_PKCS #1 standards */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - - if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { - if ((err = mp_init(&zero)) != CRYPT_OK) { - goto LBL_ERR; - } - /* it's a private key */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, zero, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_INTEGER, 1UL, key->d, - LTC_ASN1_INTEGER, 1UL, key->p, - LTC_ASN1_INTEGER, 1UL, key->q, - LTC_ASN1_INTEGER, 1UL, key->dP, - LTC_ASN1_INTEGER, 1UL, key->dQ, - LTC_ASN1_INTEGER, 1UL, key->qP, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - mp_clear(zero); - goto LBL_ERR; - } - mp_clear(zero); - key->type = PK_PRIVATE; - } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) { - /* we don't support multi-prime RSA */ - err = CRYPT_PK_INVALID_TYPE; - goto LBL_ERR; - } else { - /* it's a public key and we lack e */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - key->type = PK_PUBLIC; - } - return CRYPT_OK; -LBL_ERR: - mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); - return err; -} - -#endif /* LTC_MRSA */ - - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ -/* $Revision: 1.23 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c deleted file mode 100644 index bd37b4ae1cb..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_make_key.c +++ /dev/null @@ -1,112 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file rsa_make_key.c - RSA key generation, Tom St Denis -*/ - -#ifdef LTC_MRSA - -/** - Create an RSA key - @param prng An active PRNG state - @param wprng The index of the PRNG desired - @param size The size of the modulus (key size) desired (octets) - @param e The "e" value (public key). e==65537 is a good choice - @param key [out] Destination of a newly created private key pair - @return CRYPT_OK if successful, upon error all allocated ram is freed -*/ -int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) -{ - void *p, *q, *tmp1, *tmp2, *tmp3; - int err; - - LTC_ARGCHK(ltc_mp.name != NULL); - LTC_ARGCHK(key != NULL); - - if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { - return CRYPT_INVALID_KEYSIZE; - } - - if ((e < 3) || ((e & 1) == 0)) { - return CRYPT_INVALID_ARG; - } - - if ((err = prng_is_valid(wprng)) != CRYPT_OK) { - return err; - } - - if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { - return err; - } - - /* make primes p and q (optimization provided by Wayne Scott) */ - if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto errkey; } /* tmp3 = e */ - - /* make prime "p" */ - do { - if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } - if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = p-1 */ - if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(p-1, e) */ - } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */ - - /* make prime "q" */ - do { - if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } - if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ - if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(q-1, e) */ - } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */ - - /* tmp1 = lcm(p-1, q-1) */ - if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ - /* tmp1 = q-1 (previous do/while loop) */ - if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = lcm(p-1, q-1) */ - - /* make key */ - if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { - goto errkey; - } - - if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */ - if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */ - if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */ - - /* optimize for CRT now */ - /* find d mod q-1 and d mod p-1 */ - if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ - if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ - if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */ - if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */ - if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */ - - if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; } - if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; } - - /* set key type (in this case it's CRT optimized) */ - key->type = PK_PRIVATE; - - /* return ok and free temps */ - err = CRYPT_OK; - goto cleanup; -errkey: - mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); -cleanup: - mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL); - return err; -} - -#endif - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_make_key.c,v $ */ -/* $Revision: 1.16 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c deleted file mode 100644 index 103ae2f5303..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_hash.c +++ /dev/null @@ -1,167 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file rsa_verify_hash.c - RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange -*/ - -#ifdef LTC_MRSA - -/** - LTC_PKCS #1 de-sign then v1.5 or PSS depad - @param sig The signature data - @param siglen The length of the signature data (octets) - @param hash The hash of the message that was signed - @param hashlen The length of the hash of the message that was signed (octets) - @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) - @param hash_idx The index of the desired hash - @param saltlen The length of the salt used during signature - @param stat [out] The result of the signature comparison, 1==valid, 0==invalid - @param key The public RSA key corresponding to the key that performed the signature - @return CRYPT_OK on success (even if the signature is invalid) -*/ -int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int padding, - int hash_idx, unsigned long saltlen, - int *stat, rsa_key *key) -{ - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; - unsigned char *tmpbuf; - - LTC_ARGCHK(hash != NULL); - LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(stat != NULL); - LTC_ARGCHK(key != NULL); - - /* default to invalid */ - *stat = 0; - - /* valid padding? */ - - if ((padding != LTC_LTC_PKCS_1_V1_5) && - (padding != LTC_LTC_PKCS_1_PSS)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_LTC_PKCS_1_PSS) { - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - } - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits( (key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size( (key->N)); - if (modulus_bytelen != siglen) { - return CRYPT_INVALID_PACKET; - } - - /* allocate temp buffer for decoded sig */ - tmpbuf = XMALLOC(siglen); - if (tmpbuf == NULL) { - return CRYPT_MEM; - } - - /* RSA decode it */ - x = siglen; - if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { - XFREE(tmpbuf); - return err; - } - - /* make sure the output is the right size */ - if (x != siglen) { - XFREE(tmpbuf); - return CRYPT_INVALID_PACKET; - } - - if (padding == LTC_LTC_PKCS_1_PSS) { - /* PSS decode and verify it */ - err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); - } else { - /* LTC_PKCS #1 v1.5 decode it */ - unsigned char *out; - unsigned long outlen, loid[16]; - int decoded; - ltc_asn1_list digestinfo[2], siginfo[2]; - - /* not all hashes have OIDs... so sad */ - if (hash_descriptor[hash_idx].OIDlen == 0) { - err = CRYPT_INVALID_ARG; - goto bail_2; - } - - /* allocate temp buffer for decoded hash */ - outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; - out = XMALLOC(outlen); - if (out == NULL) { - err = CRYPT_MEM; - goto bail_2; - } - - if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { - XFREE(out); - goto bail_2; - } - - /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ - /* construct the SEQUENCE - SEQUENCE { - SEQUENCE {hashoid OID - blah NULL - } - hash OCTET STRING - } - */ - LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); - LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); - LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); - LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); - - if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { - XFREE(out); - goto bail_2; - } - - /* test OID */ - if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && - (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && - (siginfo[1].size == hashlen) && - (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { - *stat = 1; - } - -#ifdef LTC_CLEAN_STACK - zeromem(out, outlen); -#endif - XFREE(out); - } - -bail_2: -#ifdef LTC_CLEAN_STACK - zeromem(tmpbuf, siglen); -#endif - XFREE(tmpbuf); - return err; -} - -#endif /* LTC_MRSA */ - -/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_verify_hash.c,v $ */ -/* $Revision: 1.13 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ diff --git a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c b/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c deleted file mode 100644 index 6d8888c858d..00000000000 --- a/dep/StormLib/src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c +++ /dev/null @@ -1,87 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../../headers/tomcrypt.h" - -/** - @file rsa_verify_simple.c - Created by Ladislav Zezula (zezula@volny.cz) as modification - for Blizzard strong signature verification -*/ - -#ifdef LTC_MRSA - -/** - Simple RSA decryption - @param sig The signature data - @param siglen The length of the signature data (octets) - @param hash The hash of the message that was signed - @param hashlen The length of the hash of the message that was signed (octets) - @param stat [out] The result of the signature comparison, 1==valid, 0==invalid - @param key The public RSA key corresponding - @return Error code -*/ -int rsa_verify_simple(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, - rsa_key *key) -{ - unsigned long modulus_bitlen, modulus_bytelen, x; - unsigned char *tmpbuf; - int err; - - LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(hash != NULL); - LTC_ARGCHK(stat != NULL); - LTC_ARGCHK(key != NULL); - - /* default to invalid */ - *stat = 0; - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits( (key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size( (key->N)); - if (modulus_bytelen != siglen) { - return CRYPT_INVALID_PACKET; - } - - /* allocate temp buffer for decoded sig */ - tmpbuf = XMALLOC(siglen); - if (tmpbuf == NULL) { - return CRYPT_MEM; - } - - /* RSA decode it */ - x = siglen; - if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { - XFREE(tmpbuf); - return err; - } - - /* make sure the output is the right size */ - if (x != siglen) { - XFREE(tmpbuf); - return CRYPT_INVALID_PACKET; - } - - /* compare the decrypted signature with the given hash */ - if(x == hashlen && XMEMCMP(tmpbuf, hash, hashlen) == 0) - *stat = 1; - -#ifdef LTC_CLEAN_STACK - zeromem(tmpbuf, siglen); -#endif - XFREE(tmpbuf); - return CRYPT_OK; -} - -#endif /* LTC_MRSA */ diff --git a/dep/StormLib/src/libtommath/bn_fast_mp_invmod.c b/dep/StormLib/src/libtommath/bn_fast_mp_invmod.c deleted file mode 100644 index 597d7a9b5fa..00000000000 --- a/dep/StormLib/src/libtommath/bn_fast_mp_invmod.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "tommath.h" -#ifdef BN_FAST_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes the modular inverse via binary extended euclidean algorithm, - * that is c = 1/a mod b - * - * Based on slow invmod except this is optimized for the case where b is - * odd as per HAC Note 14.64 on pp. 610 - */ -int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, B, D; - int res, neg; - - /* 2. [modified] b must be odd */ - if (mp_iseven (b) == 1) { - return MP_VAL; - } - - /* init all our temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x == modulus, y == value to invert */ - if ((res = mp_copy (b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - - /* we need y = |a| */ - if ((res = mp_mod (a, b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if B is odd then */ - if (mp_isodd (&B) == 1) { - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* B = B/2 */ - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if D is odd then */ - if (mp_isodd (&D) == 1) { - /* D = (D-x)/2 */ - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* D = D/2 */ - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == MP_NEG) { - if ((res = mp_add (&D, b, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_exch (&D, c); - c->sign = neg; - res = MP_OKAY; - -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_fast_mp_invmod.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c b/dep/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c deleted file mode 100644 index 65eed7da1fe..00000000000 --- a/dep/StormLib/src/libtommath/bn_fast_mp_montgomery_reduce.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "tommath.h" -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction - * - * This is an optimized implementation of montgomery_reduce - * which uses the comba method to quickly calculate the columns of the - * reduction. - * - * Based on Algorithm 14.32 on pp.601 of HAC. -*/ -int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, olduse; - mp_word W[MP_WARRAY]; - - /* get old used count */ - olduse = x->used; - - /* grow a as required */ - if (x->alloc < n->used + 1) { - if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { - return res; - } - } - - /* first we have to get the digits of the input into - * an array of double precision words W[...] - */ - { - register mp_word *_W; - register mp_digit *tmpx; - - /* alias for the W[] array */ - _W = W; - - /* alias for the digits of x*/ - tmpx = x->dp; - - /* copy the digits of a into W[0..a->used-1] */ - for (ix = 0; ix < x->used; ix++) { - *_W++ = *tmpx++; - } - - /* zero the high words of W[a->used..m->used*2] */ - for (; ix < n->used * 2 + 1; ix++) { - *_W++ = 0; - } - } - - /* now we proceed to zero successive digits - * from the least significant upwards - */ - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b - * - * We avoid a double precision multiplication (which isn't required) - * by casting the value down to a mp_digit. Note this requires - * that W[ix-1] have the carry cleared (see after the inner loop) - */ - register mp_digit mu; - mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); - - /* a = a + mu * m * b**i - * - * This is computed in place and on the fly. The multiplication - * by b**i is handled by offseting which columns the results - * are added to. - * - * Note the comba method normally doesn't handle carries in the - * inner loop In this case we fix the carry from the previous - * column since the Montgomery reduction requires digits of the - * result (so far) [see above] to work. This is - * handled by fixing up one carry after the inner loop. The - * carry fixups are done in order so after these loops the - * first m->used words of W[] have the carries fixed - */ - { - register int iy; - register mp_digit *tmpn; - register mp_word *_W; - - /* alias for the digits of the modulus */ - tmpn = n->dp; - - /* Alias for the columns set by an offset of ix */ - _W = W + ix; - - /* inner loop */ - for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); - } - } - - /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); - } - - /* now we have to propagate the carries and - * shift the words downward [all those least - * significant digits we zeroed]. - */ - { - register mp_digit *tmpx; - register mp_word *_W, *_W1; - - /* nox fix rest of carries */ - - /* alias for current word */ - _W1 = W + ix; - - /* alias for next word, where the carry goes */ - _W = W + ++ix; - - for (; ix <= n->used * 2 + 1; ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); - } - - /* copy out, A = A/b**n - * - * The result is A/b**n but instead of converting from an - * array of mp_word to mp_digit than calling mp_rshd - * we just copy them in the right order - */ - - /* alias for destination word */ - tmpx = x->dp; - - /* alias for shifted double precision result */ - _W = W + n->used; - - for (ix = 0; ix < n->used + 1; ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); - } - - /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits - */ - for (; ix < olduse; ix++) { - *tmpx++ = 0; - } - } - - /* set the max used and clamp */ - x->used = n->used + 1; - mp_clamp (x); - - /* if A >= m then A = A - m */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c b/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c deleted file mode 100644 index df83f89ecab..00000000000 --- a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_digs.c +++ /dev/null @@ -1,107 +0,0 @@ -#include "tommath.h" -#ifdef BN_FAST_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Fast (comba) multiplier - * - * This is the fast column-array [comba] multiplier. It is - * designed to compute the columns of the product first - * then handle the carries afterwards. This has the effect - * of making the nested loops that compute the columns very - * simple and schedulable on super-scalar processors. - * - * This has been modified to produce a variable number of - * digits of output so if say only a half-product is required - * you don't have to compute the upper half (a feature - * required for fast Barrett reduction). - * - * Based on Algorithm 14.12 on pp.595 of HAC. - * - */ -int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - register mp_word _W; - - /* grow the destination as required */ - if (c->alloc < digs) { - if ((res = mp_grow (c, digs)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = MIN(digs, a->used + b->used); - - /* clear the carry */ - _W = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty; - int iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - tmpc = c->dp; - for (ix = 0; ix < pa+1; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_digs.c,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c b/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c deleted file mode 100644 index 6866aab7529..00000000000 --- a/dep/StormLib/src/libtommath/bn_fast_s_mp_mul_high_digs.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "tommath.h" -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* this is a modified version of fast_s_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mul_digs - * to see how it works. - * - * This is used in the Barrett reduction since for one of the multiplications - * only the higher digits were needed. This essentially halves the work. - * - * Based on Algorithm 14.12 on pp.595 of HAC. - */ -int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - pa = a->used + b->used; - if (c->alloc < pa) { - if ((res = mp_grow (c, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = a->used + b->used; - _W = 0; - for (ix = digs; ix < pa; ix++) { - int tx, ty, iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - - tmpc = c->dp + digs; - for (ix = digs; ix < pa; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_high_digs.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_fast_s_mp_sqr.c b/dep/StormLib/src/libtommath/bn_fast_s_mp_sqr.c deleted file mode 100644 index 5f9d58cac62..00000000000 --- a/dep/StormLib/src/libtommath/bn_fast_s_mp_sqr.c +++ /dev/null @@ -1,114 +0,0 @@ -#include "tommath.h" -#ifdef BN_FAST_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* the jist of squaring... - * you do like mult except the offset of the tmpx [one that - * starts closer to zero] can't equal the offset of tmpy. - * So basically you set up iy like before then you min it with - * (ty-tx) so that it never happens. You double all those - * you add in the inner loop - -After that loop you do the squares and add them in. -*/ - -int fast_s_mp_sqr (mp_int * a, mp_int * b) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY], *tmpx; - mp_word W1; - - /* grow the destination as required */ - pa = a->used + a->used; - if (b->alloc < pa) { - if ((res = mp_grow (b, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - W1 = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - mp_word _W; - mp_digit *tmpy; - - /* clear counter */ - _W = 0; - - /* get offsets into the two bignums */ - ty = MIN(a->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = a->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach at a rate of 2x - * and we have to round because odd cases need to be executed - */ - iy = MIN(iy, (ty-tx+1)>>1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* double the inner product and add carry */ - _W = _W + _W + W1; - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); - } - - /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); - - /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = b->used; - b->used = a->used+a->used; - - { - mp_digit *tmpb; - tmpb = b->dp; - for (ix = 0; ix < pa; ix++) { - *tmpb++ = W[ix] & MP_MASK; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpb++ = 0; - } - } - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_sqr.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_2expt.c b/dep/StormLib/src/libtommath/bn_mp_2expt.c deleted file mode 100644 index f899eaee43e..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_2expt.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_2EXPT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes a = 2**b - * - * Simple algorithm which zeroes the int, grows it then just sets one bit - * as required. - */ -int -mp_2expt (mp_int * a, int b) -{ - int res; - - /* zero a as per default */ - mp_zero (a); - - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - - /* set the used count of where the bit will go */ - a->used = b / DIGIT_BIT + 1; - - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_2expt.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_abs.c b/dep/StormLib/src/libtommath/bn_mp_abs.c deleted file mode 100644 index 14f3a7e074d..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_abs.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_ABS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = |a| - * - * Simple function copies the input and fixes the sign to positive - */ -int -mp_abs (mp_int * a, mp_int * b) -{ - int res; - - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - /* force the sign of b to positive */ - b->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_abs.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_add.c b/dep/StormLib/src/libtommath/bn_mp_add.c deleted file mode 100644 index b368b21c7cb..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_add.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level addition (handles signs) */ -int mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; - - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (mp_cmp_mag (a, b) == MP_LT) { - c->sign = sb; - res = s_mp_sub (b, a, c); - } else { - c->sign = sa; - res = s_mp_sub (a, b, c); - } - } - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_add.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_add_d.c b/dep/StormLib/src/libtommath/bn_mp_add_d.c deleted file mode 100644 index c147554bdb8..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_add_d.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_ADD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* single digit addition */ -int -mp_add_d (mp_int * a, mp_digit b, mp_int * c) -{ - int res, ix, oldused; - mp_digit *tmpa, *tmpc, mu; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative and |a| >= b, call c = |a| - b */ - if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { - /* temporarily fix sign of a */ - a->sign = MP_ZPOS; - - /* c = |a| - b */ - res = mp_sub_d(a, b, c); - - /* fix sign */ - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* old number of used digits in c */ - oldused = c->used; - - /* sign always positive */ - c->sign = MP_ZPOS; - - /* source alias */ - tmpa = a->dp; - - /* destination alias */ - tmpc = c->dp; - - /* if a is positive */ - if (a->sign == MP_ZPOS) { - /* add digit, after this we're propagating - * the carry. - */ - *tmpc = *tmpa++ + b; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - - /* now handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ + mu; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - } - /* set final carry */ - ix++; - *tmpc++ = mu; - - /* setup size */ - c->used = a->used + 1; - } else { - /* a was negative and |a| < b */ - c->used = 1; - - /* the result is a single digit */ - if (a->used == 1) { - *tmpc++ = b - a->dp[0]; - } else { - *tmpc++ = b; - } - - /* setup count so the clearing of oldused - * can fall through correctly - */ - ix = 1; - } - - /* now zero to oldused */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_addmod.c b/dep/StormLib/src/libtommath/bn_mp_addmod.c deleted file mode 100644 index 0a21f62e9a6..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_addmod.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_ADDMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a + b (mod c) */ -int -mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_add (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_addmod.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_and.c b/dep/StormLib/src/libtommath/bn_mp_and.c deleted file mode 100644 index 6b7afc104a8..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_and.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_AND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* AND two ints together */ -int -mp_and (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] &= x->dp[ix]; - } - - /* zero digits above the last from the smallest mp_int */ - for (; ix < t.used; ix++) { - t.dp[ix] = 0; - } - - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_and.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_clamp.c b/dep/StormLib/src/libtommath/bn_mp_clamp.c deleted file mode 100644 index d3cc21c3eff..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_clamp.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_CLAMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* trim unused digits - * - * This is used to ensure that leading zero digits are - * trimed and the leading "used" digit will be non-zero - * Typically very fast. Also fixes the sign if there - * are no more leading digits - */ -void -mp_clamp (mp_int * a) -{ - /* decrease used while the most significant digit is - * zero. - */ - while (a->used > 0 && a->dp[a->used - 1] == 0) { - --(a->used); - } - - /* reset the sign flag if used == 0 */ - if (a->used == 0) { - a->sign = MP_ZPOS; - } -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_clamp.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_clear.c b/dep/StormLib/src/libtommath/bn_mp_clear.c deleted file mode 100644 index 7644c382512..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_clear.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_CLEAR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* clear one (frees) */ -void -mp_clear (mp_int * a) -{ - int i; - - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - for (i = 0; i < a->used; i++) { - a->dp[i] = 0; - } - - /* free ram */ - XFREE(a->dp); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_clear.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_clear_multi.c b/dep/StormLib/src/libtommath/bn_mp_clear_multi.c deleted file mode 100644 index a1076243675..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_clear_multi.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_CLEAR_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include <stdarg.h> - -void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_clear_multi.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_cmp.c b/dep/StormLib/src/libtommath/bn_mp_cmp.c deleted file mode 100644 index 761d2b0dc75..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_cmp.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_CMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare two ints (signed)*/ -int -mp_cmp (mp_int * a, mp_int * b) -{ - /* compare based on sign */ - if (a->sign != b->sign) { - if (a->sign == MP_NEG) { - return MP_LT; - } else { - return MP_GT; - } - } - - /* compare digits */ - if (a->sign == MP_NEG) { - /* if negative compare opposite direction */ - return mp_cmp_mag(b, a); - } else { - return mp_cmp_mag(a, b); - } -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_cmp.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_cmp_d.c b/dep/StormLib/src/libtommath/bn_mp_cmp_d.c deleted file mode 100644 index 420dfd31aa1..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_cmp_d.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_CMP_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare a digit */ -int mp_cmp_d(mp_int * a, mp_digit b) -{ - /* compare based on sign */ - if (a->sign == MP_NEG) { - return MP_LT; - } - - /* compare based on magnitude */ - if (a->used > 1) { - return MP_GT; - } - - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return MP_GT; - } else if (a->dp[0] < b) { - return MP_LT; - } else { - return MP_EQ; - } -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_d.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_cmp_mag.c b/dep/StormLib/src/libtommath/bn_mp_cmp_mag.c deleted file mode 100644 index 92565a3b896..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_cmp_mag.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_CMP_MAG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare maginitude of two ints (unsigned) */ -int mp_cmp_mag (mp_int * a, mp_int * b) -{ - int n; - mp_digit *tmpa, *tmpb; - - /* compare based on # of non-zero digits */ - if (a->used > b->used) { - return MP_GT; - } - - if (a->used < b->used) { - return MP_LT; - } - - /* alias for a */ - tmpa = a->dp + (a->used - 1); - - /* alias for b */ - tmpb = b->dp + (a->used - 1); - - /* compare based on digits */ - for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { - if (*tmpa > *tmpb) { - return MP_GT; - } - - if (*tmpa < *tmpb) { - return MP_LT; - } - } - return MP_EQ; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_mag.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_cnt_lsb.c b/dep/StormLib/src/libtommath/bn_mp_cnt_lsb.c deleted file mode 100644 index 60406610ed6..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_cnt_lsb.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_CNT_LSB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a) -{ - int x; - mp_digit q, qq; - - /* easy out */ - if (mp_iszero(a) == 1) { - return 0; - } - - /* scan lower digits until non-zero */ - for (x = 0; x < a->used && a->dp[x] == 0; x++); - q = a->dp[x]; - x *= DIGIT_BIT; - - /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { - do { - qq = q & 15; - x += lnz[qq]; - q >>= 4; - } while (qq == 0); - } - return x; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_cnt_lsb.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_copy.c b/dep/StormLib/src/libtommath/bn_mp_copy.c deleted file mode 100644 index 7828592da5d..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_copy.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* copy, b = a */ -int -mp_copy (mp_int * a, mp_int * b) -{ - int res, n; - - /* if dst == src do nothing */ - if (a == b) { - return MP_OKAY; - } - - /* grow dest */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - /* zero b and copy the parameters over */ - { - register mp_digit *tmpa, *tmpb; - - /* pointer aliases */ - - /* source */ - tmpa = a->dp; - - /* destination */ - tmpb = b->dp; - - /* copy all the digits */ - for (n = 0; n < a->used; n++) { - *tmpb++ = *tmpa++; - } - - /* clear high digits */ - for (; n < b->used; n++) { - *tmpb++ = 0; - } - } - - /* copy used count and sign */ - b->used = a->used; - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_copy.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_count_bits.c b/dep/StormLib/src/libtommath/bn_mp_count_bits.c deleted file mode 100644 index 9d8640fdfce..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_count_bits.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_COUNT_BITS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* returns the number of bits in an int */ -int -mp_count_bits (mp_int * a) -{ - int r; - mp_digit q; - - /* shortcut */ - if (a->used == 0) { - return 0; - } - - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { - ++r; - q >>= ((mp_digit) 1); - } - return r; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_count_bits.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_div.c b/dep/StormLib/src/libtommath/bn_mp_div.c deleted file mode 100644 index 3004a3ea016..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_div.c +++ /dev/null @@ -1,292 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DIV_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -#ifdef BN_MP_DIV_SMALL - -/* slower bit-bang division... also smaller */ -int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int ta, tb, tq, q; - int res, n, n2; - - /* is divisor zero ? */ - if (mp_iszero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { - return res; - } - - - mp_set(&tq, 1); - n = mp_count_bits(a) - mp_count_bits(b); - if (((res = mp_abs(a, &ta)) != MP_OKAY) || - ((res = mp_abs(b, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { - goto LBL_ERR; - } - - while (n-- >= 0) { - if (mp_cmp(&tb, &ta) != MP_GT) { - if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { - goto LBL_ERR; - } - } - if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { - goto LBL_ERR; - } - } - - /* now q == quotient and ta == remainder */ - n = a->sign; - n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); - if (c != NULL) { - mp_exch(c, &q); - c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; - } - if (d != NULL) { - mp_exch(d, &ta); - d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; - } -LBL_ERR: - mp_clear_multi(&ta, &tb, &tq, &q, NULL); - return res; -} - -#else - -/* integer signed division. - * c*b + d == a [e.g. a/b, c=quotient, d=remainder] - * HAC pp.598 Algorithm 14.20 - * - * Note that the description in HAC is horribly - * incomplete. For example, it doesn't consider - * the case where digits are removed from 'x' in - * the inner loop. It also doesn't consider the - * case that y has fewer than three digits, etc.. - * - * The overall algorithm is as described as - * 14.20 from HAC but fixed to treat these cases. -*/ -int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int q, x, y, t1, t2; - int res, n, t, i, norm, neg; - - /* is divisor zero ? */ - if (mp_iszero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { - return res; - } - q.used = a->used + 2; - - if ((res = mp_init (&t1)) != MP_OKAY) { - goto LBL_Q; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init_copy (&x, a)) != MP_OKAY) { - goto LBL_T2; - } - - if ((res = mp_init_copy (&y, b)) != MP_OKAY) { - goto LBL_X; - } - - /* fix the sign */ - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - x.sign = y.sign = MP_ZPOS; - - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; - if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { - goto LBL_Y; - } - } else { - norm = 0; - } - - /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ - n = x.used - 1; - t = y.used - 1; - - /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ - goto LBL_Y; - } - - while (mp_cmp (&x, &y) != MP_LT) { - ++(q.dp[n - t]); - if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { - goto LBL_Y; - } - } - - /* reset y by shifting it back down */ - mp_rshd (&y, n - t); - - /* step 3. for i from n down to (t + 1) */ - for (i = n; i >= (t + 1); i--) { - if (i > x.used) { - continue; - } - - /* step 3.1 if xi == yt then set q{i-t-1} to b-1, - * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ - if (x.dp[i] == y.dp[t]) { - q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); - } else { - mp_word tmp; - tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); - tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); - if (tmp > (mp_word) MP_MASK) - tmp = MP_MASK; - q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); - } - - /* while (q{i-t-1} * (yt * b + y{t-1})) > - xi * b**2 + xi-1 * b + xi-2 - - do q{i-t-1} -= 1; - */ - q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; - do { - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; - - /* find left hand */ - mp_zero (&t1); - t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; - t1.dp[1] = y.dp[t]; - t1.used = 2; - if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - /* find right hand */ - t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; - t2.dp[2] = x.dp[i]; - t2.used = 3; - } while (mp_cmp_mag(&t1, &t2) == MP_GT); - - /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ - if (x.sign == MP_NEG) { - if ((res = mp_copy (&y, &t1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; - } - } - - /* now q is the quotient and x is the remainder - * [which we have to normalize] - */ - - /* get sign before writing to c */ - x.sign = x.used == 0 ? MP_ZPOS : a->sign; - - if (c != NULL) { - mp_clamp (&q); - mp_exch (&q, c); - c->sign = neg; - } - - if (d != NULL) { - mp_div_2d (&x, norm, &x, NULL); - mp_exch (&x, d); - } - - res = MP_OKAY; - -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); -LBL_Q:mp_clear (&q); - return res; -} - -#endif - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_div.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_div_2.c b/dep/StormLib/src/libtommath/bn_mp_div_2.c deleted file mode 100644 index f3b9d16fa37..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_div_2.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DIV_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = a/2 */ -int mp_div_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_div_2.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_div_2d.c b/dep/StormLib/src/libtommath/bn_mp_div_2d.c deleted file mode 100644 index 861ea23a31a..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_div_2d.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DIV_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) -{ - mp_digit D, r, rr; - int x, res; - mp_int t; - - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (mp_digit) (b % DIGIT_BIT); - if (D != 0) { - register mp_digit *tmpc, mask, shift; - - /* mask */ - mask = (((mp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from the previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } - } - mp_clamp (c); - if (d != NULL) { - mp_exch (&t, d); - } - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_div_2d.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_div_3.c b/dep/StormLib/src/libtommath/bn_mp_div_3.c deleted file mode 100644 index 4fc08fc4da4..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_div_3.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DIV_3_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* divide by three (based on routine from MPI and the GMP manual) */ -int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) -{ - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } - - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_div_3.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_div_d.c b/dep/StormLib/src/libtommath/bn_mp_div_d.c deleted file mode 100644 index c0318a4a1be..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_div_d.c +++ /dev/null @@ -1,115 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DIV_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static int s_is_power_of_two(mp_digit b, int *p) -{ - int x; - - /* fast return if no power of two */ - if ((b==0) || (b & (b-1))) { - return 0; - } - - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<<x)) { - *p = x; - return 1; - } - } - return 0; -} - -/* single digit division (based on routine from MPI) */ -int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) -{ - mp_int q; - mp_word w; - mp_digit t; - int res, ix; - - /* cannot divide by zero */ - if (b == 0) { - return MP_VAL; - } - - /* quick outs */ - if (b == 1 || mp_iszero(a) == 1) { - if (d != NULL) { - *d = 0; - } - if (c != NULL) { - return mp_copy(a, c); - } - return MP_OKAY; - } - - /* power of two ? */ - if (s_is_power_of_two(b, &ix) == 1) { - if (d != NULL) { - *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1); - } - if (c != NULL) { - return mp_div_2d(a, ix, c, NULL); - } - return MP_OKAY; - } - -#ifdef BN_MP_DIV_3_C - /* three? */ - if (b == 3) { - return mp_div_3(a, c, d); - } -#endif - - /* no easy answer [c'est la vie]. Just division */ - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= b) { - t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - if (d != NULL) { - *d = (mp_digit)w; - } - - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_div_d.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2007/01/09 04:44:32 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_dr_is_modulus.c b/dep/StormLib/src/libtommath/bn_mp_dr_is_modulus.c deleted file mode 100644 index 22ba5df3d0a..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_dr_is_modulus.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DR_IS_MODULUS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - /* must be of the form b**k - a [a <= b] so all - * but the first digit must be equal to -1 (mod b). - */ - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_dr_is_modulus.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_dr_reduce.c b/dep/StormLib/src/libtommath/bn_mp_dr_reduce.c deleted file mode 100644 index 0afac941fca..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_dr_reduce.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DR_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. - * - * Based on algorithm from the paper - * - * "Generating Efficient Primes for Discrete Log Cryptosystems" - * Chae Hoon Lim, Pil Joong Lee, - * POSTECH Information Research Laboratories - * - * The modulus must be of a special format [see manual] - * - * Has been modified to use algorithm 7.10 from the LTM book instead - * - * Input x must be in the range 0 <= x <= (n-1)**2 - */ -int -mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) -{ - int err, i, m; - mp_word r; - mp_digit mu, *tmpx1, *tmpx2; - - /* m = digits in modulus */ - m = n->used; - - /* ensure that "x" has at least 2m digits */ - if (x->alloc < m + m) { - if ((err = mp_grow (x, m + m)) != MP_OKAY) { - return err; - } - } - -/* top of loop, this is where the code resumes if - * another reduction pass is required. - */ -top: - /* aliases for digits */ - /* alias for lower half of x */ - tmpx1 = x->dp; - - /* alias for upper half of x, or x/B**m */ - tmpx2 = x->dp + m; - - /* set carry to zero */ - mu = 0; - - /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ - for (i = 0; i < m; i++) { - r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; - *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); - } - - /* set final carry */ - *tmpx1++ = mu; - - /* zero words above m */ - for (i = m + 1; i < x->used; i++) { - *tmpx1++ = 0; - } - - /* clamp, sub and return */ - mp_clamp (x); - - /* if x >= n then subtract and reduce again - * Each successive "recursion" makes the input smaller and smaller. - */ - if (mp_cmp_mag (x, n) != MP_LT) { - s_mp_sub(x, n, x); - goto top; - } - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_dr_reduce.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_dr_setup.c b/dep/StormLib/src/libtommath/bn_mp_dr_setup.c deleted file mode 100644 index a5152f713bd..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_dr_setup.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_DR_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_dr_setup.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_exch.c b/dep/StormLib/src/libtommath/bn_mp_exch.c deleted file mode 100644 index e5ec7f57730..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_exch.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_EXCH_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* swap the elements of two integers, for cases where you can't simply swap the - * mp_int pointers around - */ -void -mp_exch (mp_int * a, mp_int * b) -{ - mp_int t; - - t = *a; - *a = *b; - *b = t; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_exch.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_expt_d.c b/dep/StormLib/src/libtommath/bn_mp_expt_d.c deleted file mode 100644 index 7bf371ce6ae..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_expt_d.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_EXPT_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* calculate c = a**b using a square-multiply algorithm */ -int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) -{ - int res, x; - mp_int g; - - if ((res = mp_init_copy (&g, a)) != MP_OKAY) { - return res; - } - - /* set initial result */ - mp_set (c, 1); - - for (x = 0; x < (int) DIGIT_BIT; x++) { - /* square */ - if ((res = mp_sqr (c, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - - /* if the bit is set multiply */ - if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { - if ((res = mp_mul (c, &g, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* shift to next bit */ - b <<= 1; - } - - mp_clear (&g); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_expt_d.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_exptmod.c b/dep/StormLib/src/libtommath/bn_mp_exptmod.c deleted file mode 100644 index 27c46ea0ab2..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_exptmod.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - - -/* this is a shell function that calls either the normal or Montgomery - * exptmod functions. Originally the call to the montgomery code was - * embedded in the normal function but that wasted alot of stack space - * for nothing (since 99% of the time the Montgomery code would be called) - */ -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -{ - int dr; - - /* modulus P must be positive */ - if (P->sign == MP_NEG) { - return MP_VAL; - } - - /* if exponent X is negative we have to recurse */ - if (X->sign == MP_NEG) { -#ifdef BN_MP_INVMOD_C - mp_int tmpG, tmpX; - int err; - - /* first compute 1/G mod P */ - if ((err = mp_init(&tmpG)) != MP_OKAY) { - return err; - } - if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - - /* now get |X| */ - if ((err = mp_init(&tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; - } - - /* and now compute (1/G)**|X| instead of G**X [X < 0] */ - err = mp_exptmod(&tmpG, &tmpX, P, Y); - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; -#else - /* no invmod */ - return MP_VAL; -#endif - } - -/* modified diminished radix reduction */ -#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) - if (mp_reduce_is_2k_l(P) == MP_YES) { - return s_mp_exptmod(G, X, P, Y, 1); - } -#endif - -#ifdef BN_MP_DR_IS_MODULUS_C - /* is it a DR modulus? */ - dr = mp_dr_is_modulus(P); -#else - /* default to no */ - dr = 0; -#endif - -#ifdef BN_MP_REDUCE_IS_2K_C - /* if not, is it a unrestricted DR modulus? */ - if (dr == 0) { - dr = mp_reduce_is_2k(P) << 1; - } -#endif - - /* if the modulus is odd or dr != 0 use the montgomery method */ -#ifdef BN_MP_EXPTMOD_FAST_C - if (mp_isodd (P) == 1 || dr != 0) { - return mp_exptmod_fast (G, X, P, Y, dr); - } else { -#endif -#ifdef BN_S_MP_EXPTMOD_C - /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y, 0); -#else - /* no exptmod for evens */ - return MP_VAL; -#endif -#ifdef BN_MP_EXPTMOD_FAST_C - } -#endif -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_exptmod_fast.c b/dep/StormLib/src/libtommath/bn_mp_exptmod_fast.c deleted file mode 100644 index 31205d4e20c..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_exptmod_fast.c +++ /dev/null @@ -1,321 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_EXPTMOD_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 - * - * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. - * The value of k changes based on the size of the exponent. - * - * Uses Montgomery or Diminished Radix reduction [whichever appropriate] - */ - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res; - mp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* use a pointer to the reduction algorithm. This allows us to use - * one of many reduction algorithms without modding the guts of - * the code with if statements everywhere. - */ - int (*redux)(mp_int*,mp_int*,mp_digit); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* determine and setup reduction code */ - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_SETUP_C - /* now setup montgomery */ - if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { - goto LBL_M; - } -#else - err = MP_VAL; - goto LBL_M; -#endif - - /* automatically pick the comba one if available (saves quite a few calls/ifs) */ -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C - if (((P->used * 2 + 1) < MP_WARRAY) && - P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - redux = fast_mp_montgomery_reduce; - } else -#endif - { -#ifdef BN_MP_MONTGOMERY_REDUCE_C - /* use slower baseline Montgomery method */ - redux = mp_montgomery_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - } else if (redmode == 1) { -#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) - /* setup DR reduction for moduli of the form B**k - b */ - mp_dr_setup(P, &mp); - redux = mp_dr_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } else { -#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) - /* setup DR reduction for moduli of the form 2**k - b */ - if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { - goto LBL_M; - } - redux = mp_reduce_2k; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_M; - } - - /* create M table - * - - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - /* now we need R mod m */ - if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { - goto LBL_RES; - } -#else - err = MP_VAL; - goto LBL_RES; -#endif - - /* now set M[1] to G * R mod m */ - if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } else { - mp_set(&res, 1); - if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[x], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - if (redmode == 0) { - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - if ((err = redux(&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* swap res with Y */ - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - - -/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod_fast.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_exteuclid.c b/dep/StormLib/src/libtommath/bn_mp_exteuclid.c deleted file mode 100644 index 9881d6edc80..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_exteuclid.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_EXTEUCLID_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Extended euclidean algorithm of (a, b) produces - a*u1 + b*u2 = u3 - */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) -{ - mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; - int err; - - if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { - return err; - } - - /* initialize, (u1,u2,u3) = (1,0,a) */ - mp_set(&u1, 1); - if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } - - /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&v2, 1); - if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } - - /* loop while v3 != 0 */ - while (mp_iszero(&v3) == MP_NO) { - /* q = u3/v3 */ - if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } - - /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } - - /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } - - /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } - } - - /* make sure U3 >= 0 */ - if (u3.sign == MP_NEG) { - mp_neg(&u1, &u1); - mp_neg(&u2, &u2); - mp_neg(&u3, &u3); - } - - /* copy result out */ - if (U1 != NULL) { mp_exch(U1, &u1); } - if (U2 != NULL) { mp_exch(U2, &u2); } - if (U3 != NULL) { mp_exch(U3, &u3); } - - err = MP_OKAY; -_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_exteuclid.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_fread.c b/dep/StormLib/src/libtommath/bn_mp_fread.c deleted file mode 100644 index 2976b30aa68..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_fread.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_FREAD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read a bigint from a file stream in ASCII */ -int mp_fread(mp_int *a, int radix, FILE *stream) -{ - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - - /* if first digit is - then set negative */ - ch = fgetc(stream); - if (ch == '-') { - neg = MP_NEG; - ch = fgetc(stream); - } else { - neg = MP_ZPOS; - } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } - } - if (y == radix) { - break; - } - - /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { - return err; - } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { - return err; - } - - ch = fgetc(stream); - } - if (mp_cmp_d(a, 0) != MP_EQ) { - a->sign = neg; - } - - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_fread.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_fwrite.c b/dep/StormLib/src/libtommath/bn_mp_fwrite.c deleted file mode 100644 index 6782b2e19f7..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_fwrite.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_FWRITE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -int mp_fwrite(mp_int *a, int radix, FILE *stream) -{ - char *buf; - int err, len, x; - - if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { - return err; - } - - buf = OPT_CAST(char) XMALLOC (len); - if (buf == NULL) { - return MP_MEM; - } - - if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { - XFREE (buf); - return err; - } - - for (x = 0; x < len; x++) { - if (fputc(buf[x], stream) == EOF) { - XFREE (buf); - return MP_VAL; - } - } - - XFREE (buf); - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_fwrite.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_gcd.c b/dep/StormLib/src/libtommath/bn_mp_gcd.c deleted file mode 100644 index ce980eb6bb0..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_gcd.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_GCD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Greatest Common Divisor using the binary method */ -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int u, v; - int k, u_lsb, v_lsb, res; - - /* either zero than gcd is the largest */ - if (mp_iszero (a) == MP_YES) { - return mp_abs (b, c); - } - if (mp_iszero (b) == MP_YES) { - return mp_abs (a, c); - } - - /* get copies of a and b we can modify */ - if ((res = mp_init_copy (&u, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init_copy (&v, b)) != MP_OKAY) { - goto LBL_U; - } - - /* must be positive for the remainder of the algorithm */ - u.sign = v.sign = MP_ZPOS; - - /* B1. Find the common power of two for u and v */ - u_lsb = mp_cnt_lsb(&u); - v_lsb = mp_cnt_lsb(&v); - k = MIN(u_lsb, v_lsb); - - if (k > 0) { - /* divide the power of two out */ - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* divide any remaining factors of two out */ - if (u_lsb != k) { - if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - if (v_lsb != k) { - if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - while (mp_iszero(&v) == 0) { - /* make sure v is the largest */ - if (mp_cmp_mag(&u, &v) == MP_GT) { - /* swap u and v to make sure v is >= u */ - mp_exch(&u, &v); - } - - /* subtract smallest from largest */ - if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { - goto LBL_V; - } - - /* Divide out all factors of two */ - if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* multiply by 2**k which we divided out at the beginning */ - if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto LBL_V; - } - c->sign = MP_ZPOS; - res = MP_OKAY; -LBL_V:mp_clear (&u); -LBL_U:mp_clear (&v); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_gcd.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_get_int.c b/dep/StormLib/src/libtommath/bn_mp_get_int.c deleted file mode 100644 index d9c76d0d15c..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_get_int.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_GET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the lower 32-bits of an mp_int */ -unsigned long mp_get_int(mp_int * a) -{ - int i; - unsigned long res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } - - /* force result to 32-bits always so it is consistent on non 32-bit platforms */ - return res & 0xFFFFFFFFUL; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_get_int.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_grow.c b/dep/StormLib/src/libtommath/bn_mp_grow.c deleted file mode 100644 index a05dad73bc1..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_grow.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_GROW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* grow as required */ -int mp_grow (mp_int * a, int size) -{ - int i; - mp_digit *tmp; - - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } - - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_grow.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_init.c b/dep/StormLib/src/libtommath/bn_mp_init.c deleted file mode 100644 index 107d98be6e8..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_init.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INIT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* init a new mp_int */ -int mp_init (mp_int * a) -{ - int i; - - /* allocate memory required and clear it */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_init.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_init_copy.c b/dep/StormLib/src/libtommath/bn_mp_init_copy.c deleted file mode 100644 index 3ca1186ce1d..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_init_copy.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INIT_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* creates "a" then copies b into it */ -int mp_init_copy (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_init (a)) != MP_OKAY) { - return res; - } - return mp_copy (b, a); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_init_copy.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_init_multi.c b/dep/StormLib/src/libtommath/bn_mp_init_multi.c deleted file mode 100644 index 4f6f367ffd5..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_init_multi.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INIT_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include <stdarg.h> - -int mp_init_multi(mp_int *mp, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; - - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* end the current list */ - va_end(args); - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n--) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_init_multi.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_init_set.c b/dep/StormLib/src/libtommath/bn_mp_init_set.c deleted file mode 100644 index 853323f3aaa..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_init_set.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INIT_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - mp_set(a, b); - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_init_set.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_init_set_int.c b/dep/StormLib/src/libtommath/bn_mp_init_set_int.c deleted file mode 100644 index b2f8727e336..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_init_set_int.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INIT_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set_int (mp_int * a, unsigned long b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - return mp_set_int(a, b); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_init_set_int.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_init_size.c b/dep/StormLib/src/libtommath/bn_mp_init_size.c deleted file mode 100644 index 17b8d9fceb0..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_init_size.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INIT_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* init an mp_init for a given size */ -int mp_init_size (mp_int * a, int size) -{ - int x; - - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; - - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_init_size.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_invmod.c b/dep/StormLib/src/libtommath/bn_mp_invmod.c deleted file mode 100644 index 038e584a25c..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_invmod.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - -#ifdef BN_FAST_MP_INVMOD_C - /* if the modulus is odd we can use a faster routine instead */ - if (mp_isodd (b) == 1) { - return fast_mp_invmod (a, b, c); - } -#endif - -#ifdef BN_MP_INVMOD_SLOW_C - return mp_invmod_slow(a, b, c); -#endif - - return MP_VAL; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_invmod.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_invmod_slow.c b/dep/StormLib/src/libtommath/bn_mp_invmod_slow.c deleted file mode 100644 index 3792a4c2333..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_invmod_slow.c +++ /dev/null @@ -1,175 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_INVMOD_SLOW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - - /* init temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, - &A, &B, &C, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x = a, y = b */ - if ((res = mp_mod(a, b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 2. [modified] if x,y are both even then return an error! */ - if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { - res = MP_VAL; - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&A, 1); - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if A or B is odd then */ - if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { - /* A = (A+y)/2, B = (B-x)/2 */ - if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* A = A/2, B = B/2 */ - if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if C or D is odd then */ - if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { - /* C = (C+y)/2, D = (D-x)/2 */ - if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* C = C/2, D = D/2 */ - if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, A = A - C, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, C = C - A, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { - if ((res = mp_add(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* too big */ - while (mp_cmp_mag(&C, b) != MP_LT) { - if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* C is now the inverse */ - mp_exch (&C, c); - res = MP_OKAY; -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_invmod_slow.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_is_square.c b/dep/StormLib/src/libtommath/bn_mp_is_square.c deleted file mode 100644 index 5d2fa072ce9..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_is_square.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_IS_SQUARE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Check if remainders are possible squares - fast exclude non-squares */ -static const char rem_128[128] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 -}; - -static const char rem_105[105] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 -}; - -/* Store non-zero to ret if arg is square, and zero if not */ -int mp_is_square(mp_int *arg,int *ret) -{ - int res; - mp_digit c; - mp_int t; - unsigned long r; - - /* Default to Non-square :) */ - *ret = MP_NO; - - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* digits used? (TSD) */ - if (arg->used == 0) { - return MP_OKAY; - } - - /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ - if (rem_128[127 & DIGIT(arg,0)] == 1) { - return MP_OKAY; - } - - /* Next check mod 105 (3*5*7) */ - if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { - return res; - } - if (rem_105[c] == 1) { - return MP_OKAY; - } - - - if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { - return res; - } - if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { - goto ERR; - } - r = mp_get_int(&t); - /* Check for other prime modules, note it's not an ERROR but we must - * free "t" so the easiest way is to goto ERR. We know that res - * is already equal to MP_OKAY from the mp_mod call - */ - if ( (1L<<(r%11)) & 0x5C4L ) goto ERR; - if ( (1L<<(r%13)) & 0x9E4L ) goto ERR; - if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR; - if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR; - if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR; - if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR; - if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR; - - /* Final check - is sqr(sqrt(arg)) == arg ? */ - if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&t,&t)) != MP_OKAY) { - goto ERR; - } - - *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; -ERR:mp_clear(&t); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_is_square.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_jacobi.c b/dep/StormLib/src/libtommath/bn_mp_jacobi.c deleted file mode 100644 index c70b946f316..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_jacobi.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_JACOBI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes the jacobi c = (a | n) (or Legendre if n is prime) - * HAC pp. 73 Algorithm 2.149 - */ -int mp_jacobi (mp_int * a, mp_int * p, int *c) -{ - mp_int a1, p1; - int k, s, r, res; - mp_digit residue; - - /* if p <= 0 return MP_VAL */ - if (mp_cmp_d(p, 0) != MP_GT) { - return MP_VAL; - } - - /* step 1. if a == 0, return 0 */ - if (mp_iszero (a) == 1) { - *c = 0; - return MP_OKAY; - } - - /* step 2. if a == 1, return 1 */ - if (mp_cmp_d (a, 1) == MP_EQ) { - *c = 1; - return MP_OKAY; - } - - /* default */ - s = 0; - - /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&p1)) != MP_OKAY) { - goto LBL_A1; - } - - /* divide out larger power of two */ - k = mp_cnt_lsb(&a1); - if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { - goto LBL_P1; - } - - /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { - s = 1; - } else { - /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = p->dp[0] & 7; - - if (residue == 1 || residue == 7) { - s = 1; - } else if (residue == 3 || residue == 5) { - s = -1; - } - } - - /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { - s = -s; - } - - /* if a1 == 1 we're done */ - if (mp_cmp_d (&a1, 1) == MP_EQ) { - *c = s; - } else { - /* n1 = n mod a1 */ - if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { - goto LBL_P1; - } - if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { - goto LBL_P1; - } - *c = s * r; - } - - /* done */ - res = MP_OKAY; -LBL_P1:mp_clear (&p1); -LBL_A1:mp_clear (&a1); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_jacobi.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_karatsuba_mul.c b/dep/StormLib/src/libtommath/bn_mp_karatsuba_mul.c deleted file mode 100644 index b15ec24966b..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_karatsuba_mul.c +++ /dev/null @@ -1,167 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_KARATSUBA_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = |a| * |b| using Karatsuba Multiplication using - * three half size multiplications - * - * Let B represent the radix [e.g. 2**DIGIT_BIT] and - * let n represent half of the number of digits in - * the min(a,b) - * - * a = a1 * B**n + a0 - * b = b1 * B**n + b0 - * - * Then, a * b => - a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 - * - * Note that a1b1 and a0b0 are used twice and only need to be - * computed once. So in total three half size (half # of - * digit) multiplications are performed, a0b0, a1b1 and - * (a1+b1)(a0+b0) - * - * Note that a multiplication of half the digits requires - * 1/4th the number of single precision multiplications so in - * total after one call 25% of the single precision multiplications - * are saved. Note also that the call to mp_mul can end up back - * in this function if the a0, a1, b0, or b1 are above the threshold. - * This is known as divide-and-conquer and leads to the famous - * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than - * the standard O(N**2) that the baseline/comba methods use. - * Generally though the overhead of this method doesn't pay off - * until a certain size (N ~ 80) is reached. - */ -int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x0, x1, y0, y1, t1, x0y0, x1y1; - int B, err; - - /* default the return code to an error */ - err = MP_MEM; - - /* min # of digits */ - B = MIN (a->used, b->used); - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - if (mp_init_size (&y0, B) != MP_OKAY) - goto X1; - if (mp_init_size (&y1, b->used - B) != MP_OKAY) - goto Y0; - - /* init temps */ - if (mp_init_size (&t1, B * 2) != MP_OKAY) - goto Y1; - if (mp_init_size (&x0y0, B * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x1y1, B * 2) != MP_OKAY) - goto X0Y0; - - /* now shift the digits */ - x0.used = y0.used = B; - x1.used = a->used - B; - y1.used = b->used - B; - - { - register int x; - register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; - - /* we copy the digits directly instead of using higher level functions - * since we also need to shift the digits - */ - tmpa = a->dp; - tmpb = b->dp; - - tmpx = x0.dp; - tmpy = y0.dp; - for (x = 0; x < B; x++) { - *tmpx++ = *tmpa++; - *tmpy++ = *tmpb++; - } - - tmpx = x1.dp; - for (x = B; x < a->used; x++) { - *tmpx++ = *tmpa++; - } - - tmpy = y1.dp; - for (x = B; x < b->used; x++) { - *tmpy++ = *tmpb++; - } - } - - /* only need to clamp the lower words since by definition the - * upper words x1/y1 must have a known number of digits - */ - mp_clamp (&x0); - mp_clamp (&y0); - - /* now calc the products x0y0 and x1y1 */ - /* after this x0 is no longer required, free temp [x0==t2]! */ - if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) - goto X1Y1; /* x0y0 = x0*y0 */ - if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) - goto X1Y1; /* x1y1 = x1*y1 */ - - /* now calc x1+x0 and y1+y0 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x1 - x0 */ - if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) - goto X1Y1; /* t2 = y1 - y0 */ - if (mp_mul (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ - - /* add x0y0 */ - if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) - goto X1Y1; /* t2 = x0y0 + x1y1 */ - if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */ - if (mp_lshd (&x1y1, B * 2) != MP_OKAY) - goto X1Y1; /* x1y1 = x1y1 << 2*B */ - - if (mp_add (&x0y0, &t1, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 */ - if (mp_add (&t1, &x1y1, c) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */ - - /* Algorithm succeeded set the return code to MP_OKAY */ - err = MP_OKAY; - -X1Y1:mp_clear (&x1y1); -X0Y0:mp_clear (&x0y0); -T1:mp_clear (&t1); -Y1:mp_clear (&y1); -Y0:mp_clear (&y0); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_mul.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c b/dep/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c deleted file mode 100644 index b3a45abf70e..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_karatsuba_sqr.c +++ /dev/null @@ -1,121 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_KARATSUBA_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Karatsuba squaring, computes b = a*a using three - * half size squarings - * - * See comments of karatsuba_mul for details. It - * is essentially the same algorithm but merely - * tuned to perform recursive squarings. - */ -int mp_karatsuba_sqr (mp_int * a, mp_int * b) -{ - mp_int x0, x1, t1, t2, x0x0, x1x1; - int B, err; - - err = MP_MEM; - - /* min # of digits */ - B = a->used; - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - - /* init temps */ - if (mp_init_size (&t1, a->used * 2) != MP_OKAY) - goto X1; - if (mp_init_size (&t2, a->used * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x0x0, B * 2) != MP_OKAY) - goto T2; - if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) - goto X0X0; - - { - register int x; - register mp_digit *dst, *src; - - src = a->dp; - - /* now shift the digits */ - dst = x0.dp; - for (x = 0; x < B; x++) { - *dst++ = *src++; - } - - dst = x1.dp; - for (x = B; x < a->used; x++) { - *dst++ = *src++; - } - } - - x0.used = B; - x1.used = a->used - B; - - mp_clamp (&x0); - - /* now calc the products x0*x0 and x1*x1 */ - if (mp_sqr (&x0, &x0x0) != MP_OKAY) - goto X1X1; /* x0x0 = x0*x0 */ - if (mp_sqr (&x1, &x1x1) != MP_OKAY) - goto X1X1; /* x1x1 = x1*x1 */ - - /* now calc (x1+x0)**2 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1X1; /* t1 = x1 - x0 */ - if (mp_sqr (&t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ - - /* add x0y0 */ - if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) - goto X1X1; /* t2 = x0x0 + x1x1 */ - if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */ - if (mp_lshd (&x1x1, B * 2) != MP_OKAY) - goto X1X1; /* x1x1 = x1x1 << 2*B */ - - if (mp_add (&x0x0, &t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 */ - if (mp_add (&t1, &x1x1, b) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 + x1x1 */ - - err = MP_OKAY; - -X1X1:mp_clear (&x1x1); -X0X0:mp_clear (&x0x0); -T2:mp_clear (&t2); -T1:mp_clear (&t1); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_sqr.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_lcm.c b/dep/StormLib/src/libtommath/bn_mp_lcm.c deleted file mode 100644 index af7ae23729e..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_lcm.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_LCM_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes least common multiple as |a*b|/(a, b) */ -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t1, t2; - - - if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { - return res; - } - - /* t1 = get the GCD of the two inputs */ - if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { - goto LBL_T; - } - - /* divide the smallest by the GCD */ - if (mp_cmp_mag(a, b) == MP_LT) { - /* store quotient in t2 such that t2 * b is the LCM */ - if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(b, &t2, c); - } else { - /* store quotient in t2 such that t2 * a is the LCM */ - if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(a, &t2, c); - } - - /* fix the sign to positive */ - c->sign = MP_ZPOS; - -LBL_T: - mp_clear_multi (&t1, &t2, NULL); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_lcm.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_lshd.c b/dep/StormLib/src/libtommath/bn_mp_lshd.c deleted file mode 100644 index ffb0defd06b..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_lshd.c +++ /dev/null @@ -1,67 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_LSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift left a certain amount of digits */ -int mp_lshd (mp_int * a, int b) -{ - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < a->used + b) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - register mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = a->dp + a->used - 1 - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } - - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_lshd.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mod.c b/dep/StormLib/src/libtommath/bn_mp_mod.c deleted file mode 100644 index b24c71f9d95..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mod.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = a mod b, 0 <= c < b */ -int -mp_mod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int t; - int res; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - if (t.sign != b->sign) { - res = mp_add (b, &t, c); - } else { - res = MP_OKAY; - mp_exch (&t, c); - } - - mp_clear (&t); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mod.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mod_2d.c b/dep/StormLib/src/libtommath/bn_mp_mod_2d.c deleted file mode 100644 index a54a0242644..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mod_2d.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MOD_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* calc a value mod 2**b */ -int -mp_mod_2d (mp_int * a, int b, mp_int * c) -{ - int x, res; - - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } - - /* if the modulus is larger than the value than return */ - if (b >= (int) (a->used * DIGIT_BIT)) { - res = mp_copy (a, c); - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= - (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mod_2d.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mod_d.c b/dep/StormLib/src/libtommath/bn_mp_mod_d.c deleted file mode 100644 index 59886e7734a..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mod_d.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MOD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -int -mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) -{ - return mp_div_d(a, b, NULL, c); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mod_d.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c b/dep/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c deleted file mode 100644 index fdefcbd99d2..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_montgomery_calc_normalization.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* - * shifts with subtractions when the result is greater than b. - * - * The method is slightly modified to shift B unconditionally upto just under - * the leading bit of b. This saves alot of multiple precision shifting. - */ -int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) -{ - int x, bits, res; - - /* how many bits of last digit does b use */ - bits = mp_count_bits (b) % DIGIT_BIT; - - if (b->used > 1) { - if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { - return res; - } - } else { - mp_set(a, 1); - bits = 1; - } - - - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - if ((res = mp_mul_2 (a, a)) != MP_OKAY) { - return res; - } - if (mp_cmp_mag (a, b) != MP_LT) { - if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { - return res; - } - } - } - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_calc_normalization.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_montgomery_reduce.c b/dep/StormLib/src/libtommath/bn_mp_montgomery_reduce.c deleted file mode 100644 index 173848e0ac8..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_montgomery_reduce.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction */ -int -mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, digs; - mp_digit mu; - - /* can the fast reduction [comba] method be used? - * - * Note that unlike in mul you're safely allowed *less* - * than the available columns [255 per default] since carries - * are fixed up in the inner loop. - */ - digs = n->used * 2 + 1; - if ((digs < MP_WARRAY) && - n->used < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_mp_montgomery_reduce (x, n, rho); - } - - /* grow the input as required */ - if (x->alloc < digs) { - if ((res = mp_grow (x, digs)) != MP_OKAY) { - return res; - } - } - x->used = digs; - - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * rho mod b - * - * The value of rho must be precalculated via - * montgomery_setup() such that - * it equals -1/n0 mod b this allows the - * following inner loop to reduce the - * input one digit at a time - */ - mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); - - /* a = a + mu * m * b**i */ - { - register int iy; - register mp_digit *tmpn, *tmpx, u; - register mp_word r; - - /* alias for digits of the modulus */ - tmpn = n->dp; - - /* alias for the digits of x [the input] */ - tmpx = x->dp + ix; - - /* set the carry to zero */ - u = 0; - - /* Multiply and add in place */ - for (iy = 0; iy < n->used; iy++) { - /* compute product and sum */ - r = ((mp_word)mu) * ((mp_word)*tmpn++) + - ((mp_word) u) + ((mp_word) * tmpx); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); - } - /* At this point the ix'th digit of x should be zero */ - - - /* propagate carries upwards as required*/ - while (u) { - *tmpx += u; - u = *tmpx >> DIGIT_BIT; - *tmpx++ &= MP_MASK; - } - } - } - - /* at this point the n.used'th least - * significant digits of x are all zero - * which means we can shift x to the - * right by n.used digits and the - * residue is unchanged. - */ - - /* x = x/b**n.used */ - mp_clamp(x); - mp_rshd (x, n->used); - - /* if x >= n then x = x - n */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_reduce.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_montgomery_setup.c b/dep/StormLib/src/libtommath/bn_mp_montgomery_setup.c deleted file mode 100644 index 6f277320eb7..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_montgomery_setup.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MONTGOMERY_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* setups the montgomery reduction stuff */ -int -mp_montgomery_setup (mp_int * n, mp_digit * rho) -{ - mp_digit x, b; - -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = n->dp[0]; - - if ((b & 1) == 0) { - return MP_VAL; - } - - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - b * x; /* here x*a==1 mod 2**8 */ -#if !defined(MP_8BIT) - x *= 2 - b * x; /* here x*a==1 mod 2**16 */ -#endif -#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) - x *= 2 - b * x; /* here x*a==1 mod 2**32 */ -#endif -#ifdef MP_64BIT - x *= 2 - b * x; /* here x*a==1 mod 2**64 */ -#endif - - /* rho = -1/m mod b */ - *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_setup.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mul.c b/dep/StormLib/src/libtommath/bn_mp_mul.c deleted file mode 100644 index a1315dac30c..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mul.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level multiplication (handles sign) */ -int mp_mul (mp_int * a, mp_int * b, mp_int * c) -{ - int res, neg; - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - - /* use Toom-Cook? */ -#ifdef BN_MP_TOOM_MUL_C - if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { - res = mp_toom_mul(a, b, c); - } else -#endif -#ifdef BN_MP_KARATSUBA_MUL_C - /* use Karatsuba? */ - if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { - res = mp_karatsuba_mul (a, b, c); - } else -#endif - { - /* can we use the fast multiplier? - * - * The fast multiplier can be used if the output will - * have less than MP_WARRAY digits and the number of - * digits won't affect carry propagation - */ - int digs = a->used + b->used + 1; - -#ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < MP_WARRAY) && - MIN(a->used, b->used) <= - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - res = fast_s_mp_mul_digs (a, b, c, digs); - } else -#endif -#ifdef BN_S_MP_MUL_DIGS_C - res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ -#else - res = MP_VAL; -#endif - - } - c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mul.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mul_2.c b/dep/StormLib/src/libtommath/bn_mp_mul_2.c deleted file mode 100644 index 3315744f1ec..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mul_2.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MUL_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = a*2 */ -int mp_mul_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* grow to accomodate result */ - if (b->alloc < a->used + 1) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mul_2d.c b/dep/StormLib/src/libtommath/bn_mp_mul_2d.c deleted file mode 100644 index c636c179884..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mul_2d.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MUL_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift left by a certain bit count */ -int mp_mul_2d (mp_int * a, int b, mp_int * c) -{ - mp_digit d; - int res; - - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } - - if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { - if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } - - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - register mp_digit *tmpc, shift, mask, r, rr; - register int x; - - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; - - /* shift for msbs */ - shift = DIGIT_BIT - d; - - /* alias */ - tmpc = c->dp; - - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; - - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; - - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2d.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mul_d.c b/dep/StormLib/src/libtommath/bn_mp_mul_d.c deleted file mode 100644 index a36a76bbacf..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mul_d.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MUL_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiply by a digit */ -int -mp_mul_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; - - /* make sure c is big enough to hold a*b */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* get the original destinations used count */ - olduse = c->used; - - /* set the sign */ - c->sign = a->sign; - - /* alias for a->dp [source] */ - tmpa = a->dp; - - /* alias for c->dp [dest] */ - tmpc = c->dp; - - /* zero carry */ - u = 0; - - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); - - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - - /* store final carry [if any] and increment ix offset */ - *tmpc++ = u; - ++ix; - - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } - - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mul_d.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_mulmod.c b/dep/StormLib/src/libtommath/bn_mp_mulmod.c deleted file mode 100644 index 8ec98bbddb2..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_mulmod.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_MULMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a * b (mod c) */ -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_mulmod.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_n_root.c b/dep/StormLib/src/libtommath/bn_mp_n_root.c deleted file mode 100644 index f188f5255b3..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_n_root.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_N_ROOT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* find the n'th root of an integer - * - * Result found such that (c)**b <= a and (c+1)**b > a - * - * This algorithm uses Newton's approximation - * x[i+1] = x[i] - f(x[i])/f'(x[i]) - * which will find the root in log(N) time where - * each step involves a fair bit. This is not meant to - * find huge roots [square and cube, etc]. - */ -int mp_n_root (mp_int * a, mp_digit b, mp_int * c) -{ - mp_int t1, t2, t3; - int res, neg; - - /* input must be positive if b is even */ - if ((b & 1) == 0 && a->sign == MP_NEG) { - return MP_VAL; - } - - if ((res = mp_init (&t1)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init (&t3)) != MP_OKAY) { - goto LBL_T2; - } - - /* if a is negative fudge the sign but keep track */ - neg = a->sign; - a->sign = MP_ZPOS; - - /* t2 = 2 */ - mp_set (&t2, 2); - - do { - /* t1 = t2 */ - if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ - - /* t3 = t1**(b-1) */ - if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* numerator */ - /* t2 = t1**b */ - if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1**b - a */ - if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* denominator */ - /* t3 = t1**(b-1) * b */ - if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* t3 = (t1**b - a)/(b * t1**(b-1)) */ - if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { - goto LBL_T3; - } - - if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { - goto LBL_T3; - } - } while (mp_cmp (&t1, &t2) != MP_EQ); - - /* result can be off by a few so check */ - for (;;) { - if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - if (mp_cmp (&t2, a) == MP_GT) { - if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { - goto LBL_T3; - } - } else { - break; - } - } - - /* reset the sign of a first */ - a->sign = neg; - - /* set the result */ - mp_exch (&t1, c); - - /* set the sign of the result */ - c->sign = neg; - - res = MP_OKAY; - -LBL_T3:mp_clear (&t3); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_n_root.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_neg.c b/dep/StormLib/src/libtommath/bn_mp_neg.c deleted file mode 100644 index 87a8b500449..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_neg.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_NEG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = -a */ -int mp_neg (mp_int * a, mp_int * b) -{ - int res; - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - if (mp_iszero(b) != MP_YES) { - b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; - } else { - b->sign = MP_ZPOS; - } - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_neg.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_or.c b/dep/StormLib/src/libtommath/bn_mp_or.c deleted file mode 100644 index 12601eaf78e..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_or.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_OR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* OR two ints together */ -int mp_or (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] |= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_or.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_fermat.c b/dep/StormLib/src/libtommath/bn_mp_prime_fermat.c deleted file mode 100644 index 297e13c7960..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_prime_fermat.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_PRIME_FERMAT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* performs one Fermat test. - * - * If "a" were prime then b**a == b (mod a) since the order of - * the multiplicative sub-group would be phi(a) = a-1. That means - * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). - * - * Sets result to 1 if the congruence holds, or zero otherwise. - */ -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) -{ - mp_int t; - int err; - - /* default to composite */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* init t */ - if ((err = mp_init (&t)) != MP_OKAY) { - return err; - } - - /* compute t = b**a mod a */ - if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { - goto LBL_T; - } - - /* is it equal to b? */ - if (mp_cmp (&t, b) == MP_EQ) { - *result = MP_YES; - } - - err = MP_OKAY; -LBL_T:mp_clear (&t); - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_fermat.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_is_divisible.c b/dep/StormLib/src/libtommath/bn_mp_prime_is_divisible.c deleted file mode 100644 index 0ae64983512..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_prime_is_divisible.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_PRIME_IS_DIVISIBLE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if an integers is divisible by one - * of the first PRIME_SIZE primes or not - * - * sets result to 0 if not, 1 if yes - */ -int mp_prime_is_divisible (mp_int * a, int *result) -{ - int err, ix; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < PRIME_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_divisible.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_is_prime.c b/dep/StormLib/src/libtommath/bn_mp_prime_is_prime.c deleted file mode 100644 index 0e1e94bad5b..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_prime_is_prime.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_PRIME_IS_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* performs a variable number of rounds of Miller-Rabin - * - * Probability of error after t rounds is no more than - - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime (mp_int * a, int t, int *result) -{ - mp_int b; - int ix, err, res; - - /* default to no */ - *result = MP_NO; - - /* valid value of t? */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIME_SIZE; ix++) { - if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { - *result = 1; - return MP_OKAY; - } - } - - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } - - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } - - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } - - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, ltm_prime_tab[ix]); - - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto LBL_B; - } - - if (res == MP_NO) { - goto LBL_B; - } - } - - /* passed the test */ - *result = MP_YES; -LBL_B:mp_clear (&b); - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_prime.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c b/dep/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c deleted file mode 100644 index 47385bc815c..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_prime_miller_rabin.c +++ /dev/null @@ -1,103 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_PRIME_MILLER_RABIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Miller-Rabin test of "a" to the base of "b" as described in - * HAC pp. 139 Algorithm 4.24 - * - * Sets result to 0 if definitely composite or 1 if probably prime. - * Randomly the chance of error is no more than 1/4 and often - * very much lower. - */ -int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) -{ - mp_int n1, y, r; - int s, j, err; - - /* default */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* get n1 = a - 1 */ - if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { - return err; - } - if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* set 2**s * r = n1 */ - if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* count the number of least significant bits - * which are zero - */ - s = mp_cnt_lsb(&r); - - /* now divide n - 1 by 2**s */ - if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { - goto LBL_R; - } - - /* compute y = b**r mod a */ - if ((err = mp_init (&y)) != MP_OKAY) { - goto LBL_R; - } - if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y != 1 and y != n1 do */ - if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { - if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y == 1 then composite */ - if (mp_cmp_d (&y, 1) == MP_EQ) { - goto LBL_Y; - } - - ++j; - } - - /* if y != n1 then composite */ - if (mp_cmp (&y, &n1) != MP_EQ) { - goto LBL_Y; - } - } - - /* probably prime now */ - *result = MP_YES; -LBL_Y:mp_clear (&y); -LBL_R:mp_clear (&r); -LBL_N1:mp_clear (&n1); - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_miller_rabin.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_next_prime.c b/dep/StormLib/src/libtommath/bn_mp_prime_next_prime.c deleted file mode 100644 index 833992bac48..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_prime_next_prime.c +++ /dev/null @@ -1,170 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_PRIME_NEXT_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* finds the next prime after the number "a" using "t" trials - * of Miller-Rabin. - * - * bbs_style = 1 means the prime must be congruent to 3 mod 4 - */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style) -{ - int err, res, x, y; - mp_digit res_tab[PRIME_SIZE], step, kstep; - mp_int b; - - /* ensure t is valid */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* force positive */ - a->sign = MP_ZPOS; - - /* simple algo if a is less than the largest prime in the table */ - if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { - /* find which prime it is bigger than */ - for (x = PRIME_SIZE - 2; x >= 0; x--) { - if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { - if (bbs_style == 1) { - /* ok we found a prime smaller or - * equal [so the next is larger] - * - * however, the prime must be - * congruent to 3 mod 4 - */ - if ((ltm_prime_tab[x + 1] & 3) != 3) { - /* scan upwards for a prime congruent to 3 mod 4 */ - for (y = x + 1; y < PRIME_SIZE; y++) { - if ((ltm_prime_tab[y] & 3) == 3) { - mp_set(a, ltm_prime_tab[y]); - return MP_OKAY; - } - } - } - } else { - mp_set(a, ltm_prime_tab[x + 1]); - return MP_OKAY; - } - } - } - /* at this point a maybe 1 */ - if (mp_cmp_d(a, 1) == MP_EQ) { - mp_set(a, 2); - return MP_OKAY; - } - /* fall through to the sieve */ - } - - /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ - if (bbs_style == 1) { - kstep = 4; - } else { - kstep = 2; - } - - /* at this point we will use a combination of a sieve and Miller-Rabin */ - - if (bbs_style == 1) { - /* if a mod 4 != 3 subtract the correct value to make it so */ - if ((a->dp[0] & 3) != 3) { - if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; - } - } else { - if (mp_iseven(a) == 1) { - /* force odd */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { - return err; - } - } - } - - /* generate the restable */ - for (x = 1; x < PRIME_SIZE; x++) { - if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { - return err; - } - } - - /* init temp used for Miller-Rabin Testing */ - if ((err = mp_init(&b)) != MP_OKAY) { - return err; - } - - for (;;) { - /* skip to the next non-trivially divisible candidate */ - step = 0; - do { - /* y == 1 if any residue was zero [e.g. cannot be prime] */ - y = 0; - - /* increase step to next candidate */ - step += kstep; - - /* compute the new residue without using division */ - for (x = 1; x < PRIME_SIZE; x++) { - /* add the step to each residue */ - res_tab[x] += kstep; - - /* subtract the modulus [instead of using division] */ - if (res_tab[x] >= ltm_prime_tab[x]) { - res_tab[x] -= ltm_prime_tab[x]; - } - - /* set flag if zero */ - if (res_tab[x] == 0) { - y = 1; - } - } - } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep)); - - /* add the step */ - if ((err = mp_add_d(a, step, a)) != MP_OKAY) { - goto LBL_ERR; - } - - /* if didn't pass sieve and step == MAX then skip test */ - if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) { - continue; - } - - /* is this prime? */ - for (x = 0; x < t; x++) { - mp_set(&b, ltm_prime_tab[t]); - if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { - goto LBL_ERR; - } - if (res == MP_NO) { - break; - } - } - - if (res == MP_YES) { - break; - } - } - - err = MP_OKAY; -LBL_ERR: - mp_clear(&b); - return err; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_next_prime.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c b/dep/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c deleted file mode 100644 index 3f7608aa7f3..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_prime_rabin_miller_trials.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - - -static const struct { - int k, t; -} sizes[] = { -{ 128, 28 }, -{ 256, 16 }, -{ 384, 10 }, -{ 512, 7 }, -{ 640, 6 }, -{ 768, 5 }, -{ 896, 4 }, -{ 1024, 4 } -}; - -/* returns # of RM trials required for a given bit size */ -int mp_prime_rabin_miller_trials(int size) -{ - int x; - - for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { - if (sizes[x].k == size) { - return sizes[x].t; - } else if (sizes[x].k > size) { - return (x == 0) ? sizes[0].t : sizes[x - 1].t; - } - } - return sizes[x-1].t + 1; -} - - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_rabin_miller_trials.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_prime_random_ex.c b/dep/StormLib/src/libtommath/bn_mp_prime_random_ex.c deleted file mode 100644 index 4eec3f69e3e..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_prime_random_ex.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_PRIME_RANDOM_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* makes a truly random prime of a given size (bits), - * - * Flags are as follows: - * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - */ - -/* This is possibly the mother of all prime generation functions, muahahahahaha! */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) -{ - unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; - int res, err, bsize, maskOR_msb_offset; - - /* sanity check the input */ - if (size <= 1 || t <= 0) { - return MP_VAL; - } - - /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ - if (flags & LTM_PRIME_SAFE) { - flags |= LTM_PRIME_BBS; - } - - /* calc the byte size */ - bsize = (size>>3) + ((size&7)?1:0); - - /* we need a buffer of bsize bytes */ - tmp = OPT_CAST(unsigned char) XMALLOC(bsize); - if (tmp == NULL) { - return MP_MEM; - } - - /* calc the maskAND value for the MSbyte*/ - maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); - - /* calc the maskOR_msb */ - maskOR_msb = 0; - maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; - if (flags & LTM_PRIME_2MSB_ON) { - maskOR_msb |= 0x80 >> ((9 - size) & 7); - } - - /* get the maskOR_lsb */ - maskOR_lsb = 1; - if (flags & LTM_PRIME_BBS) { - maskOR_lsb |= 3; - } - - do { - /* read the bytes */ - if (cb(tmp, bsize, dat) != bsize) { - err = MP_VAL; - goto error; - } - - /* work over the MSbyte */ - tmp[0] &= maskAND; - tmp[0] |= 1 << ((size - 1) & 7); - - /* mix in the maskORs */ - tmp[maskOR_msb_offset] |= maskOR_msb; - tmp[bsize-1] |= maskOR_lsb; - - /* read it in */ - if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - if (res == MP_NO) { - continue; - } - - if (flags & LTM_PRIME_SAFE) { - /* see if (a-1)/2 is prime */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } - if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - } - } while (res == MP_NO); - - if (flags & LTM_PRIME_SAFE) { - /* restore a to the original value */ - if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } - if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } - } - - err = MP_OKAY; -error: - XFREE(tmp); - return err; -} - - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_random_ex.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_radix_size.c b/dep/StormLib/src/libtommath/bn_mp_radix_size.c deleted file mode 100644 index 2378f1fc1ac..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_radix_size.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_RADIX_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* returns size of ASCII reprensentation */ -int mp_radix_size (mp_int * a, int radix, int *size) -{ - int res, digs; - mp_int t; - mp_digit d; - - *size = 0; - - /* special case for binary */ - if (radix == 2) { - *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; - return MP_OKAY; - } - - /* make sure the radix is in range */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - if (mp_iszero(a) == MP_YES) { - *size = 2; - return MP_OKAY; - } - - /* digs is the digit count */ - digs = 0; - - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; - } - - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* force temp to positive */ - t.sign = MP_ZPOS; - - /* fetch out all of the digits */ - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - ++digs; - } - mp_clear (&t); - - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_radix_size.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_radix_smap.c b/dep/StormLib/src/libtommath/bn_mp_radix_smap.c deleted file mode 100644 index 5cbe9520b5b..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_radix_smap.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_RADIX_SMAP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_radix_smap.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_rand.c b/dep/StormLib/src/libtommath/bn_mp_rand.c deleted file mode 100644 index e1241785e88..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_rand.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_RAND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* makes a pseudo-random int of a given size */ -int -mp_rand (mp_int * a, int digits) -{ - int res; - mp_digit d; - - mp_zero (a); - if (digits <= 0) { - return MP_OKAY; - } - - /* first place a random non-zero digit */ - do { - d = ((mp_digit) abs (rand ())) & MP_MASK; - } while (d == 0); - - if ((res = mp_add_d (a, d, a)) != MP_OKAY) { - return res; - } - - while (--digits > 0) { - if ((res = mp_lshd (a, 1)) != MP_OKAY) { - return res; - } - - if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { - return res; - } - } - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_rand.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_read_radix.c b/dep/StormLib/src/libtommath/bn_mp_read_radix.c deleted file mode 100644 index 6869668fb88..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_read_radix.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_READ_RADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, const char *str, int radix) -{ - int y, res, neg; - char ch; - - /* zero the digit bignum */ - mp_zero(a); - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? toupper (*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != 1) { - a->sign = neg; - } - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_read_radix.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_read_signed_bin.c b/dep/StormLib/src/libtommath/bn_mp_read_signed_bin.c deleted file mode 100644 index e9a780c28aa..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_read_signed_bin.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_READ_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read signed bin, big endian, first byte is 0==positive or 1==negative */ -int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* read magnitude */ - if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { - return res; - } - - /* first byte is 0 for positive, non-zero for negative */ - if (b[0] == 0) { - a->sign = MP_ZPOS; - } else { - a->sign = MP_NEG; - } - - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_read_signed_bin.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c b/dep/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c deleted file mode 100644 index 7d35370418c..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_read_unsigned_bin.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_READ_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* make sure there are at least two digits */ - if (a->alloc < 2) { - if ((res = mp_grow(a, 2)) != MP_OKAY) { - return res; - } - } - - /* zero the int */ - mp_zero (a); - - /* read the bytes in */ - while (c-- > 0) { - if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { - return res; - } - -#ifndef MP_8BIT - a->dp[0] |= *b++; - a->used += 1; -#else - a->dp[0] = (*b & MP_MASK); - a->dp[1] |= ((*b++ >> 7U) & 1); - a->used += 2; -#endif - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_read_unsigned_bin.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce.c b/dep/StormLib/src/libtommath/bn_mp_reduce.c deleted file mode 100644 index 3a6bb5aca90..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces x mod m, assumes 0 < x < m**2, mu is - * precomputed via mp_reduce_setup. - * From HAC pp.604 Algorithm 14.42 - */ -int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) -{ - mp_int q; - int res, um = m->used; - - /* q = x */ - if ((res = mp_init_copy (&q, x)) != MP_OKAY) { - return res; - } - - /* q1 = x / b**(k-1) */ - mp_rshd (&q, um - 1); - - /* according to HAC this optimization is ok */ - if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { - if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { - goto CLEANUP; - } - } else { -#ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#else - { - res = MP_VAL; - goto CLEANUP; - } -#endif - } - - /* q3 = q2 / b**(k+1) */ - mp_rshd (&q, um + 1); - - /* x = x mod b**(k+1), quick (no division) */ - if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { - goto CLEANUP; - } - - /* q = q * m mod b**(k+1), quick (no division) */ - if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { - goto CLEANUP; - } - - /* x = x - q */ - if ((res = mp_sub (x, &q, x)) != MP_OKAY) { - goto CLEANUP; - } - - /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d (x, 0) == MP_LT) { - mp_set (&q, 1); - if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if ((res = mp_add (x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while (mp_cmp (x, m) != MP_LT) { - if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { - goto CLEANUP; - } - } - -CLEANUP: - mp_clear (&q); - - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k.c deleted file mode 100644 index 3191d829179..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (d != 1) { - /* q = q * d */ - if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_l.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k_l.c deleted file mode 100644 index 49b7e344ed9..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_l.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d - This differs from reduce_2k since "d" can be larger - than a single digit. -*/ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - /* q = q * d */ - if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_l.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c deleted file mode 100644 index aa3b3bad8db..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_2K_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c b/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c deleted file mode 100644 index 4eca87040bc..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce_2k_setup_l.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_2K_SETUP_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) -{ - int res; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { - goto ERR; - } - - if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear(&tmp); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup_l.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k.c b/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k.c deleted file mode 100644 index b9ede978964..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_IS_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if mp_reduce_2k can be used */ -int mp_reduce_is_2k(mp_int *a) -{ - int ix, iy, iw; - mp_digit iz; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - iy = mp_count_bits(a); - iz = 1; - iw = 1; - - /* Test every bit from the second digit up, must be 1 */ - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { - return MP_NO; - } - iz <<= 1; - if (iz > (mp_digit)MP_MASK) { - ++iw; - iz = 1; - } - } - } - return MP_YES; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c b/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c deleted file mode 100644 index 787875f8bbb..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce_is_2k_l.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_IS_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if reduce_2k_l can be used */ -int mp_reduce_is_2k_l(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - /* if more than half of the digits are -1 we're sold */ - for (iy = ix = 0; ix < a->used; ix++) { - if (a->dp[ix] == MP_MASK) { - ++iy; - } - } - return (iy >= (a->used/2)) ? MP_YES : MP_NO; - - } - return MP_NO; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k_l.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_reduce_setup.c b/dep/StormLib/src/libtommath/bn_mp_reduce_setup.c deleted file mode 100644 index 00e0a62b9bd..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_reduce_setup.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_REDUCE_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -int mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_setup.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_rshd.c b/dep/StormLib/src/libtommath/bn_mp_rshd.c deleted file mode 100644 index eac6721baf0..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_rshd.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_RSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift right a certain amount of digits */ -void mp_rshd (mp_int * a, int b) -{ - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return; - } - - { - register mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } - - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_rshd.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_set.c b/dep/StormLib/src/libtommath/bn_mp_set.c deleted file mode 100644 index d76d5bbd324..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_set.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set to a digit */ -void mp_set (mp_int * a, mp_digit b) -{ - mp_zero (a); - a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_set.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_set_int.c b/dep/StormLib/src/libtommath/bn_mp_set_int.c deleted file mode 100644 index 68cf0e32b27..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_set_int.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set a 32-bit const */ -int mp_set_int (mp_int * a, unsigned long b) -{ - int x, res; - - mp_zero (a); - - /* set four bits at a time */ - for (x = 0; x < 8; x++) { - /* shift the number up four bits */ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { - return res; - } - - /* OR in the top four bits of the source */ - a->dp[0] |= (b >> 28) & 15; - - /* shift the source up to the next four bits */ - b <<= 4; - - /* ensure that digits are not clamped off */ - a->used += 1; - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_set_int.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_shrink.c b/dep/StormLib/src/libtommath/bn_mp_shrink.c deleted file mode 100644 index 54920d1400a..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_shrink.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SHRINK_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shrink a bignum */ -int mp_shrink (mp_int * a) -{ - mp_digit *tmp; - if (a->alloc != a->used && a->used > 0) { - if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) { - return MP_MEM; - } - a->dp = tmp; - a->alloc = a->used; - } - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_shrink.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_signed_bin_size.c b/dep/StormLib/src/libtommath/bn_mp_signed_bin_size.c deleted file mode 100644 index b9492a5e5ed..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_signed_bin_size.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the size for an signed equivalent */ -int mp_signed_bin_size (mp_int * a) -{ - return 1 + mp_unsigned_bin_size (a); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_signed_bin_size.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_sqr.c b/dep/StormLib/src/libtommath/bn_mp_sqr.c deleted file mode 100644 index c10fa6f3b6e..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_sqr.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes b = a*a */ -int -mp_sqr (mp_int * a, mp_int * b) -{ - int res; - -#ifdef BN_MP_TOOM_SQR_C - /* use Toom-Cook? */ - if (a->used >= TOOM_SQR_CUTOFF) { - res = mp_toom_sqr(a, b); - /* Karatsuba? */ - } else -#endif -#ifdef BN_MP_KARATSUBA_SQR_C -if (a->used >= KARATSUBA_SQR_CUTOFF) { - res = mp_karatsuba_sqr (a, b); - } else -#endif - { -#ifdef BN_FAST_S_MP_SQR_C - /* can we use the fast comba multiplier? */ - if ((a->used * 2 + 1) < MP_WARRAY && - a->used < - (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { - res = fast_s_mp_sqr (a, b); - } else -#endif -#ifdef BN_S_MP_SQR_C - res = s_mp_sqr (a, b); -#else - res = MP_VAL; -#endif - } - b->sign = MP_ZPOS; - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_sqr.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_sqrmod.c b/dep/StormLib/src/libtommath/bn_mp_sqrmod.c deleted file mode 100644 index 5f4b2f3d663..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_sqrmod.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SQRMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = a * a (mod b) */ -int -mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sqr (a, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, b, c); - mp_clear (&t); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_sqrmod.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_sqrt.c b/dep/StormLib/src/libtommath/bn_mp_sqrt.c deleted file mode 100644 index e15ba98ca88..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_sqrt.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SQRT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* this function is less generic than mp_n_root, simpler and faster */ -int mp_sqrt(mp_int *arg, mp_int *ret) -{ - int res; - mp_int t1,t2; - - /* must be positive */ - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* easy out */ - if (mp_iszero(arg) == MP_YES) { - mp_zero(ret); - return MP_OKAY; - } - - if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { - return res; - } - - if ((res = mp_init(&t2)) != MP_OKAY) { - goto E2; - } - - /* First approx. (not very bad for large arg) */ - mp_rshd (&t1,t1.used/2); - - /* t1 > 0 */ - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* And now t1 > sqrt(arg) */ - do { - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* t1 >= sqrt(arg) >= t2 at this point */ - } while (mp_cmp_mag(&t1,&t2) == MP_GT); - - mp_exch(&t1,ret); - -E1: mp_clear(&t2); -E2: mp_clear(&t1); - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_sub.c b/dep/StormLib/src/libtommath/bn_mp_sub.c deleted file mode 100644 index 6e72138610f..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_sub.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level subtraction (handles signs) */ -int -mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (mp_cmp_mag (a, b) != MP_LT) { - /* Copy the sign from the first */ - c->sign = sa; - /* The first has a larger or equal magnitude */ - res = s_mp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; - /* The second has a larger magnitude */ - res = s_mp_sub (b, a, c); - } - } - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_sub.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_sub_d.c b/dep/StormLib/src/libtommath/bn_mp_sub_d.c deleted file mode 100644 index aa08e31b30b..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_sub_d.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SUB_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* single digit subtraction */ -int -mp_sub_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; - - /* if a <= b simply fix the single digit */ - if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; - - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; - - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - } - } - - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_submod.c b/dep/StormLib/src/libtommath/bn_mp_submod.c deleted file mode 100644 index 6617ff42ceb..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_submod.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_SUBMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a - b (mod c) */ -int -mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sub (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_submod.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin.c b/dep/StormLib/src/libtommath/bn_mp_to_signed_bin.c deleted file mode 100644 index 154f64b5667..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TO_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin (mp_int * a, unsigned char *b) -{ - int res; - - if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { - return res; - } - b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c b/dep/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c deleted file mode 100644 index e119c380a91..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_to_signed_bin_n.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TO_SIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_signed_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_signed_bin_size(a); - return mp_to_signed_bin(a, b); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin_n.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c b/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c deleted file mode 100644 index ce69e5bf364..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TO_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin (mp_int * a, unsigned char *b) -{ - int x, res; - mp_int t; - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - x = 0; - while (mp_iszero (&t) == 0) { -#ifndef MP_8BIT - b[x++] = (unsigned char) (t.dp[0] & 255); -#else - b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); -#endif - if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - bn_reverse (b, x); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c b/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c deleted file mode 100644 index dfa27c41bab..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_to_unsigned_bin_n.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TO_UNSIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_unsigned_bin_size(a); - return mp_to_unsigned_bin(a, b); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin_n.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_toom_mul.c b/dep/StormLib/src/libtommath/bn_mp_toom_mul.c deleted file mode 100644 index e48c6b355c0..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_toom_mul.c +++ /dev/null @@ -1,284 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TOOM_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplication using the Toom-Cook 3-way algorithm - * - * Much more complicated than Karatsuba but has a lower - * asymptotic running time of O(N**1.464). This algorithm is - * only particularly useful on VERY large inputs - * (we're talking 1000s of digits here...). -*/ -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_toom_mul.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_toom_sqr.c b/dep/StormLib/src/libtommath/bn_mp_toom_sqr.c deleted file mode 100644 index fd8bc672a1a..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_toom_sqr.c +++ /dev/null @@ -1,226 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TOOM_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* squaring using Toom-Cook 3-way algorithm */ -int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_toom_sqr.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_toradix.c b/dep/StormLib/src/libtommath/bn_mp_toradix.c deleted file mode 100644 index 539abe9ba6d..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_toradix.c +++ /dev/null @@ -1,75 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TORADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) */ -int mp_toradix (mp_int * a, char *str, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the radix */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == 1) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - ++_s; - *str++ = '-'; - t.sign = MP_ZPOS; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number] - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_toradix.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_toradix_n.c b/dep/StormLib/src/libtommath/bn_mp_toradix_n.c deleted file mode 100644 index 0322f8d4b2a..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_toradix_n.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_TORADIX_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) - * - * Stores upto maxlen-1 chars and always a NULL byte - */ -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the maxlen, radix */ - if (maxlen < 2 || radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - /* we have to reverse our digits later... but not the - sign!! */ - ++_s; - - /* store the flag and mark the number as positive */ - *str++ = '-'; - t.sign = MP_ZPOS; - - /* subtract a char */ - --maxlen; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if (--maxlen < 1) { - /* no more room */ - break; - } - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_toradix_n.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c b/dep/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c deleted file mode 100644 index 88f3e92dde8..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_unsigned_bin_size.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_UNSIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) -{ - int size = mp_count_bits (a); - return (size / 8 + ((size & 7) != 0 ? 1 : 0)); -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_unsigned_bin_size.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_xor.c b/dep/StormLib/src/libtommath/bn_mp_xor.c deleted file mode 100644 index bf0446ecfe8..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_xor.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_XOR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* XOR two ints together */ -int -mp_xor (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] ^= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_xor.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_mp_zero.c b/dep/StormLib/src/libtommath/bn_mp_zero.c deleted file mode 100644 index f21db5ed589..00000000000 --- a/dep/StormLib/src/libtommath/bn_mp_zero.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "tommath.h" -#ifdef BN_MP_ZERO_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set to zero */ -void mp_zero (mp_int * a) -{ - int n; - mp_digit *tmp; - - a->sign = MP_ZPOS; - a->used = 0; - - tmp = a->dp; - for (n = 0; n < a->alloc; n++) { - *tmp++ = 0; - } -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_zero.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_prime_tab.c b/dep/StormLib/src/libtommath/bn_prime_tab.c deleted file mode 100644 index 7d306dd56a6..00000000000 --- a/dep/StormLib/src/libtommath/bn_prime_tab.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "tommath.h" -#ifdef BN_PRIME_TAB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -const mp_digit ltm_prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, -#ifndef MP_8BIT - 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 -#endif -}; -#endif - -/* $Source: /cvs/libtom/libtommath/bn_prime_tab.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_reverse.c b/dep/StormLib/src/libtommath/bn_reverse.c deleted file mode 100644 index d4a919af486..00000000000 --- a/dep/StormLib/src/libtommath/bn_reverse.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "tommath.h" -#ifdef BN_REVERSE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reverse an array, used for radix code */ -void -bn_reverse (unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_reverse.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_s_mp_add.c b/dep/StormLib/src/libtommath/bn_s_mp_add.c deleted file mode 100644 index 5ea9c6d205c..00000000000 --- a/dep/StormLib/src/libtommath/bn_s_mp_add.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "tommath.h" -#ifdef BN_S_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level addition, based on HAC pp.594, Algorithm 14.7 */ -int -s_mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int *x; - int olduse, res, min, max; - - /* find sizes, we let |a| <= |b| which means we have to sort - * them. "x" will point to the input with the most digits - */ - if (a->used > b->used) { - min = b->used; - max = a->used; - x = a; - } else { - min = a->used; - max = b->used; - x = b; - } - - /* init result */ - if (c->alloc < max + 1) { - if ((res = mp_grow (c, max + 1)) != MP_OKAY) { - return res; - } - } - - /* get old used digit count and set new one */ - olduse = c->used; - c->used = max + 1; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - - /* first input */ - tmpa = a->dp; - - /* second input */ - tmpb = b->dp; - - /* destination */ - tmpc = c->dp; - - /* zero the carry */ - u = 0; - for (i = 0; i < min; i++) { - /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ - *tmpc = *tmpa++ + *tmpb++ + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, that is in A+B - * if A or B has more digits add those in - */ - if (min != max) { - for (; i < max; i++) { - /* T[i] = X[i] + U */ - *tmpc = x->dp[i] + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - } - - /* add carry */ - *tmpc++ = u; - - /* clear digits above oldused */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_s_mp_add.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_s_mp_exptmod.c b/dep/StormLib/src/libtommath/bn_s_mp_exptmod.c deleted file mode 100644 index 9fb2da8fd21..00000000000 --- a/dep/StormLib/src/libtommath/bn_s_mp_exptmod.c +++ /dev/null @@ -1,252 +0,0 @@ -#include "tommath.h" -#ifdef BN_S_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res, mu; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int*,mp_int*,mp_int*); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* create mu, used for Barrett reduction */ - if ((err = mp_init (&mu)) != MP_OKAY) { - goto LBL_M; - } - - if (redmode == 0) { - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce; - } else { - if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce_2k_l; - } - - /* create M table - * - * The M table contains powers of the base, - * e.g. M[x] = G**x mod P - * - * The first half of the table is not - * computed though accept for M[0] and M[1] - */ - if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { - goto LBL_MU; - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - for (x = 0; x < (winsize - 1); x++) { - /* square it */ - if ((err = mp_sqr (&M[1 << (winsize - 1)], - &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - /* reduce modulo P */ - if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) - * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) - */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_MU; - } - if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_MU; - } - mp_set (&res, 1); - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits */ - if (digidx == -1) { - break; - } - /* read next digit and reset the bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_MU:mp_clear (&mu); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_s_mp_exptmod.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_s_mp_mul_digs.c b/dep/StormLib/src/libtommath/bn_s_mp_mul_digs.c deleted file mode 100644 index f04dacfb9ea..00000000000 --- a/dep/StormLib/src/libtommath/bn_s_mp_mul_digs.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "tommath.h" -#ifdef BN_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and only computes upto digs digits of result - * HAC pp. 595, Algorithm 14.12 Modified so you can control how - * many digits of output are created. - */ -int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ - if (((digs) < MP_WARRAY) && - MIN (a->used, b->used) < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_digs (a, b, c, digs); - } - - if ((res = mp_init_size (&t, digs)) != MP_OKAY) { - return res; - } - t.used = digs; - - /* compute the digits of the product directly */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* set the carry to zero */ - u = 0; - - /* limit ourselves to making digs digits of output */ - pb = MIN (b->used, digs - ix); - - /* setup some aliases */ - /* copy of the digit from a used within the nested loop */ - tmpx = a->dp[ix]; - - /* an alias for the destination shifted ix places */ - tmpt = t.dp + ix; - - /* an alias for the digits of b */ - tmpy = b->dp; - - /* compute the columns of the output and propagate the carry */ - for (iy = 0; iy < pb; iy++) { - /* compute the column as a mp_word */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry word from the result */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - /* set carry if it is placed below digs */ - if (ix + iy < digs) { - *tmpt = u; - } - } - - mp_clamp (&t); - mp_exch (&t, c); - - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_digs.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c b/dep/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c deleted file mode 100644 index b1d019925a6..00000000000 --- a/dep/StormLib/src/libtommath/bn_s_mp_mul_high_digs.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "tommath.h" -#ifdef BN_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and does not compute the lower digs digits - * [meant to get the higher part of the product] - */ -int -s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C - if (((a->used + b->used + 1) < MP_WARRAY) - && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_high_digs (a, b, c, digs); - } -#endif - - if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { - return res; - } - t.used = a->used + b->used + 1; - - pa = a->used; - pb = b->used; - for (ix = 0; ix < pa; ix++) { - /* clear the carry */ - u = 0; - - /* left hand side of A[ix] * B[iy] */ - tmpx = a->dp[ix]; - - /* alias to the address of where the digits will be stored */ - tmpt = &(t.dp[digs]); - - /* alias for where to read the right hand side from */ - tmpy = b->dp + (digs - ix); - - for (iy = digs - ix; iy < pb; iy++) { - /* calculate the double precision result */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* get the lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* carry the carry */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - *tmpt = u; - } - mp_clamp (&t); - mp_exch (&t, c); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_high_digs.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_s_mp_sqr.c b/dep/StormLib/src/libtommath/bn_s_mp_sqr.c deleted file mode 100644 index c1e994efddf..00000000000 --- a/dep/StormLib/src/libtommath/bn_s_mp_sqr.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "tommath.h" -#ifdef BN_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -int s_mp_sqr (mp_int * a, mp_int * b) -{ - mp_int t; - int res, ix, iy, pa; - mp_word r; - mp_digit u, tmpx, *tmpt; - - pa = a->used; - if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { - return res; - } - - /* default used is maximum possible size */ - t.used = 2*pa + 1; - - for (ix = 0; ix < pa; ix++) { - /* first calculate the digit at 2*ix */ - /* calculate double precision result */ - r = ((mp_word) t.dp[2*ix]) + - ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); - - /* store lower part in result */ - t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* left hand side of A[ix] * A[iy] */ - tmpx = a->dp[ix]; - - /* alias for where to store the results */ - tmpt = t.dp + (2*ix + 1); - - for (iy = ix + 1; iy < pa; iy++) { - /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); - - /* now calculate the double precision result, note we use - * addition instead of *2 since it's easier to optimize - */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); - - /* store lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - } - - mp_clamp (&t); - mp_exch (&t, b); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_s_mp_sqr.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bn_s_mp_sub.c b/dep/StormLib/src/libtommath/bn_s_mp_sub.c deleted file mode 100644 index 0ae91cc4d17..00000000000 --- a/dep/StormLib/src/libtommath/bn_s_mp_sub.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "tommath.h" -#ifdef BN_S_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -int -s_mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int olduse, res, min, max; - - /* find sizes */ - min = b->used; - max = a->used; - - /* init result */ - if (c->alloc < max) { - if ((res = mp_grow (c, max)) != MP_OKAY) { - return res; - } - } - olduse = c->used; - c->used = max; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - tmpa = a->dp; - tmpb = b->dp; - tmpc = c->dp; - - /* set carry to zero */ - u = 0; - for (i = 0; i < min; i++) { - /* T[i] = A[i] - B[i] - U */ - *tmpc = *tmpa++ - *tmpb++ - u; - - /* U = carry bit of T[i] - * Note this saves performing an AND operation since - * if a carry does occur it will propagate all the way to the - * MSB. As a result a single shift is enough to get the carry - */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, e.g. if A has more digits than B */ - for (; i < max; i++) { - /* T[i] = A[i] - U */ - *tmpc = *tmpa++ - u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* clear digits above used (since we may not have grown result above) */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_s_mp_sub.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/bncore.c b/dep/StormLib/src/libtommath/bncore.c deleted file mode 100644 index ad7347f8424..00000000000 --- a/dep/StormLib/src/libtommath/bncore.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "tommath.h" -#ifdef BNCORE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Known optimal configurations - - CPU /Compiler /MUL CUTOFF/SQR CUTOFF -------------------------------------------------------------- - Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) - AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 - -*/ - -int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ - KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ - - TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ - TOOM_SQR_CUTOFF = 400; -#endif - -/* $Source: /cvs/libtom/libtommath/bncore.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/dep/StormLib/src/libtommath/tommath.h b/dep/StormLib/src/libtommath/tommath.h deleted file mode 100644 index 1ead3d04bf5..00000000000 --- a/dep/StormLib/src/libtommath/tommath.h +++ /dev/null @@ -1,584 +0,0 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com - */ -#ifndef BN_H_ -#define BN_H_ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> -#include <limits.h> - -#include "tommath_class.h" - -#ifndef MIN - #define MIN(x,y) ((x)<(y)?(x):(y)) -#endif - -#ifndef MAX - #define MAX(x,y) ((x)>(y)?(x):(y)) -#endif - -#ifdef __cplusplus -extern "C" { - -/* C++ compilers don't like assigning void * to mp_digit * */ -#define OPT_CAST(x) (x *) - -#else - -/* C on the other hand doesn't care */ -#define OPT_CAST(x) - -#endif - - -/* detect 64-bit mode if possible */ -#if defined(__x86_64__) - #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) - #define MP_64BIT - #endif -#endif - -/* some default configurations. - * - * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits - * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits - * - * At the very least a mp_digit must be able to hold 7 bits - * [any size beyond that is ok provided it doesn't overflow the data type] - */ -#ifdef MP_8BIT - typedef unsigned char mp_digit; - typedef unsigned short mp_word; -#elif defined(MP_16BIT) - typedef unsigned short mp_digit; - typedef unsigned long mp_word; -#elif defined(MP_64BIT) - /* for GCC only on supported platforms */ -#ifndef CRYPT - typedef unsigned long long ulong64; - typedef signed long long long64; -#endif - - typedef unsigned long mp_digit; - typedef unsigned long mp_word __attribute__ ((mode(TI))); - - #define DIGIT_BIT 60 -#else - /* this is the default case, 28-bit digits */ - - /* this is to make porting into LibTomCrypt easier :-) */ -#ifndef CRYPT - #if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 ulong64; - typedef signed __int64 long64; - #else - typedef unsigned long long ulong64; - typedef signed long long long64; - #endif -#endif - - typedef unsigned long mp_digit; - typedef ulong64 mp_word; - -#ifdef MP_31BIT - /* this is an extension that uses 31-bit digits */ - #define DIGIT_BIT 31 -#else - /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ - #define DIGIT_BIT 28 - #define MP_28BIT -#endif -#endif - -/* define heap macros */ -#ifndef CRYPT - /* default to libc stuff */ - #ifndef XMALLOC - #define XMALLOC malloc - #define XFREE free - #define XREALLOC realloc - #define XCALLOC calloc - #else - /* prototypes for our heap functions */ - extern void *XMALLOC(size_t n); - extern void *XREALLOC(void *p, size_t n); - extern void *XCALLOC(size_t n, size_t s); - extern void XFREE(void *p); - #endif -#endif - - -/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ -#ifndef DIGIT_BIT - #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ -#endif - -#define MP_DIGIT_BIT DIGIT_BIT -#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) -#define MP_DIGIT_MAX MP_MASK - -/* equalities */ -#define MP_LT -1 /* less than */ -#define MP_EQ 0 /* equal to */ -#define MP_GT 1 /* greater than */ - -#define MP_ZPOS 0 /* positive integer */ -#define MP_NEG 1 /* negative */ - -#define MP_OKAY 0 /* ok result */ -#define MP_MEM -2 /* out of mem */ -#define MP_VAL -3 /* invalid input */ -#define MP_RANGE MP_VAL - -#define MP_YES 1 /* yes response */ -#define MP_NO 0 /* no response */ - -/* Primality generation flags */ -#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ -#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ -#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ - -typedef int mp_err; - -/* you'll have to tune these... */ -extern int KARATSUBA_MUL_CUTOFF, - KARATSUBA_SQR_CUTOFF, - TOOM_MUL_CUTOFF, - TOOM_SQR_CUTOFF; - -/* define this to use lower memory usage routines (exptmods mostly) */ -/* #define MP_LOW_MEM */ - -/* default precision */ -#ifndef MP_PREC - #ifndef MP_LOW_MEM - #define MP_PREC 32 /* default digits of precision */ - #else - #define MP_PREC 8 /* default digits of precision */ - #endif -#endif - -/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ -#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) - -/* the infamous mp_int structure */ -typedef struct { - int used, alloc, sign; - mp_digit *dp; -} mp_int; - -/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ -typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); - - -#define USED(m) ((m)->used) -#define DIGIT(m,k) ((m)->dp[(k)]) -#define SIGN(m) ((m)->sign) - -/* error code to char* string */ -char *mp_error_to_string(int code); - -/* ---> init and deinit bignum functions <--- */ -/* init a bignum */ -int mp_init(mp_int *a); - -/* free a bignum */ -void mp_clear(mp_int *a); - -/* init a null terminated series of arguments */ -int mp_init_multi(mp_int *mp, ...); - -/* clear a null terminated series of arguments */ -void mp_clear_multi(mp_int *mp, ...); - -/* exchange two ints */ -void mp_exch(mp_int *a, mp_int *b); - -/* shrink ram required for a bignum */ -int mp_shrink(mp_int *a); - -/* grow an int to a given size */ -int mp_grow(mp_int *a, int size); - -/* init to a given number of digits */ -int mp_init_size(mp_int *a, int size); - -/* ---> Basic Manipulations <--- */ -#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) -#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) -#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) - -/* set to zero */ -void mp_zero(mp_int *a); - -/* set to a digit */ -void mp_set(mp_int *a, mp_digit b); - -/* set a 32-bit const */ -int mp_set_int(mp_int *a, unsigned long b); - -/* get a 32-bit value */ -unsigned long mp_get_int(mp_int * a); - -/* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b); - -/* initialize and set 32-bit value */ -int mp_init_set_int (mp_int * a, unsigned long b); - -/* copy, b = a */ -int mp_copy(mp_int *a, mp_int *b); - -/* inits and copies, a = b */ -int mp_init_copy(mp_int *a, mp_int *b); - -/* trim unused digits */ -void mp_clamp(mp_int *a); - -/* ---> digit manipulation <--- */ - -/* right shift by "b" digits */ -void mp_rshd(mp_int *a, int b); - -/* left shift by "b" digits */ -int mp_lshd(mp_int *a, int b); - -/* c = a / 2**b */ -int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); - -/* b = a/2 */ -int mp_div_2(mp_int *a, mp_int *b); - -/* c = a * 2**b */ -int mp_mul_2d(mp_int *a, int b, mp_int *c); - -/* b = a*2 */ -int mp_mul_2(mp_int *a, mp_int *b); - -/* c = a mod 2**d */ -int mp_mod_2d(mp_int *a, int b, mp_int *c); - -/* computes a = 2**b */ -int mp_2expt(mp_int *a, int b); - -/* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a); - -/* I Love Earth! */ - -/* makes a pseudo-random int of a given size */ -int mp_rand(mp_int *a, int digits); - -/* ---> binary operations <--- */ -/* c = a XOR b */ -int mp_xor(mp_int *a, mp_int *b, mp_int *c); - -/* c = a OR b */ -int mp_or(mp_int *a, mp_int *b, mp_int *c); - -/* c = a AND b */ -int mp_and(mp_int *a, mp_int *b, mp_int *c); - -/* ---> Basic arithmetic <--- */ - -/* b = -a */ -int mp_neg(mp_int *a, mp_int *b); - -/* b = |a| */ -int mp_abs(mp_int *a, mp_int *b); - -/* compare a to b */ -int mp_cmp(mp_int *a, mp_int *b); - -/* compare |a| to |b| */ -int mp_cmp_mag(mp_int *a, mp_int *b); - -/* c = a + b */ -int mp_add(mp_int *a, mp_int *b, mp_int *c); - -/* c = a - b */ -int mp_sub(mp_int *a, mp_int *b, mp_int *c); - -/* c = a * b */ -int mp_mul(mp_int *a, mp_int *b, mp_int *c); - -/* b = a*a */ -int mp_sqr(mp_int *a, mp_int *b); - -/* a/b => cb + d == a */ -int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* c = a mod b, 0 <= c < b */ -int mp_mod(mp_int *a, mp_int *b, mp_int *c); - -/* ---> single digit functions <--- */ - -/* compare against a single digit */ -int mp_cmp_d(mp_int *a, mp_digit b); - -/* c = a + b */ -int mp_add_d(mp_int *a, mp_digit b, mp_int *c); - -/* c = a - b */ -int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); - -/* c = a * b */ -int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); - -/* a/b => cb + d == a */ -int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); - -/* a/3 => 3c + d == a */ -int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); - -/* c = a**b */ -int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); - -/* c = a mod b, 0 <= c < b */ -int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); - -/* ---> number theory <--- */ - -/* d = a + b (mod c) */ -int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* d = a - b (mod c) */ -int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* d = a * b (mod c) */ -int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* c = a * a (mod b) */ -int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); - -/* c = 1/a (mod b) */ -int mp_invmod(mp_int *a, mp_int *b, mp_int *c); - -/* c = (a, b) */ -int mp_gcd(mp_int *a, mp_int *b, mp_int *c); - -/* produces value such that U1*a + U2*b = U3 */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); - -/* c = [a, b] or (a*b)/(a, b) */ -int mp_lcm(mp_int *a, mp_int *b, mp_int *c); - -/* finds one of the b'th root of a, such that |c|**b <= |a| - * - * returns error if a < 0 and b is even - */ -int mp_n_root(mp_int *a, mp_digit b, mp_int *c); - -/* special sqrt algo */ -int mp_sqrt(mp_int *arg, mp_int *ret); - -/* is number a square? */ -int mp_is_square(mp_int *arg, int *ret); - -/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ -int mp_jacobi(mp_int *a, mp_int *n, int *c); - -/* used to setup the Barrett reduction for a given modulus b */ -int mp_reduce_setup(mp_int *a, mp_int *b); - -/* Barrett Reduction, computes a (mod b) with a precomputed value c - * - * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely - * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. - */ -int mp_reduce(mp_int *a, mp_int *b, mp_int *c); - -/* setups the montgomery reduction */ -int mp_montgomery_setup(mp_int *a, mp_digit *mp); - -/* computes a = B**n mod b without division or multiplication useful for - * normalizing numbers in a Montgomery system. - */ -int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); - -/* computes x/R == x (mod N) via Montgomery Reduction */ -int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); - -/* returns 1 if a is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a); - -/* sets the value of "d" required for mp_dr_reduce */ -void mp_dr_setup(mp_int *a, mp_digit *d); - -/* reduces a modulo b using the Diminished Radix method */ -int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); - -/* returns true if a can be reduced with mp_reduce_2k */ -int mp_reduce_is_2k(mp_int *a); - -/* determines k value for 2k reduction */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d); - -/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); - -/* returns true if a can be reduced with mp_reduce_2k_l */ -int mp_reduce_is_2k_l(mp_int *a); - -/* determines k value for 2k reduction */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); - -/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); - -/* d = a**b (mod c) */ -int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* ---> Primes <--- */ - -/* number of primes */ -#ifdef MP_8BIT - #define PRIME_SIZE 31 -#else - #define PRIME_SIZE 256 -#endif - -/* table of first PRIME_SIZE primes */ -extern const mp_digit ltm_prime_tab[]; - -/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ -int mp_prime_is_divisible(mp_int *a, int *result); - -/* performs one Fermat test of "a" using base "b". - * Sets result to 0 if composite or 1 if probable prime - */ -int mp_prime_fermat(mp_int *a, mp_int *b, int *result); - -/* performs one Miller-Rabin test of "a" using base "b". - * Sets result to 0 if composite or 1 if probable prime - */ -int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); - -/* This gives [for a given bit size] the number of trials required - * such that Miller-Rabin gives a prob of failure lower than 2^-96 - */ -int mp_prime_rabin_miller_trials(int size); - -/* performs t rounds of Miller-Rabin on "a" using the first - * t prime bases. Also performs an initial sieve of trial - * division. Determines if "a" is prime with probability - * of error no more than (1/4)**t. - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime(mp_int *a, int t, int *result); - -/* finds the next prime after the number "a" using "t" trials - * of Miller-Rabin. - * - * bbs_style = 1 means the prime must be congruent to 3 mod 4 - */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style); - -/* makes a truly random prime of a given size (bytes), - * call with bbs = 1 if you want it to be congruent to 3 mod 4 - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - * The prime generated will be larger than 2^(8*size). - */ -#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) - -/* makes a truly random prime of a given size (bits), - * - * Flags are as follows: - * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); - -/* ---> radix conversion <--- */ -int mp_count_bits(mp_int *a); - -int mp_unsigned_bin_size(mp_int *a); -int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c); -int mp_to_unsigned_bin(mp_int *a, unsigned char *b); -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); - -int mp_signed_bin_size(mp_int *a); -int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c); -int mp_to_signed_bin(mp_int *a, unsigned char *b); -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); - -int mp_read_radix(mp_int *a, const char *str, int radix); -int mp_toradix(mp_int *a, char *str, int radix); -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen); -int mp_radix_size(mp_int *a, int radix, int *size); - -int mp_fread(mp_int *a, int radix, FILE *stream); -int mp_fwrite(mp_int *a, int radix, FILE *stream); - -#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) -#define mp_raw_size(mp) mp_signed_bin_size(mp) -#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) -#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) -#define mp_mag_size(mp) mp_unsigned_bin_size(mp) -#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) - -#define mp_tobinary(M, S) mp_toradix((M), (S), 2) -#define mp_tooctal(M, S) mp_toradix((M), (S), 8) -#define mp_todecimal(M, S) mp_toradix((M), (S), 10) -#define mp_tohex(M, S) mp_toradix((M), (S), 16) - -/* lowlevel functions, do not call! */ -int s_mp_add(mp_int *a, mp_int *b, mp_int *c); -int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); -#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) -int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int fast_s_mp_sqr(mp_int *a, mp_int *b); -int s_mp_sqr(mp_int *a, mp_int *b); -int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); -int mp_karatsuba_sqr(mp_int *a, mp_int *b); -int mp_toom_sqr(mp_int *a, mp_int *b); -int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); -int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); -int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode); -void bn_reverse(unsigned char *s, int len); - -extern const char *mp_s_rmap; - -#ifdef __cplusplus - } -#endif - -#endif - - -/* $Source: /cvs/libtom/libtommath/tommath.h,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2006/03/31 14:18:44 $ */ diff --git a/dep/StormLib/src/libtommath/tommath_class.h b/dep/StormLib/src/libtommath/tommath_class.h deleted file mode 100644 index 18d1553dee7..00000000000 --- a/dep/StormLib/src/libtommath/tommath_class.h +++ /dev/null @@ -1,999 +0,0 @@ -#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) -#if defined(LTM2) -#define LTM3 -#endif -#if defined(LTM1) -#define LTM2 -#endif -#define LTM1 - -#if defined(LTM_ALL) -#define BN_ERROR_C -#define BN_FAST_MP_INVMOD_C -#define BN_FAST_MP_MONTGOMERY_REDUCE_C -#define BN_FAST_S_MP_MUL_DIGS_C -#define BN_FAST_S_MP_MUL_HIGH_DIGS_C -#define BN_FAST_S_MP_SQR_C -#define BN_MP_2EXPT_C -#define BN_MP_ABS_C -#define BN_MP_ADD_C -#define BN_MP_ADD_D_C -#define BN_MP_ADDMOD_C -#define BN_MP_AND_C -#define BN_MP_CLAMP_C -#define BN_MP_CLEAR_C -#define BN_MP_CLEAR_MULTI_C -#define BN_MP_CMP_C -#define BN_MP_CMP_D_C -#define BN_MP_CMP_MAG_C -#define BN_MP_CNT_LSB_C -#define BN_MP_COPY_C -#define BN_MP_COUNT_BITS_C -#define BN_MP_DIV_C -#define BN_MP_DIV_2_C -#define BN_MP_DIV_2D_C -#define BN_MP_DIV_3_C -#define BN_MP_DIV_D_C -#define BN_MP_DR_IS_MODULUS_C -#define BN_MP_DR_REDUCE_C -#define BN_MP_DR_SETUP_C -#define BN_MP_EXCH_C -#define BN_MP_EXPT_D_C -#define BN_MP_EXPTMOD_C -#define BN_MP_EXPTMOD_FAST_C -#define BN_MP_EXTEUCLID_C -#define BN_MP_FREAD_C -#define BN_MP_FWRITE_C -#define BN_MP_GCD_C -#define BN_MP_GET_INT_C -#define BN_MP_GROW_C -#define BN_MP_INIT_C -#define BN_MP_INIT_COPY_C -#define BN_MP_INIT_MULTI_C -#define BN_MP_INIT_SET_C -#define BN_MP_INIT_SET_INT_C -#define BN_MP_INIT_SIZE_C -#define BN_MP_INVMOD_C -#define BN_MP_INVMOD_SLOW_C -#define BN_MP_IS_SQUARE_C -#define BN_MP_JACOBI_C -#define BN_MP_KARATSUBA_MUL_C -#define BN_MP_KARATSUBA_SQR_C -#define BN_MP_LCM_C -#define BN_MP_LSHD_C -#define BN_MP_MOD_C -#define BN_MP_MOD_2D_C -#define BN_MP_MOD_D_C -#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -#define BN_MP_MONTGOMERY_REDUCE_C -#define BN_MP_MONTGOMERY_SETUP_C -#define BN_MP_MUL_C -#define BN_MP_MUL_2_C -#define BN_MP_MUL_2D_C -#define BN_MP_MUL_D_C -#define BN_MP_MULMOD_C -#define BN_MP_N_ROOT_C -#define BN_MP_NEG_C -#define BN_MP_OR_C -#define BN_MP_PRIME_FERMAT_C -#define BN_MP_PRIME_IS_DIVISIBLE_C -#define BN_MP_PRIME_IS_PRIME_C -#define BN_MP_PRIME_MILLER_RABIN_C -#define BN_MP_PRIME_NEXT_PRIME_C -#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C -#define BN_MP_PRIME_RANDOM_EX_C -#define BN_MP_RADIX_SIZE_C -#define BN_MP_RADIX_SMAP_C -#define BN_MP_RAND_C -#define BN_MP_READ_RADIX_C -#define BN_MP_READ_SIGNED_BIN_C -#define BN_MP_READ_UNSIGNED_BIN_C -#define BN_MP_REDUCE_C -#define BN_MP_REDUCE_2K_C -#define BN_MP_REDUCE_2K_L_C -#define BN_MP_REDUCE_2K_SETUP_C -#define BN_MP_REDUCE_2K_SETUP_L_C -#define BN_MP_REDUCE_IS_2K_C -#define BN_MP_REDUCE_IS_2K_L_C -#define BN_MP_REDUCE_SETUP_C -#define BN_MP_RSHD_C -#define BN_MP_SET_C -#define BN_MP_SET_INT_C -#define BN_MP_SHRINK_C -#define BN_MP_SIGNED_BIN_SIZE_C -#define BN_MP_SQR_C -#define BN_MP_SQRMOD_C -#define BN_MP_SQRT_C -#define BN_MP_SUB_C -#define BN_MP_SUB_D_C -#define BN_MP_SUBMOD_C -#define BN_MP_TO_SIGNED_BIN_C -#define BN_MP_TO_SIGNED_BIN_N_C -#define BN_MP_TO_UNSIGNED_BIN_C -#define BN_MP_TO_UNSIGNED_BIN_N_C -#define BN_MP_TOOM_MUL_C -#define BN_MP_TOOM_SQR_C -#define BN_MP_TORADIX_C -#define BN_MP_TORADIX_N_C -#define BN_MP_UNSIGNED_BIN_SIZE_C -#define BN_MP_XOR_C -#define BN_MP_ZERO_C -#define BN_PRIME_TAB_C -#define BN_REVERSE_C -#define BN_S_MP_ADD_C -#define BN_S_MP_EXPTMOD_C -#define BN_S_MP_MUL_DIGS_C -#define BN_S_MP_MUL_HIGH_DIGS_C -#define BN_S_MP_SQR_C -#define BN_S_MP_SUB_C -#define BNCORE_C -#endif - -#if defined(BN_ERROR_C) - #define BN_MP_ERROR_TO_STRING_C -#endif - -#if defined(BN_FAST_MP_INVMOD_C) - #define BN_MP_ISEVEN_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_COPY_C - #define BN_MP_MOD_C - #define BN_MP_SET_C - #define BN_MP_DIV_2_C - #define BN_MP_ISODD_C - #define BN_MP_SUB_C - #define BN_MP_CMP_C - #define BN_MP_ISZERO_C - #define BN_MP_CMP_D_C - #define BN_MP_ADD_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) - #define BN_MP_GROW_C - #define BN_MP_RSHD_C - #define BN_MP_CLAMP_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_FAST_S_MP_MUL_DIGS_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_FAST_S_MP_SQR_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_2EXPT_C) - #define BN_MP_ZERO_C - #define BN_MP_GROW_C -#endif - -#if defined(BN_MP_ABS_C) - #define BN_MP_COPY_C -#endif - -#if defined(BN_MP_ADD_C) - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_ADD_D_C) - #define BN_MP_GROW_C - #define BN_MP_SUB_D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_ADDMOD_C) - #define BN_MP_INIT_C - #define BN_MP_ADD_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_AND_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_CLAMP_C) -#endif - -#if defined(BN_MP_CLEAR_C) -#endif - -#if defined(BN_MP_CLEAR_MULTI_C) - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_CMP_C) - #define BN_MP_CMP_MAG_C -#endif - -#if defined(BN_MP_CMP_D_C) -#endif - -#if defined(BN_MP_CMP_MAG_C) -#endif - -#if defined(BN_MP_CNT_LSB_C) - #define BN_MP_ISZERO_C -#endif - -#if defined(BN_MP_COPY_C) - #define BN_MP_GROW_C -#endif - -#if defined(BN_MP_COUNT_BITS_C) -#endif - -#if defined(BN_MP_DIV_C) - #define BN_MP_ISZERO_C - #define BN_MP_CMP_MAG_C - #define BN_MP_COPY_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_SET_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_ABS_C - #define BN_MP_MUL_2D_C - #define BN_MP_CMP_C - #define BN_MP_SUB_C - #define BN_MP_ADD_C - #define BN_MP_DIV_2D_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_INIT_C - #define BN_MP_INIT_COPY_C - #define BN_MP_LSHD_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_D_C - #define BN_MP_CLAMP_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_DIV_2_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_DIV_2D_C) - #define BN_MP_COPY_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_C - #define BN_MP_MOD_2D_C - #define BN_MP_CLEAR_C - #define BN_MP_RSHD_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_MP_DIV_3_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_DIV_D_C) - #define BN_MP_ISZERO_C - #define BN_MP_COPY_C - #define BN_MP_DIV_2D_C - #define BN_MP_DIV_3_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_DR_IS_MODULUS_C) -#endif - -#if defined(BN_MP_DR_REDUCE_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_DR_SETUP_C) -#endif - -#if defined(BN_MP_EXCH_C) -#endif - -#if defined(BN_MP_EXPT_D_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_SET_C - #define BN_MP_SQR_C - #define BN_MP_CLEAR_C - #define BN_MP_MUL_C -#endif - -#if defined(BN_MP_EXPTMOD_C) - #define BN_MP_INIT_C - #define BN_MP_INVMOD_C - #define BN_MP_CLEAR_C - #define BN_MP_ABS_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_REDUCE_IS_2K_L_C - #define BN_S_MP_EXPTMOD_C - #define BN_MP_DR_IS_MODULUS_C - #define BN_MP_REDUCE_IS_2K_C - #define BN_MP_ISODD_C - #define BN_MP_EXPTMOD_FAST_C -#endif - -#if defined(BN_MP_EXPTMOD_FAST_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C - #define BN_MP_MONTGOMERY_SETUP_C - #define BN_FAST_MP_MONTGOMERY_REDUCE_C - #define BN_MP_MONTGOMERY_REDUCE_C - #define BN_MP_DR_SETUP_C - #define BN_MP_DR_REDUCE_C - #define BN_MP_REDUCE_2K_SETUP_C - #define BN_MP_REDUCE_2K_C - #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - #define BN_MP_MULMOD_C - #define BN_MP_SET_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_SQR_C - #define BN_MP_MUL_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_MP_EXTEUCLID_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_SET_C - #define BN_MP_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_C - #define BN_MP_MUL_C - #define BN_MP_SUB_C - #define BN_MP_NEG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_FREAD_C) - #define BN_MP_ZERO_C - #define BN_MP_S_RMAP_C - #define BN_MP_MUL_D_C - #define BN_MP_ADD_D_C - #define BN_MP_CMP_D_C -#endif - -#if defined(BN_MP_FWRITE_C) - #define BN_MP_RADIX_SIZE_C - #define BN_MP_TORADIX_C -#endif - -#if defined(BN_MP_GCD_C) - #define BN_MP_ISZERO_C - #define BN_MP_ABS_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_S_MP_SUB_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_GET_INT_C) -#endif - -#if defined(BN_MP_GROW_C) -#endif - -#if defined(BN_MP_INIT_C) -#endif - -#if defined(BN_MP_INIT_COPY_C) - #define BN_MP_COPY_C -#endif - -#if defined(BN_MP_INIT_MULTI_C) - #define BN_MP_ERR_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_INIT_SET_C) - #define BN_MP_INIT_C - #define BN_MP_SET_C -#endif - -#if defined(BN_MP_INIT_SET_INT_C) - #define BN_MP_INIT_C - #define BN_MP_SET_INT_C -#endif - -#if defined(BN_MP_INIT_SIZE_C) - #define BN_MP_INIT_C -#endif - -#if defined(BN_MP_INVMOD_C) - #define BN_MP_ISZERO_C - #define BN_MP_ISODD_C - #define BN_FAST_MP_INVMOD_C - #define BN_MP_INVMOD_SLOW_C -#endif - -#if defined(BN_MP_INVMOD_SLOW_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_ISEVEN_C - #define BN_MP_SET_C - #define BN_MP_DIV_2_C - #define BN_MP_ISODD_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_CMP_C - #define BN_MP_CMP_D_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_IS_SQUARE_C) - #define BN_MP_MOD_D_C - #define BN_MP_INIT_SET_INT_C - #define BN_MP_MOD_C - #define BN_MP_GET_INT_C - #define BN_MP_SQRT_C - #define BN_MP_SQR_C - #define BN_MP_CMP_MAG_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_JACOBI_C) - #define BN_MP_CMP_D_C - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_MOD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_KARATSUBA_MUL_C) - #define BN_MP_MUL_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_SUB_C - #define BN_MP_ADD_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_KARATSUBA_SQR_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_SQR_C - #define BN_MP_SUB_C - #define BN_S_MP_ADD_C - #define BN_MP_LSHD_C - #define BN_MP_ADD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_LCM_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_GCD_C - #define BN_MP_CMP_MAG_C - #define BN_MP_DIV_C - #define BN_MP_MUL_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_LSHD_C) - #define BN_MP_GROW_C - #define BN_MP_RSHD_C -#endif - -#if defined(BN_MP_MOD_C) - #define BN_MP_INIT_C - #define BN_MP_DIV_C - #define BN_MP_CLEAR_C - #define BN_MP_ADD_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_MP_MOD_2D_C) - #define BN_MP_ZERO_C - #define BN_MP_COPY_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_MOD_D_C) - #define BN_MP_DIV_D_C -#endif - -#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_2EXPT_C - #define BN_MP_SET_C - #define BN_MP_MUL_2_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_MONTGOMERY_REDUCE_C) - #define BN_FAST_MP_MONTGOMERY_REDUCE_C - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C - #define BN_MP_RSHD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_MONTGOMERY_SETUP_C) -#endif - -#if defined(BN_MP_MUL_C) - #define BN_MP_TOOM_MUL_C - #define BN_MP_KARATSUBA_MUL_C - #define BN_FAST_S_MP_MUL_DIGS_C - #define BN_S_MP_MUL_C - #define BN_S_MP_MUL_DIGS_C -#endif - -#if defined(BN_MP_MUL_2_C) - #define BN_MP_GROW_C -#endif - -#if defined(BN_MP_MUL_2D_C) - #define BN_MP_COPY_C - #define BN_MP_GROW_C - #define BN_MP_LSHD_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_MUL_D_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_MULMOD_C) - #define BN_MP_INIT_C - #define BN_MP_MUL_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_N_ROOT_C) - #define BN_MP_INIT_C - #define BN_MP_SET_C - #define BN_MP_COPY_C - #define BN_MP_EXPT_D_C - #define BN_MP_MUL_C - #define BN_MP_SUB_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_C - #define BN_MP_CMP_C - #define BN_MP_SUB_D_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_NEG_C) - #define BN_MP_COPY_C - #define BN_MP_ISZERO_C -#endif - -#if defined(BN_MP_OR_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_FERMAT_C) - #define BN_MP_CMP_D_C - #define BN_MP_INIT_C - #define BN_MP_EXPTMOD_C - #define BN_MP_CMP_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) - #define BN_MP_MOD_D_C -#endif - -#if defined(BN_MP_PRIME_IS_PRIME_C) - #define BN_MP_CMP_D_C - #define BN_MP_PRIME_IS_DIVISIBLE_C - #define BN_MP_INIT_C - #define BN_MP_SET_C - #define BN_MP_PRIME_MILLER_RABIN_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_MILLER_RABIN_C) - #define BN_MP_CMP_D_C - #define BN_MP_INIT_COPY_C - #define BN_MP_SUB_D_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_EXPTMOD_C - #define BN_MP_CMP_C - #define BN_MP_SQRMOD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_NEXT_PRIME_C) - #define BN_MP_CMP_D_C - #define BN_MP_SET_C - #define BN_MP_SUB_D_C - #define BN_MP_ISEVEN_C - #define BN_MP_MOD_D_C - #define BN_MP_INIT_C - #define BN_MP_ADD_D_C - #define BN_MP_PRIME_MILLER_RABIN_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) -#endif - -#if defined(BN_MP_PRIME_RANDOM_EX_C) - #define BN_MP_READ_UNSIGNED_BIN_C - #define BN_MP_PRIME_IS_PRIME_C - #define BN_MP_SUB_D_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_D_C -#endif - -#if defined(BN_MP_RADIX_SIZE_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_RADIX_SMAP_C) - #define BN_MP_S_RMAP_C -#endif - -#if defined(BN_MP_RAND_C) - #define BN_MP_ZERO_C - #define BN_MP_ADD_D_C - #define BN_MP_LSHD_C -#endif - -#if defined(BN_MP_READ_RADIX_C) - #define BN_MP_ZERO_C - #define BN_MP_S_RMAP_C - #define BN_MP_RADIX_SMAP_C - #define BN_MP_MUL_D_C - #define BN_MP_ADD_D_C - #define BN_MP_ISZERO_C -#endif - -#if defined(BN_MP_READ_SIGNED_BIN_C) - #define BN_MP_READ_UNSIGNED_BIN_C -#endif - -#if defined(BN_MP_READ_UNSIGNED_BIN_C) - #define BN_MP_GROW_C - #define BN_MP_ZERO_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_REDUCE_C) - #define BN_MP_REDUCE_SETUP_C - #define BN_MP_INIT_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_C - #define BN_S_MP_MUL_HIGH_DIGS_C - #define BN_FAST_S_MP_MUL_HIGH_DIGS_C - #define BN_MP_MOD_2D_C - #define BN_S_MP_MUL_DIGS_C - #define BN_MP_SUB_C - #define BN_MP_CMP_D_C - #define BN_MP_SET_C - #define BN_MP_LSHD_C - #define BN_MP_ADD_C - #define BN_MP_CMP_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_2K_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_DIV_2D_C - #define BN_MP_MUL_D_C - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_2K_L_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_DIV_2D_C - #define BN_MP_MUL_C - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_2K_SETUP_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_2EXPT_C - #define BN_MP_CLEAR_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_REDUCE_2K_SETUP_L_C) - #define BN_MP_INIT_C - #define BN_MP_2EXPT_C - #define BN_MP_COUNT_BITS_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_IS_2K_C) - #define BN_MP_REDUCE_2K_C - #define BN_MP_COUNT_BITS_C -#endif - -#if defined(BN_MP_REDUCE_IS_2K_L_C) -#endif - -#if defined(BN_MP_REDUCE_SETUP_C) - #define BN_MP_2EXPT_C - #define BN_MP_DIV_C -#endif - -#if defined(BN_MP_RSHD_C) - #define BN_MP_ZERO_C -#endif - -#if defined(BN_MP_SET_C) - #define BN_MP_ZERO_C -#endif - -#if defined(BN_MP_SET_INT_C) - #define BN_MP_ZERO_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_SHRINK_C) -#endif - -#if defined(BN_MP_SIGNED_BIN_SIZE_C) - #define BN_MP_UNSIGNED_BIN_SIZE_C -#endif - -#if defined(BN_MP_SQR_C) - #define BN_MP_TOOM_SQR_C - #define BN_MP_KARATSUBA_SQR_C - #define BN_FAST_S_MP_SQR_C - #define BN_S_MP_SQR_C -#endif - -#if defined(BN_MP_SQRMOD_C) - #define BN_MP_INIT_C - #define BN_MP_SQR_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_SQRT_C) - #define BN_MP_N_ROOT_C - #define BN_MP_ISZERO_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_DIV_C - #define BN_MP_ADD_C - #define BN_MP_DIV_2_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_SUB_C) - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_SUB_D_C) - #define BN_MP_GROW_C - #define BN_MP_ADD_D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_SUBMOD_C) - #define BN_MP_INIT_C - #define BN_MP_SUB_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_TO_SIGNED_BIN_C) - #define BN_MP_TO_UNSIGNED_BIN_C -#endif - -#if defined(BN_MP_TO_SIGNED_BIN_N_C) - #define BN_MP_SIGNED_BIN_SIZE_C - #define BN_MP_TO_SIGNED_BIN_C -#endif - -#if defined(BN_MP_TO_UNSIGNED_BIN_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_2D_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) - #define BN_MP_UNSIGNED_BIN_SIZE_C - #define BN_MP_TO_UNSIGNED_BIN_C -#endif - -#if defined(BN_MP_TOOM_MUL_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_2D_C - #define BN_MP_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2D_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_3_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_TOOM_SQR_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_2D_C - #define BN_MP_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_SQR_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2D_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_3_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_TORADIX_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C - #define BN_MP_S_RMAP_C -#endif - -#if defined(BN_MP_TORADIX_N_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C - #define BN_MP_S_RMAP_C -#endif - -#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) - #define BN_MP_COUNT_BITS_C -#endif - -#if defined(BN_MP_XOR_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_ZERO_C) -#endif - -#if defined(BN_PRIME_TAB_C) -#endif - -#if defined(BN_REVERSE_C) -#endif - -#if defined(BN_S_MP_ADD_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_S_MP_EXPTMOD_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C - #define BN_MP_REDUCE_SETUP_C - #define BN_MP_REDUCE_C - #define BN_MP_REDUCE_2K_SETUP_L_C - #define BN_MP_REDUCE_2K_L_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_SQR_C - #define BN_MP_MUL_C - #define BN_MP_SET_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_S_MP_MUL_DIGS_C) - #define BN_FAST_S_MP_MUL_DIGS_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_S_MP_MUL_HIGH_DIGS_C) - #define BN_FAST_S_MP_MUL_HIGH_DIGS_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_S_MP_SQR_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_S_MP_SUB_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BNCORE_C) -#endif - -#ifdef LTM3 -#define LTM_LAST -#endif -#include "tommath_superclass.h" -#include "tommath_class.h" -#else -#define LTM_LAST -#endif - -/* $Source: /cvs/libtom/libtommath/tommath_class.h,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2005/07/28 11:59:32 $ */ diff --git a/dep/StormLib/src/libtommath/tommath_superclass.h b/dep/StormLib/src/libtommath/tommath_superclass.h deleted file mode 100644 index 2fdebe6838f..00000000000 --- a/dep/StormLib/src/libtommath/tommath_superclass.h +++ /dev/null @@ -1,76 +0,0 @@ -/* super class file for PK algos */ - -/* default ... include all MPI */ -#define LTM_ALL - -/* RSA only (does not support DH/DSA/ECC) */ -/* #define SC_RSA_1 */ - -/* For reference.... On an Athlon64 optimizing for speed... - - LTM's mpi.o with all functions [striped] is 142KiB in size. - -*/ - -/* Works for RSA only, mpi.o is 68KiB */ -#ifdef SC_RSA_1 - #define BN_MP_SHRINK_C - #define BN_MP_LCM_C - #define BN_MP_PRIME_RANDOM_EX_C - #define BN_MP_INVMOD_C - #define BN_MP_GCD_C - #define BN_MP_MOD_C - #define BN_MP_MULMOD_C - #define BN_MP_ADDMOD_C - #define BN_MP_EXPTMOD_C - #define BN_MP_SET_INT_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_UNSIGNED_BIN_SIZE_C - #define BN_MP_TO_UNSIGNED_BIN_C - #define BN_MP_MOD_D_C - #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C - #define BN_REVERSE_C - #define BN_PRIME_TAB_C - - /* other modifiers */ - #define BN_MP_DIV_SMALL /* Slower division, not critical */ - - /* here we are on the last pass so we turn things off. The functions classes are still there - * but we remove them specifically from the build. This also invokes tweaks in functions - * like removing support for even moduli, etc... - */ -#ifdef LTM_LAST - #undef BN_MP_TOOM_MUL_C - #undef BN_MP_TOOM_SQR_C - #undef BN_MP_KARATSUBA_MUL_C - #undef BN_MP_KARATSUBA_SQR_C - #undef BN_MP_REDUCE_C - #undef BN_MP_REDUCE_SETUP_C - #undef BN_MP_DR_IS_MODULUS_C - #undef BN_MP_DR_SETUP_C - #undef BN_MP_DR_REDUCE_C - #undef BN_MP_REDUCE_IS_2K_C - #undef BN_MP_REDUCE_2K_SETUP_C - #undef BN_MP_REDUCE_2K_C - #undef BN_S_MP_EXPTMOD_C - #undef BN_MP_DIV_3_C - #undef BN_S_MP_MUL_HIGH_DIGS_C - #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C - #undef BN_FAST_MP_INVMOD_C - - /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold - * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] - * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without - * trouble. - */ - #undef BN_S_MP_MUL_DIGS_C - #undef BN_S_MP_SQR_C - #undef BN_MP_MONTGOMERY_REDUCE_C -#endif - -#endif - -/* $Source: /cvs/libtom/libtommath/tommath_superclass.h,v $ */ -/* $Revision: 1.3 $ */ -/* $Date: 2005/05/14 13:29:17 $ */ diff --git a/dep/StormLib/src/lzma/C/LzFind.c b/dep/StormLib/src/lzma/C/LzFind.c deleted file mode 100644 index e3ecb05420e..00000000000 --- a/dep/StormLib/src/lzma/C/LzFind.c +++ /dev/null @@ -1,761 +0,0 @@ -/* LzFind.c -- Match finder for LZ algorithms -2009-04-22 : 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; - if (p->directInput) - { - UInt32 curSize = 0xFFFFFFFF - p->streamPos; - if (curSize > p->directInputRem) - curSize = (UInt32)p->directInputRem; - p->directInputRem -= curSize; - p->streamPos += curSize; - if (p->directInputRem == 0) - p->streamEndWasReached = 1; - 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->directInput) - return 0; - /* 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->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 + 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 |= 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/dep/StormLib/src/lzma/C/LzFind.h b/dep/StormLib/src/lzma/C/LzFind.h deleted file mode 100644 index 010c4b92ba3..00000000000 --- a/dep/StormLib/src/lzma/C/LzFind.h +++ /dev/null @@ -1,115 +0,0 @@ -/* LzFind.h -- Match finder for LZ algorithms -2009-04-22 : Igor Pavlov : Public domain */ - -#ifndef __LZ_FIND_H -#define __LZ_FIND_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -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; - size_t directInputRem; - int btMode; - 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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/dep/StormLib/src/lzma/C/LzFindMt.c b/dep/StormLib/src/lzma/C/LzFindMt.c deleted file mode 100644 index aa41ed98a57..00000000000 --- a/dep/StormLib/src/lzma/C/LzFindMt.c +++ /dev/null @@ -1,793 +0,0 @@ -/* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2009-09-20 : 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_MT do { GET_NEXT_BLOCK_IF_REQUIRED -#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; -#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); - -void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER2_MT { p->btNumAvailBytes--; - SKIP_FOOTER_MT -} - -void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(2) - UInt32 hash2Value; - MT_HASH2_CALC - hash[hash2Value] = p->lzPos; - SKIP_FOOTER_MT -} - -void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(3) - UInt32 hash2Value, hash3Value; - MT_HASH3_CALC - hash[kFix3HashSize + hash3Value] = - hash[ hash2Value] = - p->lzPos; - SKIP_FOOTER_MT -} - -/* -void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(4) - UInt32 hash2Value, hash3Value, hash4Value; - MT_HASH4_CALC - hash[kFix4HashSize + hash4Value] = - hash[kFix3HashSize + hash3Value] = - hash[ hash2Value] = - p->lzPos; - SKIP_FOOTER_MT -} -*/ - -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/dep/StormLib/src/lzma/C/LzFindMt.h b/dep/StormLib/src/lzma/C/LzFindMt.h deleted file mode 100644 index b985af5fee2..00000000000 --- a/dep/StormLib/src/lzma/C/LzFindMt.h +++ /dev/null @@ -1,105 +0,0 @@ -/* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __LZ_FIND_MT_H -#define __LZ_FIND_MT_H - -#include "LzFind.h" -#include "Threads.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/dep/StormLib/src/lzma/C/LzHash.h b/dep/StormLib/src/lzma/C/LzHash.h deleted file mode 100644 index f3e89966cc7..00000000000 --- a/dep/StormLib/src/lzma/C/LzHash.h +++ /dev/null @@ -1,54 +0,0 @@ -/* LzHash.h -- HASH functions for LZ algorithms -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __LZ_HASH_H -#define __LZ_HASH_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/dep/StormLib/src/lzma/C/LzmaDec.c b/dep/StormLib/src/lzma/C/LzmaDec.c deleted file mode 100644 index 2036761bf14..00000000000 --- a/dep/StormLib/src/lzma/C/LzmaDec.c +++ /dev/null @@ -1,999 +0,0 @@ -/* LzmaDec.c -- LZMA Decoder -2009-09-20 : 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 - -#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) - { - state -= (state < 4) ? state : 3; - 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; - state -= (state < 10) ? 3 : 6; - 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++; - 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; - } - - 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/dep/StormLib/src/lzma/C/LzmaDec.h b/dep/StormLib/src/lzma/C/LzmaDec.h deleted file mode 100644 index bf7f084ba3d..00000000000 --- a/dep/StormLib/src/lzma/C/LzmaDec.h +++ /dev/null @@ -1,231 +0,0 @@ -/* LzmaDec.h -- LZMA Decoder -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_DEC_H -#define __LZMA_DEC_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* #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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/dep/StormLib/src/lzma/C/LzmaEnc.c b/dep/StormLib/src/lzma/C/LzmaEnc.c deleted file mode 100644 index 169d4f4639e..00000000000 --- a/dep/StormLib/src/lzma/C/LzmaEnc.c +++ /dev/null @@ -1,2268 +0,0 @@ -/* LzmaEnc.c -- LZMA Encoder -2009-11-24 : 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" -#ifndef _7ZIP_ST -#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 = - #ifndef _7ZIP_ST - ((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 -{ - 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 >> 1)) - -#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 -{ - UInt32 range; - Byte cache; - UInt64 low; - UInt64 cacheSize; - Byte *buf; - Byte *bufLim; - Byte *bufBase; - ISeqOutStream *outStream; - UInt64 processed; - SRes res; -} CRangeEnc; - -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 -{ - IMatchFinder matchFinder; - void *matchFinderObj; - - #ifndef _7ZIP_ST - Bool mtMode; - CMatchFinderMt matchFinderMt; - #endif - - CMatchFinder matchFinderBase; - - #ifndef _7ZIP_ST - 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; - - int needInit; - - 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; - - #ifndef _7ZIP_ST - /* - 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); - #ifndef _7ZIP_ST - 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) -{ - #ifndef _7ZIP_ST - 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->needInit) - { - p->matchFinder.Init(p->matchFinderObj); - p->needInit = 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); - #ifndef _7ZIP_ST - 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; - - #ifndef _7ZIP_ST - 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, ISeqOutStream *outStream, ISeqInStream *inStream, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - p->matchFinderBase.stream = inStream; - p->needInit = 1; - 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->matchFinderBase.stream = inStream; - p->needInit = 1; - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -} - -static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -{ - p->matchFinderBase.directInput = 1; - p->matchFinderBase.bufferBase = (Byte *)src; - p->matchFinderBase.directInputRem = 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->needInit = 1; - - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -} - -void LzmaEnc_Finish(CLzmaEncHandle pp) -{ - #ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; - if (p->mtMode) - MatchFinderMt_ReleaseStream(&p->matchFinderMt); - #else - pp = pp; - #endif -} - -typedef struct -{ - 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; -} - -static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -{ - SRes res = SZ_OK; - - #ifndef _7ZIP_ST - Byte allocaDummy[0x300]; - int i = 0; - for (i = 0; i < 16; i++) - allocaDummy[i] = (Byte)i; - #endif - - 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(p); - return res; -} - -SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); - return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -} - -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; - - p->rc.outStream = &outStream.funcTable; - res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); - if (res == SZ_OK) - res = LzmaEnc_Encode2(p, progress); - - *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/dep/StormLib/src/lzma/C/LzmaEnc.h b/dep/StormLib/src/lzma/C/LzmaEnc.h deleted file mode 100644 index 200d60eb83c..00000000000 --- a/dep/StormLib/src/lzma/C/LzmaEnc.h +++ /dev/null @@ -1,80 +0,0 @@ -/* LzmaEnc.h -- LZMA Encoder -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_ENC_H -#define __LZMA_ENC_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/dep/StormLib/src/lzma/C/Threads.c b/dep/StormLib/src/lzma/C/Threads.c deleted file mode 100644 index 7af1da2e26e..00000000000 --- a/dep/StormLib/src/lzma/C/Threads.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Threads.c -- multithreading library -2009-09-20 : Igor Pavlov : Public domain */ - -#ifndef _WIN32_WCE -#include <process.h> -#endif - -#include "Threads.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(); } - -WRes HandlePtr_Close(HANDLE *p) -{ - if (*p != NULL) - if (!CloseHandle(*p)) - return GetError(); - *p = NULL; - return 0; -} - -WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); } - -WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) -{ - unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ - *p = - #ifdef UNDER_CE - CreateThread(0, 0, func, param, 0, &threadId); - #else - (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); - #endif - /* maybe we must use errno here, but probably GetLastError() is also OK. */ - return HandleToWRes(*p); -} - -WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) -{ - *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); - return HandleToWRes(*p); -} - -WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } -WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } - -WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } -WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } - - -WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) -{ - *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); - return HandleToWRes(*p); -} - -static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) - { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) - { return Semaphore_Release(p, (LONG)num, NULL); } -WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } - -WRes CriticalSection_Init(CCriticalSection *p) -{ - /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ - #ifdef _MSC_VER - __try - #endif - { - InitializeCriticalSection(p); - /* InitializeCriticalSectionAndSpinCount(p, 0); */ - } - #ifdef _MSC_VER - __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } - #endif - return 0; -} diff --git a/dep/StormLib/src/lzma/C/Threads.h b/dep/StormLib/src/lzma/C/Threads.h deleted file mode 100644 index d0ddd80e227..00000000000 --- a/dep/StormLib/src/lzma/C/Threads.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Threads.h -- multithreading library -2009-03-27 : Igor Pavlov : Public domain */ - -#ifndef __7Z_THREADS_H -#define __7Z_THREADS_H - -#include "Types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -WRes HandlePtr_Close(HANDLE *h); -WRes Handle_WaitObject(HANDLE h); - -typedef HANDLE CThread; -#define Thread_Construct(p) *(p) = NULL -#define Thread_WasCreated(p) (*(p) != NULL) -#define Thread_Close(p) HandlePtr_Close(p) -#define Thread_Wait(p) Handle_WaitObject(*(p)) -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 -typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); -WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param); - -typedef HANDLE CEvent; -typedef CEvent CAutoResetEvent; -typedef CEvent CManualResetEvent; -#define Event_Construct(p) *(p) = NULL -#define Event_IsCreated(p) (*(p) != NULL) -#define Event_Close(p) HandlePtr_Close(p) -#define Event_Wait(p) Handle_WaitObject(*(p)) -WRes Event_Set(CEvent *p); -WRes Event_Reset(CEvent *p); -WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); -WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); - -typedef HANDLE CSemaphore; -#define Semaphore_Construct(p) (*p) = NULL -#define Semaphore_Close(p) HandlePtr_Close(p) -#define Semaphore_Wait(p) Handle_WaitObject(*(p)) -WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); -WRes Semaphore_Release1(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) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/dep/StormLib/src/lzma/C/Types.h b/dep/StormLib/src/lzma/C/Types.h deleted file mode 100644 index 0526cb47b6e..00000000000 --- a/dep/StormLib/src/lzma/C/Types.h +++ /dev/null @@ -1,236 +0,0 @@ -/* Types.h -- Basic types -2010-03-11 : Igor Pavlov : Public domain */ - -#ifndef __7Z_TYPES_H -#define __7Z_TYPES_H - -#include <stddef.h> - -#ifdef _WIN32 -#include <windows.h> -#endif - -#ifndef EXTERN_C_BEGIN -#ifdef __cplusplus -#define EXTERN_C_BEGIN extern "C" { -#define EXTERN_C_END } -#else -#define EXTERN_C_BEGIN -#define EXTERN_C_END -#endif -#endif - -EXTERN_C_BEGIN - -#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 _WIN32 -#define MY_STD_CALL __stdcall -#else -#define MY_STD_CALL -#endif - -#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_FAST_CALL __fastcall - -#else - -#define MY_CDECL -#define MY_FAST_CALL - -#endif - - -/* The following interfaces use first parameter as pointer to structure */ - -typedef struct -{ - Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ -} IByteIn; - -typedef struct -{ - void (*Write)(void *p, Byte b); -} IByteOut; - -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, const 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) - -EXTERN_C_END - -#endif diff --git a/dep/StormLib/src/lzma/info.txt b/dep/StormLib/src/lzma/info.txt deleted file mode 100644 index 4cee86e3542..00000000000 --- a/dep/StormLib/src/lzma/info.txt +++ /dev/null @@ -1 +0,0 @@ -Taken from LZMA SDK v 9.11
\ No newline at end of file diff --git a/dep/StormLib/src/pklib/crc32.c b/dep/StormLib/src/pklib/crc32.c deleted file mode 100644 index cd47b1d4a9b..00000000000 --- a/dep/StormLib/src/pklib/crc32.c +++ /dev/null @@ -1,66 +0,0 @@ -/*****************************************************************************/ -/* crc32.c Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Pkware Data Compression Library Version 1.11 */ -/* Dissassembled method crc32 - cdecl version */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 09.04.03 1.00 Lad The first version of crc32.c */ -/* 02.05.03 1.00 Lad Stress test done */ -/*****************************************************************************/ - -#include "pklib.h" - -static unsigned long crc_table[] = -{ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - - -unsigned long PKEXPORT crc32_pklib(char * buffer, unsigned int * psize, unsigned long * old_crc) -{ - unsigned int size = *psize; - unsigned long ch; - unsigned long crc_value = *old_crc; - - while(size-- != 0) - { - ch = *buffer++ ^ (char)crc_value; - crc_value >>= 8; - - crc_value = crc_table[ch & 0x0FF] ^ crc_value; - } - return crc_value; -} diff --git a/dep/StormLib/src/pklib/explode.c b/dep/StormLib/src/pklib/explode.c deleted file mode 100644 index 0d327a5da84..00000000000 --- a/dep/StormLib/src/pklib/explode.c +++ /dev/null @@ -1,522 +0,0 @@ -/*****************************************************************************/ -/* explode.c Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Implode function of PKWARE Data Compression library */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ -/* 08.04.03 1.01 Lad Renamed to explode.c to be compatible with pklib */ -/* 02.05.03 1.01 Lad Stress test done */ -/* 22.04.10 1.01 Lad Documented */ -/*****************************************************************************/ - -#include <assert.h> -#include <string.h> - -#include "pklib.h" - -#define PKDCL_OK 0 -#define PKDCL_STREAM_END 1 // All data from the input stream is read -#define PKDCL_NEED_DICT 2 // Need more data (dictionary) -#define PKDCL_CONTINUE 10 // Internal flag, not returned to user -#define PKDCL_GET_INPUT 11 // Internal flag, not returned to user - -char CopyrightPkware[] = "PKWARE Data Compression Library for Win32\r\n" - "Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" - "Patent No. 5,051,745\r\n" - "PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" - "Version 1.11\r\n"; - -//----------------------------------------------------------------------------- -// Tables - -static unsigned char DistBits[] = -{ - 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 -}; - -static unsigned char DistCode[] = -{ - 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, - 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, - 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, - 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 -}; - -static unsigned char ExLenBits[] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 -}; - -static unsigned short LenBase[] = -{ - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 -}; - -static unsigned char LenBits[] = -{ - 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 -}; - -static unsigned char LenCode[] = -{ - 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 -}; - -static unsigned char ChBitsAsc[] = -{ - 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, - 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, - 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, - 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, - 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, - 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, - 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D -}; - -static unsigned short ChCodeAsc[] = -{ - 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, - 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, - 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, - 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, - 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, - 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, - 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, - 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, - 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, - 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, - 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, - 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, - 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, - 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, - 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, - 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, - 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, - 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, - 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, - 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, - 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, - 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, - 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, - 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, - 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, - 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, - 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, - 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, - 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, - 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, - 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, - 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 -}; - -//----------------------------------------------------------------------------- -// Local functions - -static void GenDecodeTabs( - unsigned char * positions, // [out] Table of positions - unsigned char * start_indexes, // [in] Table of start indexes - unsigned char * length_bits, // [in] Table of lengths. Each length is stored as number of bits - size_t elements) // [in] Number of elements in start_indexes and length_bits -{ - unsigned long index; - unsigned long length; - size_t i; - - for(i = 0; i < elements; i++) - { - length = 1 << length_bits[i]; // Get the length in bytes - - for(index = start_indexes[i]; index < 0x100; index += length) - { - positions[index] = (unsigned char)i; - } - } -} - -static void GenAscTabs(TDcmpStruct * pWork) -{ - unsigned short * pChCodeAsc = &ChCodeAsc[0xFF]; - unsigned long acc, add; - unsigned short count; - - for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--) - { - unsigned char * pChBitsAsc = pWork->ChBitsAsc + count; - unsigned char bits_asc = *pChBitsAsc; - - if(bits_asc <= 8) - { - add = (1 << bits_asc); - acc = *pChCodeAsc; - - do - { - pWork->offs2C34[acc] = (unsigned char)count; - acc += add; - } - while(acc < 0x100); - } - else if((acc = (*pChCodeAsc & 0xFF)) != 0) - { - pWork->offs2C34[acc] = 0xFF; - - if(*pChCodeAsc & 0x3F) - { - bits_asc -= 4; - *pChBitsAsc = bits_asc; - - add = (1 << bits_asc); - acc = *pChCodeAsc >> 4; - do - { - pWork->offs2D34[acc] = (unsigned char)count; - acc += add; - } - while(acc < 0x100); - } - else - { - bits_asc -= 6; - *pChBitsAsc = bits_asc; - - add = (1 << bits_asc); - acc = *pChCodeAsc >> 6; - do - { - pWork->offs2E34[acc] = (unsigned char)count; - acc += add; - } - while(acc < 0x80); - } - } - else - { - bits_asc -= 8; - *pChBitsAsc = bits_asc; - - add = (1 << bits_asc); - acc = *pChCodeAsc >> 8; - do - { - pWork->offs2EB4[acc] = (unsigned char)count; - acc += add; - } - while(acc < 0x100); - } - } -} - -//----------------------------------------------------------------------------- -// Removes given number of bits in the bit buffer. New bits are reloaded from -// the input buffer, if needed. -// Returns: PKDCL_OK: Operation was successful -// PKDCL_STREAM_END: There are no more bits in the input buffer - -static int WasteBits(TDcmpStruct * pWork, unsigned long nBits) -{ - // If number of bits required is less than number of (bits in the buffer) ? - if(nBits <= pWork->extra_bits) - { - pWork->extra_bits -= nBits; - pWork->bit_buff >>= nBits; - return PKDCL_OK; - } - - // Load input buffer if necessary - pWork->bit_buff >>= pWork->extra_bits; - if(pWork->in_pos == pWork->in_bytes) - { - pWork->in_pos = sizeof(pWork->in_buff); - if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0) - return PKDCL_STREAM_END; - pWork->in_pos = 0; - } - - // Update bit buffer - pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8); - pWork->bit_buff >>= (nBits - pWork->extra_bits); - pWork->extra_bits = (pWork->extra_bits - nBits) + 8; - return PKDCL_OK; -} - -//----------------------------------------------------------------------------- -// Decodes next literal from the input (compressed) data. -// Returns : 0x000: One byte 0x00 -// 0x001: One byte 0x01 -// ... -// 0x0FF: One byte 0xFF -// 0x100: Repetition, length of 0x02 bytes -// 0x101: Repetition, length of 0x03 bytes -// ... -// 0x304: Repetition, length of 0x206 bytes -// 0x305: End of stream -// 0x306: Error - -static unsigned long DecodeLit(TDcmpStruct * pWork) -{ - unsigned long extra_length_bits; // Number of bits of extra literal length - unsigned long length_code; // Length code - unsigned long value; - - // Test the current bit in byte buffer. If is not set, simply return the next 8 bits. - if(pWork->bit_buff & 1) - { - // Remove one bit from the input data - if(WasteBits(pWork, 1)) - return 0x306; - - // The next 8 bits hold the index to the length code table - length_code = pWork->LengthCodes[pWork->bit_buff & 0xFF]; - - // Remove the apropriate number of bits - if(WasteBits(pWork, pWork->LenBits[length_code])) - return 0x306; - - // Are there some extra bits for the obtained length code ? - if((extra_length_bits = pWork->ExLenBits[length_code]) != 0) - { - unsigned long extra_length = pWork->bit_buff & ((1 << extra_length_bits) - 1); - - if(WasteBits(pWork, extra_length_bits)) - { - if((length_code + extra_length) != 0x10E) - return 0x306; - } - length_code = pWork->LenBase[length_code] + extra_length; - } - - // In order to distinguish uncompressed byte from repetition length, - // we have to add 0x100 to the length. - return length_code + 0x100; - } - - // Remove one bit from the input data - if(WasteBits(pWork, 1)) - return 0x306; - - // If the binary compression type, read 8 bits and return them as one byte. - if(pWork->ctype == CMP_BINARY) - { - unsigned long uncompressed_byte = pWork->bit_buff & 0xFF; - - if(WasteBits(pWork, 8)) - return 0x306; - return uncompressed_byte; - } - - // When ASCII compression ... - if(pWork->bit_buff & 0xFF) - { - value = pWork->offs2C34[pWork->bit_buff & 0xFF]; - - if(value == 0xFF) - { - if(pWork->bit_buff & 0x3F) - { - if(WasteBits(pWork, 4)) - return 0x306; - - value = pWork->offs2D34[pWork->bit_buff & 0xFF]; - } - else - { - if(WasteBits(pWork, 6)) - return 0x306; - - value = pWork->offs2E34[pWork->bit_buff & 0x7F]; - } - } - } - else - { - if(WasteBits(pWork, 8)) - return 0x306; - - value = pWork->offs2EB4[pWork->bit_buff & 0xFF]; - } - - return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value; -} - -//----------------------------------------------------------------------------- -// Decodes the distance of the repetition, backwards relative to the -// current output buffer position - -static unsigned long DecodeDist(TDcmpStruct * pWork, unsigned long rep_length) -{ - unsigned long dist_pos_code; // Distance position code - unsigned long dist_pos_bits; // Number of bits of distance position - unsigned long distance; // Distance position - - // Next 2-8 bits in the input buffer is the distance position code - dist_pos_code = pWork->DistPosCodes[pWork->bit_buff & 0xFF]; - dist_pos_bits = pWork->DistBits[dist_pos_code]; - if(WasteBits(pWork, dist_pos_bits)) - return 0; - - if(rep_length == 2) - { - // If the repetition is only 2 bytes length, - // then take 2 bits from the stream in order to get the distance - distance = (dist_pos_code << 2) | (pWork->bit_buff & 0x03); - if(WasteBits(pWork, 2)) - return 0; - } - else - { - // If the repetition is more than 2 bytes length, - // then take "dsize_bits" bits in order to get the distance - distance = (dist_pos_code << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask); - if(WasteBits(pWork, pWork->dsize_bits)) - return 0; - } - return distance + 1; -} - -static unsigned long Expand(TDcmpStruct * pWork) -{ - unsigned long next_literal; // Literal decoded from the compressed data - unsigned long result; // Value to be returned - unsigned int copyBytes; // Number of bytes to copy to the output buffer - - pWork->outputPos = 0x1000; // Initialize output buffer position - - // Decode the next literal from the input data. - // The returned literal can either be an uncompressed byte (next_literal < 0x100) - // or an encoded length of the repeating byte sequence that - // is to be copied to the current buffer position - while((result = next_literal = DecodeLit(pWork)) < 0x305) - { - // If the literal is greater than 0x100, it holds length - // of repeating byte sequence - // literal of 0x100 means repeating sequence of 0x2 bytes - // literal of 0x101 means repeating sequence of 0x3 bytes - // ... - // literal of 0x305 means repeating sequence of 0x207 bytes - if(next_literal >= 0x100) - { - unsigned char * source; - unsigned char * target; - unsigned long rep_length; // Length of the repetition, in bytes - unsigned long minus_dist; // Backward distance to the repetition, relative to the current buffer position - - // Get the length of the repeating sequence. - // Note that the repeating block may overlap the current output position, - // for example if there was a sequence of equal bytes - rep_length = next_literal - 0xFE; - - // Get backward distance to the repetition - if((minus_dist = DecodeDist(pWork, rep_length)) == 0) - { - result = 0x306; - break; - } - - // Target and source pointer - target = &pWork->out_buff[pWork->outputPos]; - source = target - minus_dist; - - // Update buffer output position - pWork->outputPos += rep_length; - - // Copy the repeating sequence - while(rep_length-- > 0) - *target++ = *source++; - } - else - { - pWork->out_buff[pWork->outputPos++] = (unsigned char)next_literal; - } - - // Flush the output buffer, if number of extracted bytes has reached the end - if(pWork->outputPos >= 0x2000) - { - // Copy decompressed data into user buffer - copyBytes = 0x1000; - pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); - - // Now copy the decompressed data to the first half of the buffer. - // This is needed because the decompression might reuse them as repetitions. - // Note that if the output buffer overflowed previously, the extra decompressed bytes - // are stored in "out_buff_overflow", and they will now be - // within decompressed part of the output buffer. - memcpy(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000); - pWork->outputPos -= 0x1000; - } - } - - // Flush any remaining decompressed bytes - copyBytes = pWork->outputPos - 0x1000; - pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); - return result; -} - - -//----------------------------------------------------------------------------- -// Main exploding function. - -unsigned int explode( - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), - void (*write_buf)(char *buf, unsigned int *size, void *param), - char *work_buf, - void *param) -{ - TDcmpStruct * pWork = (TDcmpStruct *)work_buf; - - // Initialize work struct and load compressed data - // Note: The caller must zero the "work_buff" before passing it to explode - pWork->read_buf = read_buf; - pWork->write_buf = write_buf; - pWork->param = param; - pWork->in_pos = sizeof(pWork->in_buff); - pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param); - if(pWork->in_bytes <= 4) - return CMP_BAD_DATA; - - pWork->ctype = pWork->in_buff[0]; // Get the compression type (CMP_BINARY or CMP_ASCII) - pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size - pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer - pWork->extra_bits = 0; // Extra (over 8) bits - pWork->in_pos = 3; // Position in input buffer - - // Test for the valid dictionary size - if(4 > pWork->dsize_bits || pWork->dsize_bits > 6) - return CMP_INVALID_DICTSIZE; - - pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction - - if(pWork->ctype != CMP_BINARY) - { - if(pWork->ctype != CMP_ASCII) - return CMP_INVALID_MODE; - - memcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc)); - GenAscTabs(pWork); - } - - memcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits)); - GenDecodeTabs(pWork->LengthCodes, LenCode, pWork->LenBits, sizeof(pWork->LenBits)); - memcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits)); - memcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase)); - memcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits)); - GenDecodeTabs(pWork->DistPosCodes, DistCode, pWork->DistBits, sizeof(pWork->DistBits)); - if(Expand(pWork) != 0x306) - return CMP_NO_ERROR; - - return CMP_ABORT; -} diff --git a/dep/StormLib/src/pklib/implode.c b/dep/StormLib/src/pklib/implode.c deleted file mode 100644 index 1771b1862a0..00000000000 --- a/dep/StormLib/src/pklib/implode.c +++ /dev/null @@ -1,769 +0,0 @@ -/*****************************************************************************/ -/* implode.c Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Implode function of PKWARE Data Compression library */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 11.04.03 1.00 Lad First version of implode.c */ -/* 02.05.03 1.00 Lad Stress test done */ -/* 22.04.10 1.01 Lad Documented */ -/*****************************************************************************/ - -#include <assert.h> -#include <string.h> - -#include "pklib.h" - -#if ((1200 < _MSC_VER) && (_MSC_VER < 1400)) -#pragma optimize("", off) // Fucking Microsoft VS.NET 2003 compiler !!! (_MSC_VER=1310) -#endif - -//----------------------------------------------------------------------------- -// Defines - -#define MAX_REP_LENGTH 0x204 // The longest allowed repetition - -//----------------------------------------------------------------------------- -// Tables - -static unsigned char DistBits[] = -{ - 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 -}; - -static unsigned char DistCode[] = -{ - 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, - 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, - 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, - 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 -}; - -static unsigned char ExLenBits[] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 -}; - -static unsigned char LenBits[] = -{ - 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 -}; - -static unsigned char LenCode[] = -{ - 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 -}; - -static unsigned char ChBitsAsc[] = -{ - 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, - 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, - 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, - 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, - 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, - 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, - 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D -}; - -static unsigned short ChCodeAsc[] = -{ - 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, - 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, - 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, - 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, - 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, - 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, - 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, - 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, - 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, - 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, - 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, - 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, - 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, - 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, - 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, - 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, - 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, - 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, - 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, - 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, - 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, - 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, - 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, - 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, - 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, - 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, - 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, - 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, - 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, - 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, - 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, - 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 -}; - -//----------------------------------------------------------------------------- -// Macros - -// Macro for calculating hash of the current byte pair. -// Note that most exact byte pair hash would be buffer[0] + buffer[1] << 0x08, -// but even this way gives nice indication of equal byte pairs, with significantly -// smaller size of the array that holds numbers of those hashes -#define BYTE_PAIR_HASH(buffer) ((buffer[0] * 4) + (buffer[1] * 5)) - -//----------------------------------------------------------------------------- -// Local functions - -// Builds the "hash_to_index" table and "pair_hash_offsets" table. -// Every element of "hash_to_index" will contain lowest index to the -// "pair_hash_offsets" table, effectively giving offset of the first -// occurence of the given PAIR_HASH in the input data. -static void SortBuffer(TCmpStruct * pWork, unsigned char * buffer_begin, unsigned char * buffer_end) -{ - unsigned short * phash_to_index; - unsigned char * buffer_ptr; - unsigned short total_sum = 0; - unsigned long byte_pair_hash; // Hash value of the byte pair - unsigned short byte_pair_offs; // Offset of the byte pair, relative to "work_buff" - - // Zero the entire "phash_to_index" table - memset(pWork->phash_to_index, 0, sizeof(pWork->phash_to_index)); - - // Step 1: Count amount of each PAIR_HASH in the input buffer - // The table will look like this: - // offs 0x000: Number of occurences of PAIR_HASH 0 - // offs 0x001: Number of occurences of PAIR_HASH 1 - // ... - // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 (the highest hash value) - for(buffer_ptr = buffer_begin; buffer_ptr < buffer_end; buffer_ptr++) - pWork->phash_to_index[BYTE_PAIR_HASH(buffer_ptr)]++; - - // Step 2: Convert the table to the array of PAIR_HASH amounts. - // Each element contains count of PAIR_HASHes that is less or equal - // to element index - // The table will look like this: - // offs 0x000: Number of occurences of PAIR_HASH 0 or lower - // offs 0x001: Number of occurences of PAIR_HASH 1 or lower - // ... - // offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 or lower - for(phash_to_index = pWork->phash_to_index; phash_to_index < &pWork->phash_to_index_end; phash_to_index++) - { - total_sum = total_sum + phash_to_index[0]; - phash_to_index[0] = total_sum; - } - - // Step 3: Convert the table to the array of indexes. - // Now, each element contains index to the first occurence of given PAIR_HASH - for(buffer_end--; buffer_end >= buffer_begin; buffer_end--) - { - byte_pair_hash = BYTE_PAIR_HASH(buffer_end); - byte_pair_offs = (unsigned short)(buffer_end - pWork->work_buff); - - pWork->phash_to_index[byte_pair_hash]--; - pWork->phash_offs[pWork->phash_to_index[byte_pair_hash]] = byte_pair_offs; - } -} - -static void FlushBuf(TCmpStruct * pWork) -{ - unsigned char save_ch1; - unsigned char save_ch2; - unsigned int size = 0x800; - - pWork->write_buf(pWork->out_buff, &size, pWork->param); - - save_ch1 = pWork->out_buff[0x800]; - save_ch2 = pWork->out_buff[pWork->out_bytes]; - pWork->out_bytes -= 0x800; - - memset(pWork->out_buff, 0, sizeof(pWork->out_buff)); - - if(pWork->out_bytes != 0) - pWork->out_buff[0] = save_ch1; - if(pWork->out_bits != 0) - pWork->out_buff[pWork->out_bytes] = save_ch2; -} - -static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit_buff) -{ - unsigned int out_bits; - - // If more than 8 bits to output, do recursion - if(nbits > 8) - { - OutputBits(pWork, 8, bit_buff); - bit_buff >>= 8; - nbits -= 8; - } - - // Add bits to the last out byte in out_buff; - out_bits = pWork->out_bits; - pWork->out_buff[pWork->out_bytes] |= (unsigned char)(bit_buff << out_bits); - pWork->out_bits += nbits; - - // If 8 or more bits, increment number of bytes - if(pWork->out_bits > 8) - { - pWork->out_bytes++; - bit_buff >>= (8 - out_bits); - - pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff; - pWork->out_bits &= 7; - } - else - { - pWork->out_bits &= 7; - if(pWork->out_bits == 0) - pWork->out_bytes++; - } - - // If there is enough compressed bytes, flush them - if(pWork->out_bytes >= 0x800) - FlushBuf(pWork); -} - -// This function searches for a repetition -// (a previous occurence of the current byte sequence) -// Returns length of the repetition, and stores the backward distance -// to pWork structure. -static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data) -{ - unsigned short * phash_to_index; // Pointer into pWork->phash_to_index table - unsigned short * phash_offs; // Pointer to the table containing offsets of each PAIR_HASH - unsigned char * repetition_limit; // An eventual repetition must be at position below this pointer - unsigned char * prev_repetition; // Pointer to the previous occurence of the current PAIR_HASH - unsigned char * prev_rep_end; // End of the previous repetition - unsigned char * input_data_ptr; - unsigned short phash_offs_index; // Index to the table with PAIR_HASH positions - unsigned short min_phash_offs; // The lowest allowed hash offset - unsigned short offs_in_rep; // Offset within found repetition - unsigned int equal_byte_count; // Number of bytes that are equal to the previous occurence - unsigned int rep_length = 1; // Length of the found repetition - unsigned int rep_length2; // Secondary repetition - unsigned char pre_last_byte; // Last but one byte from a repetion - unsigned short di_val; - - // Calculate the previous position of the PAIR_HASH - phash_to_index = pWork->phash_to_index + BYTE_PAIR_HASH(input_data); - min_phash_offs = (unsigned short)((input_data - pWork->work_buff) - pWork->dsize_bytes + 1); - phash_offs_index = phash_to_index[0]; - - // If the PAIR_HASH offset is below the limit, find a next one - phash_offs = pWork->phash_offs + phash_offs_index; - if(*phash_offs < min_phash_offs) - { - while(*phash_offs < min_phash_offs) - { - phash_offs_index++; - phash_offs++; - } - *phash_to_index = phash_offs_index; - } - - // Get the first location of the PAIR_HASH, - // and thus the first eventual location of byte repetition - phash_offs = pWork->phash_offs + phash_offs_index; - prev_repetition = pWork->work_buff + phash_offs[0]; - repetition_limit = input_data - 1; - - // If the current PAIR_HASH was not encountered before, - // we haven't found a repetition. - if(prev_repetition >= repetition_limit) - return 0; - - // We have found a match of a PAIR_HASH. Now we have to make sure - // that it is also a byte match, because PAIR_HASH is not unique. - // We compare the bytes and count the length of the repetition - input_data_ptr = input_data; - for(;;) - { - // If the first byte of the repetition and the so-far-last byte - // of the repetition are equal, we will compare the blocks. - if(*input_data_ptr == *prev_repetition && input_data_ptr[rep_length-1] == prev_repetition[rep_length-1]) - { - // Skip the current byte - prev_repetition++; - input_data_ptr++; - equal_byte_count = 2; - - // Now count how many more bytes are equal - while(equal_byte_count < MAX_REP_LENGTH) - { - prev_repetition++; - input_data_ptr++; - - // Are the bytes different ? - if(*prev_repetition != *input_data_ptr) - break; - - equal_byte_count++; - } - - // If we found a repetition of at least the same length, take it. - // If there are multiple repetitions in the input buffer, this will - // make sure that we find the most recent one, which in turn allows - // us to store backward length in less amount of bits - input_data_ptr = input_data; - if(equal_byte_count >= rep_length) - { - // Calculate the backward distance of the repetition. - // Note that the distance is stored as decremented by 1 - pWork->distance = (unsigned int)(input_data - prev_repetition + equal_byte_count - 1); - - // Repetitions longer than 10 bytes will be stored in more bits, - // so they need a bit different handling - if((rep_length = equal_byte_count) > 10) - break; - } - } - - // Move forward in the table of PAIR_HASH repetitions. - // There might be a more recent occurence of the same repetition. - phash_offs_index++; - phash_offs++; - prev_repetition = pWork->work_buff + phash_offs[0]; - - // If the next repetition is beyond the minimum allowed repetition, we are done. - if(prev_repetition >= repetition_limit) - { - // A repetition must have at least 2 bytes, otherwise it's not worth it - return (rep_length >= 2) ? rep_length : 0; - } - } - - // If the repetition has max length of 0x204 bytes, we can't go any fuhrter - if(equal_byte_count == MAX_REP_LENGTH) - { - pWork->distance--; - return equal_byte_count; - } - - // Check for possibility of a repetition that occurs at more recent position - phash_offs = pWork->phash_offs + phash_offs_index; - if(pWork->work_buff + phash_offs[1] >= repetition_limit) - return rep_length; - - // - // The following part checks if there isn't a longer repetition at - // a latter offset, that would lead to better compression. - // - // Example of data that can trigger this optimization: - // - // "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQQQQQQQQQQQQ" - // "XYZ" - // "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ"; - // - // Description of data in this buffer - // [0x00] Single byte "E" - // [0x01] Single byte "E" - // [0x02] Repeat 0x1E bytes from [0x00] - // [0x20] Single byte "X" - // [0x21] Single byte "Y" - // [0x22] Single byte "Z" - // [0x23] 17 possible previous repetitions of length at least 0x10 bytes: - // - Repetition of 0x10 bytes from [0x00] "EEEEEEEEEEEEEEEE" - // - Repetition of 0x10 bytes from [0x01] "EEEEEEEEEEEEEEEE" - // - Repetition of 0x10 bytes from [0x02] "EEEEEEEEEEEEEEEE" - // ... - // - Repetition of 0x10 bytes from [0x0F] "EEEEEEEEEEEEEEEE" - // - Repetition of 0x1C bytes from [0x10] "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ" - // The last repetition is the best one. - // - - pWork->offs09BC[0] = 0xFFFF; - pWork->offs09BC[1] = 0x0000; - di_val = 0; - - // Note: I failed to figure out what does the table "offs09BC" mean. - // If anyone has an idea, let me know to zezula_at_volny_dot_cz - for(offs_in_rep = 1; offs_in_rep < rep_length; ) - { - if(input_data[offs_in_rep] != input_data[di_val]) - { - di_val = pWork->offs09BC[di_val]; - if(di_val != 0xFFFF) - continue; - } - pWork->offs09BC[++offs_in_rep] = ++di_val; - } - - // - // Now go through all the repetitions from the first found one - // to the current input data, and check if any of them migh be - // a start of a greater sequence match. - // - - prev_repetition = pWork->work_buff + phash_offs[0]; - prev_rep_end = prev_repetition + rep_length; - rep_length2 = rep_length; - - for(;;) - { - rep_length2 = pWork->offs09BC[rep_length2]; - if(rep_length2 == 0xFFFF) - rep_length2 = 0; - - // Get the pointer to the previous repetition - phash_offs = pWork->phash_offs + phash_offs_index; - - // Skip those repetitions that don't reach the end - // of the first found repetition - do - { - phash_offs++; - phash_offs_index++; - prev_repetition = pWork->work_buff + *phash_offs; - if(prev_repetition >= repetition_limit) - return rep_length; - } - while(prev_repetition + rep_length2 < prev_rep_end); - - // Verify if the last but one byte from the repetition matches - // the last but one byte from the input data. - // If not, find a next repetition - pre_last_byte = input_data[rep_length - 2]; - if(pre_last_byte == prev_repetition[rep_length - 2]) - { - // If the new repetition reaches beyond the end - // of previously found repetition, reset the repetition length to zero. - if(prev_repetition + rep_length2 != prev_rep_end) - { - prev_rep_end = prev_repetition; - rep_length2 = 0; - } - } - else - { - phash_offs = pWork->phash_offs + phash_offs_index; - do - { - phash_offs++; - phash_offs_index++; - prev_repetition = pWork->work_buff + *phash_offs; - if(prev_repetition >= repetition_limit) - return rep_length; - } - while(prev_repetition[rep_length - 2] != pre_last_byte || prev_repetition[0] != input_data[0]); - - // Reset the length of the repetition to 2 bytes only - prev_rep_end = prev_repetition + 2; - rep_length2 = 2; - } - - // Find out how many more characters are equal to the first repetition. - while(*prev_rep_end == input_data[rep_length2]) - { - if(++rep_length2 >= 0x204) - break; - prev_rep_end++; - } - - // Is the newly found repetion at least as long as the previous one ? - if(rep_length2 >= rep_length) - { - // Calculate the distance of the new repetition - pWork->distance = (unsigned int)(input_data - prev_repetition - 1); - if((rep_length = rep_length2) == 0x204) - return rep_length; - - // Update the additional elements in the "offs09BC" table - // to reflect new rep length - while(offs_in_rep < rep_length2) - { - if(input_data[offs_in_rep] != input_data[di_val]) - { - di_val = pWork->offs09BC[di_val]; - if(di_val != 0xFFFF) - continue; - } - pWork->offs09BC[++offs_in_rep] = ++di_val; - } - } - } -} - -static void WriteCmpData(TCmpStruct * pWork) -{ - unsigned char * input_data_end; // Pointer to the end of the input data - unsigned char * input_data = pWork->work_buff + pWork->dsize_bytes + 0x204; - unsigned int input_data_ended = 0; // If 1, then all data from the input stream have been already loaded - unsigned int save_rep_length; // Saved length of current repetition - unsigned int save_distance = 0; // Saved distance of current repetition - unsigned int rep_length; // Length of the found repetition - unsigned int phase = 0; // - - // Store the compression type and dictionary size - pWork->out_buff[0] = (char)pWork->ctype; - pWork->out_buff[1] = (char)pWork->dsize_bits; - pWork->out_bytes = 2; - - // Reset output buffer to zero - memset(&pWork->out_buff[2], 0, sizeof(pWork->out_buff) - 2); - pWork->out_bits = 0; - - while(input_data_ended == 0) - { - unsigned int bytes_to_load = 0x1000; - int total_loaded = 0; - int bytes_loaded; - - // Load the bytes from the input stream, up to 0x1000 bytes - while(bytes_to_load != 0) - { - bytes_loaded = pWork->read_buf((char *)pWork->work_buff + pWork->dsize_bytes + 0x204 + total_loaded, - &bytes_to_load, - pWork->param); - if(bytes_loaded == 0) - { - if(total_loaded == 0 && phase == 0) - goto __Exit; - input_data_ended = 1; - break; - } - else - { - bytes_to_load -= bytes_loaded; - total_loaded += bytes_loaded; - } - } - - input_data_end = pWork->work_buff + pWork->dsize_bytes + total_loaded; - if(input_data_ended) - input_data_end += 0x204; - - // - // Warning: The end of the buffer passed to "SortBuffer" is actually 2 bytes beyond - // valid data. It is questionable if this is actually a bug or not, - // but it might cause the compressed data output to be dependent on random bytes - // that are in the buffer. - // To prevent that, the calling application must always zero the compression - // buffer before passing it to "implode" - // - - // Search the PAIR_HASHes of the loaded blocks. Also, include - // previously compressed data, if any. - switch(phase) - { - case 0: - SortBuffer(pWork, input_data, input_data_end + 1); - phase++; - if(pWork->dsize_bytes != 0x1000) - phase++; - break; - - case 1: - SortBuffer(pWork, input_data - pWork->dsize_bytes + 0x204, input_data_end + 1); - phase++; - break; - - default: - SortBuffer(pWork, input_data - pWork->dsize_bytes, input_data_end + 1); - break; - } - - // Perform the compression of the current block - while(input_data < input_data_end) - { - // Find if the current byte sequence wasn't there before. - rep_length = FindRep(pWork, input_data); - while(rep_length != 0) - { - // If we found repetition of 2 bytes, that is 0x100 or fuhrter back, - // don't bother. Storing the distance of 0x100 bytes would actually - // take more space than storing the 2 bytes as-is. - if(rep_length == 2 && pWork->distance >= 0x100) - break; - - // When we are at the end of the input data, we cannot allow - // the repetition to go past the end of the input data. - if(input_data_ended && input_data + rep_length > input_data_end) - { - // Shorten the repetition length so that it only covers valid data - rep_length = (unsigned long)(input_data_end - input_data); - if(rep_length < 2) - break; - - // If we got repetition of 2 bytes, that is 0x100 or more backward, don't bother - if(rep_length == 2 && pWork->distance >= 0x100) - break; - goto __FlushRepetition; - } - - if(rep_length >= 8 || input_data + 1 >= input_data_end) - goto __FlushRepetition; - - // Try to find better repetition 1 byte later. - // Example: "ARROCKFORT" "AROCKFORT" - // When "input_data" points to the second string, FindRep - // returns the occurence of "AR". But there is longer repetition "ROCKFORT", - // beginning 1 byte after. - save_rep_length = rep_length; - save_distance = pWork->distance; - rep_length = FindRep(pWork, input_data + 1); - - // Only use the new repetition if it's length is greater than the previous one - if(rep_length > save_rep_length) - { - // If the new repetition if only 1 byte better - // and the previous distance is less than 0x80 bytes, use the previous repetition - if(rep_length > save_rep_length + 1 || save_distance > 0x80) - { - // Flush one byte, so that input_data will point to the secondary repetition - OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); - input_data++; - continue; - } - } - - // Revert to the previous repetition - rep_length = save_rep_length; - pWork->distance = save_distance; - - __FlushRepetition: - - OutputBits(pWork, pWork->nChBits[rep_length + 0xFE], pWork->nChCodes[rep_length + 0xFE]); - if(rep_length == 2) - { - OutputBits(pWork, pWork->dist_bits[pWork->distance >> 2], - pWork->dist_codes[pWork->distance >> 2]); - OutputBits(pWork, 2, pWork->distance & 3); - } - else - { - OutputBits(pWork, pWork->dist_bits[pWork->distance >> pWork->dsize_bits], - pWork->dist_codes[pWork->distance >> pWork->dsize_bits]); - OutputBits(pWork, pWork->dsize_bits, pWork->dsize_mask & pWork->distance); - } - - // Move the begin of the input data by the length of the repetition - input_data += rep_length; - goto _00402252; - } - - // If there was no previous repetition for the current position in the input data, - // just output the 9-bit literal for the one character - OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); - input_data++; -_00402252:; - } - - if(input_data_ended == 0) - { - input_data -= 0x1000; - memcpy(pWork->work_buff, pWork->work_buff + 0x1000, pWork->dsize_bytes + 0x204); - } - } - -__Exit: - - // Write the termination literal - OutputBits(pWork, pWork->nChBits[0x305], pWork->nChCodes[0x305]); - if(pWork->out_bits != 0) - pWork->out_bytes++; - pWork->write_buf(pWork->out_buff, &pWork->out_bytes, pWork->param); - return; -} - -//----------------------------------------------------------------------------- -// Main imploding function - -unsigned int PKEXPORT implode( - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), - void (*write_buf)(char *buf, unsigned int *size, void *param), - char *work_buf, - void *param, - unsigned int *type, - unsigned int *dsize) -{ - TCmpStruct * pWork = (TCmpStruct *)work_buf; - unsigned int nChCode; - unsigned int nCount; - unsigned int i; - int nCount2; - - // Fill the work buffer information - // Note: The caller must zero the "work_buff" before passing it to implode - pWork->read_buf = read_buf; - pWork->write_buf = write_buf; - pWork->dsize_bytes = *dsize; - pWork->ctype = *type; - pWork->param = param; - pWork->dsize_bits = 4; - pWork->dsize_mask = 0x0F; - - // Test dictionary size - switch(*dsize) - { - case CMP_IMPLODE_DICT_SIZE3: // 0x1000 bytes - pWork->dsize_bits++; - pWork->dsize_mask |= 0x20; - // No break here !!! - - case CMP_IMPLODE_DICT_SIZE2: // 0x800 bytes - pWork->dsize_bits++; - pWork->dsize_mask |= 0x10; - // No break here !!! - - case CMP_IMPLODE_DICT_SIZE1: // 0x400 - break; - - default: - return CMP_INVALID_DICTSIZE; - } - - // Test the compression type - switch(*type) - { - case CMP_BINARY: // We will compress data with binary compression type - for(nChCode = 0, nCount = 0; nCount < 0x100; nCount++) - { - pWork->nChBits[nCount] = 9; - pWork->nChCodes[nCount] = (unsigned short)nChCode; - nChCode = (nChCode & 0x0000FFFF) + 2; - } - break; - - - case CMP_ASCII: // We will compress data with ASCII compression type - for(nCount = 0; nCount < 0x100; nCount++) - { - pWork->nChBits[nCount] = (unsigned char )(ChBitsAsc[nCount] + 1); - pWork->nChCodes[nCount] = (unsigned short)(ChCodeAsc[nCount] * 2); - } - break; - - default: - return CMP_INVALID_MODE; - } - - for(i = 0; i < 0x10; i++) - { - if(1 << ExLenBits[i]) - { - for(nCount2 = 0; nCount2 < (1 << ExLenBits[i]); nCount2++) - { - pWork->nChBits[nCount] = (unsigned char)(ExLenBits[i] + LenBits[i] + 1); - pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1); - nCount++; - } - } - } - - // Copy the distance codes and distance bits and perform the compression - memcpy(&pWork->dist_codes, DistCode, sizeof(DistCode)); - memcpy(&pWork->dist_bits, DistBits, sizeof(DistBits)); - WriteCmpData(pWork); - return CMP_NO_ERROR; -} diff --git a/dep/StormLib/src/pklib/pklib.h b/dep/StormLib/src/pklib/pklib.h deleted file mode 100644 index f43da153be6..00000000000 --- a/dep/StormLib/src/pklib/pklib.h +++ /dev/null @@ -1,148 +0,0 @@ -/*****************************************************************************/ -/* pklib.h Copyright (c) Ladislav Zezula 2003 */ -/*---------------------------------------------------------------------------*/ -/* Header file for PKWARE Data Compression Library */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 31.03.03 1.00 Lad The first version of pkware.h */ -/*****************************************************************************/ - -#ifndef __PKLIB_H__ -#define __PKLIB_H__ - -#include "../StormPort.h" - -//----------------------------------------------------------------------------- -// Defines - -#define CMP_BINARY 0 // Binary compression -#define CMP_ASCII 1 // Ascii compression - -#define CMP_NO_ERROR 0 -#define CMP_INVALID_DICTSIZE 1 -#define CMP_INVALID_MODE 2 -#define CMP_BAD_DATA 3 -#define CMP_ABORT 4 - -#define CMP_IMPLODE_DICT_SIZE1 1024 // Dictionary size of 1024 -#define CMP_IMPLODE_DICT_SIZE2 2048 // Dictionary size of 2048 -#define CMP_IMPLODE_DICT_SIZE3 4096 // Dictionary size of 4096 - -//----------------------------------------------------------------------------- -// Define calling convention - -#ifndef PKEXPORT -#ifdef WIN32 -#define PKEXPORT __cdecl // Use for normal __cdecl calling -#else -#define PKEXPORT -#endif -#endif - -//----------------------------------------------------------------------------- -// Internal structures - -// Compression structure -typedef struct -{ - unsigned int distance; // 0000: Backward distance of the currently found repetition, decreased by 1 - unsigned int out_bytes; // 0004: # bytes available in out_buff - unsigned int out_bits; // 0008: # of bits available in the last out byte - unsigned int dsize_bits; // 000C: Number of bits needed for dictionary size. 4 = 0x400, 5 = 0x800, 6 = 0x1000 - unsigned int dsize_mask; // 0010: Bit mask for dictionary. 0x0F = 0x400, 0x1F = 0x800, 0x3F = 0x1000 - unsigned int ctype; // 0014: Compression type (CMP_ASCII or CMP_BINARY) - unsigned int dsize_bytes; // 0018: Dictionary size in bytes - unsigned char dist_bits[0x40]; // 001C: Distance bits - unsigned char dist_codes[0x40]; // 005C: Distance codes - unsigned char nChBits[0x306]; // 009C: Table of literal bit lengths to be put to the output stream - unsigned short nChCodes[0x306]; // 03A2: Table of literal codes to be put to the output stream - unsigned short offs09AE; // 09AE: - - void * param; // 09B0: User parameter - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 9B4 - void (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8 - - unsigned short offs09BC[0x204]; // 09BC: - unsigned long offs0DC4; // 0DC4: - unsigned short phash_to_index[0x900]; // 0DC8: Array of indexes (one for each PAIR_HASH) to the "pair_hash_offsets" table - unsigned short phash_to_index_end; // 1FC8: End marker for "phash_to_index" table - char out_buff[0x802]; // 1FCA: Compressed data - unsigned char work_buff[0x2204]; // 27CC: Work buffer - // + DICT_OFFSET => Dictionary - // + UNCMP_OFFSET => Uncompressed data - unsigned short phash_offs[0x2204]; // 49D0: Table of offsets for each PAIR_HASH -} TCmpStruct; - -#define CMP_BUFFER_SIZE sizeof(TCmpStruct) // Size of compression structure. - // Defined as 36312 in pkware header file - - -// Decompression structure -typedef struct -{ - unsigned long offs0000; // 0000 - unsigned long ctype; // 0004: Compression type (CMP_BINARY or CMP_ASCII) - unsigned long outputPos; // 0008: Position in output buffer - unsigned long dsize_bits; // 000C: Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) - unsigned long dsize_mask; // 0010: Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) - unsigned long bit_buff; // 0014: 16-bit buffer for processing input data - unsigned long extra_bits; // 0018: Number of extra (above 8) bits in bit buffer - unsigned int in_pos; // 001C: Position in in_buff - unsigned long in_bytes; // 0020: Number of bytes in input buffer - void * param; // 0024: Custom parameter - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // Pointer to function that reads data from the input stream - void (*write_buf)(char *buf, unsigned int *size, void *param);// Pointer to function that writes data to the output stream - - unsigned char out_buff[0x2204]; // 0030: Output circle buffer. - // 0x0000 - 0x0FFF: Previous uncompressed data, kept for repetitions - // 0x1000 - 0x1FFF: Currently decompressed data - // 0x2000 - 0x2203: Reserve space for the longest possible repetition - unsigned char in_buff[0x800]; // 2234: Buffer for data to be decompressed - unsigned char DistPosCodes[0x100]; // 2A34: Table of distance position codes - unsigned char LengthCodes[0x100]; // 2B34: Table of length codes - unsigned char offs2C34[0x100]; // 2C34: Buffer for - unsigned char offs2D34[0x100]; // 2D34: Buffer for - unsigned char offs2E34[0x80]; // 2EB4: Buffer for - unsigned char offs2EB4[0x100]; // 2EB4: Buffer for - unsigned char ChBitsAsc[0x100]; // 2FB4: Buffer for - unsigned char DistBits[0x40]; // 30B4: Numbers of bytes to skip copied block length - unsigned char LenBits[0x10]; // 30F4: Numbers of bits for skip copied block length - unsigned char ExLenBits[0x10]; // 3104: Number of valid bits for copied block - unsigned short LenBase[0x10]; // 3114: Buffer for -} TDcmpStruct; - -#define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompression structure - // Defined as 12596 in pkware headers - -//----------------------------------------------------------------------------- -// Public functions - -#ifdef __cplusplus - extern "C" { -#endif - -unsigned int PKEXPORT implode( - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), - void (*write_buf)(char *buf, unsigned int *size, void *param), - char *work_buf, - void *param, - unsigned int *type, - unsigned int *dsize); - - -unsigned int PKEXPORT explode( - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), - void (*write_buf)(char *buf, unsigned int *size, void *param), - char *work_buf, - void *param); - -// The original name "crc32" was changed to "crc32pk" due -// to compatibility with zlib -unsigned long PKEXPORT crc32_pklib(char *buffer, unsigned int *size, unsigned long *old_crc); - -#ifdef __cplusplus - } // End of 'extern "C"' declaration -#endif - -#endif // __PKLIB_H__ diff --git a/dep/StormLib/src/sparse/sparse.cpp b/dep/StormLib/src/sparse/sparse.cpp deleted file mode 100644 index 6df7021fc8a..00000000000 --- a/dep/StormLib/src/sparse/sparse.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/*****************************************************************************/ -/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */ -/*---------------------------------------------------------------------------*/ -/* This module contains Huffmann (de)compression methods */ -/* */ -/* Authors : Ladislav Zezula (ladik.zezula.net) */ -/* ShadowFlare (BlakFlare@hotmail.com) */ -/* */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */ -/* 03.05.03 1.00 Lad Added compression methods */ -/* 19.11.03 1.01 Dan Big endian handling */ -/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */ -/*****************************************************************************/ - -#include <assert.h> -#include <string.h> - -#include "sparse.h" - -//----------------------------------------------------------------------------- -// Public functions - -void CompressSparse(unsigned char * pbOutBuffer, int * pcbOutBuffer, unsigned char * pbInBuffer, int cbInBuffer) -{ - unsigned char * pbOutBufferEnd = pbOutBuffer + *pcbOutBuffer; - unsigned char * pbInBufferEnd = pbInBuffer + cbInBuffer; - unsigned char * pbLastNonZero = pbInBuffer; - unsigned char * pbOutBuffer0 = pbOutBuffer; - unsigned char * pbInBuffPtr = pbInBuffer; - size_t NumberOfNonZeros; - size_t NumberOfZeros; - - // There must be at least 4 bytes of free space in the output buffer now - if((pbInBuffer + 4) >= pbInBufferEnd) - return; - - // Put the original data length (in little endian) - *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x18); - *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x10); - *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x08); - *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x00); - - // If there is at least 3 bytes in the input buffer, do this loop - while(pbInBuffer < (pbInBufferEnd - 3)) - { - // Reset the zero count and frontal pointer - pbLastNonZero = pbInBuffer; - pbInBuffPtr = pbInBuffer; - NumberOfZeros = 0; - - if(pbInBuffPtr < pbInBufferEnd) - { - do - { - // Count number of zeros - if(*pbInBuffPtr == 0) - { - NumberOfZeros++; - } - else - { - // Were there at least 3 zeros before? If yes, we need to flush the data - if(NumberOfZeros >= 3) - break; - pbLastNonZero = pbInBuffPtr + 1; - NumberOfZeros = 0; - } - } - while(++pbInBuffPtr < pbInBufferEnd); - } - - // Get number of nonzeros that we found so far and flush them - NumberOfNonZeros = pbLastNonZero - pbInBuffer; - if(NumberOfNonZeros != 0) - { - // Process blocks that are longer than 0x81 nonzero bytes - while(NumberOfNonZeros > 0x81) - { - // Verify if we still have enough space in output buffer - if((pbOutBuffer + 0x81) >= pbOutBufferEnd) - return; - - // Put marker that means "0x80 of nonzeros" - *pbOutBuffer++ = 0xFF; - memcpy(pbOutBuffer, pbInBuffer, 0x80); - - // Adjust counter of nonzeros and both pointers - NumberOfNonZeros -= 0x80; - pbOutBuffer += 0x80; - pbInBuffer += 0x80; - } - - // BUGBUG: The following code will be triggered if the NumberOfNonZeros - // was 0x81 before. It will copy just one byte. This seems like a bug to me, - // but since I want StormLib to be exact like Blizzard code is, I will keep - // it that way here - if(NumberOfNonZeros > 0x80) - { - // Verify if we still have enough space in output buffer - if((pbOutBuffer + 2) >= pbOutBufferEnd) - return; - - // Put marker that means "1 nonzero byte" - *pbOutBuffer++ = 0x80; - memcpy(pbOutBuffer, pbInBuffer, 1); - - // Adjust counter of nonzeros and both pointers - NumberOfNonZeros--; - pbOutBuffer++; - pbInBuffer++; - } - - // If there is 1 nonzero or more, put the block - if(NumberOfNonZeros >= 0x01) - { - // Verify if we still have enough space in output buffer - if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd) - return; - - // Put marker that means "Several nonzero bytes" - *pbOutBuffer++ = (unsigned char)(0x80 | (NumberOfNonZeros - 1)); - memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros); - - // Adjust pointers - pbOutBuffer += NumberOfNonZeros; - pbInBuffer += NumberOfNonZeros; - } - else - { - // Verify if we still have enough space in output buffer - if((pbOutBuffer + 2) >= pbOutBufferEnd) - return; - - // Put marker that means "1 nonzero byte" - *pbOutBuffer++ = 0x80; - memcpy(pbOutBuffer, pbInBuffer, 1); - - // Adjust pointers - pbOutBuffer++; - pbInBuffer++; - } - } - - // Now flush all zero bytes - while(NumberOfZeros > 0x85) - { - // Do we have at least 2 bytes in the output buffer ? - if((pbOutBuffer + 1) >= pbOutBufferEnd) - return; - - // Put marker that means "0x82 zeros" - *pbOutBuffer++ = 0x7F; - - // Adjust zero counter and input pointer - NumberOfZeros -= 0x82; - pbInBuffer += 0x82; - } - - // If we got more than 0x82 zeros, flush 3 of them now - if(NumberOfZeros > 0x82) - { - // Do we have at least 2 bytes in the output buffer ? - if((pbOutBuffer + 1) >= pbOutBufferEnd) - return; - - // Put marker that means "0x03 zeros" - *pbOutBuffer++ = 0; - - // Adjust zero counter and input pointer - NumberOfZeros -= 0x03; - pbInBuffer += 0x03; - } - - // Is there at least three zeros ? - if(NumberOfZeros >= 3) - { - // Do we have at least 2 bytes in the output buffer ? - if((pbOutBuffer + 1) >= pbOutBufferEnd) - return; - - // Put marker that means "Several zeros" - *pbOutBuffer++ = (unsigned char)(NumberOfZeros - 3); - - // Adjust pointer - pbInBuffer += NumberOfZeros; - } - } - - // Flush last three bytes - if(pbInBuffer < pbInBufferEnd) - { - pbInBuffPtr = pbInBuffer; - - for(;;) - { - if(*pbInBuffPtr++ != 0) - { - // Get number of bytes remaining - NumberOfNonZeros = (pbInBufferEnd - pbInBuffer); - - // Not enough space in the output buffer ==> exit - if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd) - return; - - // Terminate with a marker that means "0x80 of nonzeros" - *pbOutBuffer++ = 0xFF; - memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros); - - // Adjust pointer - pbOutBuffer += NumberOfNonZeros; - break; - } - else - { - // Is there are more chars in the input buffer - if(pbInBuffPtr < pbInBufferEnd) - continue; - - // If the compression will not compress it by even 1 byte, do nothing - if((pbOutBuffer + 1) >= pbOutBufferEnd) - return; - - // Terminate with a chunk that means "0x82 of zeros" - *pbOutBuffer++ = 0x7F; - break; - } - } - } - - // Out the length of the output buffer - *pcbOutBuffer = (int)(pbOutBuffer - pbOutBuffer0); -} - -int DecompressSparse(unsigned char * pbOutBuffer, int * pcbOutBuffer, unsigned char * pbInBuffer, int cbInBuffer) -{ - unsigned char * pbInBufferEnd = pbInBuffer + cbInBuffer; - unsigned int cbChunkSize; - unsigned int cbOutBuffer = 0; - unsigned int OneByte; - - // Don't decompress anything that is shorter than 5 bytes - if(cbInBuffer < 5) - return 0; - - // Get the 32-bits from the input stream - OneByte = *pbInBuffer++; - cbOutBuffer |= (OneByte << 0x18); - OneByte = *pbInBuffer++; - cbOutBuffer |= (OneByte << 0x10); - OneByte = *pbInBuffer++; - cbOutBuffer |= (OneByte << 0x08); - OneByte = *pbInBuffer++; - cbOutBuffer |= (OneByte << 0x00); - - // Verify the size of the stream against the output buffer size - if(cbOutBuffer > *pcbOutBuffer) - return 0; - - // Put the output size to the buffer - *pcbOutBuffer = cbOutBuffer; - - // Process the input buffer - while(pbInBuffer < pbInBufferEnd) - { - // Get (next) byte from the stream - OneByte = *pbInBuffer++; - - // If highest bit, it means that that normal data follow - if(OneByte & 0x80) - { - cbChunkSize = (OneByte & 0x7F) + 1; - cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer; - memcpy(pbOutBuffer, pbInBuffer, cbChunkSize); - pbInBuffer += cbChunkSize; - } - else - { - cbChunkSize = (OneByte & 0x7F) + 3; - cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer; - memset(pbOutBuffer, 0, cbChunkSize); - } - - // Increment output buffer pointer - pbOutBuffer += cbChunkSize; - cbOutBuffer -= cbChunkSize; - } - - return 1; -} diff --git a/dep/StormLib/src/sparse/sparse.h b/dep/StormLib/src/sparse/sparse.h deleted file mode 100644 index 032395f0b94..00000000000 --- a/dep/StormLib/src/sparse/sparse.h +++ /dev/null @@ -1,19 +0,0 @@ -/*****************************************************************************/ -/* sparse.h Copyright (c) Ladislav Zezula 2010 */ -/*---------------------------------------------------------------------------*/ -/* implementation of Sparse compression, used in Starcraft II */ -/*---------------------------------------------------------------------------*/ -/* Date Ver Who Comment */ -/* -------- ---- --- ------- */ -/* 05.03.10 1.00 Lad The first version of sparse.h */ -/*****************************************************************************/ - -#ifndef __SPARSE_H__ -#define __SPARSE_H__ - -#include "../StormPort.h" - -void CompressSparse(unsigned char * pbOutBuffer, int * pcbOutLength, unsigned char * pbInBuffer, int cbInLength); -int DecompressSparse(unsigned char * pbOutBuffer, int * pcbOutLength, unsigned char * pbInBuffer, int cbInLength); - -#endif // __SPARSE_H__ diff --git a/dep/StormLib/src/zlib/adler32.c b/dep/StormLib/src/zlib/adler32.c deleted file mode 100644 index 007ba26277c..00000000000 --- a/dep/StormLib/src/zlib/adler32.c +++ /dev/null @@ -1,149 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware */ -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD4(a) \ - do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD4(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 > BASE) sum1 -= BASE; - if (sum1 > BASE) sum1 -= BASE; - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 > BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} diff --git a/dep/StormLib/src/zlib/compress2.c b/dep/StormLib/src/zlib/compress2.c deleted file mode 100644 index df04f0148e6..00000000000 --- a/dep/StormLib/src/zlib/compress2.c +++ /dev/null @@ -1,79 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; -} diff --git a/dep/StormLib/src/zlib/crc32.c b/dep/StormLib/src/zlib/crc32.c deleted file mode 100644 index f658a9ef55e..00000000000 --- a/dep/StormLib/src/zlib/crc32.c +++ /dev/null @@ -1,423 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - */ - -#ifdef MAKECRCH -# include <stdio.h> -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include <limits.h> -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - unsigned long c; - int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const unsigned long FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case */ - if (len2 == 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320L; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} diff --git a/dep/StormLib/src/zlib/crc32.h b/dep/StormLib/src/zlib/crc32.h deleted file mode 100644 index 8053b6117c0..00000000000 --- a/dep/StormLib/src/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const unsigned long FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/dep/StormLib/src/zlib/deflate.c b/dep/StormLib/src/zlib/deflate.c deleted file mode 100644 index 29ce1f64a57..00000000000 --- a/dep/StormLib/src/zlib/deflate.c +++ /dev/null @@ -1,1736 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifndef FASTEST -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif -#endif -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); - dictionary += dictLength - length; /* use the tail of the dictionary */ - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds - * for every combination of windowBits and memLevel, as well as wrap. - * But even the conservative upper bound of about 14% expansion does not - * seem onerous for output buffer allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong destLen; - - /* conservative upper bound */ - destLen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; - - /* if can't get parameters, return conservative bound */ - if (strm == Z_NULL || strm->state == Z_NULL) - return destLen; - - /* if not default parameters, return conservative bound */ - s = strm->state; - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return destLen; - - /* default settings: return tight bound for that case */ - return compressBound(sourceLen); -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ -#endif /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for level == 1 or strategy == Z_RLE only - */ -local uInt longest_match_fast(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - /* %%% avoid this when Z_RLE */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ -#ifdef FASTEST - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { - s->match_length = longest_match_fast (s, hash_head); - } -#else - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } -#endif - /* longest_match() or longest_match_fast() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } - /* longest_match() or longest_match_fast() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ - -#if 0 -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt run; /* length of run */ - uInt max; /* maximum length of run */ - uInt prev; /* byte at distance one to match */ - Bytef *scan; /* scan for end of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. - */ - if (s->lookahead < MAX_MATCH) { - fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - run = 0; - if (s->strstart > 0) { /* if there is a previous byte, that is */ - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; - scan = s->window + s->strstart - 1; - prev = *scan++; - do { - if (*scan++ != prev) - break; - } while (++run < max); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (run >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, run); - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); - s->lookahead -= run; - s->strstart += run; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif diff --git a/dep/StormLib/src/zlib/deflate.h b/dep/StormLib/src/zlib/deflate.h deleted file mode 100644 index 05a5ab3a2c1..00000000000 --- a/dep/StormLib/src/zlib/deflate.h +++ /dev/null @@ -1,331 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2004 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch _length_code[]; - extern uch _dist_code[]; -#else - extern const uch _length_code[]; - extern const uch _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/dep/StormLib/src/zlib/inffast.c b/dep/StormLib/src/zlib/inffast.c deleted file mode 100644 index bbee92ed1e6..00000000000 --- a/dep/StormLib/src/zlib/inffast.c +++ /dev/null @@ -1,318 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code this; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - write = state->write; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = lcode[hold & lmask]; - dolen: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op == 0) { /* literal */ - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - PUP(out) = (unsigned char)(this.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = dcode[hold & dmask]; - dodist: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - from = window - OFF; - if (write == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (write < op) { /* wrap around window */ - from += wsize + write - op; - op -= write; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (write < len) { /* some from start of window */ - op = write; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += write - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - this = dcode[this.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - this = lcode[this.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and write == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/dep/StormLib/src/zlib/inffast.h b/dep/StormLib/src/zlib/inffast.h deleted file mode 100644 index 1e88d2d97b5..00000000000 --- a/dep/StormLib/src/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/dep/StormLib/src/zlib/inffixed.h b/dep/StormLib/src/zlib/inffixed.h deleted file mode 100644 index 75ed4b5978d..00000000000 --- a/dep/StormLib/src/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/dep/StormLib/src/zlib/inflate.c b/dep/StormLib/src/zlib/inflate.c deleted file mode 100644 index 792fdee8e9c..00000000000 --- a/dep/StormLib/src/zlib/inflate.c +++ /dev/null @@ -1,1368 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common write == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->write = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - if (windowBits < 0) { - state->wrap = 0; - windowBits = -windowBits; - } - else { - state->wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) windowBits &= 15; -#endif - } - if (windowBits < 8 || windowBits > 15) { - ZFREE(strm, state); - strm->state = Z_NULL; - return Z_STREAM_ERROR; - } - state->wbits = (unsigned)windowBits; - state->window = Z_NULL; - return inflateReset(strm); -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include <stdio.h> - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->write = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->write = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->write; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->write, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->write = copy; - state->whave = state->wsize; - } - else { - state->write += dist; - if (state->write == state->wsize) state->write = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; - } - else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - break; - } - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.op && (this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - if ((int)(this.op) == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - state->mode = LIT; - break; - } - if (this.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - if (this.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(this.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->mode = DIST; - case DIST: - for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if ((this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - if (this.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)this.val; - state->extra = (unsigned)(this.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - if (state->offset > state->whave + out - left) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->write) { - copy -= state->write; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->write - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} diff --git a/dep/StormLib/src/zlib/inflate.h b/dep/StormLib/src/zlib/inflate.h deleted file mode 100644 index 07bd3e78a7c..00000000000 --- a/dep/StormLib/src/zlib/inflate.h +++ /dev/null @@ -1,115 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN, /* i: waiting for length/lit code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to the BAD or MEM mode -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME - NAME -> COMMENT -> HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - Read deflate blocks: - TYPE -> STORED or TABLE or LEN or CHECK - STORED -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN - Read deflate codes: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 7K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ -}; diff --git a/dep/StormLib/src/zlib/inftrees.c b/dep/StormLib/src/zlib/inftrees.c deleted file mode 100644 index 8a9c13ff03d..00000000000 --- a/dep/StormLib/src/zlib/inftrees.c +++ /dev/null @@ -1,329 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code this; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)1; - this.val = (unsigned short)0; - *(*table)++ = this; /* make a table to force an error */ - *(*table)++ = this; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min <= MAXBITS; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked when a LENS table is being made - against the space in *table, ENOUGH, minus the maximum space needed by - the worst case distance code, MAXD. This should never happen, but the - sufficiency of ENOUGH has not been proven exhaustively, hence the check. - This assumes that when type == LENS, bits == 9. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - this.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - this.op = (unsigned char)0; - this.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - this.op = (unsigned char)(extra[work[sym]]); - this.val = base[work[sym]]; - } - else { - this.op = (unsigned char)(32 + 64); /* end of block */ - this.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = this; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)(len - drop); - this.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - this.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = this; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/dep/StormLib/src/zlib/inftrees.h b/dep/StormLib/src/zlib/inftrees.h deleted file mode 100644 index b1104c87e76..00000000000 --- a/dep/StormLib/src/zlib/inftrees.h +++ /dev/null @@ -1,55 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1444 code structures (852 for length/literals - and 592 for distances, the latter actually the result of an - exhaustive search). The true maximum is not known, but the value - below is more than safe. */ -#define ENOUGH 2048 -#define MAXD 592 - -/* Type of code to build for inftable() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -extern int inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/dep/StormLib/src/zlib/trees.c b/dep/StormLib/src/zlib/trees.c deleted file mode 100644 index 395e4e16814..00000000000 --- a/dep/StormLib/src/zlib/trees.c +++ /dev/null @@ -1,1219 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2005 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include <ctype.h> -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1<<extra_lbits[code]); n++) { - _length_code[length++] = (uch)code; - } - } - Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length-1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<<extra_dbits[code]); n++) { - _dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include <stdio.h> -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void _tr_flush_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) - set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (eof) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to BINARY or TEXT, using a crude approximation: - * set it to Z_TEXT if all symbols are either printable characters (33 to 255) - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local void set_data_type(s) - deflate_state *s; -{ - int n; - - for (n = 0; n < 9; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - if (n == 9) - for (n = 14; n < 32; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/dep/StormLib/src/zlib/trees.h b/dep/StormLib/src/zlib/trees.h deleted file mode 100644 index 72facf900f7..00000000000 --- a/dep/StormLib/src/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/dep/StormLib/src/zlib/zconf.h b/dep/StormLib/src/zlib/zconf.h deleted file mode 100644 index 03a9431c8be..00000000000 --- a/dep/StormLib/src/zlib/zconf.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include <windows.h> - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include <sys/types.h> /* for off_t */ -# include <unistd.h> /* for SEEK_* and off_t */ -# ifdef VMS -# include <unixio.h> /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/dep/StormLib/src/zlib/zlib.h b/dep/StormLib/src/zlib/zlib.h deleted file mode 100644 index 022817927ce..00000000000 --- a/dep/StormLib/src/zlib/zlib.h +++ /dev/null @@ -1,1357 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 - - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - -typedef voidp gzFile; - -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns 1 if file is being read directly without decompression, otherwise - zero. -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); -/* - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - -/* - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/dep/StormLib/src/zlib/zutil.c b/dep/StormLib/src/zlib/zutil.c deleted file mode 100644 index d55f5948a37..00000000000 --- a/dep/StormLib/src/zlib/zutil.c +++ /dev/null @@ -1,318 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch (sizeof(uInt)) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch (sizeof(uLong)) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch (sizeof(voidpf)) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch (sizeof(z_off_t)) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int z_verbose = verbose; - -void z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ diff --git a/dep/StormLib/src/zlib/zutil.h b/dep/StormLib/src/zlib/zutil.h deleted file mode 100644 index b7d5eff81b6..00000000000 --- a/dep/StormLib/src/zlib/zutil.h +++ /dev/null @@ -1,269 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#define ZLIB_INTERNAL -#include "zlib.h" - -#ifdef STDC -# ifndef _WIN32_WCE -# include <stddef.h> -# endif -# include <string.h> -# include <stdlib.h> -#endif -#ifdef NO_ERRNO_H -# ifdef _WIN32_WCE - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. We rename it to - * avoid conflict with other libraries that use the same workaround. - */ -# define errno z_errno -# endif - extern int errno; -#else -# ifndef _WIN32_WCE -# include <errno.h> -# endif -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include <alloc.h> -# endif -# else /* MSC or DJGPP */ -# include <malloc.h> -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# ifdef M_I86 - #include <malloc.h> -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include <unix.h> /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# define vsnprintf _vsnprintf -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif -#ifdef VMS -# define NO_vsnprintf -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include <stdio.h> - extern int z_verbose; - extern void z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ |