Merge remote-tracking branch 'origin/master' into materials

This commit is contained in:
Magnus Norddahl 2018-01-23 20:16:32 +01:00
commit c7ec489846
68 changed files with 2248 additions and 945 deletions

View file

@ -1,5 +1,5 @@
/* 7z.h -- 7z interface /* 7z.h -- 7z interface
2015-11-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_H #ifndef __7Z_H
#define __7Z_H #define __7Z_H
@ -98,7 +98,7 @@ UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos, ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain); ISzAllocPtr allocMain);
typedef struct typedef struct
{ {
@ -131,7 +131,7 @@ typedef struct
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i]) #define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
void SzArEx_Init(CSzArEx *p); void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
@ -179,8 +179,8 @@ SRes SzArEx_Extract(
size_t *outBufferSize, /* buffer size for output buffer */ size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */ size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */ size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain, ISzAllocPtr allocMain,
ISzAlloc *allocTemp); ISzAllocPtr allocTemp);
/* /*
@ -195,7 +195,7 @@ SZ_ERROR_FAIL
*/ */
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp); ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
EXTERN_C_END EXTERN_C_END

View file

@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions /* 7zArcIn.c -- 7z Input functions
2015-11-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -11,7 +11,7 @@
#include "CpuArch.h" #include "CpuArch.h"
#define MY_ALLOC(T, p, size, alloc) { \ #define MY_ALLOC(T, p, size, alloc) { \
if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } #define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
@ -60,7 +60,7 @@ const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } #define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc) static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc)
{ {
if (num == 0) if (num == 0)
{ {
@ -75,18 +75,18 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
return SZ_OK; return SZ_OK;
} }
void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc) void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc)
{ {
IAlloc_Free(alloc, p->Defs); p->Defs = NULL; ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
IAlloc_Free(alloc, p->Vals); p->Vals = NULL; ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
} }
#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } #define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc) void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc)
{ {
IAlloc_Free(alloc, p->Defs); p->Defs = NULL; ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
IAlloc_Free(alloc, p->Vals); p->Vals = NULL; ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
} }
@ -107,18 +107,18 @@ static void SzAr_Init(CSzAr *p)
p->CodersData = NULL; p->CodersData = NULL;
} }
static void SzAr_Free(CSzAr *p, ISzAlloc *alloc) static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc)
{ {
IAlloc_Free(alloc, p->PackPositions); ISzAlloc_Free(alloc, p->PackPositions);
SzBitUi32s_Free(&p->FolderCRCs, alloc); SzBitUi32s_Free(&p->FolderCRCs, alloc);
IAlloc_Free(alloc, p->FoCodersOffsets); ISzAlloc_Free(alloc, p->FoCodersOffsets);
IAlloc_Free(alloc, p->FoStartPackStreamIndex); ISzAlloc_Free(alloc, p->FoStartPackStreamIndex);
IAlloc_Free(alloc, p->FoToCoderUnpackSizes); ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes);
IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex); ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
IAlloc_Free(alloc, p->CoderUnpackSizes); ISzAlloc_Free(alloc, p->CoderUnpackSizes);
IAlloc_Free(alloc, p->CodersData); ISzAlloc_Free(alloc, p->CodersData);
SzAr_Init(p); SzAr_Init(p);
} }
@ -147,16 +147,16 @@ void SzArEx_Init(CSzArEx *p)
SzBitUi64s_Init(&p->CTime); SzBitUi64s_Init(&p->CTime);
} }
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc)
{ {
IAlloc_Free(alloc, p->UnpackPositions); ISzAlloc_Free(alloc, p->UnpackPositions);
IAlloc_Free(alloc, p->IsDirs); ISzAlloc_Free(alloc, p->IsDirs);
IAlloc_Free(alloc, p->FolderToFile); ISzAlloc_Free(alloc, p->FolderToFile);
IAlloc_Free(alloc, p->FileToFolder); ISzAlloc_Free(alloc, p->FileToFolder);
IAlloc_Free(alloc, p->FileNameOffsets); ISzAlloc_Free(alloc, p->FileNameOffsets);
IAlloc_Free(alloc, p->FileNames); ISzAlloc_Free(alloc, p->FileNames);
SzBitUi32s_Free(&p->CRCs, alloc); SzBitUi32s_Free(&p->CRCs, alloc);
SzBitUi32s_Free(&p->Attribs, alloc); SzBitUi32s_Free(&p->Attribs, alloc);
@ -305,7 +305,7 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
return sum; return sum;
} }
static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc) static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc)
{ {
Byte allAreDefined; Byte allAreDefined;
Byte *v2; Byte *v2;
@ -328,12 +328,12 @@ static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I
{ {
unsigned numBits = (unsigned)numItems & 7; unsigned numBits = (unsigned)numItems & 7;
if (numBits != 0) if (numBits != 0)
v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
} }
return SZ_OK; return SZ_OK;
} }
static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc) static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
{ {
UInt32 i; UInt32 i;
CSzData sd; CSzData sd;
@ -354,7 +354,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
return SZ_OK; return SZ_OK;
} }
static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc) static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
{ {
SzBitUi32s_Free(crcs, alloc); SzBitUi32s_Free(crcs, alloc);
RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)); RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
@ -380,7 +380,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
return SZ_OK; return SZ_OK;
} }
static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc) static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc)
{ {
RINOK(SzReadNumber32(sd, &p->NumPackStreams)); RINOK(SzReadNumber32(sd, &p->NumPackStreams));
@ -635,7 +635,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
CSzData *sd2, CSzData *sd2,
UInt32 numFoldersMax, UInt32 numFoldersMax,
const CBuf *tempBufs, UInt32 numTempBufs, const CBuf *tempBufs, UInt32 numTempBufs,
ISzAlloc *alloc) ISzAllocPtr alloc)
{ {
CSzData sd; CSzData sd;
@ -788,13 +788,9 @@ static SRes ReadUnpackInfo(CSzAr *p,
numCodersOutStreams += numCoders; numCodersOutStreams += numCoders;
if (numCodersOutStreams < numCoders) if (numCodersOutStreams < numCoders)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (numPackStreams > p->NumPackStreams - packStreamIndex)
packStreamIndex += numPackStreams;
if (packStreamIndex < numPackStreams)
return SZ_ERROR_UNSUPPORTED;
if (packStreamIndex > p->NumPackStreams)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
packStreamIndex += numPackStreams;
} }
} }
@ -938,7 +934,7 @@ static SRes SzReadStreamsInfo(CSzAr *p,
UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
UInt64 *dataOffset, UInt64 *dataOffset,
CSubStreamInfo *ssi, CSubStreamInfo *ssi,
ISzAlloc *alloc) ISzAllocPtr alloc)
{ {
UInt64 type; UInt64 type;
@ -980,7 +976,7 @@ static SRes SzReadAndDecodePackedStreams(
UInt32 numFoldersMax, UInt32 numFoldersMax,
UInt64 baseOffset, UInt64 baseOffset,
CSzAr *p, CSzAr *p,
ISzAlloc *allocTemp) ISzAllocPtr allocTemp)
{ {
UInt64 dataStartPos; UInt64 dataStartPos;
UInt32 fo; UInt32 fo;
@ -1047,7 +1043,7 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
CSzData *sd2, CSzData *sd2,
const CBuf *tempBufs, UInt32 numTempBufs, const CBuf *tempBufs, UInt32 numTempBufs,
ISzAlloc *alloc) ISzAllocPtr alloc)
{ {
CSzData sd; CSzData sd;
UInt32 i; UInt32 i;
@ -1100,17 +1096,15 @@ static SRes SzReadHeader2(
CSzData *sd, CSzData *sd,
ILookInStream *inStream, ILookInStream *inStream,
CBuf *tempBufs, UInt32 *numTempBufs, CBuf *tempBufs, UInt32 *numTempBufs,
ISzAlloc *allocMain, ISzAllocPtr allocMain,
ISzAlloc *allocTemp ISzAllocPtr allocTemp
) )
{ {
UInt64 type;
UInt32 numFiles = 0;
UInt32 numEmptyStreams = 0;
CSubStreamInfo ssi; CSubStreamInfo ssi;
const Byte *emptyStreams = NULL;
const Byte *emptyFiles = NULL;
{
UInt64 type;
SzData_Clear(&ssi.sdSizes); SzData_Clear(&ssi.sdSizes);
SzData_Clear(&ssi.sdCRCs); SzData_Clear(&ssi.sdCRCs);
SzData_Clear(&ssi.sdNumSubStreams); SzData_Clear(&ssi.sdNumSubStreams);
@ -1124,9 +1118,9 @@ static SRes SzReadHeader2(
{ {
for (;;) for (;;)
{ {
UInt64 type; UInt64 type2;
RINOK(ReadID(sd, &type)); RINOK(ReadID(sd, &type2));
if (type == k7zIdEnd) if (type2 == k7zIdEnd)
break; break;
RINOK(SkipData(sd)); RINOK(SkipData(sd));
} }
@ -1164,6 +1158,13 @@ static SRes SzReadHeader2(
if (type != k7zIdFilesInfo) if (type != k7zIdFilesInfo)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
}
{
UInt32 numFiles = 0;
UInt32 numEmptyStreams = 0;
const Byte *emptyStreams = NULL;
const Byte *emptyFiles = NULL;
RINOK(SzReadNumber32(sd, &numFiles)); RINOK(SzReadNumber32(sd, &numFiles));
p->NumFiles = numFiles; p->NumFiles = numFiles;
@ -1462,7 +1463,7 @@ static SRes SzReadHeader2(
if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0) if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
} }
}
return SZ_OK; return SZ_OK;
} }
@ -1471,8 +1472,8 @@ static SRes SzReadHeader(
CSzArEx *p, CSzArEx *p,
CSzData *sd, CSzData *sd,
ILookInStream *inStream, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAllocPtr allocMain,
ISzAlloc *allocTemp) ISzAllocPtr allocTemp)
{ {
UInt32 i; UInt32 i;
UInt32 numTempBufs = 0; UInt32 numTempBufs = 0;
@ -1500,8 +1501,8 @@ static SRes SzReadHeader(
static SRes SzArEx_Open2( static SRes SzArEx_Open2(
CSzArEx *p, CSzArEx *p,
ILookInStream *inStream, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAllocPtr allocMain,
ISzAlloc *allocTemp) ISzAllocPtr allocTemp)
{ {
Byte header[k7zStartHeaderSize]; Byte header[k7zStartHeaderSize];
Int64 startArcPos; Int64 startArcPos;
@ -1512,7 +1513,7 @@ static SRes SzArEx_Open2(
SRes res; SRes res;
startArcPos = 0; startArcPos = 0;
RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR));
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
@ -1541,7 +1542,7 @@ static SRes SzArEx_Open2(
{ {
Int64 pos = 0; Int64 pos = 0;
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END));
if ((UInt64)pos < startArcPos + nextHeaderOffset || if ((UInt64)pos < startArcPos + nextHeaderOffset ||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
@ -1622,7 +1623,7 @@ static SRes SzArEx_Open2(
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp) ISzAllocPtr allocMain, ISzAllocPtr allocTemp)
{ {
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
if (res != SZ_OK) if (res != SZ_OK)
@ -1640,8 +1641,8 @@ SRes SzArEx_Extract(
size_t *outBufferSize, size_t *outBufferSize,
size_t *offset, size_t *offset,
size_t *outSizeProcessed, size_t *outSizeProcessed,
ISzAlloc *allocMain, ISzAllocPtr allocMain,
ISzAlloc *allocTemp) ISzAllocPtr allocTemp)
{ {
UInt32 folderIndex = p->FileToFolder[fileIndex]; UInt32 folderIndex = p->FileToFolder[fileIndex];
SRes res = SZ_OK; SRes res = SZ_OK;
@ -1651,7 +1652,7 @@ SRes SzArEx_Extract(
if (folderIndex == (UInt32)-1) if (folderIndex == (UInt32)-1)
{ {
IAlloc_Free(allocMain, *tempBuf); ISzAlloc_Free(allocMain, *tempBuf);
*blockIndex = folderIndex; *blockIndex = folderIndex;
*tempBuf = NULL; *tempBuf = NULL;
*outBufferSize = 0; *outBufferSize = 0;
@ -1663,7 +1664,7 @@ SRes SzArEx_Extract(
UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
/* /*
UInt64 unpackSizeSpec = UInt64 unpackSizeSpec =
p->UnpackPositions[p->FolderToFile[folderIndex + 1]] - p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] -
p->UnpackPositions[p->FolderToFile[folderIndex]]; p->UnpackPositions[p->FolderToFile[folderIndex]];
*/ */
size_t unpackSize = (size_t)unpackSizeSpec; size_t unpackSize = (size_t)unpackSizeSpec;
@ -1671,7 +1672,7 @@ SRes SzArEx_Extract(
if (unpackSize != unpackSizeSpec) if (unpackSize != unpackSizeSpec)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
*blockIndex = folderIndex; *blockIndex = folderIndex;
IAlloc_Free(allocMain, *tempBuf); ISzAlloc_Free(allocMain, *tempBuf);
*tempBuf = NULL; *tempBuf = NULL;
if (res == SZ_OK) if (res == SZ_OK)
@ -1679,7 +1680,7 @@ SRes SzArEx_Extract(
*outBufferSize = unpackSize; *outBufferSize = unpackSize;
if (unpackSize != 0) if (unpackSize != 0)
{ {
*tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize); *tempBuf = (Byte *)ISzAlloc_Alloc(allocMain, unpackSize);
if (*tempBuf == NULL) if (*tempBuf == NULL)
res = SZ_ERROR_MEM; res = SZ_ERROR_MEM;
} }
@ -1696,7 +1697,7 @@ SRes SzArEx_Extract(
{ {
UInt64 unpackPos = p->UnpackPositions[fileIndex]; UInt64 unpackPos = p->UnpackPositions[fileIndex];
*offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]); *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
*outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos); *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos);
if (*offset + *outSizeProcessed > *outBufferSize) if (*offset + *outSizeProcessed > *outBufferSize)
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
if (SzBitWithVals_Check(&p->CRCs, fileIndex)) if (SzBitWithVals_Check(&p->CRCs, fileIndex))

View file

@ -1,5 +1,5 @@
/* 7zBuf.c -- Byte Buffer /* 7zBuf.c -- Byte Buffer
2013-01-21 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -11,7 +11,7 @@ void Buf_Init(CBuf *p)
p->size = 0; p->size = 0;
} }
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
{ {
p->size = 0; p->size = 0;
if (size == 0) if (size == 0)
@ -19,8 +19,8 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
p->data = 0; p->data = 0;
return 1; return 1;
} }
p->data = (Byte *)alloc->Alloc(alloc, size); p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
if (p->data != 0) if (p->data)
{ {
p->size = size; p->size = size;
return 1; return 1;
@ -28,9 +28,9 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
return 0; return 0;
} }
void Buf_Free(CBuf *p, ISzAlloc *alloc) void Buf_Free(CBuf *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->data); ISzAlloc_Free(alloc, p->data);
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
} }

View file

@ -1,5 +1,5 @@
/* 7zBuf.h -- Byte Buffer /* 7zBuf.h -- Byte Buffer
2013-01-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H #ifndef __7Z_BUF_H
#define __7Z_BUF_H #define __7Z_BUF_H
@ -15,8 +15,8 @@ typedef struct
} CBuf; } CBuf;
void Buf_Init(CBuf *p); void Buf_Init(CBuf *p);
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
void Buf_Free(CBuf *p, ISzAlloc *alloc); void Buf_Free(CBuf *p, ISzAllocPtr alloc);
typedef struct typedef struct
{ {
@ -27,8 +27,8 @@ typedef struct
void DynBuf_Construct(CDynBuf *p); void DynBuf_Construct(CDynBuf *p);
void DynBuf_SeekToBeg(CDynBuf *p); void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END

View file

@ -1,5 +1,5 @@
/* 7zCrc.c -- CRC32 init /* 7zCrc.c -- CRC32 init
2015-03-10 : Igor Pavlov : Public domain */ 2017-06-06 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -61,12 +61,12 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 r = i; UInt32 r = i;
unsigned j; unsigned j;
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
g_CrcTable[i] = r; g_CrcTable[i] = r;
} }
for (; i < 256 * CRC_NUM_TABLES; i++) for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
{ {
UInt32 r = g_CrcTable[i - 256]; UInt32 r = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
} }
@ -86,8 +86,8 @@ void MY_FAST_CALL CrcGenerateTable()
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder()) if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif #endif
g_CrcUpdate = CrcUpdateT8;
#endif #endif
#else #else
@ -101,7 +101,7 @@ void MY_FAST_CALL CrcGenerateTable()
g_CrcUpdate = CrcUpdateT4; g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8 #if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8; g_CrcUpdateT8 = CrcUpdateT8;
// g_CrcUpdate = CrcUpdateT8; g_CrcUpdate = CrcUpdateT8;
#endif #endif
} }
else if (p[0] != 1 || p[1] != 2) else if (p[0] != 1 || p[1] != 2)
@ -111,14 +111,14 @@ void MY_FAST_CALL CrcGenerateTable()
{ {
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{ {
UInt32 x = g_CrcTable[i - 256]; UInt32 x = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x); g_CrcTable[i] = CRC_UINT32_SWAP(x);
} }
g_CrcUpdateT4 = CrcUpdateT1_BeT4; g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4; g_CrcUpdate = CrcUpdateT1_BeT4;
#if CRC_NUM_TABLES >= 8 #if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT1_BeT8; g_CrcUpdateT8 = CrcUpdateT1_BeT8;
// g_CrcUpdate = CrcUpdateT1_BeT8; g_CrcUpdate = CrcUpdateT1_BeT8;
#endif #endif
} }
} }

View file

@ -1,5 +1,5 @@
/* 7zCrcOpt.c -- CRC32 calculation /* 7zCrcOpt.c -- CRC32 calculation
2015-03-01 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -18,10 +18,10 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U
{ {
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
table[0x300 + ((v ) & 0xFF)] (table + 0x300)[((v ) & 0xFF)]
^ table[0x200 + ((v >> 8) & 0xFF)] ^ (table + 0x200)[((v >> 8) & 0xFF)]
^ table[0x100 + ((v >> 16) & 0xFF)] ^ (table + 0x100)[((v >> 16) & 0xFF)]
^ table[0x000 + ((v >> 24))]; ^ (table + 0x000)[((v >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
@ -38,16 +38,16 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
UInt32 d; UInt32 d;
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
table[0x700 + ((v ) & 0xFF)] (table + 0x700)[((v ) & 0xFF)]
^ table[0x600 + ((v >> 8) & 0xFF)] ^ (table + 0x600)[((v >> 8) & 0xFF)]
^ table[0x500 + ((v >> 16) & 0xFF)] ^ (table + 0x500)[((v >> 16) & 0xFF)]
^ table[0x400 + ((v >> 24))]; ^ (table + 0x400)[((v >> 24))];
d = *((const UInt32 *)p + 1); d = *((const UInt32 *)p + 1);
v ^= v ^=
table[0x300 + ((d ) & 0xFF)] (table + 0x300)[((d ) & 0xFF)]
^ table[0x200 + ((d >> 8) & 0xFF)] ^ (table + 0x200)[((d >> 8) & 0xFF)]
^ table[0x100 + ((d >> 16) & 0xFF)] ^ (table + 0x100)[((d >> 16) & 0xFF)]
^ table[0x000 + ((d >> 24))]; ^ (table + 0x000)[((d >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
@ -74,10 +74,10 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, co
{ {
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
table[0x000 + ((v ) & 0xFF)] (table + 0x000)[((v ) & 0xFF)]
^ table[0x100 + ((v >> 8) & 0xFF)] ^ (table + 0x100)[((v >> 8) & 0xFF)]
^ table[0x200 + ((v >> 16) & 0xFF)] ^ (table + 0x200)[((v >> 16) & 0xFF)]
^ table[0x300 + ((v >> 24))]; ^ (table + 0x300)[((v >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p); v = CRC_UPDATE_BYTE_2_BE(v, *p);
@ -96,16 +96,16 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, co
UInt32 d; UInt32 d;
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
table[0x400 + ((v ) & 0xFF)] (table + 0x400)[((v ) & 0xFF)]
^ table[0x500 + ((v >> 8) & 0xFF)] ^ (table + 0x500)[((v >> 8) & 0xFF)]
^ table[0x600 + ((v >> 16) & 0xFF)] ^ (table + 0x600)[((v >> 16) & 0xFF)]
^ table[0x700 + ((v >> 24))]; ^ (table + 0x700)[((v >> 24))];
d = *((const UInt32 *)p + 1); d = *((const UInt32 *)p + 1);
v ^= v ^=
table[0x000 + ((d ) & 0xFF)] (table + 0x000)[((d ) & 0xFF)]
^ table[0x100 + ((d >> 8) & 0xFF)] ^ (table + 0x100)[((d >> 8) & 0xFF)]
^ table[0x200 + ((d >> 16) & 0xFF)] ^ (table + 0x200)[((d >> 16) & 0xFF)]
^ table[0x300 + ((d >> 24))]; ^ (table + 0x300)[((d >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p); v = CRC_UPDATE_BYTE_2_BE(v, *p);

View file

@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder /* 7zDec.c -- Decoding from 7z folder
2015-11-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -39,28 +39,28 @@
typedef struct typedef struct
{ {
IByteIn p; IByteIn vt;
const Byte *cur; const Byte *cur;
const Byte *end; const Byte *end;
const Byte *begin; const Byte *begin;
UInt64 processed; UInt64 processed;
Bool extra; Bool extra;
SRes res; SRes res;
ILookInStream *inStream; const ILookInStream *inStream;
} CByteInToLook; } CByteInToLook;
static Byte ReadByte(void *pp) static Byte ReadByte(const IByteIn *pp)
{ {
CByteInToLook *p = (CByteInToLook *)pp; CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
if (p->cur != p->end) if (p->cur != p->end)
return *p->cur++; return *p->cur++;
if (p->res == SZ_OK) if (p->res == SZ_OK)
{ {
size_t size = p->cur - p->begin; size_t size = p->cur - p->begin;
p->processed += size; p->processed += size;
p->res = p->inStream->Skip(p->inStream, size); p->res = ILookInStream_Skip(p->inStream, size);
size = (1 << 25); size = (1 << 25);
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
p->cur = p->begin; p->cur = p->begin;
p->end = p->begin + size; p->end = p->begin + size;
if (size != 0) if (size != 0)
@ -70,14 +70,14 @@ static Byte ReadByte(void *pp)
return 0; return 0;
} }
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{ {
CPpmd7 ppmd; CPpmd7 ppmd;
CByteInToLook s; CByteInToLook s;
SRes res = SZ_OK; SRes res = SZ_OK;
s.p.Read = ReadByte; s.vt.Read = ReadByte;
s.inStream = inStream; s.inStream = inStream;
s.begin = s.end = s.cur = NULL; s.begin = s.end = s.cur = NULL;
s.extra = False; s.extra = False;
@ -103,7 +103,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
{ {
CPpmd7z_RangeDec rc; CPpmd7z_RangeDec rc;
Ppmd7z_RangeDec_CreateVTable(&rc); Ppmd7z_RangeDec_CreateVTable(&rc);
rc.Stream = &s.p; rc.Stream = &s.vt;
if (!Ppmd7z_RangeDec_Init(&rc)) if (!Ppmd7z_RangeDec_Init(&rc))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
else if (s.extra) else if (s.extra)
@ -113,7 +113,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
SizeT i; SizeT i;
for (i = 0; i < outSize; i++) for (i = 0; i < outSize; i++)
{ {
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);
if (s.extra || sym < 0) if (s.extra || sym < 0)
break; break;
outBuffer[i] = (Byte)sym; outBuffer[i] = (Byte)sym;
@ -132,7 +132,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{ {
CLzmaDec state; CLzmaDec state;
SRes res = SZ_OK; SRes res = SZ_OK;
@ -149,7 +149,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
size_t lookahead = (1 << 18); size_t lookahead = (1 << 18);
if (lookahead > inSize) if (lookahead > inSize)
lookahead = (size_t)inSize; lookahead = (size_t)inSize;
res = inStream->Look(inStream, &inBuf, &lookahead); res = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@ -178,7 +178,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
break; break;
} }
res = inStream->Skip((void *)inStream, inProcessed); res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
} }
@ -192,7 +192,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
#ifndef _7Z_NO_METHOD_LZMA2 #ifndef _7Z_NO_METHOD_LZMA2
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{ {
CLzma2Dec state; CLzma2Dec state;
SRes res = SZ_OK; SRes res = SZ_OK;
@ -211,7 +211,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
size_t lookahead = (1 << 18); size_t lookahead = (1 << 18);
if (lookahead > inSize) if (lookahead > inSize)
lookahead = (size_t)inSize; lookahead = (size_t)inSize;
res = inStream->Look(inStream, &inBuf, &lookahead); res = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@ -237,7 +237,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
break; break;
} }
res = inStream->Skip((void *)inStream, inProcessed); res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
} }
@ -258,13 +258,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
size_t curSize = (1 << 18); size_t curSize = (1 << 18);
if (curSize > inSize) if (curSize > inSize)
curSize = (size_t)inSize; curSize = (size_t)inSize;
RINOK(inStream->Look(inStream, &inBuf, &curSize)); RINOK(ILookInStream_Look(inStream, &inBuf, &curSize));
if (curSize == 0) if (curSize == 0)
return SZ_ERROR_INPUT_EOF; return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize); memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize; outBuffer += curSize;
inSize -= curSize; inSize -= curSize;
RINOK(inStream->Skip((void *)inStream, curSize)); RINOK(ILookInStream_Skip(inStream, curSize));
} }
return SZ_OK; return SZ_OK;
} }
@ -372,7 +372,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
const UInt64 *unpackSizes, const UInt64 *unpackSizes,
const UInt64 *packPositions, const UInt64 *packPositions,
ILookInStream *inStream, UInt64 startPos, ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
Byte *tempBuf[]) Byte *tempBuf[])
{ {
UInt32 ci; UInt32 ci;
@ -404,7 +404,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
outSizeCur = (SizeT)unpackSize; outSizeCur = (SizeT)unpackSize;
if (outSizeCur != unpackSize) if (outSizeCur != unpackSize)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
if (!temp && outSizeCur != 0) if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp; outBufCur = tempBuf[1 - ci] = temp;
@ -421,7 +421,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
offset = packPositions[si]; offset = packPositions[si];
inSize = packPositions[si + 1] - offset; inSize = packPositions[(size_t)si + 1] - offset;
RINOK(LookInStream_SeekTo(inStream, startPos + offset)); RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy) if (coder->MethodID == k_Copy)
@ -460,7 +460,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
tempSizes[2] = (SizeT)s3Size; tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size) if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
if (!tempBuf[2] && tempSizes[2] != 0) if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
@ -549,7 +549,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos, ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain) ISzAllocPtr allocMain)
{ {
SRes res; SRes res;
CSzFolder folder; CSzFolder folder;
@ -557,7 +557,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data; sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd); res = SzGetNextFolderItem(&folder, &sd);
@ -579,7 +579,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
outBuffer, (SizeT)outSize, allocMain, tempBuf); outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]); ISzAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK) if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex)) if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))

View file

@ -1,5 +1,5 @@
/* 7zStream.c -- 7z Stream functions /* 7zStream.c -- 7z Stream functions
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -7,12 +7,12 @@
#include "7zTypes.h" #include "7zTypes.h"
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(stream->Read(stream, buf, &processed)); RINOK(ISeqInStream_Read(stream, buf, &processed));
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((Byte *)buf + processed); buf = (void *)((Byte *)buf + processed);
@ -21,40 +21,42 @@ SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorT
return SZ_OK; return SZ_OK;
} }
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
{ {
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
{ {
size_t processed = 1; size_t processed = 1;
RINOK(stream->Read(stream, buf, &processed)); RINOK(ISeqInStream_Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
} }
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
{ {
Int64 t = offset; Int64 t = offset;
return stream->Seek(stream, &t, SZ_SEEK_SET); return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
} }
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
{ {
const void *lookBuf; const void *lookBuf;
if (*size == 0) if (*size == 0)
return SZ_OK; return SZ_OK;
RINOK(stream->Look(stream, &lookBuf, size)); RINOK(ILookInStream_Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size); memcpy(buf, lookBuf, *size);
return stream->Skip(stream, *size); return ILookInStream_Skip(stream, *size);
} }
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(stream->Read(stream, buf, &processed)); RINOK(ILookInStream_Read(stream, buf, &processed));
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((Byte *)buf + processed); buf = (void *)((Byte *)buf + processed);
@ -63,61 +65,67 @@ SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes erro
return SZ_OK; return SZ_OK;
} }
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
{ {
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) if (size2 == 0 && *size != 0)
{ {
p->pos = 0; p->pos = 0;
size2 = LookToRead_BUF_SIZE; p->size = 0;
res = p->realStream->Read(p->realStream, p->buf, &size2); size2 = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, &size2);
p->size = size2; p->size = size2;
} }
if (size2 < *size) if (*size > size2)
*size = size2; *size = size2;
*buf = p->buf + p->pos; *buf = p->buf + p->pos;
return res; return res;
} }
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) if (size2 == 0 && *size != 0)
{ {
p->pos = 0; p->pos = 0;
if (*size > LookToRead_BUF_SIZE) p->size = 0;
*size = LookToRead_BUF_SIZE; if (*size > p->bufSize)
res = p->realStream->Read(p->realStream, p->buf, size); *size = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, size);
size2 = p->size = *size; size2 = p->size = *size;
} }
if (size2 < *size) if (*size > size2)
*size = size2; *size = size2;
*buf = p->buf + p->pos; *buf = p->buf + p->pos;
return res; return res;
} }
static SRes LookToRead_Skip(void *pp, size_t offset) static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
{ {
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
p->pos += offset; p->pos += offset;
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead_Read(void *pp, void *buf, size_t *size) static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
{ {
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
size_t rem = p->size - p->pos; size_t rem = p->size - p->pos;
if (rem == 0) if (rem == 0)
return p->realStream->Read(p->realStream, buf, size); return ISeekInStream_Read(p->realStream, buf, size);
if (rem > *size) if (rem > *size)
rem = *size; rem = *size;
memcpy(buf, p->buf + p->pos, rem); memcpy(buf, p->buf + p->pos, rem);
@ -126,46 +134,43 @@ static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
{ {
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
p->pos = p->size = 0; p->pos = p->size = 0;
return p->realStream->Seek(p->realStream, pos, origin); return ISeekInStream_Seek(p->realStream, pos, origin);
} }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead) void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
{ {
p->s.Look = lookahead ? p->vt.Look = lookahead ?
LookToRead_Look_Lookahead : LookToRead2_Look_Lookahead :
LookToRead_Look_Exact; LookToRead2_Look_Exact;
p->s.Skip = LookToRead_Skip; p->vt.Skip = LookToRead2_Skip;
p->s.Read = LookToRead_Read; p->vt.Read = LookToRead2_Read;
p->s.Seek = LookToRead_Seek; p->vt.Seek = LookToRead2_Seek;
} }
void LookToRead_Init(CLookToRead *p)
{
p->pos = p->size = 0;
}
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CSecToLook *p = (CSecToLook *)pp; CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
return LookInStream_LookRead(p->realStream, buf, size); return LookInStream_LookRead(p->realStream, buf, size);
} }
void SecToLook_CreateVTable(CSecToLook *p) void SecToLook_CreateVTable(CSecToLook *p)
{ {
p->s.Read = SecToLook_Read; p->vt.Read = SecToLook_Read;
} }
static SRes SecToRead_Read(void *pp, void *buf, size_t *size) static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CSecToRead *p = (CSecToRead *)pp; CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
return p->realStream->Read(p->realStream, buf, size); return ILookInStream_Read(p->realStream, buf, size);
} }
void SecToRead_CreateVTable(CSecToRead *p) void SecToRead_CreateVTable(CSecToRead *p)
{ {
p->s.Read = SecToRead_Read; p->vt.Read = SecToRead_Read;
} }

View file

@ -1,11 +1,11 @@
/* 7zTypes.h -- Basic types /* 7zTypes.h -- Basic types
2013-11-12 : Igor Pavlov : Public domain */ 2017-07-17 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> /* #include <windows.h> */
#endif #endif
#include <stddef.h> #include <stddef.h>
@ -42,13 +42,23 @@ EXTERN_C_BEGIN
typedef int SRes; typedef int SRes;
#ifdef _WIN32 #ifdef _WIN32
typedef DWORD WRes;
/* typedef unsigned WRes; */ /* typedef DWORD WRes; */
typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else #else
typedef int WRes; typedef int WRes;
#define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif #endif
#ifndef RINOK #ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif #endif
@ -112,48 +122,72 @@ typedef int Bool;
#define MY_NO_INLINE #define MY_NO_INLINE
#endif #endif
#define MY_FORCE_INLINE __forceinline
#define MY_CDECL __cdecl #define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall #define MY_FAST_CALL __fastcall
#else #else
#define MY_NO_INLINE #define MY_NO_INLINE
#define MY_FORCE_INLINE
#define MY_CDECL #define MY_CDECL
#define MY_FAST_CALL #define MY_FAST_CALL
/* inline keyword : for C++ / C99 */
/* GCC, clang: */
/*
#if defined (__GNUC__) && (__GNUC__ >= 4)
#define MY_FORCE_INLINE __attribute__((always_inline))
#define MY_NO_INLINE __attribute__((noinline))
#endif
*/
#endif #endif
/* The following interfaces use first parameter as pointer to structure */ /* The following interfaces use first parameter as pointer to structure */
typedef struct typedef struct IByteIn IByteIn;
struct IByteIn
{ {
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn; };
#define IByteIn_Read(p) (p)->Read(p)
typedef struct
{
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct typedef struct IByteOut IByteOut;
struct IByteOut
{ {
SRes (*Read)(void *p, void *buf, size_t *size); void (*Write)(const IByteOut *p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream
{
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
} ISeqInStream; };
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */ /* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
typedef struct
typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream
{ {
size_t (*Write)(void *p, const void *buf, size_t size); size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes. /* Returns: result - the number of actually written bytes.
(result < size) means error */ (result < size) means error */
} ISeqOutStream; };
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum typedef enum
{ {
@ -162,78 +196,162 @@ typedef enum
SZ_SEEK_END = 2 SZ_SEEK_END = 2
} ESzSeek; } 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 typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream
{ {
SRes (*Look)(void *p, const void **buf, size_t *size); SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
typedef struct ILookInStream ILookInStream;
struct ILookInStream
{
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed (output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset); SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */ /* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size); SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */ /* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
} ILookInStream; };
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); #define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); #define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */ /* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct typedef struct
{ {
ILookInStream s; ILookInStream vt;
ISeekInStream *realStream; const ISeekInStream *realStream;
size_t pos; size_t pos;
size_t size; size_t size; /* it's data size */
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead; /* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream vt;
ILookInStream *realStream; const ILookInStream *realStream;
} CSecToLook; } CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p); void SecToLook_CreateVTable(CSecToLook *p);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream vt;
ILookInStream *realStream; const ILookInStream *realStream;
} CSecToRead; } CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p); void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
typedef struct ICompressProgress ICompressProgress;
struct ICompressProgress
{ {
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break. /* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */ Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress; };
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{ {
void *(*Alloc)(void *p, size_t size); void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */ void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
} ISzAlloc; };
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef MY_container_of
/*
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
#endif
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
/*
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
*/
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
*/
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32 #ifdef _WIN32

View file

@ -1,14 +1,21 @@
#define MY_VER_MAJOR 15 #define MY_VER_MAJOR 17
#define MY_VER_MINOR 14 #define MY_VER_MINOR 01
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.14" #define MY_VERSION_NUMBERS "17.01 beta"
#define MY_VERSION "15.14" #define MY_VERSION MY_VERSION_NUMBERS
#define MY_DATE "2015-12-31"
#ifdef MY_CPU_NAME
#define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
#else
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2017-08-28"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov" #define MY_COPYRIGHT_CR "Copyright (c) 1999-2017 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR #ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR
@ -16,4 +23,5 @@
#define MY_COPYRIGHT MY_COPYRIGHT_PD #define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif #endif
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE #define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE

View file

@ -1,5 +1,5 @@
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2015-08-01 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -61,7 +61,8 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p)
Byte *dest = p->dest; Byte *dest = p->dest;
if (dest == p->destLim) if (dest == p->destLim)
return SZ_OK; return SZ_OK;
*dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0]; *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
p->state++;
p->dest = dest + 1; p->dest = dest + 1;
} }
} }

View file

@ -1,135 +1,230 @@
/* Bra.c -- Converters for RISC code /* Bra.c -- Converters for RISC code
2010-04-16 : Igor Pavlov : Public domain */ 2017-04-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h"
#include "Bra.h" #include "Bra.h"
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; Byte *p;
if (size < 4) const Byte *lim;
return 0; size &= ~(size_t)3;
size -= 4; ip += 4;
ip += 8; p = data;
for (i = 0; i <= size; i += 4) lim = data + size;
if (encoding)
for (;;)
{ {
if (data[i + 3] == 0xEB) for (;;)
{ {
UInt32 dest; if (p >= lim)
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); return p - data;
src <<= 2; p += 4;
if (encoding) if (p[-1] == 0xEB)
dest = ip + (UInt32)i + src; break;
else }
dest = src - (ip + (UInt32)i); {
dest >>= 2; UInt32 v = GetUi32(p - 4);
data[i + 2] = (Byte)(dest >> 16); v <<= 2;
data[i + 1] = (Byte)(dest >> 8); v += ip + (UInt32)(p - data);
data[i + 0] = (Byte)dest; v >>= 2;
v &= 0x00FFFFFF;
v |= 0xEB000000;
SetUi32(p - 4, v);
}
}
for (;;)
{
for (;;)
{
if (p >= lim)
return p - data;
p += 4;
if (p[-1] == 0xEB)
break;
}
{
UInt32 v = GetUi32(p - 4);
v <<= 2;
v -= ip + (UInt32)(p - data);
v >>= 2;
v &= 0x00FFFFFF;
v |= 0xEB000000;
SetUi32(p - 4, v);
} }
} }
return i;
} }
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; Byte *p;
if (size < 4) const Byte *lim;
return 0; size &= ~(size_t)1;
size -= 4; p = data;
ip += 4; lim = data + size - 4;
for (i = 0; i <= size; i += 2)
if (encoding)
for (;;)
{ {
if ((data[i + 1] & 0xF8) == 0xF0 && UInt32 b1;
(data[i + 3] & 0xF8) == 0xF8) for (;;)
{ {
UInt32 dest; UInt32 b3;
UInt32 src = if (p > lim)
(((UInt32)data[i + 1] & 0x7) << 19) | return p - data;
((UInt32)data[i + 0] << 11) | b1 = p[1];
(((UInt32)data[i + 3] & 0x7) << 8) | b3 = p[3];
(data[i + 2]); p += 2;
b1 ^= 8;
src <<= 1; if ((b3 & b1) >= 0xF8)
if (encoding) break;
dest = ip + (UInt32)i + src; }
else {
dest = src - (ip + (UInt32)i); UInt32 v =
dest >>= 1; ((UInt32)b1 << 19)
+ (((UInt32)p[1] & 0x7) << 8)
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); + (((UInt32)p[-2] << 11))
data[i + 0] = (Byte)(dest >> 11); + (p[0]);
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
data[i + 2] = (Byte)dest; p += 2;
i += 2; {
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
v += cur;
}
p[-4] = (Byte)(v >> 11);
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
p[-2] = (Byte)v;
p[-1] = (Byte)(0xF8 | (v >> 8));
}
}
for (;;)
{
UInt32 b1;
for (;;)
{
UInt32 b3;
if (p > lim)
return p - data;
b1 = p[1];
b3 = p[3];
p += 2;
b1 ^= 8;
if ((b3 & b1) >= 0xF8)
break;
}
{
UInt32 v =
((UInt32)b1 << 19)
+ (((UInt32)p[1] & 0x7) << 8)
+ (((UInt32)p[-2] << 11))
+ (p[0]);
p += 2;
{
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
v -= cur;
}
/*
SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
SetUi16(p - 2, (UInt16)(v | 0xF800));
*/
p[-4] = (Byte)(v >> 11);
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
p[-2] = (Byte)v;
p[-1] = (Byte)(0xF8 | (v >> 8));
} }
} }
return i;
} }
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; Byte *p;
if (size < 4) const Byte *lim;
return 0; size &= ~(size_t)3;
size -= 4; ip -= 4;
for (i = 0; i <= size; i += 4) p = data;
lim = data + size;
for (;;)
{ {
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) for (;;)
{ {
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | if (p >= lim)
((UInt32)data[i + 1] << 16) | return p - data;
((UInt32)data[i + 2] << 8) | p += 4;
((UInt32)data[i + 3] & (~3)); /* if ((v & 0xFC000003) == 0x48000001) */
if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
UInt32 dest; break;
}
{
UInt32 v = GetBe32(p - 4);
if (encoding) if (encoding)
dest = ip + (UInt32)i + src; v += ip + (UInt32)(p - data);
else else
dest = src - (ip + (UInt32)i); v -= ip + (UInt32)(p - data);
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); v &= 0x03FFFFFF;
data[i + 1] = (Byte)(dest >> 16); v |= 0x48000000;
data[i + 2] = (Byte)(dest >> 8); SetBe32(p - 4, v);
data[i + 3] &= 0x3;
data[i + 3] |= dest;
} }
} }
return i;
} }
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
UInt32 i; Byte *p;
if (size < 4) const Byte *lim;
return 0; size &= ~(size_t)3;
size -= 4; ip -= 4;
for (i = 0; i <= size; i += 4) p = data;
{ lim = data + size;
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
{
UInt32 src =
((UInt32)data[i + 0] << 24) |
((UInt32)data[i + 1] << 16) |
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3]);
UInt32 dest;
src <<= 2;
if (encoding)
dest = ip + i + src;
else
dest = src - (ip + i);
dest >>= 2;
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
data[i + 0] = (Byte)(dest >> 24); for (;;)
data[i + 1] = (Byte)(dest >> 16); {
data[i + 2] = (Byte)(dest >> 8); for (;;)
data[i + 3] = (Byte)dest; {
if (p >= lim)
return p - data;
/*
v = GetBe32(p);
p += 4;
m = v + ((UInt32)5 << 29);
m ^= (UInt32)7 << 29;
m += (UInt32)1 << 22;
if ((m & ((UInt32)0x1FF << 23)) == 0)
break;
*/
p += 4;
if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
(p[-4] == 0x7F && (p[-3] >= 0xC0)))
break;
}
{
UInt32 v = GetBe32(p - 4);
v <<= 2;
if (encoding)
v += ip + (UInt32)(p - data);
else
v -= ip + (UInt32)(p - data);
v &= 0x01FFFFFF;
v -= (UInt32)1 << 24;
v ^= 0xFF000000;
v >>= 2;
v |= 0x40000000;
SetBe32(p - 4, v);
} }
} }
return i;
} }

View file

@ -1,5 +1,5 @@
/* Bra86.c -- Converter for x86 code (BCJ) /* Bra86.c -- Converter for x86 code (BCJ)
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
else else
{ {
mask >>= (unsigned)d; mask >>= (unsigned)d;
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
{ {
mask = (mask >> 1) | 4; mask = (mask >> 1) | 4;
pos++; pos++;

View file

@ -1,69 +1,53 @@
/* BraIA64.c -- Converter for IA-64 code /* BraIA64.c -- Converter for IA-64 code
2013-11-12 : Igor Pavlov : Public domain */ 2017-01-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h"
#include "Bra.h" #include "Bra.h"
static const Byte kBranchTable[32] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 6, 6, 0, 0, 7, 7,
4, 4, 0, 0, 4, 4, 0, 0
};
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; SizeT i;
if (size < 16) if (size < 16)
return 0; return 0;
size -= 16; size -= 16;
for (i = 0; i <= size; i += 16) i = 0;
do
{ {
UInt32 instrTemplate = data[i] & 0x1F; unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
UInt32 mask = kBranchTable[instrTemplate]; if (m)
UInt32 bitPos = 5;
int slot;
for (slot = 0; slot < 3; slot++, bitPos += 41)
{ {
UInt32 bytePos, bitRes; m++;
UInt64 instruction, instNorm; do
int j;
if (((mask >> slot) & 1) == 0)
continue;
bytePos = (bitPos >> 3);
bitRes = bitPos & 0x7;
instruction = 0;
for (j = 0; j < 6; j++)
instruction += (UInt64)data[i + j + bytePos] << (8 * j);
instNorm = instruction >> bitRes;
if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
{ {
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); Byte *p = data + (i + (size_t)m * 5 - 8);
UInt32 dest; if (((p[3] >> m) & 15) == 5
src |= ((UInt32)(instNorm >> 36) & 1) << 20; && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
{
src <<= 4; unsigned raw = GetUi32(p);
unsigned v = raw >> m;
if (encoding) v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
dest = ip + (UInt32)i + src;
else v <<= 4;
dest = src - (ip + (UInt32)i); if (encoding)
v += ip + (UInt32)i;
dest >>= 4; else
v -= ip + (UInt32)i;
instNorm &= ~((UInt64)(0x8FFFFF) << 13); v >>= 4;
instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); v &= 0x1FFFFF;
v += 0x700000;
instruction &= (1 << bitRes) - 1; v &= 0x8FFFFF;
instruction |= (instNorm << bitRes); raw &= ~((UInt32)0x8FFFFF << m);
for (j = 0; j < 6; j++) raw |= (v << m);
data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); SetUi32(p, raw);
}
} }
while (++m <= 4);
} }
i += 16;
} }
while (i <= size);
return i; return i;
} }

View file

@ -1,5 +1,5 @@
/* Compiler.h /* Compiler.h
2015-08-02 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H #ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H #define __7Z_COMPILER_H
@ -21,6 +21,7 @@
#pragma warning(disable : 4514) // unreferenced inline function has been removed #pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code #pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined #pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif #endif

View file

@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2015-03-25: Igor Pavlov : Public domain */ 2016-02-25: Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
"push %%EDX\n\t" "push %%EDX\n\t"
"popf\n\t" "popf\n\t"
"andl %%EAX, %0\n\t": "andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag)); "=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif #endif
return flag; return flag;
} }
@ -79,7 +80,13 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
#if defined(MY_CPU_X86) && defined(__PIC__) #if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;"
"cpuid;"
"xchg %%rbx, %%rdi;"
: "=a" (*a) ,
"=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;" "mov %%ebx, %%edi;"
"cpuid;" "cpuid;"
"xchgl %%ebx, %%edi;" "xchgl %%ebx, %%edi;"

View file

@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2015-12-01: Igor Pavlov : Public domain */ 2017-06-30 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
@ -16,48 +16,122 @@ If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of pl
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
*/ */
#if defined(_M_X64) \ #if defined(_M_X64) \
|| defined(_M_AMD64) \ || defined(_M_AMD64) \
|| defined(__x86_64__) \ || defined(__x86_64__) \
|| defined(__AMD64__) \ || defined(__AMD64__) \
|| defined(__amd64__) || defined(__amd64__)
#define MY_CPU_AMD64 #define MY_CPU_AMD64
#endif #ifdef __ILP32__
#define MY_CPU_NAME "x32"
#if defined(MY_CPU_AMD64) \ #else
|| defined(_M_IA64) \ #define MY_CPU_NAME "x64"
|| defined(__AARCH64EL__) \ #endif
|| defined(__AARCH64EB__)
#define MY_CPU_64BIT #define MY_CPU_64BIT
#endif #endif
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86 #if defined(_M_IX86) \
|| defined(__i386__)
#define MY_CPU_X86
#define MY_CPU_NAME "x86"
#define MY_CPU_32BIT
#endif #endif
#if defined(_M_ARM64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \
|| defined(__aarch64__)
#define MY_CPU_ARM64
#define MY_CPU_NAME "arm64"
#define MY_CPU_64BIT
#endif
#if defined(_M_ARM) \
|| defined(_M_ARM_NT) \
|| defined(_M_ARMT) \
|| defined(__arm__) \
|| defined(__thumb__) \
|| defined(__ARMEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEL__) \
|| defined(__THUMBEB__)
#define MY_CPU_ARM
#define MY_CPU_NAME "arm"
#define MY_CPU_32BIT
#endif
#if defined(_M_IA64) \
|| defined(__ia64__)
#define MY_CPU_IA64
#define MY_CPU_NAME "ia64"
#define MY_CPU_64BIT
#endif
#if defined(__mips64) \
|| defined(__mips64__) \
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
#define MY_CPU_NAME "mips64"
#define MY_CPU_64BIT
#elif defined(__mips__)
#define MY_CPU_NAME "mips"
/* #define MY_CPU_32BIT */
#endif
#if defined(__ppc64__) \
|| defined(__powerpc64__)
#ifdef __ILP32__
#define MY_CPU_NAME "ppc64-32"
#else
#define MY_CPU_NAME "ppc64"
#endif
#define MY_CPU_64BIT
#elif defined(__ppc__) \
|| defined(__powerpc__)
#define MY_CPU_NAME "ppc"
#define MY_CPU_32BIT
#endif
#if defined(__sparc64__)
#define MY_CPU_NAME "sparc64"
#define MY_CPU_64BIT
#elif defined(__sparc__)
#define MY_CPU_NAME "sparc"
/* #define MY_CPU_32BIT */
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64 #define MY_CPU_X86_OR_AMD64
#endif #endif
#if defined(MY_CPU_X86) \
|| defined(_M_ARM) \ #ifdef _WIN32
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \ #ifdef MY_CPU_ARM
|| defined(__ARMEB__) \ #define MY_CPU_ARM_LE
|| defined(__THUMBEB__) #endif
#define MY_CPU_32BIT
#ifdef MY_CPU_ARM64
#define MY_CPU_ARM64_LE
#endif
#ifdef _M_IA64
#define MY_CPU_IA64_LE
#endif
#endif #endif
#if defined(_WIN32) && defined(_M_ARM)
#define MY_CPU_ARM_LE
#endif
#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64) \ #if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \ || defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \ || defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \ || defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \ || defined(__ARMEL__) \
@ -66,6 +140,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
|| defined(__MIPSEL__) \ || defined(__MIPSEL__) \
|| defined(__MIPSEL) \ || defined(__MIPSEL) \
|| defined(_MIPSEL) \ || defined(_MIPSEL) \
|| defined(__BFIN__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE #define MY_CPU_LE
#endif #endif
@ -85,14 +160,37 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
#define MY_CPU_BE #define MY_CPU_BE
#endif #endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE) #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian #error Stop_Compiling_Bad_Endian
#endif #endif
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
#error Stop_Compiling_Bad_32_64_BIT
#endif
#ifndef MY_CPU_NAME
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif MY_CPU_BE
#define MY_CPU_NAME "BE"
#else
/*
#define MY_CPU_NAME ""
*/
#endif
#endif
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \ #if defined(MY_CPU_X86_OR_AMD64) \
/* || defined(__AARCH64EL__) */ || defined(MY_CPU_ARM64) \
|| defined(__ARM_FEATURE_UNALIGNED)
#define MY_CPU_LE_UNALIGN #define MY_CPU_LE_UNALIGN
#endif #endif
#endif #endif
@ -138,6 +236,11 @@ Stop_Compiling_Bad_Endian
#endif #endif
#ifdef __has_builtin
#define MY__has_builtin(x) __has_builtin(x)
#else
#define MY__has_builtin(x) 0
#endif
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
@ -145,15 +248,21 @@ Stop_Compiling_Bad_Endian
#include <stdlib.h> #include <stdlib.h>
#pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64) #pragma intrinsic(_byteswap_uint64)
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) #elif defined(MY_CPU_LE_UNALIGN) && ( \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
@ -178,10 +287,14 @@ Stop_Compiling_Bad_Endian
#endif #endif
#ifndef GetBe16
#define GetBe16(p) ( (UInt16) ( \ #define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \ ((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] )) ((const Byte *)(p))[1] ))
#endif
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64

View file

@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms /* LzFind.c -- Match finder for LZ algorithms
2015-10-15 : Igor Pavlov : Public domain */ 2017-06-10 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -16,18 +16,18 @@
#define kStartMaxLen 3 #define kStartMaxLen 3
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
{ {
if (!p->directInput) if (!p->directInput)
{ {
alloc->Free(alloc, p->bufferBase); ISzAlloc_Free(alloc, p->bufferBase);
p->bufferBase = NULL; p->bufferBase = NULL;
} }
} }
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ /* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
{ {
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
if (p->directInput) if (p->directInput)
@ -39,7 +39,7 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
{ {
LzInWindow_Free(p, alloc); LzInWindow_Free(p, alloc);
p->blockSize = blockSize; p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
} }
return (p->bufferBase != NULL); return (p->bufferBase != NULL);
} }
@ -81,7 +81,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
if (size == 0) if (size == 0)
return; return;
p->result = p->stream->Read(p->stream, dest, &size); p->result = ISeqInStream_Read(p->stream, dest, &size);
if (p->result != SZ_OK) if (p->result != SZ_OK)
return; return;
if (size == 0) if (size == 0)
@ -142,6 +142,7 @@ void MatchFinder_Construct(CMatchFinder *p)
p->bufferBase = NULL; p->bufferBase = NULL;
p->directInput = 0; p->directInput = 0;
p->hash = NULL; p->hash = NULL;
p->expectedDataSize = (UInt64)(Int64)-1;
MatchFinder_SetDefaultSettings(p); MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -149,34 +150,34 @@ void MatchFinder_Construct(CMatchFinder *p)
UInt32 r = i; UInt32 r = i;
unsigned j; unsigned j;
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
p->crc[i] = r; p->crc[i] = r;
} }
} }
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->hash); ISzAlloc_Free(alloc, p->hash);
p->hash = NULL; p->hash = NULL;
} }
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
{ {
MatchFinder_FreeThisClassMemory(p, alloc); MatchFinder_FreeThisClassMemory(p, alloc);
LzInWindow_Free(p, alloc); LzInWindow_Free(p, alloc);
} }
static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc) static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
{ {
size_t sizeInBytes = (size_t)num * sizeof(CLzRef); size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num) if (sizeInBytes / sizeof(CLzRef) != num)
return NULL; return NULL;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
} }
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc) ISzAllocPtr alloc)
{ {
UInt32 sizeReserv; UInt32 sizeReserv;
@ -208,7 +209,11 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
hs = (1 << 16) - 1; hs = (1 << 16) - 1;
else else
{ {
hs = historySize - 1; hs = historySize;
if (hs > p->expectedDataSize)
hs = (UInt32)p->expectedDataSize;
if (hs != 0)
hs--;
hs |= (hs >> 1); hs |= (hs >> 1);
hs |= (hs >> 2); hs |= (hs >> 2);
hs |= (hs >> 4); hs |= (hs >> 4);
@ -292,17 +297,33 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
p->posLimit = p->pos + limit; p->posLimit = p->pos + limit;
} }
void MatchFinder_Init_2(CMatchFinder *p, int readData)
void MatchFinder_Init_LowHash(CMatchFinder *p)
{
size_t i;
CLzRef *items = p->hash;
size_t numItems = p->fixedHashSize;
for (i = 0; i < numItems; i++)
items[i] = kEmptyHashValue;
}
void MatchFinder_Init_HighHash(CMatchFinder *p)
{
size_t i;
CLzRef *items = p->hash + p->fixedHashSize;
size_t numItems = (size_t)p->hashMask + 1;
for (i = 0; i < numItems; i++)
items[i] = kEmptyHashValue;
}
void MatchFinder_Init_3(CMatchFinder *p, int readData)
{ {
UInt32 i;
UInt32 *hash = p->hash;
UInt32 num = p->hashSizeSum;
for (i = 0; i < num; i++)
hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0; p->cyclicBufferPos = 0;
p->buffer = p->bufferBase; p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize; p->pos =
p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK; p->result = SZ_OK;
p->streamEndWasReached = 0; p->streamEndWasReached = 0;
@ -312,10 +333,14 @@ void MatchFinder_Init_2(CMatchFinder *p, int readData)
MatchFinder_SetLimits(p); MatchFinder_SetLimits(p);
} }
void MatchFinder_Init(CMatchFinder *p) void MatchFinder_Init(CMatchFinder *p)
{ {
MatchFinder_Init_2(p, True); MatchFinder_Init_HighHash(p);
MatchFinder_Init_LowHash(p);
MatchFinder_Init_3(p, True);
} }
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{ {
@ -558,10 +583,10 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
d2 = pos - hash[h2]; d2 = pos - hash[h2];
curMatch = hash[kFix3HashSize + hv]; curMatch = (hash + kFix3HashSize)[hv];
hash[h2] = pos; hash[h2] = pos;
hash[kFix3HashSize + hv] = pos; (hash + kFix3HashSize)[hv] = pos;
maxLen = 2; maxLen = 2;
offset = 0; offset = 0;
@ -594,13 +619,13 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + hv] = pos; (hash + kFix4HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -615,7 +640,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{ {
maxLen = 3; maxLen = 3;
distances[offset + 1] = d3 - 1; distances[(size_t)offset + 1] = d3 - 1;
offset += 2; offset += 2;
d2 = d3; d2 = d3;
} }
@ -623,7 +648,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@ -650,15 +675,15 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
d4 = pos - hash[kFix4HashSize + h4]; d4 = pos - (hash + kFix4HashSize)[h4];
curMatch = hash[kFix5HashSize + hv]; curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + h4] = pos; (hash + kFix4HashSize)[h4] = pos;
hash[kFix5HashSize + hv] = pos; (hash + kFix5HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -691,7 +716,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
&& *(cur - d4 + 3) == *(cur + 3)) && *(cur - d4 + 3) == *(cur + 3))
{ {
maxLen = 4; maxLen = 4;
distances[offset + 1] = d4 - 1; distances[(size_t)offset + 1] = d4 - 1;
offset += 2; offset += 2;
d2 = d4; d2 = d4;
} }
@ -699,7 +724,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@ -726,13 +751,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + hv] = pos; (hash + kFix4HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -747,7 +772,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{ {
maxLen = 3; maxLen = 3;
distances[offset + 1] = d3 - 1; distances[(size_t)offset + 1] = d3 - 1;
offset += 2; offset += 2;
d2 = d3; d2 = d3;
} }
@ -755,7 +780,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
@ -784,15 +809,15 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
d4 = pos - hash[kFix4HashSize + h4]; d4 = pos - (hash + kFix4HashSize)[h4];
curMatch = hash[kFix5HashSize + hv]; curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + h4] = pos; (hash + kFix4HashSize)[h4] = pos;
hash[kFix5HashSize + hv] = pos; (hash + kFix5HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -825,7 +850,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
&& *(cur - d4 + 3) == *(cur + 3)) && *(cur - d4 + 3) == *(cur + 3))
{ {
maxLen = 4; maxLen = 4;
distances[offset + 1] = d4 - 1; distances[(size_t)offset + 1] = d4 - 1;
offset += 2; offset += 2;
d2 = d4; d2 = d4;
} }
@ -833,7 +858,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
@ -897,9 +922,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(3) SKIP_HEADER(3)
HASH3_CALC; HASH3_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix3HashSize + hv]; curMatch = (hash + kFix3HashSize)[hv];
hash[h2] = hash[h2] =
hash[kFix3HashSize + hv] = p->pos; (hash + kFix3HashSize)[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@ -914,10 +939,10 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + hv] = p->pos; (hash + kFix4HashSize)[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@ -933,11 +958,11 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(5) SKIP_HEADER(5)
HASH5_CALC; HASH5_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix5HashSize + hv]; curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + h4] = (hash + kFix4HashSize)[h4] =
hash[kFix5HashSize + hv] = p->pos; (hash + kFix5HashSize)[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@ -953,10 +978,10 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + hv] = p->pos; (hash + kFix4HashSize)[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS MOVE_POS
} }
@ -973,11 +998,11 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(5) SKIP_HEADER(5)
HASH5_CALC; HASH5_CALC;
hash = p->hash; hash = p->hash;
curMatch = p->hash[kFix5HashSize + hv]; curMatch = hash + kFix5HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + h4] = (hash + kFix4HashSize)[h4] =
hash[kFix5HashSize + hv] = p->pos; (hash + kFix5HashSize)[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS MOVE_POS
} }

View file

@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2015-10-15 : Igor Pavlov : Public domain */ 2017-06-10 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H #ifndef __LZ_FIND_H
#define __LZ_FIND_H #define __LZ_FIND_H
@ -47,6 +47,8 @@ typedef struct _CMatchFinder
SRes result; SRes result;
UInt32 crc[256]; UInt32 crc[256];
size_t numRefs; size_t numRefs;
UInt64 expectedDataSize;
} CMatchFinder; } CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
@ -71,8 +73,8 @@ void MatchFinder_Construct(CMatchFinder *p);
*/ */
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc); ISzAllocPtr alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
@ -103,7 +105,9 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init_2(CMatchFinder *p, int readData); void MatchFinder_Init_LowHash(CMatchFinder *p);
void MatchFinder_Init_HighHash(CMatchFinder *p);
void MatchFinder_Init_3(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p); void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);

View file

@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms /* LzFindMt.c -- multithreaded Match finder for LZ algorithms
2015-10-15 : Igor Pavlov : Public domain */ 2017-06-10 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -33,6 +33,8 @@ static void MtSync_GetNextBlock(CMtSync *p)
Event_Set(&p->canStart); Event_Set(&p->canStart);
Event_Wait(&p->wasStarted); Event_Wait(&p->wasStarted);
// if (mt) MatchFinder_Init_LowHash(mt->MatchFinder);
} }
else else
{ {
@ -155,6 +157,9 @@ static void HashThreadFunc(CMatchFinderMt *mt)
UInt32 numProcessedBlocks = 0; UInt32 numProcessedBlocks = 0;
Event_Wait(&p->canStart); Event_Wait(&p->canStart);
Event_Set(&p->wasStarted); Event_Set(&p->wasStarted);
MatchFinder_Init_HighHash(mt->MatchFinder);
for (;;) for (;;)
{ {
if (p->exit) if (p->exit)
@ -205,7 +210,7 @@ static void HashThreadFunc(CMatchFinderMt *mt)
if (num > kMtHashBlockSize - 2) if (num > kMtHashBlockSize - 2)
num = kMtHashBlockSize - 2; num = kMtHashBlockSize - 2;
mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
heads[0] += num; heads[0] = 2 + num;
} }
mf->pos += num; mf->pos += num;
mf->buffer += num; mf->buffer += num;
@ -443,13 +448,13 @@ void MatchFinderMt_Construct(CMatchFinderMt *p)
MtSync_Construct(&p->btSync); MtSync_Construct(&p->btSync);
} }
static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->hashBuf); ISzAlloc_Free(alloc, p->hashBuf);
p->hashBuf = NULL; p->hashBuf = NULL;
} }
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
{ {
MtSync_Destruct(&p->hashSync); MtSync_Destruct(&p->hashSync);
MtSync_Destruct(&p->btSync); MtSync_Destruct(&p->btSync);
@ -472,7 +477,7 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
} }
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc) UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc)
{ {
CMatchFinder *mf = p->MatchFinder; CMatchFinder *mf = p->MatchFinder;
p->historySize = historySize; p->historySize = historySize;
@ -480,7 +485,7 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
if (!p->hashBuf) if (!p->hashBuf)
{ {
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
if (!p->hashBuf) if (!p->hashBuf)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
p->btBuf = p->hashBuf + kHashBufferSize; p->btBuf = p->hashBuf + kHashBufferSize;
@ -496,14 +501,18 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
} }
/* Call it after ReleaseStream / SetStream */ /* Call it after ReleaseStream / SetStream */
void MatchFinderMt_Init(CMatchFinderMt *p) static void MatchFinderMt_Init(CMatchFinderMt *p)
{ {
CMatchFinder *mf = p->MatchFinder; CMatchFinder *mf = p->MatchFinder;
p->btBufPos = p->btBufPosLimit = 0;
p->hashBufPos = p->hashBufPosLimit = 0; p->btBufPos =
p->btBufPosLimit = 0;
p->hashBufPos =
p->hashBufPosLimit = 0;
/* Init without data reading. We don't want to read data in this thread */ /* Init without data reading. We don't want to read data in this thread */
MatchFinder_Init_2(mf, False); MatchFinder_Init_3(mf, False);
MatchFinder_Init_LowHash(mf);
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf); p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
p->btNumAvailBytes = 0; p->btNumAvailBytes = 0;
@ -591,10 +600,10 @@ static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *dista
MT_HASH3_CALC MT_HASH3_CALC
curMatch2 = hash[ h2]; curMatch2 = hash[ h2];
curMatch3 = hash[kFix3HashSize + h3]; curMatch3 = (hash + kFix3HashSize)[h3];
hash[ h2] = lzPos; hash[ h2] = lzPos;
hash[kFix3HashSize + h3] = lzPos; (hash + kFix3HashSize)[h3] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{ {
@ -627,12 +636,12 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distan
MT_HASH4_CALC MT_HASH4_CALC
curMatch2 = hash[ h2]; curMatch2 = hash[ h2];
curMatch3 = hash[kFix3HashSize + h3]; curMatch3 = (hash + kFix3HashSize)[h3];
curMatch4 = hash[kFix4HashSize + h4]; curMatch4 = (hash + kFix4HashSize)[h4];
hash[ h2] = lzPos; hash[ h2] = lzPos;
hash[kFix3HashSize + h3] = lzPos; (hash + kFix3HashSize)[h3] = lzPos;
hash[kFix4HashSize + h4] = lzPos; (hash + kFix4HashSize)[h4] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{ {
@ -684,8 +693,12 @@ static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
UInt32 i; UInt32 i;
for (i = 0; i < len; i += 2) for (i = 0; i < len; i += 2)
{ {
*distances++ = *btBuf++; UInt32 v0 = btBuf[0];
*distances++ = *btBuf++; UInt32 v1 = btBuf[1];
btBuf += 2;
distances[0] = v0;
distances[1] = v1;
distances += 2;
} }
} }
INCREASE_LZ_POS INCREASE_LZ_POS
@ -712,8 +725,12 @@ static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances); distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
do do
{ {
*distances2++ = *btBuf++; UInt32 v0 = btBuf[0];
*distances2++ = *btBuf++; UInt32 v1 = btBuf[1];
btBuf += 2;
distances2[0] = v0;
distances2[1] = v1;
distances2 += 2;
} }
while ((len -= 2) != 0); while ((len -= 2) != 0);
len = (UInt32)(distances2 - (distances)); len = (UInt32)(distances2 - (distances));
@ -746,7 +763,7 @@ static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
SKIP_HEADER_MT(3) SKIP_HEADER_MT(3)
UInt32 h2, h3; UInt32 h2, h3;
MT_HASH3_CALC MT_HASH3_CALC
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[ h2] = hash[ h2] =
p->lzPos; p->lzPos;
SKIP_FOOTER_MT SKIP_FOOTER_MT
@ -758,8 +775,8 @@ static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
SKIP_HEADER_MT(4) SKIP_HEADER_MT(4)
UInt32 h2, h3, h4; UInt32 h2, h3, h4;
MT_HASH4_CALC MT_HASH4_CALC
hash[kFix4HashSize + h4] = (hash + kFix4HashSize)[h4] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[ h2] = hash[ h2] =
p->lzPos; p->lzPos;
SKIP_FOOTER_MT SKIP_FOOTER_MT
@ -777,7 +794,7 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
{ {
case 2: case 2:
p->GetHeadsFunc = GetHeads2; p->GetHeadsFunc = GetHeads2;
p->MixMatchesFunc = (Mf_Mix_Matches)0; p->MixMatchesFunc = (Mf_Mix_Matches)NULL;
vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip; vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches; vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
break; break;

View file

@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2015-05-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H #ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H #define __LZ_FIND_MT_H
@ -90,9 +90,9 @@ typedef struct _CMatchFinderMt
} CMatchFinderMt; } CMatchFinderMt;
void MatchFinderMt_Construct(CMatchFinderMt *p); void MatchFinderMt_Construct(CMatchFinderMt *p);
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);

View file

@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2015-11-09 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
@ -74,14 +74,14 @@ static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
return SZ_OK; return SZ_OK;
} }
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
@ -105,16 +105,16 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
p->control = b; p->control = b;
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos)); PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", (unsigned)b)); PRF(printf(" %2X", (unsigned)b));
if (p->control == 0) if (b == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{ {
if ((p->control & 0x7F) > 2) if (b > 2)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
p->unpackSize = 0; p->unpackSize = 0;
} }
else else
p->unpackSize = (UInt32)(p->control & 0x1F) << 16; p->unpackSize = (UInt32)(b & 0x1F) << 16;
return LZMA2_STATE_UNPACK0; return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0: case LZMA2_STATE_UNPACK0:
@ -169,6 +169,7 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
@ -176,12 +177,17 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
*srcLen = 0; *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_FINISHED) while (p->state != LZMA2_STATE_ERROR)
{ {
SizeT dicPos = p->decoder.dicPos; SizeT dicPos;
if (p->state == LZMA2_STATE_FINISHED)
{
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
if (p->state == LZMA2_STATE_ERROR) dicPos = p->decoder.dicPos;
return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{ {
@ -198,29 +204,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
} }
(*srcLen)++; (*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++); p->state = Lzma2Dec_UpdateState(p, *src++);
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
{ break;
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
continue; continue;
} }
{ {
SizeT destSizeCur = dicLimit - dicPos; SizeT inCur = inSize - *srcLen;
SizeT srcSizeCur = inSize - *srcLen; SizeT outCur = dicLimit - dicPos;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur) if (outCur >= p->unpackSize)
{ {
destSizeCur = (SizeT)p->unpackSize; outCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END; curFinishMode = LZMA_FINISH_END;
} }
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{ {
if (*srcLen == inSize) if (inCur == 0)
{ {
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
@ -232,33 +234,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (initDic) if (initDic)
p->needInitProp = p->needInitState = True; p->needInitProp = p->needInitState = True;
else if (p->needInitDic) else if (p->needInitDic)
{ break;
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
p->needInitDic = False; p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False); LzmaDec_InitDicAndState(&p->decoder, initDic, False);
} }
if (srcSizeCur > destSizeCur) if (inCur > outCur)
srcSizeCur = destSizeCur; inCur = outCur;
if (inCur == 0)
break;
if (srcSizeCur == 0) LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); src += inCur;
*srcLen += inCur;
src += srcSizeCur; p->unpackSize -= (UInt32)inCur;
*srcLen += srcSizeCur;
p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
} }
else else
{ {
SizeT outSizeProcessed;
SRes res; SRes res;
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
@ -267,96 +261,98 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
Bool initDic = (mode == 3); Bool initDic = (mode == 3);
Bool initState = (mode != 0); Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
{ break;
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
LzmaDec_InitDicAndState(&p->decoder, initDic, initState); LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False; p->needInitDic = False;
p->needInitState = False; p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT; p->state = LZMA2_STATE_DATA_CONT;
} }
if (srcSizeCur > p->packSize) if (inCur > p->packSize)
srcSizeCur = (SizeT)p->packSize; inCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
src += srcSizeCur; src += inCur;
*srcLen += srcSizeCur; *srcLen += inCur;
p->packSize -= (UInt32)srcSizeCur; p->packSize -= (UInt32)inCur;
outCur = p->decoder.dicPos - dicPos;
p->unpackSize -= (UInt32)outCur;
outSizeProcessed = p->decoder.dicPos - dicPos; if (res != 0)
p->unpackSize -= (UInt32)outSizeProcessed; break;
RINOK(res);
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res; {
if (p->packSize == 0)
break;
return SZ_OK;
}
if (srcSizeCur == 0 && outSizeProcessed == 0) if (inCur == 0 && outCur == 0)
{ {
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0 || p->unpackSize != 0
|| p->packSize != 0) || p->packSize != 0)
{ break;
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
} }
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) *status = LZMA_STATUS_NOT_SPECIFIED;
*status = LZMA_STATUS_NOT_FINISHED;
} }
} }
} }
*status = LZMA_STATUS_FINISHED_WITH_MARK; *status = LZMA_STATUS_NOT_SPECIFIED;
return SZ_OK; p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
} }
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen, inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0; *srcLen = *destLen = 0;
for (;;) for (;;)
{ {
SizeT srcSizeCur = inSize, outSizeCur, dicPos; SizeT inCur = inSize, outCur, dicPos;
ELzmaFinishMode curFinishMode; ELzmaFinishMode curFinishMode;
SRes res; SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize) if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0; p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos; dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos) curFinishMode = LZMA_FINISH_ANY;
outCur = p->decoder.dicBufSize - dicPos;
if (outCur >= outSize)
{ {
outSizeCur = p->decoder.dicBufSize; outCur = outSize;
curFinishMode = LZMA_FINISH_ANY;
}
else
{
outSizeCur = dicPos + outSize;
curFinishMode = finishMode; curFinishMode = finishMode;
} }
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
src += srcSizeCur;
inSize -= srcSizeCur; src += inCur;
*srcLen += srcSizeCur; inSize -= inCur;
outSizeCur = p->decoder.dicPos - dicPos; *srcLen += inCur;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur); outCur = p->decoder.dicPos - dicPos;
dest += outSizeCur; memcpy(dest, p->decoder.dic + dicPos, outCur);
outSize -= outSizeCur; dest += outCur;
*destLen += outSizeCur; outSize -= outCur;
*destLen += outCur;
if (res != 0) if (res != 0)
return res; return res;
if (outSizeCur == 0 || outSize == 0) if (outCur == 0 || outSize == 0)
return SZ_OK; return SZ_OK;
} }
} }
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
{ {
CLzma2Dec p; CLzma2Dec p;
SRes res; SRes res;

View file

@ -1,5 +1,5 @@
/* Lzma2Dec.h -- LZMA2 Decoder /* Lzma2Dec.h -- LZMA2 Decoder
2015-05-13 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H #ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H #define __LZMA2_DEC_H
@ -26,8 +26,8 @@ typedef struct
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); #define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); #define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p); void Lzma2Dec_Init(CLzma2Dec *p);
@ -73,7 +73,7 @@ Returns:
*/ */
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END

View file

@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder /* LzmaDec.c -- LZMA Decoder
2015-06-23 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -294,14 +294,14 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
#ifdef _LZMA_SIZE_OPT #ifdef _LZMA_SIZE_OPT
{ {
unsigned limit, offset; unsigned lim, offset;
CLzmaProb *probLen = prob + LenChoice; CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0; offset = 0;
limit = (1 << kLenNumLowBits); lim = (1 << kLenNumLowBits);
} }
else else
{ {
@ -312,17 +312,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits); probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols; offset = kLenNumLowSymbols;
limit = (1 << kLenNumMidBits); lim = (1 << kLenNumMidBits);
} }
else else
{ {
UPDATE_1(probLen); UPDATE_1(probLen);
probLen = prob + LenHigh; probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols; offset = kLenNumLowSymbols + kLenNumMidSymbols;
limit = (1 << kLenNumHighBits); lim = (1 << kLenNumHighBits);
} }
} }
TREE_DECODE(probLen, limit, len); TREE_DECODE(probLen, lim, len);
len += offset; len += offset;
} }
#else #else
@ -975,19 +975,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
} }
} }
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->probs); ISzAlloc_Free(alloc, p->probs);
p->probs = NULL; p->probs = NULL;
} }
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->dic); ISzAlloc_Free(alloc, p->dic);
p->dic = NULL; p->dic = NULL;
} }
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc); LzmaDec_FreeDict(p, alloc);
@ -1019,13 +1019,13 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
return SZ_OK; return SZ_OK;
} }
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
{ {
UInt32 numProbs = LzmaProps_GetNumProbs(propNew); UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (!p->probs || numProbs != p->numProbs) if (!p->probs || numProbs != p->numProbs)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs; p->numProbs = numProbs;
if (!p->probs) if (!p->probs)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
@ -1033,7 +1033,7 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
return SZ_OK; return SZ_OK;
} }
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{ {
CLzmaProps propNew; CLzmaProps propNew;
RINOK(LzmaProps_Decode(&propNew, props, propsSize)); RINOK(LzmaProps_Decode(&propNew, props, propsSize));
@ -1042,7 +1042,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I
return SZ_OK; return SZ_OK;
} }
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{ {
CLzmaProps propNew; CLzmaProps propNew;
SizeT dicBufSize; SizeT dicBufSize;
@ -1062,7 +1062,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
if (!p->dic || dicBufSize != p->dicBufSize) if (!p->dic || dicBufSize != p->dicBufSize)
{ {
LzmaDec_FreeDict(p, alloc); LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
if (!p->dic) if (!p->dic)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
@ -1076,7 +1076,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc) ELzmaStatus *status, ISzAllocPtr alloc)
{ {
CLzmaDec p; CLzmaDec p;
SRes res; SRes res;

View file

@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2013-01-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H #ifndef __LZMA_DEC_H
#define __LZMA_DEC_H #define __LZMA_DEC_H
@ -129,11 +129,11 @@ LzmaDec_Allocate* can return:
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); void LzmaDec_Free(CLzmaDec *state, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */ /* ---------- Dictionary Interface ---------- */
@ -220,7 +220,7 @@ Returns:
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc); ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END

View file

@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder /* LzmaEnc.c -- LZMA Encoder
2015-11-08 : Igor Pavlov : Public domain */ 2017-06-22 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -23,8 +23,8 @@
static unsigned g_STAT_OFFSET = 0; static unsigned g_STAT_OFFSET = 0;
#endif #endif
#define kMaxHistorySize ((UInt32)3 << 29) #define kLzmaMaxHistorySize ((UInt32)3 << 29)
/* #define kMaxHistorySize ((UInt32)7 << 29) */ /* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) #define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
@ -62,14 +62,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if (level < 0) level = 5; if (level < 0) level = 5;
p->level = level; p->level = level;
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26)));
if (p->dictSize > p->reduceSize) if (p->dictSize > p->reduceSize)
{ {
unsigned i; unsigned i;
UInt32 reduceSize = (UInt32)p->reduceSize;
for (i = 11; i <= 30; i++) for (i = 11; i <= 30; i++)
{ {
if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
} }
} }
@ -108,7 +109,7 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
#define kDicLogSizeMaxCompress 32 #define kDicLogSizeMaxCompress 32
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } #define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
static UInt32 GetPosSlot1(UInt32 pos) static UInt32 GetPosSlot1(UInt32 pos)
{ {
@ -145,19 +146,19 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos)
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ /* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
/* /*
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ #define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
res = p->g_FastPos[pos >> i] + (i * 2); } res = p->g_FastPos[pos >> zz] + (zz * 2); }
*/ */
/* /*
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ #define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
res = p->g_FastPos[pos >> i] + (i * 2); } res = p->g_FastPos[pos >> zz] + (zz * 2); }
*/ */
#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ #define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
res = p->g_FastPos[pos >> i] + (i * 2); } res = p->g_FastPos[pos >> zz] + (zz * 2); }
/* /*
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
@ -445,7 +446,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|| props.lp > LZMA_LP_MAX || props.lp > LZMA_LP_MAX
|| props.pb > LZMA_PB_MAX || props.pb > LZMA_PB_MAX
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|| props.dictSize > kMaxHistorySize) || props.dictSize > kLzmaMaxHistorySize)
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
p->dictSize = props.dictSize; p->dictSize = props.dictSize;
@ -492,6 +493,15 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
return SZ_OK; return SZ_OK;
} }
void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.expectedDataSize = expectedDataSiize;
}
static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; 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 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 kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
@ -512,11 +522,11 @@ static void RangeEnc_Construct(CRangeEnc *p)
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) #define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
#define RC_BUF_SIZE (1 << 16) #define RC_BUF_SIZE (1 << 16)
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
{ {
if (!p->bufBase) if (!p->bufBase)
{ {
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
if (!p->bufBase) if (!p->bufBase)
return 0; return 0;
p->bufLim = p->bufBase + RC_BUF_SIZE; p->bufLim = p->bufBase + RC_BUF_SIZE;
@ -524,9 +534,9 @@ static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
return 1; return 1;
} }
static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->bufBase); ISzAlloc_Free(alloc, p->bufBase);
p->bufBase = 0; p->bufBase = 0;
} }
@ -550,7 +560,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
if (p->res != SZ_OK) if (p->res != SZ_OK)
return; return;
num = p->buf - p->bufBase; num = p->buf - p->bufBase;
if (num != p->outStream->Write(p->outStream, p->bufBase, num)) if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
p->res = SZ_ERROR_WRITE; p->res = SZ_ERROR_WRITE;
p->processed += num; p->processed += num;
p->buf = p->bufBase; p->buf = p->bufBase;
@ -882,7 +892,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
if (numPairs > 0) if (numPairs > 0)
{ {
lenRes = p->matches[numPairs - 2]; lenRes = p->matches[(size_t)numPairs - 2];
if (lenRes == p->numFastBytes) if (lenRes == p->numFastBytes)
{ {
UInt32 numAvail = p->numAvail; UInt32 numAvail = p->numAvail;
@ -891,7 +901,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
{ {
const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
const Byte *pby = pbyCur + lenRes; const Byte *pby = pbyCur + lenRes;
ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1]; ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];
const Byte *pbyLim = pbyCur + numAvail; const Byte *pbyLim = pbyCur + numAvail;
for (; pby != pbyLim && *pby == pby[dif]; pby++); for (; pby != pbyLim && *pby == pby[dif]; pby++);
lenRes = (UInt32)(pby - pbyCur); lenRes = (UInt32)(pby - pbyCur);
@ -939,7 +949,7 @@ static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32
static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
{ {
return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + return p->repLenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN] +
GetPureRepPrice(p, repIndex, state, posState); GetPureRepPrice(p, repIndex, state, posState);
} }
@ -956,9 +966,9 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
p->opt[posMem].posPrev = posMem - 1; p->opt[posMem].posPrev = posMem - 1;
if (p->opt[cur].prev2) if (p->opt[cur].prev2)
{ {
p->opt[posMem - 1].prev1IsChar = False; p->opt[(size_t)posMem - 1].prev1IsChar = False;
p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; p->opt[(size_t)posMem - 1].posPrev = p->opt[cur].posPrev2;
p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; p->opt[(size_t)posMem - 1].backPrev = p->opt[cur].backPrev2;
} }
} }
{ {
@ -983,12 +993,17 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{ {
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; UInt32 lenEnd, cur;
UInt32 matchPrice, repMatchPrice, normalMatchPrice;
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
UInt32 *matches; UInt32 *matches;
{
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;
UInt32 matchPrice, repMatchPrice, normalMatchPrice;
const Byte *data; const Byte *data;
Byte curByte, matchByte; Byte curByte, matchByte;
if (p->optimumEndIndex != p->optimumCurrentIndex) if (p->optimumEndIndex != p->optimumCurrentIndex)
{ {
const COptimal *opt = &p->opt[p->optimumCurrentIndex]; const COptimal *opt = &p->opt[p->optimumCurrentIndex];
@ -1046,7 +1061,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
matches = p->matches; matches = p->matches;
if (mainLen >= p->numFastBytes) if (mainLen >= p->numFastBytes)
{ {
*backRes = matches[numPairs - 1] + LZMA_NUM_REPS; *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
MovePos(p, mainLen - 1); MovePos(p, mainLen - 1);
return mainLen; return mainLen;
} }
@ -1111,7 +1126,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
do do
{ {
UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];
COptimal *opt = &p->opt[repLen]; COptimal *opt = &p->opt[repLen];
if (curAndLenPrice < opt->price) if (curAndLenPrice < opt->price)
{ {
@ -1135,9 +1150,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
for (; ; len++) for (; ; len++)
{ {
COptimal *opt; COptimal *opt;
UInt32 distance = matches[offs + 1]; UInt32 distance = matches[(size_t)offs + 1];
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
UInt32 lenToPosState = GetLenToPosState(len); UInt32 lenToPosState = GetLenToPosState(len);
if (distance < kNumFullDistances) if (distance < kNumFullDistances)
curAndLenPrice += p->distancesPrices[lenToPosState][distance]; curAndLenPrice += p->distancesPrices[lenToPosState][distance];
@ -1176,8 +1191,11 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
} }
#endif #endif
}
for (;;) for (;;)
{ {
UInt32 numAvail;
UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
Bool nextIsChar; Bool nextIsChar;
@ -1248,7 +1266,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 i; UInt32 i;
reps[0] = prevOpt->backs[pos]; reps[0] = prevOpt->backs[pos];
for (i = 1; i <= pos; i++) for (i = 1; i <= pos; i++)
reps[i] = prevOpt->backs[i - 1]; reps[i] = prevOpt->backs[(size_t)i - 1];
for (; i < LZMA_NUM_REPS; i++) for (; i < LZMA_NUM_REPS; i++)
reps[i] = prevOpt->backs[i]; reps[i] = prevOpt->backs[i];
} }
@ -1257,7 +1275,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 i; UInt32 i;
reps[0] = (pos - LZMA_NUM_REPS); reps[0] = (pos - LZMA_NUM_REPS);
for (i = 1; i < LZMA_NUM_REPS; i++) for (i = 1; i < LZMA_NUM_REPS; i++)
reps[i] = prevOpt->backs[i - 1]; reps[i] = prevOpt->backs[(size_t)i - 1];
} }
} }
curOpt->state = (CState)state; curOpt->state = (CState)state;
@ -1284,7 +1302,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
LitEnc_GetPrice(probs, curByte, p->ProbPrices)); LitEnc_GetPrice(probs, curByte, p->ProbPrices));
} }
nextOpt = &p->opt[cur + 1]; nextOpt = &p->opt[(size_t)cur + 1];
if (curAnd1Price < nextOpt->price) if (curAnd1Price < nextOpt->price)
{ {
@ -1377,7 +1395,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
do do
{ {
UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)lenTest - 2];
COptimal *opt = &p->opt[cur + lenTest]; COptimal *opt = &p->opt[cur + lenTest];
if (curAndLenPrice < opt->price) if (curAndLenPrice < opt->price)
{ {
@ -1407,9 +1425,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 state2 = kRepNextStates[state]; UInt32 state2 = kRepNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = UInt32 curAndLenCharPrice =
price + p->repLenEnc.prices[posState][lenTest - 2] + price + p->repLenEnc.prices[posState][(size_t)lenTest - 2] +
GET_PRICE_0(p->isMatch[state2][posStateNext]) + GET_PRICE_0(p->isMatch[state2][posStateNext]) +
LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
data[lenTest], data2[lenTest], p->ProbPrices); data[lenTest], data2[lenTest], p->ProbPrices);
state2 = kLiteralNextStates[state2]; state2 = kLiteralNextStates[state2];
posStateNext = (position + lenTest + 1) & p->pbMask; posStateNext = (position + lenTest + 1) & p->pbMask;
@ -1460,11 +1478,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
offs = 0; offs = 0;
while (startLen > matches[offs]) while (startLen > matches[offs])
offs += 2; offs += 2;
curBack = matches[offs + 1]; curBack = matches[(size_t)offs + 1];
GetPosSlot2(curBack, posSlot); GetPosSlot2(curBack, posSlot);
for (lenTest = /*2*/ startLen; ; lenTest++) for (lenTest = /*2*/ startLen; ; lenTest++)
{ {
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)lenTest - LZMA_MATCH_LEN_MIN];
{
UInt32 lenToPosState = GetLenToPosState(lenTest); UInt32 lenToPosState = GetLenToPosState(lenTest);
COptimal *opt; COptimal *opt;
if (curBack < kNumFullDistances) if (curBack < kNumFullDistances)
@ -1480,6 +1499,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
opt->backPrev = curBack + LZMA_NUM_REPS; opt->backPrev = curBack + LZMA_NUM_REPS;
opt->prev1IsChar = False; opt->prev1IsChar = False;
} }
}
if (/*_maxMode && */lenTest == matches[offs]) if (/*_maxMode && */lenTest == matches[offs])
{ {
@ -1498,7 +1518,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = curAndLenPrice + UInt32 curAndLenCharPrice = curAndLenPrice +
GET_PRICE_0(p->isMatch[state2][posStateNext]) + GET_PRICE_0(p->isMatch[state2][posStateNext]) +
LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
data[lenTest], data2[lenTest], p->ProbPrices); data[lenTest], data2[lenTest], p->ProbPrices);
state2 = kLiteralNextStates[state2]; state2 = kLiteralNextStates[state2];
posStateNext = (posStateNext + 1) & p->pbMask; posStateNext = (posStateNext + 1) & p->pbMask;
@ -1509,15 +1529,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
/* for (; lenTest2 >= 2; lenTest2--) */ /* for (; lenTest2 >= 2; lenTest2--) */
{ {
UInt32 offset = cur + lenTest + 1 + lenTest2; UInt32 offset = cur + lenTest + 1 + lenTest2;
UInt32 curAndLenPrice; UInt32 curAndLenPrice2;
COptimal *opt; COptimal *opt;
while (lenEnd < offset) while (lenEnd < offset)
p->opt[++lenEnd].price = kInfinityPrice; p->opt[++lenEnd].price = kInfinityPrice;
curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
opt = &p->opt[offset]; opt = &p->opt[offset];
if (curAndLenPrice < opt->price) if (curAndLenPrice2 < opt->price)
{ {
opt->price = curAndLenPrice; opt->price = curAndLenPrice2;
opt->posPrev = cur + lenTest + 1; opt->posPrev = cur + lenTest + 1;
opt->backPrev = 0; opt->backPrev = 0;
opt->prev1IsChar = True; opt->prev1IsChar = True;
@ -1530,7 +1550,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
offs += 2; offs += 2;
if (offs == numPairs) if (offs == numPairs)
break; break;
curBack = matches[offs + 1]; curBack = matches[(size_t)offs + 1];
if (curBack >= kNumFullDistances) if (curBack >= kNumFullDistances)
GetPosSlot2(curBack, posSlot); GetPosSlot2(curBack, posSlot);
} }
@ -1587,7 +1607,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
matches = p->matches; matches = p->matches;
if (mainLen >= p->numFastBytes) if (mainLen >= p->numFastBytes)
{ {
*backRes = matches[numPairs - 1] + LZMA_NUM_REPS; *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
MovePos(p, mainLen - 1); MovePos(p, mainLen - 1);
return mainLen; return mainLen;
} }
@ -1595,14 +1615,14 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
mainDist = 0; /* for GCC */ mainDist = 0; /* for GCC */
if (mainLen >= 2) if (mainLen >= 2)
{ {
mainDist = matches[numPairs - 1]; mainDist = matches[(size_t)numPairs - 1];
while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) while (numPairs > 2 && mainLen == matches[(size_t)numPairs - 4] + 1)
{ {
if (!ChangePair(matches[numPairs - 3], mainDist)) if (!ChangePair(matches[(size_t)numPairs - 3], mainDist))
break; break;
numPairs -= 2; numPairs -= 2;
mainLen = matches[numPairs - 2]; mainLen = matches[(size_t)numPairs - 2];
mainDist = matches[numPairs - 1]; mainDist = matches[(size_t)numPairs - 1];
} }
if (mainLen == 2 && mainDist >= 0x80) if (mainLen == 2 && mainDist >= 0x80)
mainLen = 1; mainLen = 1;
@ -1624,7 +1644,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
if (p->longestMatchLength >= 2) if (p->longestMatchLength >= 2)
{ {
UInt32 newDistance = matches[p->numPairs - 1]; UInt32 newDistance = matches[(size_t)p->numPairs - 1];
if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
(p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
(p->longestMatchLength > mainLen + 1) || (p->longestMatchLength > mainLen + 1) ||
@ -1718,7 +1738,6 @@ static void FillDistancesPrices(CLzmaEnc *p)
{ {
UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
UInt32 i;
for (i = 0; i < kStartPosModelIndex; i++) for (i = 0; i < kStartPosModelIndex; i++)
distancesPrices[i] = posSlotPrices[i]; distancesPrices[i] = posSlotPrices[i];
for (; i < kNumFullDistances; i++) for (; i < kNumFullDistances; i++)
@ -1753,24 +1772,24 @@ void LzmaEnc_Construct(CLzmaEnc *p)
p->saveState.litProbs = NULL; p->saveState.litProbs = NULL;
} }
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
{ {
void *p; void *p;
p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
if (p) if (p)
LzmaEnc_Construct((CLzmaEnc *)p); LzmaEnc_Construct((CLzmaEnc *)p);
return p; return p;
} }
void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->litProbs); ISzAlloc_Free(alloc, p->litProbs);
alloc->Free(alloc, p->saveState.litProbs); ISzAlloc_Free(alloc, p->saveState.litProbs);
p->litProbs = NULL; p->litProbs = NULL;
p->saveState.litProbs = NULL; p->saveState.litProbs = NULL;
} }
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
@ -1781,10 +1800,10 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
RangeEnc_Free(&p->rc, alloc); RangeEnc_Free(&p->rc, alloc);
} }
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
alloc->Free(alloc, p); ISzAlloc_Free(alloc, p);
} }
static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
@ -1951,7 +1970,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
#define kBigHashDicLimit ((UInt32)1 << 24) #define kBigHashDicLimit ((UInt32)1 << 24)
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
UInt32 beforeSize = kNumOpts; UInt32 beforeSize = kNumOpts;
if (!RangeEnc_Alloc(&p->rc, alloc)) if (!RangeEnc_Alloc(&p->rc, alloc))
@ -1966,8 +1985,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
{ {
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
if (!p->litProbs || !p->saveState.litProbs) if (!p->litProbs || !p->saveState.litProbs)
{ {
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
@ -1987,6 +2006,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
{ {
RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
p->matchFinderObj = &p->matchFinderMt; p->matchFinderObj = &p->matchFinderMt;
p->matchFinderBase.bigHash = (Byte)(
(p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);
MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
} }
else else
@ -2075,7 +2096,7 @@ void LzmaEnc_InitPrices(CLzmaEnc *p)
LenPriceEnc_UpdateTables(&p->repLenEnc, 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) static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
UInt32 i; UInt32 i;
for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
@ -2093,7 +2114,7 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a
} }
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
ISzAlloc *alloc, ISzAlloc *allocBig) ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream; p->matchFinderBase.stream = inStream;
@ -2104,7 +2125,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
ISeqInStream *inStream, UInt32 keepWindowSize, ISeqInStream *inStream, UInt32 keepWindowSize,
ISzAlloc *alloc, ISzAlloc *allocBig) ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream; p->matchFinderBase.stream = inStream;
@ -2120,12 +2141,13 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
} }
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
LzmaEnc_SetInputBuf(p, src, srcLen); LzmaEnc_SetInputBuf(p, src, srcLen);
p->needInit = 1; p->needInit = 1;
LzmaEnc_SetDataSize(pp, srcLen);
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
} }
@ -2143,15 +2165,15 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
typedef struct typedef struct
{ {
ISeqOutStream funcTable; ISeqOutStream vt;
Byte *data; Byte *data;
SizeT rem; SizeT rem;
Bool overflow; Bool overflow;
} CSeqOutStreamBuf; } CLzmaEnc_SeqOutStreamBuf;
static size_t MyWrite(void *pp, const void *data, size_t size) static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size)
{ {
CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt);
if (p->rem < size) if (p->rem < size)
{ {
size = p->rem; size = p->rem;
@ -2184,9 +2206,9 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
UInt64 nowPos64; UInt64 nowPos64;
SRes res; SRes res;
CSeqOutStreamBuf outStream; CLzmaEnc_SeqOutStreamBuf outStream;
outStream.funcTable.Write = MyWrite; outStream.vt.Write = SeqOutStreamBuf_Write;
outStream.data = dest; outStream.data = dest;
outStream.rem = *destLen; outStream.rem = *destLen;
outStream.overflow = False; outStream.overflow = False;
@ -2200,7 +2222,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
LzmaEnc_InitPrices(p); LzmaEnc_InitPrices(p);
nowPos64 = p->nowPos64; nowPos64 = p->nowPos64;
RangeEnc_Init(&p->rc); RangeEnc_Init(&p->rc);
p->rc.outStream = &outStream.funcTable; p->rc.outStream = &outStream.vt;
res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
@ -2230,7 +2252,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
break; break;
if (progress) if (progress)
{ {
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
if (res != SZ_OK) if (res != SZ_OK)
{ {
res = SZ_ERROR_PROGRESS; res = SZ_ERROR_PROGRESS;
@ -2242,7 +2264,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
LzmaEnc_Finish(p); LzmaEnc_Finish(p);
/* /*
if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase)) if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
res = SZ_ERROR_FAIL; res = SZ_ERROR_FAIL;
} }
*/ */
@ -2252,7 +2274,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
ISzAlloc *alloc, ISzAlloc *allocBig) ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
@ -2287,21 +2309,27 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
} }
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp)
{
return ((CLzmaEnc *)pp)->writeEndMark;
}
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
SRes res; SRes res;
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
CSeqOutStreamBuf outStream; CLzmaEnc_SeqOutStreamBuf outStream;
outStream.funcTable.Write = MyWrite; outStream.vt.Write = SeqOutStreamBuf_Write;
outStream.data = dest; outStream.data = dest;
outStream.rem = *destLen; outStream.rem = *destLen;
outStream.overflow = False; outStream.overflow = False;
p->writeEndMark = writeEndMark; p->writeEndMark = writeEndMark;
p->rc.outStream = &outStream.funcTable; p->rc.outStream = &outStream.vt;
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
@ -2321,7 +2349,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
SRes res; SRes res;

View file

@ -1,5 +1,5 @@
/* LzmaEnc.h -- LZMA Encoder /* LzmaEnc.h -- LZMA Encoder
2013-01-18 : Igor Pavlov : Public domain */ 2017-07-27 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H #ifndef __LZMA_ENC_H
#define __LZMA_ENC_H #define __LZMA_ENC_H
@ -12,12 +12,10 @@ EXTERN_C_BEGIN
typedef struct _CLzmaEncProps typedef struct _CLzmaEncProps
{ {
int level; /* 0 <= level <= 9 */ int level; /* 0 <= level <= 9 */
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version (1 << 12) <= dictSize <= (3 << 29) for 64-bit version
default = (1 << 24) */ default = (1 << 24) */
UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
Encoder uses this value to reduce dictionary size */
int lc; /* 0 <= lc <= 8, default = 3 */ int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */ int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */ int pb; /* 0 <= pb <= 4, default = 2 */
@ -25,9 +23,12 @@ typedef struct _CLzmaEncProps
int fb; /* 5 <= fb <= 273, default = 32 */ int fb; /* 5 <= fb <= 273, default = 32 */
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
int numHashBytes; /* 2, 3 or 4, default = 4 */ int numHashBytes; /* 2, 3 or 4, default = 4 */
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
int numThreads; /* 1 or 2, default = 2 */ int numThreads; /* 1 or 2, default = 2 */
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
Encoder uses this value to reduce dictionary size */
} CLzmaEncProps; } CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p); void LzmaEncProps_Init(CLzmaEncProps *p);
@ -37,41 +38,38 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
/* ---------- CLzmaEncHandle Interface ---------- */ /* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc_* functions can return the following exit codes: /* LzmaEnc* functions can return the following exit codes:
Returns: SRes:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - Write callback error. SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/ */
typedef void * CLzmaEncHandle; typedef void * CLzmaEncHandle;
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
/* ---------- One Call Interface ---------- */ /* ---------- 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, SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
EXTERN_C_END EXTERN_C_END

View file

@ -1,5 +1,5 @@
/* Ppmd.h -- PPMD codec common code /* Ppmd.h -- PPMD codec common code
2013-01-18 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H #ifndef __PPMD_H
@ -77,8 +77,8 @@ typedef
CPpmd_Byte_Ref; CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \ #define PPMD_SetAllBitsIn256Bytes(p) \
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \ { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }} p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
EXTERN_C_END EXTERN_C_END

View file

@ -1,5 +1,5 @@
/* Ppmd7.c -- PPMdH codec /* Ppmd7.c -- PPMdH codec
2015-09-28 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
#define UNIT_SIZE 12 #define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
#define U2I(nu) (p->Units2Indx[(nu) - 1]) #define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx]) #define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
@ -88,29 +88,31 @@ void Ppmd7_Construct(CPpmd7 *p)
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
} }
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->Base); ISzAlloc_Free(alloc, p->Base);
p->Size = 0; p->Size = 0;
p->Base = 0; p->Base = 0;
} }
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
{ {
if (p->Base == 0 || p->Size != size) if (!p->Base || p->Size != size)
{ {
size_t size2;
Ppmd7_Free(p, alloc); Ppmd7_Free(p, alloc);
size2 = 0
#ifndef PPMD_32BIT
+ UNIT_SIZE
#endif
;
p->AlignOffset = p->AlignOffset =
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
(4 - size) & 3; (4 - size) & 3;
#else #else
4 - (size & 3); 4 - (size & 3);
#endif #endif
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0)
#ifndef PPMD_32BIT
+ UNIT_SIZE
#endif
)) == 0)
return False; return False;
p->Size = size; p->Size = size;
} }
@ -276,12 +278,12 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU
return oldPtr; return oldPtr;
} }
#define SUCCESSOR(p) ((CPpmd_Void_Ref)(size_t)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) #define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
{ {
(p)->SuccessorLow = (UInt16)((UInt32)((size_t)v) & 0xFFFF); (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
(p)->SuccessorHigh = (UInt16)(((UInt32)((size_t)v) >> 16) & 0xFFFF); (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
} }
static void RestartModel(CPpmd7 *p) static void RestartModel(CPpmd7 *p)
@ -513,7 +515,7 @@ static void UpdateModel(CPpmd7 *p)
/* Expand for one UNIT */ /* Expand for one UNIT */
unsigned oldNU = ns1 >> 1; unsigned oldNU = ns1 >> 1;
unsigned i = U2I(oldNU); unsigned i = U2I(oldNU);
if (i != U2I(oldNU + 1)) if (i != U2I((size_t)oldNU + 1))
{ {
void *ptr = AllocUnits(p, i + 1); void *ptr = AllocUnits(p, i + 1);
void *oldPtr; void *oldPtr;
@ -639,10 +641,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
unsigned nonMasked = p->MinContext->NumStats - numMasked; unsigned nonMasked = p->MinContext->NumStats - numMasked;
if (p->MinContext->NumStats != 256) if (p->MinContext->NumStats != 256)
{ {
see = p->See[p->NS2Indx[nonMasked - 1]] + see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] +
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + 2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
4 * (numMasked > nonMasked) + 4 * (unsigned)(numMasked > nonMasked) +
p->HiBitsFlag; p->HiBitsFlag;
{ {
unsigned r = (see->Summ >> see->Shift); unsigned r = (see->Summ >> see->Shift);

View file

@ -1,5 +1,5 @@
/* Ppmd7.h -- PPMdH compression codec /* Ppmd7.h -- PPMdH compression codec
2010-03-12 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation /* This code supports virtual RangeDecoder and includes the implementation
@ -60,8 +60,8 @@ typedef struct
} CPpmd7; } CPpmd7;
void Ppmd7_Construct(CPpmd7 *p); void Ppmd7_Construct(CPpmd7 *p);
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p);
void Ppmd7_UpdateBin(CPpmd7 *p); void Ppmd7_UpdateBin(CPpmd7 *p);
#define Ppmd7_GetBinSumm(p) \ #define Ppmd7_GetBinSumm(p) \
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ 2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
((p->RunLength >> 26) & 0x20)] ((p->RunLength >> 26) & 0x20)]
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
@ -97,16 +97,18 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
/* ---------- Decode ---------- */ /* ---------- Decode ---------- */
typedef struct typedef struct IPpmd7_RangeDec IPpmd7_RangeDec;
struct IPpmd7_RangeDec
{ {
UInt32 (*GetThreshold)(void *p, UInt32 total); UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total);
void (*Decode)(void *p, UInt32 start, UInt32 size); void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(void *p, UInt32 size0); UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0);
} IPpmd7_RangeDec; };
typedef struct typedef struct
{ {
IPpmd7_RangeDec p; IPpmd7_RangeDec vt;
UInt32 Range; UInt32 Range;
UInt32 Code; UInt32 Code;
IByteIn *Stream; IByteIn *Stream;
@ -116,7 +118,7 @@ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
/* ---------- Encode ---------- */ /* ---------- Encode ---------- */

View file

@ -1,5 +1,5 @@
/* Ppmd7Dec.c -- PPMdH Decoder /* Ppmd7Dec.c -- PPMdH Decoder
2010-03-12 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -13,44 +13,46 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
unsigned i; unsigned i;
p->Code = 0; p->Code = 0;
p->Range = 0xFFFFFFFF; p->Range = 0xFFFFFFFF;
if (p->Stream->Read((void *)p->Stream) != 0) if (IByteIn_Read(p->Stream) != 0)
return False; return False;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
return (p->Code < 0xFFFFFFFF); return (p->Code < 0xFFFFFFFF);
} }
static UInt32 Range_GetThreshold(void *pp, UInt32 total) #define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
{ {
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; GET_Ppmd7z_RangeDec
return (p->Code) / (p->Range /= total); return p->Code / (p->Range /= total);
} }
static void Range_Normalize(CPpmd7z_RangeDec *p) static void Range_Normalize(CPpmd7z_RangeDec *p)
{ {
if (p->Range < kTopValue) if (p->Range < kTopValue)
{ {
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8; p->Range <<= 8;
if (p->Range < kTopValue) if (p->Range < kTopValue)
{ {
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8; p->Range <<= 8;
} }
} }
} }
static void Range_Decode(void *pp, UInt32 start, UInt32 size) static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
{ {
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; GET_Ppmd7z_RangeDec
p->Code -= start * p->Range; p->Code -= start * p->Range;
p->Range *= size; p->Range *= size;
Range_Normalize(p); Range_Normalize(p);
} }
static UInt32 Range_DecodeBit(void *pp, UInt32 size0) static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
{ {
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; GET_Ppmd7z_RangeDec
UInt32 newBound = (p->Range >> 14) * size0; UInt32 newBound = (p->Range >> 14) * size0;
UInt32 symbol; UInt32 symbol;
if (p->Code < newBound) if (p->Code < newBound)
@ -70,15 +72,15 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{ {
p->p.GetThreshold = Range_GetThreshold; p->vt.GetThreshold = Range_GetThreshold;
p->p.Decode = Range_Decode; p->vt.Decode = Range_Decode;
p->p.DecodeBit = Range_DecodeBit; p->vt.DecodeBit = Range_DecodeBit;
} }
#define MASK(sym) ((signed char *)charMask)[sym] #define MASK(sym) ((signed char *)charMask)[sym]
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc)
{ {
size_t charMask[256 / sizeof(size_t)]; size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1) if (p->MinContext->NumStats != 1)

View file

@ -1,5 +1,5 @@
/* Threads.c -- multithreading library /* Threads.c -- multithreading library
2014-09-21 : Igor Pavlov : Public domain */ 2017-06-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -12,18 +12,20 @@
static WRes GetError() static WRes GetError()
{ {
DWORD res = GetLastError(); DWORD res = GetLastError();
return (res) ? (WRes)(res) : 1; return res ? (WRes)res : 1;
} }
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
WRes HandlePtr_Close(HANDLE *p) WRes HandlePtr_Close(HANDLE *p)
{ {
if (*p != NULL) if (*p != NULL)
{
if (!CloseHandle(*p)) if (!CloseHandle(*p))
return GetError(); return GetError();
*p = NULL; *p = NULL;
}
return 0; return 0;
} }
@ -49,7 +51,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
return HandleToWRes(*p); return HandleToWRes(*p);
} }
WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
{ {
*p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
return HandleToWRes(*p); return HandleToWRes(*p);

View file

@ -1,5 +1,5 @@
/* Threads.h -- multithreading library /* Threads.h -- multithreading library
2013-11-12 : Igor Pavlov : Public domain */ 2017-06-18 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H #ifndef __7Z_THREADS_H
#define __7Z_THREADS_H #define __7Z_THREADS_H
@ -49,7 +49,8 @@ WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
typedef HANDLE CSemaphore; typedef HANDLE CSemaphore;
#define Semaphore_Construct(p) (*p) = NULL #define Semaphore_Construct(p) *(p) = NULL
#define Semaphore_IsCreated(p) (*(p) != NULL)
#define Semaphore_Close(p) HandlePtr_Close(p) #define Semaphore_Close(p) HandlePtr_Close(p)
#define Semaphore_Wait(p) Handle_WaitObject(*(p)) #define Semaphore_Wait(p) Handle_WaitObject(*(p))
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);

View file

@ -2138,7 +2138,7 @@ static void AddAutoloadFiles(const char *autoname)
D_AddDirectory (allwads, file); D_AddDirectory (allwads, file);
#ifdef __unix__ #ifdef __unix__
file = NicePath("~/" GAME_DIR "/skins"); file = NicePath("$HOME/" GAME_DIR "/skins");
D_AddDirectory (allwads, file); D_AddDirectory (allwads, file);
#endif #endif

View file

@ -372,6 +372,7 @@ struct FMapThing
uint32_t RenderStyle; uint32_t RenderStyle;
int FloatbobPhase; int FloatbobPhase;
int friendlyseeblocks; int friendlyseeblocks;
FNameNoInit arg0str;
}; };

View file

@ -39,7 +39,6 @@
#include "actor.h" #include "actor.h"
#include "c_dispatch.h" #include "c_dispatch.h"
#include "d_net.h" #include "d_net.h"
#include "vm.h"
DStaticEventHandler* E_FirstEventHandler = nullptr; DStaticEventHandler* E_FirstEventHandler = nullptr;
DStaticEventHandler* E_LastEventHandler = nullptr; DStaticEventHandler* E_LastEventHandler = nullptr;

View file

@ -393,8 +393,8 @@ struct FileReaderLZMA::StreamPointer
CLzmaDec Stream; CLzmaDec Stream;
}; };
static void *SzAlloc(void *, size_t size) { return malloc(size); } static void *SzAlloc(ISzAllocPtr, size_t size) { return malloc(size); }
static void SzFree(void *, void *address) { free(address); } static void SzFree(ISzAllocPtr, void *address) { free(address); }
ISzAlloc g_Alloc = { SzAlloc, SzFree }; ISzAlloc g_Alloc = { SzAlloc, SzFree };
FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip) FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip)

View file

@ -114,6 +114,9 @@ DEFINE_CLASS_PROPERTY(type, S, DynamicLight)
//========================================================================== //==========================================================================
IMPLEMENT_CLASS(ADynamicLight, false, false) IMPLEMENT_CLASS(ADynamicLight, false, false)
DEFINE_FIELD(ADynamicLight, SpotInnerAngle)
DEFINE_FIELD(ADynamicLight, SpotOuterAngle)
static FRandom randLight; static FRandom randLight;
//========================================================================== //==========================================================================
@ -134,7 +137,9 @@ void ADynamicLight::Serialize(FSerializer &arc)
arc("lightflags", lightflags, def->lightflags) arc("lightflags", lightflags, def->lightflags)
("lighttype", lighttype, def->lighttype) ("lighttype", lighttype, def->lighttype)
("tickcount", m_tickCount, def->m_tickCount) ("tickcount", m_tickCount, def->m_tickCount)
("currentradius", m_currentRadius, def->m_currentRadius); ("currentradius", m_currentRadius, def->m_currentRadius)
("spotinnerangle", SpotInnerAngle, def->SpotInnerAngle)
("spotouterangle", SpotOuterAngle, def->SpotOuterAngle);
if (lighttype == PulseLight) if (lighttype == PulseLight)
arc("lastupdate", m_lastUpdate, def->m_lastUpdate) arc("lastupdate", m_lastUpdate, def->m_lastUpdate)

View file

@ -28,7 +28,8 @@ enum LightFlag
LF_DONTLIGHTSELF = 4, LF_DONTLIGHTSELF = 4,
LF_ATTENUATE = 8, LF_ATTENUATE = 8,
LF_NOSHADOWMAP = 16, LF_NOSHADOWMAP = 16,
LF_DONTLIGHTACTORS = 32 LF_DONTLIGHTACTORS = 32,
LF_SPOT = 64
}; };
typedef TFlags<LightFlag> LightFlags; typedef TFlags<LightFlag> LightFlags;
@ -42,7 +43,7 @@ enum ELightType
FlickerLight, FlickerLight,
RandomFlickerLight, RandomFlickerLight,
SectorLight, SectorLight,
SpotLight, DummyLight,
ColorPulseLight, ColorPulseLight,
ColorFlickerLight, ColorFlickerLight,
RandomColorFlickerLight RandomColorFlickerLight
@ -100,6 +101,7 @@ public:
bool IsActive() const { return !(flags2&MF2_DORMANT); } bool IsActive() const { return !(flags2&MF2_DORMANT); }
bool IsSubtractive() { return !!(lightflags & LF_SUBTRACTIVE); } bool IsSubtractive() { return !!(lightflags & LF_SUBTRACTIVE); }
bool IsAdditive() { return !!(lightflags & LF_ADDITIVE); } bool IsAdditive() { return !!(lightflags & LF_ADDITIVE); }
bool IsSpot() { return !!(lightflags & LF_SPOT); }
FState *targetState; FState *targetState;
FLightNode * touching_sides; FLightNode * touching_sides;
FLightNode * touching_subsectors; FLightNode * touching_subsectors;
@ -127,6 +129,7 @@ public:
bool shadowmapped; bool shadowmapped;
int bufferindex; int bufferindex;
LightFlags lightflags; LightFlags lightflags;
DAngle SpotInnerAngle = 10.0;
DAngle SpotOuterAngle = 25.0;
}; };

View file

@ -129,6 +129,9 @@ public:
void SetAttenuate(bool on) { m_attenuate = on; } void SetAttenuate(bool on) { m_attenuate = on; }
void SetHalo(bool halo) { m_halo = halo; } void SetHalo(bool halo) { m_halo = halo; }
void SetDontLightActors(bool on) { m_dontlightactors = on; } void SetDontLightActors(bool on) { m_dontlightactors = on; }
void SetSpot(bool spot) { m_spot = spot; }
void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; }
void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; }
void OrderIntensities() void OrderIntensities()
{ {
@ -152,6 +155,9 @@ protected:
bool m_dontlightself = false; bool m_dontlightself = false;
bool m_dontlightactors = false; bool m_dontlightactors = false;
bool m_swapped = false; bool m_swapped = false;
bool m_spot = false;
double m_spotInnerAngle = 10.0;
double m_spotOuterAngle = 25.0;
}; };
TDeletingArray<FLightDefaults *> LightDefaults; TDeletingArray<FLightDefaults *> LightDefaults;
@ -184,6 +190,10 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
if (m_additive) light->lightflags |= LF_ADDITIVE; if (m_additive) light->lightflags |= LF_ADDITIVE;
if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF; if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF;
if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS; if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS;
if (m_spot)
light->lightflags |= LF_SPOT;
light->SpotInnerAngle = m_spotInnerAngle;
light->SpotOuterAngle = m_spotOuterAngle;
light->m_tickCount = 0; light->m_tickCount = 0;
if (m_type == PulseLight) if (m_type == PulseLight)
{ {
@ -234,7 +244,8 @@ static const char *LightTags[]=
"dontlightself", "dontlightself",
"attenuate", "attenuate",
"dontlightactors", "dontlightactors",
NULL "spot",
nullptr
}; };
@ -256,6 +267,7 @@ enum {
LIGHTTAG_DONTLIGHTSELF, LIGHTTAG_DONTLIGHTSELF,
LIGHTTAG_ATTENUATE, LIGHTTAG_ATTENUATE,
LIGHTTAG_DONTLIGHTACTORS, LIGHTTAG_DONTLIGHTACTORS,
LIGHTTAG_SPOT
}; };
@ -396,6 +408,15 @@ static void ParsePointLight(FScanner &sc)
case LIGHTTAG_DONTLIGHTACTORS: case LIGHTTAG_DONTLIGHTACTORS:
defaults->SetDontLightActors(ParseInt(sc) != 0); defaults->SetDontLightActors(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_SPOT:
{
float innerAngle = ParseFloat(sc);
float outerAngle = ParseFloat(sc);
defaults->SetSpot(true);
defaults->SetSpotInnerAngle(innerAngle);
defaults->SetSpotOuterAngle(outerAngle);
}
break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }
@ -481,6 +502,15 @@ static void ParsePulseLight(FScanner &sc)
case LIGHTTAG_DONTLIGHTACTORS: case LIGHTTAG_DONTLIGHTACTORS:
defaults->SetDontLightActors(ParseInt(sc) != 0); defaults->SetDontLightActors(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_SPOT:
{
float innerAngle = ParseFloat(sc);
float outerAngle = ParseFloat(sc);
defaults->SetSpot(true);
defaults->SetSpotInnerAngle(innerAngle);
defaults->SetSpotOuterAngle(outerAngle);
}
break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }
@ -568,6 +598,15 @@ void ParseFlickerLight(FScanner &sc)
case LIGHTTAG_DONTLIGHTACTORS: case LIGHTTAG_DONTLIGHTACTORS:
defaults->SetDontLightActors(ParseInt(sc) != 0); defaults->SetDontLightActors(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_SPOT:
{
float innerAngle = ParseFloat(sc);
float outerAngle = ParseFloat(sc);
defaults->SetSpot(true);
defaults->SetSpotInnerAngle(innerAngle);
defaults->SetSpotOuterAngle(outerAngle);
}
break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }
@ -654,6 +693,15 @@ void ParseFlickerLight2(FScanner &sc)
case LIGHTTAG_DONTLIGHTACTORS: case LIGHTTAG_DONTLIGHTACTORS:
defaults->SetDontLightActors(ParseInt(sc) != 0); defaults->SetDontLightActors(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_SPOT:
{
float innerAngle = ParseFloat(sc);
float outerAngle = ParseFloat(sc);
defaults->SetSpot(true);
defaults->SetSpotInnerAngle(innerAngle);
defaults->SetSpotOuterAngle(outerAngle);
}
break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }
@ -737,6 +785,15 @@ static void ParseSectorLight(FScanner &sc)
case LIGHTTAG_DONTLIGHTACTORS: case LIGHTTAG_DONTLIGHTACTORS:
defaults->SetDontLightActors(ParseInt(sc) != 0); defaults->SetDontLightActors(ParseInt(sc) != 0);
break; break;
case LIGHTTAG_SPOT:
{
float innerAngle = ParseFloat(sc);
float outerAngle = ParseFloat(sc);
defaults->SetSpot(true);
defaults->SetSpotInnerAngle(innerAngle);
defaults->SetSpotOuterAngle(outerAngle);
}
break;
default: default:
sc.ScriptError("Unknown tag: %s\n", sc.String); sc.ScriptError("Unknown tag: %s\n", sc.String);
} }

View file

@ -125,7 +125,7 @@ FGameConfigFile::FGameConfigFile ()
SetValueForKey ("Path", "$HOME", true); SetValueForKey ("Path", "$HOME", true);
SetValueForKey ("Path", "$PROGDIR", true); SetValueForKey ("Path", "$PROGDIR", true);
#else #else
SetValueForKey ("Path", "~/" GAME_DIR, true); SetValueForKey ("Path", "$HOME/" GAME_DIR, true);
// Arch Linux likes them in /usr/share/doom // Arch Linux likes them in /usr/share/doom
// Debian likes them in /usr/share/games/doom // Debian likes them in /usr/share/games/doom
// I assume other distributions don't do anything radically different // I assume other distributions don't do anything radically different
@ -148,7 +148,7 @@ FGameConfigFile::FGameConfigFile ()
#elif !defined(__unix__) #elif !defined(__unix__)
SetValueForKey ("Path", "$PROGDIR", true); SetValueForKey ("Path", "$PROGDIR", true);
#else #else
SetValueForKey ("Path", "~/" GAME_DIR, true); SetValueForKey ("Path", "$HOME/" GAME_DIR, true);
SetValueForKey ("Path", "/usr/local/share/doom", true); SetValueForKey ("Path", "/usr/local/share/doom", true);
SetValueForKey ("Path", "/usr/local/share/games/doom", true); SetValueForKey ("Path", "/usr/local/share/games/doom", true);
SetValueForKey ("Path", "/usr/share/doom", true); SetValueForKey ("Path", "/usr/share/doom", true);

View file

@ -420,7 +420,7 @@ static void InitVertexData()
for(unsigned i = 0; i < level.vertexes.Size(); ++i) for(unsigned i = 0; i < level.vertexes.Size(); ++i)
{ {
auto vert = level.vertexes[i]; auto &vert = level.vertexes[i];
int cnt = vt_sectorlists[i].Size(); int cnt = vt_sectorlists[i].Size();
vert.dirty = true; vert.dirty = true;

View file

@ -128,7 +128,26 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata)
if (attenuate) shadowIndex = -shadowIndex; if (attenuate) shadowIndex = -shadowIndex;
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)]; float lightType = 0.0f;
float spotInnerAngle = 0.0f;
float spotOuterAngle = 0.0f;
float spotDirX = 0.0f;
float spotDirY = 0.0f;
float spotDirZ = 0.0f;
if (light->IsSpot())
{
lightType = 1.0f;
spotInnerAngle = light->SpotInnerAngle.Cos();
spotOuterAngle = light->SpotOuterAngle.Cos();
DAngle negPitch = -light->Angles.Pitch;
double xzLen = negPitch.Cos();
spotDirX = -light->Angles.Yaw.Cos() * xzLen;
spotDirY = -negPitch.Sin();
spotDirZ = -light->Angles.Yaw.Sin() * xzLen;
}
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(16)];
data[0] = pos.X; data[0] = pos.X;
data[1] = pos.Z; data[1] = pos.Z;
data[2] = pos.Y; data[2] = pos.Y;
@ -137,5 +156,13 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata)
data[5] = g; data[5] = g;
data[6] = b; data[6] = b;
data[7] = shadowIndex; data[7] = shadowIndex;
data[8] = spotDirX;
data[9] = spotDirY;
data[10] = spotDirZ;
data[11] = lightType;
data[12] = spotInnerAngle;
data[13] = spotOuterAngle;
data[14] = 0.0f; // unused
data[15] = 0.0f; // unused
} }

View file

@ -46,6 +46,7 @@
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderer.h"
#include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/models/gl_models.h" #include "gl/models/gl_models.h"
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"
#include "gl/utility/gl_convert.h" #include "gl/utility/gl_convert.h"
@ -100,7 +101,7 @@ void FGLModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectTo
if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])) if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]))
{ {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW); glFrontFace(GLPortal::isMirrored()? GL_CW : GL_CCW);
} }
gl_RenderState.mModelMatrix = objectToWorldMatrix; gl_RenderState.mModelMatrix = objectToWorldMatrix;

View file

@ -167,6 +167,8 @@ public:
return recursion; return recursion;
} }
static bool isMirrored() { return !!((MirrorFlag ^ PlaneMirrorFlag) & 1); }
virtual int ClipSeg(seg_t *seg) { return PClip_Inside; } virtual int ClipSeg(seg_t *seg) { return PClip_Inside; }
virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; } virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; }
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; } virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }

View file

@ -69,7 +69,7 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor)
if (!texture[0] || texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky; if (!texture[0] || texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky;
skytexno1 = texno; skytexno1 = texno;
x_offset[0] = s->GetTextureXOffset(pos) * (360.f/65536.f); x_offset[0] = s->GetTextureXOffset(pos) * (360.f/65536.f);
y_offset = s->GetTextureYOffset(pos) - 28.0; y_offset = s->GetTextureYOffset(pos);
mirrored = !l->args[2]; mirrored = !l->args[2];
} }
else else

View file

@ -49,6 +49,13 @@
FDynLightData modellightdata; FDynLightData modellightdata;
int modellightindex = -1; int modellightindex = -1;
template<class T>
T smoothstep(const T edge0, const T edge1, const T x)
{
auto t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
}
//========================================================================== //==========================================================================
// //
// Sets a single light value from all dynamic lights affecting the specified location // Sets a single light value from all dynamic lights affecting the specified location
@ -70,6 +77,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS)) if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS))
{ {
float dist; float dist;
FVector3 L;
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not. // This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
// This will do the calculations explicitly rather than calling one of AActor's utility functions. // This will do the calculations explicitly rather than calling one of AActor's utility functions.
@ -80,14 +88,15 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct; if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
DVector2 offset = Displacements.getOffset(fromgroup, togroup); DVector2 offset = Displacements.getOffset(fromgroup, togroup);
dist = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z()).LengthSquared(); L = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z());
} }
else else
{ {
direct: direct:
dist = FVector3(x - light->X(), y - light->Y(), z - light->Z()).LengthSquared(); L = FVector3(x - light->X(), y - light->Y(), z - light->Z());
} }
dist = L.LengthSquared();
radius = light->GetRadius(); radius = light->GetRadius();
if (dist < radius * radius) if (dist < radius * radius)
@ -96,6 +105,18 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
frac = 1.0f - (dist / radius); frac = 1.0f - (dist / radius);
if (light->IsSpot())
{
L *= -1.0f / dist;
DAngle negPitch = -light->Angles.Pitch;
double xyLen = negPitch.Cos();
double spotDirX = -light->Angles.Yaw.Cos() * xyLen;
double spotDirY = -light->Angles.Yaw.Sin() * xyLen;
double spotDirZ = -negPitch.Sin();
double cosDir = L.X * spotDirX + L.Y * spotDirY + L.Z * spotDirZ;
frac *= (float)smoothstep(light->SpotOuterAngle.Cos(), light->SpotInnerAngle.Cos(), cosDir);
}
if (frac > 0 && GLRenderer->mShadowMap.ShadowTest(light, { x, y, z })) if (frac > 0 && GLRenderer->mShadowMap.ShadowTest(light, { x, y, z }))
{ {
lr = light->GetRed() / 255.0f; lr = light->GetRed() / 255.0f;

View file

@ -988,6 +988,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoundVolume)
return 0; return 0;
} }
//========================================================================== //==========================================================================
// //
// These come from a time when DECORATE constants did not exist yet and // These come from a time when DECORATE constants did not exist yet and

25
src/p_linetracedata.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef P_LTRACEDATA_H
#define P_LTRACEDATA_H
//============================================================================
//
// Structure for passing detailed results of LineTrace to ZScript
//
//============================================================================
struct FLineTraceData
{
AActor *HitActor;
line_t *HitLine;
sector_t *HitSector;
F3DFloor *Hit3DFloor;
FTextureID HitTexture;
DVector3 HitLocation;
double Distance;
int NumPortals;
int LineSide;
int LinePart;
int SectorPlane;
ETraceResult HitType;
};
#endif

View file

@ -336,6 +336,18 @@ enum // P_LineAttack flags
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL, double sz = 0.0, double offsetforward = 0.0, double offsetside = 0.0); AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL, double sz = 0.0, double offsetforward = 0.0, double offsetside = 0.0);
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL, double sz = 0.0, double offsetforward = 0.0, double offsetside = 0.0); AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL, double sz = 0.0, double offsetforward = 0.0, double offsetside = 0.0);
enum // P_LineTrace flags
{
TRF_ABSPOSITION = 1,
TRF_ABSOFFSET = 2,
TRF_THRUSPECIES = 4,
TRF_THRUACTORS = 8,
TRF_THRUBLOCK = 16,
TRF_THRUHITSCAN = 32,
TRF_NOSKY = 64,
TRF_ALLACTORS = 128,
};
void P_TraceBleed(int damage, const DVector3 &pos, AActor *target, DAngle angle, DAngle pitch); void P_TraceBleed(int damage, const DVector3 &pos, AActor *target, DAngle angle, DAngle pitch);
void P_TraceBleed(int damage, AActor *target, DAngle angle, DAngle pitch); void P_TraceBleed(int damage, AActor *target, DAngle angle, DAngle pitch);

View file

@ -79,6 +79,7 @@
#include "p_terrain.h" #include "p_terrain.h"
#include "p_trace.h" #include "p_trace.h"
#include "p_checkposition.h" #include "p_checkposition.h"
#include "p_linetracedata.h"
#include "r_utility.h" #include "r_utility.h"
#include "p_blockmap.h" #include "p_blockmap.h"
#include "p_3dmidtex.h" #include "p_3dmidtex.h"
@ -4814,6 +4815,159 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack)
return numret; return numret;
} }
//==========================================================================
//
// P_LineTrace
//
//==========================================================================
struct CheckLineData
{
AActor *Caller;
bool ThruSpecies;
bool ThruActors;
int NumPortals;
};
static ETraceStatus CheckLineTrace(FTraceResults &res, void *userdata)
{
CheckLineData *TData = (CheckLineData *)userdata;
if ( res.HitType == TRACE_CrossingPortal )
{
TData->NumPortals++;
return TRACE_Skip;
}
if ( res.HitType != TRACE_HitActor )
{
return TRACE_Stop;
}
if ( (TData->ThruActors) || (TData->ThruSpecies && res.Actor->GetSpecies() == TData->Caller->GetSpecies()) )
{
return TRACE_Skip;
}
return TRACE_Stop;
}
bool P_LineTrace(AActor *t1, DAngle angle, double distance,
DAngle pitch, int flags, double sz, double offsetforward,
double offsetside, FLineTraceData *outdata)
{
FTraceResults trace;
CheckLineData TData;
TData.Caller = t1;
TData.ThruSpecies = !!(flags & TRF_THRUSPECIES);
TData.ThruActors = !!(flags & TRF_THRUACTORS);
TData.NumPortals = 0;
DVector3 direction;
double pc = pitch.Cos();
direction = { pc * angle.Cos(), pc * angle.Sin(), -pitch.Sin() };
DVector3 startpos;
double startz = t1->Z() - t1->Floorclip;
startz += sz;
if ( flags & TRF_ABSPOSITION )
{
startpos = DVector3(offsetforward, offsetside, sz);
}
else if ( flags & TRF_ABSOFFSET )
{
startpos = t1->Vec2OffsetZ(offsetforward, offsetside, startz);
}
else if ( (offsetforward == 0.0) && (offsetside == 0.0) )
{
startpos = t1->PosAtZ(startz);
}
else
{
const double s = angle.Sin();
const double c = angle.Cos();
startpos = t1->Vec2OffsetZ(offsetforward * c + offsetside * s, offsetforward * s - offsetside * c, startz);
}
ActorFlags aflags = (flags & TRF_ALLACTORS) ? ActorFlags::FromInt(0xFFFFFFFF) : MF_SHOOTABLE;
int lflags = 0;
if ( !(lflags & TRF_THRUBLOCK) ) lflags |= ML_BLOCKEVERYTHING;
if ( !(lflags & TRF_THRUHITSCAN) ) lflags |= ML_BLOCKHITSCAN;
int tflags = TRACE_ReportPortals;
if ( flags & TRF_NOSKY ) tflags |= TRACE_NoSky;
// Do trace
bool ret = Trace(startpos, t1->Sector, direction, distance, aflags, lflags, t1, trace, tflags, CheckLineTrace, &TData);
if ( outdata )
{
memset(outdata,0,sizeof(*outdata));
outdata->HitActor = trace.Actor;
outdata->HitLine = trace.Line;
outdata->HitSector = trace.Sector;
outdata->Hit3DFloor = trace.ffloor;
switch ( trace.HitType )
{
case TRACE_HitFloor:
outdata->SectorPlane = 0;
outdata->HitTexture = trace.Sector->planes[0].Texture;
break;
case TRACE_HitCeiling:
outdata->SectorPlane = 1;
outdata->HitTexture = trace.Sector->planes[1].Texture;
break;
case TRACE_HitWall:
outdata->LineSide = trace.Side;
int txpart;
switch ( trace.Tier )
{
case TIER_Middle:
outdata->LinePart = 1;
outdata->HitTexture = trace.Line->sidedef[trace.Side]->textures[1].texture;
break;
case TIER_Upper:
outdata->LinePart = 0;
outdata->HitTexture = trace.Line->sidedef[trace.Side]->textures[0].texture;
break;
case TIER_Lower:
outdata->LinePart = 2;
outdata->HitTexture = trace.Line->sidedef[trace.Side]->textures[2].texture;
break;
case TIER_FFloor:
txpart = (trace.ffloor->flags & FF_UPPERTEXTURE) ? 0 : (trace.ffloor->flags & FF_LOWERTEXTURE) ? 2 : 1;
outdata->HitTexture = trace.ffloor->master->sidedef[0]->textures[txpart].texture;
break;
}
default:
break;
}
outdata->HitLocation = trace.HitPos;
outdata->Distance = trace.Distance;
outdata->NumPortals = TData.NumPortals;
outdata->HitType = trace.HitType;
}
return ret;
}
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitActor);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitLine);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitSector);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, Hit3DFloor);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitTexture);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitLocation);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, Distance);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, NumPortals);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, LineSide);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, LinePart);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, SectorPlane);
DEFINE_FIELD_X(FLineTraceData, FLineTraceData, HitType);
DEFINE_ACTION_FUNCTION(AActor, LineTrace)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_ANGLE(angle);
PARAM_FLOAT(distance);
PARAM_ANGLE(pitch);
PARAM_INT_DEF(flags);
PARAM_FLOAT_DEF(offsetz);
PARAM_FLOAT_DEF(offsetforward);
PARAM_FLOAT_DEF(offsetside);
PARAM_POINTER_DEF(data, FLineTraceData);
ACTION_RETURN_BOOL(P_LineTrace(self,angle,distance,pitch,flags,offsetz,offsetforward,offsetside,data));
}
//========================================================================== //==========================================================================
// //
// P_LinePickActor // P_LinePickActor
@ -5695,6 +5849,168 @@ CUSTOM_CVAR(Float, splashfactor, 1.f, CVAR_SERVERINFO)
selfthrustscale = 1.f / self; selfthrustscale = 1.f / self;
} }
//==========================================================================
//
// P_GetRadiusDamage
//
// Part of P_RadiusAttack, separated so the GetRadiusAttack function can
// exist without needing to maintain more than one function.
//
// Used by anything without OLDRADIUSDMG flag
//==========================================================================
static double P_GetRadiusDamage(bool fromaction, AActor *bombspot, AActor *thing, int bombdamage, int bombdistance, int fulldamagedistance, bool thingbombsource)
{
// [RH] New code. The bounding box only covers the
// height of the thing and not the height of the map.
double points;
double len;
double dx, dy;
double boxradius;
double bombdistancefloat = 1. / (double)(bombdistance - fulldamagedistance);
double bombdamagefloat = (double)bombdamage;
DVector2 vec = bombspot->Vec2To(thing);
dx = fabs(vec.X);
dy = fabs(vec.Y);
boxradius = thing->radius;
// The damage pattern is square, not circular.
len = double(dx > dy ? dx : dy);
if (bombspot->Z() < thing->Z() || bombspot->Z() >= thing->Top())
{
double dz;
if (bombspot->Z() > thing->Z())
{
dz = double(bombspot->Z() - thing->Top());
}
else
{
dz = double(thing->Z() - bombspot->Z());
}
if (len <= boxradius)
{
len = dz;
}
else
{
len -= boxradius;
len = g_sqrt(len*len + dz*dz);
}
}
else
{
len -= boxradius;
if (len < 0.f)
len = 0.f;
}
len = clamp<double>(len - (double)fulldamagedistance, 0, len);
points = bombdamagefloat * (1. - len * bombdistancefloat);
// Calculate the splash and radius damage factor if called by P_RadiusAttack.
// Otherwise, just get the raw damage. This allows modders to manipulate it
// however they want.
if (!fromaction)
{
if (thingbombsource) //thing is bomb source
{
points = points * splashfactor;
}
points *= thing->RadiusDamageFactor;
}
return points;
}
//==========================================================================
//
// P_GetOldRadiusDamage
//
// Part of P_RadiusAttack, separated so the GetRadiusAttack function can
// exist without needing to maintain more than one function.
//
// Used by barrels (OLDRADIUSDMG flag). Returns calculated damage
// based on XY distance.
//==========================================================================
static int P_GetOldRadiusDamage(bool fromaction, AActor *bombspot, AActor *thing, int bombdamage, int bombdistance, int fulldamagedistance)
{
const int ret = fromaction ? 0 : -1; // -1 is specifically for P_RadiusAttack; continue onto another actor.
double dx, dy, dist;
DVector2 vec = bombspot->Vec2To(thing);
dx = fabs(vec.X);
dy = fabs(vec.Y);
dist = dx>dy ? dx : dy;
dist -= thing->radius;
if (dist < 0)
dist = 0;
if (dist >= bombdistance)
return ret; // out of range
// When called from the action function, ignore the sight check.
if (fromaction || P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
{
dist = clamp<double>(dist - fulldamagedistance, 0, dist);
int damage = Scale(bombdamage, bombdistance - int(dist), bombdistance);
if (!fromaction)
{
double factor = splashfactor * thing->RadiusDamageFactor;
damage = int(damage * factor);
}
return damage;
}
return ret; // Not in sight.
}
//==========================================================================
//
// GetRadiusDamage
//
// Returns the falloff damage from an A_Explode attack without doing any
// damage and not taking into account any damage reduction.
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, GetRadiusDamage)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(thing, AActor);
PARAM_INT(damage);
PARAM_INT(distance);
PARAM_INT_DEF(fulldmgdistance);
PARAM_BOOL_DEF(oldradiusdmg);
if (!thing)
{
ACTION_RETURN_INT(0);
}
else if (thing == self)
{ // No point in calculating falloff in this case since it is the bomb spot.
ACTION_RETURN_INT(damage);
}
fulldmgdistance = clamp<int>(fulldmgdistance, 0, distance - 1);
// Mirroring A_Explode's behavior.
if (distance <= 0)
distance = damage;
const int newdam = oldradiusdmg
? P_GetOldRadiusDamage(true, self, thing, damage, distance, fulldmgdistance)
: int(P_GetRadiusDamage(true, self, thing, damage, distance, fulldmgdistance, false));
ACTION_RETURN_INT(newdam);
}
//========================================================================== //==========================================================================
// //
// P_RadiusAttack // P_RadiusAttack
@ -5709,9 +6025,6 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom
return 0; return 0;
fulldamagedistance = clamp<int>(fulldamagedistance, 0, bombdistance - 1); fulldamagedistance = clamp<int>(fulldamagedistance, 0, bombdistance - 1);
double bombdistancefloat = 1. / (double)(bombdistance - fulldamagedistance);
double bombdamagefloat = (double)bombdamage;
FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d);
FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistance, bombspot->Height + bombdistance*2, bombdistance, false, bombspot->Sector); FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistance, bombspot->Height + bombdistance*2, bombdistance, false, bombspot->Sector);
FMultiBlockThingsIterator::CheckResult cres; FMultiBlockThingsIterator::CheckResult cres;
@ -5757,57 +6070,7 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom
// which can make them near impossible to hit with the new code. // which can make them near impossible to hit with the new code.
if ((flags & RADF_NODAMAGE) || !((bombspot->flags5 | thing->flags5) & MF5_OLDRADIUSDMG)) if ((flags & RADF_NODAMAGE) || !((bombspot->flags5 | thing->flags5) & MF5_OLDRADIUSDMG))
{ {
// [RH] New code. The bounding box only covers the double points = P_GetRadiusDamage(false, bombspot, thing, bombdamage, bombdistance, fulldamagedistance, bombsource == thing);
// height of the thing and not the height of the map.
double points;
double len;
double dx, dy;
double boxradius;
DVector2 vec = bombspot->Vec2To(thing);
dx = fabs(vec.X);
dy = fabs(vec.Y);
boxradius = thing->radius;
// The damage pattern is square, not circular.
len = double(dx > dy ? dx : dy);
if (bombspot->Z() < thing->Z() || bombspot->Z() >= thing->Top())
{
double dz;
if (bombspot->Z() > thing->Z())
{
dz = double(bombspot->Z() - thing->Top());
}
else
{
dz = double(thing->Z() - bombspot->Z());
}
if (len <= boxradius)
{
len = dz;
}
else
{
len -= boxradius;
len = g_sqrt(len*len + dz*dz);
}
}
else
{
len -= boxradius;
if (len < 0.f)
len = 0.f;
}
len = clamp<double>(len - (double)fulldamagedistance, 0, len);
points = bombdamagefloat * (1. - len * bombdistancefloat);
if (thing == bombsource)
{
points = points * splashfactor;
}
points *= thing->RadiusDamageFactor;
double check = int(points) * bombdamage; double check = int(points) * bombdamage;
// points and bombdamage should be the same sign (the double cast of 'points' is needed to prevent overflows and incorrect values slipping through.) // points and bombdamage should be the same sign (the double cast of 'points' is needed to prevent overflows and incorrect values slipping through.)
if ((check > 0 || (check == 0 && bombspot->flags7 & MF7_FORCEZERORADIUSDMG)) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) if ((check > 0 || (check == 0 && bombspot->flags7 & MF7_FORCEZERORADIUSDMG)) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
@ -5865,36 +6128,17 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom
else else
{ {
// [RH] Old code just for barrels // [RH] Old code just for barrels
double dx, dy, dist; int damage = P_GetOldRadiusDamage(false, bombspot, thing, bombdamage, bombdistance, fulldamagedistance);
DVector2 vec = bombspot->Vec2To(thing); if (damage < 0)
dx = fabs(vec.X); continue; // Sight check failed.
dy = fabs(vec.Y); else if (damage > 0 || (bombspot->flags7 & MF7_FORCEZERORADIUSDMG))
dist = dx>dy ? dx : dy;
dist -= thing->radius;
if (dist < 0)
dist = 0;
if (dist >= bombdistance)
continue; // out of range
if (P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
{ // OK to damage; target is in direct path { // OK to damage; target is in direct path
dist = clamp<double>(dist - fulldamagedistance, 0, dist); //[MC] Don't count actors saved by buddha if already at 1 health.
int damage = Scale(bombdamage, bombdistance - int(dist), bombdistance); int prehealth = thing->health;
int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod);
double factor = splashfactor * thing->RadiusDamageFactor; P_TraceBleed(newdam > 0 ? newdam : damage, thing, bombspot);
damage = int(damage * factor); if (thing->health < prehealth) count++;
if (damage > 0 || (bombspot->flags7 & MF7_FORCEZERORADIUSDMG))
{
//[MC] Don't count actors saved by buddha if already at 1 health.
int prehealth = thing->health;
int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod);
P_TraceBleed(newdam > 0 ? newdam : damage, thing, bombspot);
if (thing->health < prehealth) count++;
}
} }
} }
} }

View file

@ -108,6 +108,7 @@
#include "a_morph.h" #include "a_morph.h"
#include "events.h" #include "events.h"
#include "actorinlines.h" #include "actorinlines.h"
#include "a_dynlight.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -6003,6 +6004,8 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
} }
} }
// spawn it // spawn it
double sz; double sz;
@ -6091,6 +6094,28 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
mobj->fillcolor = (mthing->fillcolor & 0xffffff) | (ColorMatcher.Pick((mthing->fillcolor & 0xff0000) >> 16, mobj->fillcolor = (mthing->fillcolor & 0xffffff) | (ColorMatcher.Pick((mthing->fillcolor & 0xff0000) >> 16,
(mthing->fillcolor & 0xff00) >> 8, (mthing->fillcolor & 0xff)) << 24); (mthing->fillcolor & 0xff00) >> 8, (mthing->fillcolor & 0xff)) << 24);
// allow color strings for lights and reshuffle the args for spot lights
if (i->IsDescendantOf(RUNTIME_CLASS(ADynamicLight)))
{
auto light = static_cast<ADynamicLight*>(mobj);
if (mthing->arg0str != NAME_None)
{
PalEntry color = V_GetColor(nullptr, mthing->arg0str);
}
else if (light->lightflags & LF_SPOT)
{
light->args[0] = RPART(mthing->args[0]);
light->args[1] = GPART(mthing->args[0]);
light->args[2] = BPART(mthing->args[0]);
}
if (light->lightflags & LF_SPOT)
{
light->SpotInnerAngle = double(mthing->args[1]);
light->SpotOuterAngle = double(mthing->args[2]);
}
}
mobj->CallBeginPlay (); mobj->CallBeginPlay ();
if (!(mobj->ObjectFlags & OF_EuthanizeMe)) if (!(mobj->ObjectFlags & OF_EuthanizeMe))
{ {

View file

@ -42,6 +42,7 @@
#include "p_spec.h" #include "p_spec.h"
#include "g_levellocals.h" #include "g_levellocals.h"
#include "p_terrain.h" #include "p_terrain.h"
#include "vm.h"
//========================================================================== //==========================================================================
// //
@ -948,3 +949,103 @@ static bool EditTraceResult (uint32_t flags, FTraceResults &res)
} }
return true; return true;
} }
//==========================================================================
//
// [ZZ] here go the methods for the ZScript interface
//
//==========================================================================
IMPLEMENT_CLASS(DTracer, false, false)
DEFINE_FIELD_X(Tracer, DTracer, Results)
// define TraceResults fields
DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Sector, HitSector)
DEFINE_FIELD_X(TraceResults, FTraceResults, HitTexture)
DEFINE_FIELD_X(TraceResults, FTraceResults, HitPos)
DEFINE_FIELD_X(TraceResults, FTraceResults, HitVector)
DEFINE_FIELD_X(TraceResults, FTraceResults, SrcFromTarget)
DEFINE_FIELD_X(TraceResults, FTraceResults, SrcAngleFromTarget)
DEFINE_FIELD_X(TraceResults, FTraceResults, Distance)
DEFINE_FIELD_X(TraceResults, FTraceResults, Fraction)
DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Actor, HitActor)
DEFINE_FIELD_NAMED_X(TraceResults, FTraceResults, Line, HitLine)
DEFINE_FIELD_X(TraceResults, FTraceResults, Side)
DEFINE_FIELD_X(TraceResults, FTraceResults, Tier)
DEFINE_FIELD_X(TraceResults, FTraceResults, unlinked)
DEFINE_FIELD_X(TraceResults, FTraceResults, HitType)
DEFINE_FIELD_X(TraceResults, FTraceResults, CrossedWater)
DEFINE_FIELD_X(TraceResults, FTraceResults, CrossedWaterPos)
DEFINE_FIELD_X(TraceResults, FTraceResults, Crossed3DWater)
DEFINE_FIELD_X(TraceResults, FTraceResults, Crossed3DWaterPos)
DEFINE_ACTION_FUNCTION(DTracer, Trace)
{
PARAM_SELF_PROLOGUE(DTracer);
/*bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, double maxDist,
ActorFlags ActorMask, uint32_t WallMask, AActor *ignore, FTraceResults &res, uint32_t traceFlags = 0,
ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL);*/
PARAM_FLOAT(start_x);
PARAM_FLOAT(start_y);
PARAM_FLOAT(start_z);
PARAM_POINTER(sector, sector_t);
PARAM_FLOAT(direction_x);
PARAM_FLOAT(direction_y);
PARAM_FLOAT(direction_z);
PARAM_FLOAT(maxDist);
// actor flags and wall flags are not supported due to how flags are implemented on the ZScript side.
// say thanks to oversimplifying the user API.
PARAM_INT(traceFlags);
// these are internal hacks.
traceFlags &= ~(TRACE_PCross | TRACE_Impact);
// Trace(vector3 start, Sector sector, vector3 direction, double maxDist, ETraceFlags traceFlags)
bool res = Trace(DVector3(start_x, start_y, start_z), sector, DVector3(direction_x, direction_y, direction_z), maxDist,
(ActorFlag)0xFFFFFFFF, 0xFFFFFFFF, nullptr, self->Results, traceFlags, &DTracer::TraceCallback, self);
ACTION_RETURN_BOOL(res);
}
ETraceStatus DTracer::TraceCallback(FTraceResults& res, void* pthis)
{
DTracer* self = (DTracer*)pthis;
// "res" here should refer to self->Results anyway.
// patch results a bit. modders don't expect it to work like this most likely.
// code by MarisaKirisame
if (res.HitType == TRACE_HitWall)
{
int txpart;
switch (res.Tier)
{
case TIER_Middle:
res.HitTexture = res.Line->sidedef[res.Side]->textures[1].texture;
break;
case TIER_Upper:
res.HitTexture = res.Line->sidedef[res.Side]->textures[0].texture;
break;
case TIER_Lower:
res.HitTexture = res.Line->sidedef[res.Side]->textures[2].texture;
break;
case TIER_FFloor:
txpart = (res.ffloor->flags & FF_UPPERTEXTURE) ? 0 : (res.ffloor->flags & FF_LOWERTEXTURE) ? 2 : 1;
res.HitTexture = res.ffloor->master->sidedef[0]->textures[txpart].texture;
break;
}
}
return self->CallZScriptCallback();
}
ETraceStatus DTracer::CallZScriptCallback()
{
IFVIRTUAL(DTracer, TraceCallback)
{
int status;
VMReturn results[1] = { &status };
VMValue params[1] = { (DTracer*)this };
VMCall(func, params, 1, results, 1);
return (ETraceStatus)status;
}
return TRACE_Stop;
}

View file

@ -112,4 +112,14 @@ bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, d
ActorFlags ActorMask, uint32_t WallMask, AActor *ignore, FTraceResults &res, uint32_t traceFlags = 0, ActorFlags ActorMask, uint32_t WallMask, AActor *ignore, FTraceResults &res, uint32_t traceFlags = 0,
ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL); ETraceStatus(*callback)(FTraceResults &res, void *) = NULL, void *callbackdata = NULL);
// [ZZ] this is the object that's used for ZScript
class DTracer : public DObject
{
DECLARE_CLASS(DTracer, DObject)
public:
FTraceResults Results;
static ETraceStatus TraceCallback(FTraceResults& res, void* pthis);
ETraceStatus CallZScriptCallback();
};
#endif //__P_TRACE_H__ #endif //__P_TRACE_H__

View file

@ -604,6 +604,7 @@ public:
case NAME_Arg0Str: case NAME_Arg0Str:
CHECK_N(Zd); CHECK_N(Zd);
arg0str = CheckString(key); arg0str = CheckString(key);
th->arg0str = arg0str;
break; break;
case NAME_Arg1Str: case NAME_Arg1Str:

View file

@ -46,30 +46,30 @@ FString GetUserFile (const char *file)
FString path; FString path;
struct stat info; struct stat info;
path = NicePath("~/" GAME_DIR "/"); path = NicePath("$HOME/" GAME_DIR "/");
if (stat (path, &info) == -1) if (stat (path, &info) == -1)
{ {
struct stat extrainfo; struct stat extrainfo;
// Sanity check for ~/.config // Sanity check for $HOME/.config
FString configPath = NicePath("~/.config/"); FString configPath = NicePath("$HOME/.config/");
if (stat (configPath, &extrainfo) == -1) if (stat (configPath, &extrainfo) == -1)
{ {
if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
{ {
I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno)); I_FatalError ("Failed to create $HOME/.config directory:\n%s", strerror(errno));
} }
} }
else if (!S_ISDIR(extrainfo.st_mode)) else if (!S_ISDIR(extrainfo.st_mode))
{ {
I_FatalError ("~/.config must be a directory"); I_FatalError ("$HOME/.config must be a directory");
} }
// This can be removed after a release or two // This can be removed after a release or two
// Transfer the old zdoom directory to the new location // Transfer the old zdoom directory to the new location
bool moved = false; bool moved = false;
FString oldpath = NicePath("~/." GAMENAMELOWERCASE "/"); FString oldpath = NicePath("$HOME/." GAMENAMELOWERCASE "/");
if (stat (oldpath, &extrainfo) != -1) if (stat (oldpath, &extrainfo) != -1)
{ {
if (rename(oldpath, path) == -1) if (rename(oldpath, path) == -1)
@ -110,7 +110,7 @@ FString M_GetAppDataPath(bool create)
{ {
// Don't use GAME_DIR and such so that ZDoom and its child ports can // Don't use GAME_DIR and such so that ZDoom and its child ports can
// share the node cache. // share the node cache.
FString path = NicePath("~/.config/" GAMENAMELOWERCASE); FString path = NicePath("$HOME/.config/" GAMENAMELOWERCASE);
if (create) if (create)
{ {
CreatePath(path); CreatePath(path);
@ -130,7 +130,7 @@ FString M_GetCachePath(bool create)
{ {
// Don't use GAME_DIR and such so that ZDoom and its child ports can // Don't use GAME_DIR and such so that ZDoom and its child ports can
// share the node cache. // share the node cache.
FString path = NicePath("~/.config/zdoom/cache"); FString path = NicePath("$HOME/.config/zdoom/cache");
if (create) if (create)
{ {
CreatePath(path); CreatePath(path);
@ -163,7 +163,7 @@ FString M_GetCajunPath(const char *botfilename)
{ {
FString path; FString path;
// Check first in ~/.config/zdoom/botfilename. // Check first in $HOME/.config/zdoom/botfilename.
path = GetUserFile(botfilename); path = GetUserFile(botfilename);
if (!FileExists(path)) if (!FileExists(path))
{ {
@ -203,7 +203,7 @@ FString M_GetConfigPath(bool for_reading)
FString M_GetScreenshotsPath() FString M_GetScreenshotsPath()
{ {
return NicePath("~/" GAME_DIR "/screenshots/"); return NicePath("$HOME/" GAME_DIR "/screenshots/");
} }
//=========================================================================== //===========================================================================
@ -216,7 +216,7 @@ FString M_GetScreenshotsPath()
FString M_GetSavegamesPath() FString M_GetSavegamesPath()
{ {
return NicePath("~/" GAME_DIR); return NicePath("$HOME/" GAME_DIR);
} }
//=========================================================================== //===========================================================================
@ -229,5 +229,5 @@ FString M_GetSavegamesPath()
FString M_GetDocumentsPath() FString M_GetDocumentsPath()
{ {
return NicePath("~/" GAME_DIR); return NicePath("$HOME/" GAME_DIR);
} }

View file

@ -67,7 +67,7 @@ struct CZDFileInStream
File = _file; File = _file;
} }
static SRes Read(void *pp, void *buf, size_t *size) static SRes Read(const ISeekInStream *pp, void *buf, size_t *size)
{ {
CZDFileInStream *p = (CZDFileInStream *)pp; CZDFileInStream *p = (CZDFileInStream *)pp;
long numread = p->File->Read(buf, (long)*size); long numread = p->File->Read(buf, (long)*size);
@ -80,7 +80,7 @@ struct CZDFileInStream
return SZ_OK; return SZ_OK;
} }
static SRes Seek(void *pp, Int64 *pos, ESzSeek origin) static SRes Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
{ {
CZDFileInStream *p = (CZDFileInStream *)pp; CZDFileInStream *p = (CZDFileInStream *)pp;
int move_method; int move_method;
@ -111,7 +111,8 @@ struct C7zArchive
{ {
CSzArEx DB; CSzArEx DB;
CZDFileInStream ArchiveStream; CZDFileInStream ArchiveStream;
CLookToRead LookStream; CLookToRead2 LookStream;
Byte StreamBuffer[1<<14];
UInt32 BlockIndex; UInt32 BlockIndex;
Byte *OutBuffer; Byte *OutBuffer;
size_t OutBufferSize; size_t OutBufferSize;
@ -123,9 +124,11 @@ struct C7zArchive
CrcGenerateTable(); CrcGenerateTable();
} }
file->Seek(0, SEEK_SET); file->Seek(0, SEEK_SET);
LookToRead_CreateVTable(&LookStream, false); LookToRead2_CreateVTable(&LookStream, false);
LookStream.realStream = &ArchiveStream.s; LookStream.realStream = &ArchiveStream.s;
LookToRead_Init(&LookStream); LookToRead2_Init(&LookStream);
LookStream.bufSize = sizeof(StreamBuffer);
LookStream.buf = StreamBuffer;
SzArEx_Init(&DB); SzArEx_Init(&DB);
BlockIndex = 0xFFFFFFFF; BlockIndex = 0xFFFFFFFF;
OutBuffer = NULL; OutBuffer = NULL;
@ -143,13 +146,13 @@ struct C7zArchive
SRes Open() SRes Open()
{ {
return SzArEx_Open(&DB, &LookStream.s, &g_Alloc, &g_Alloc); return SzArEx_Open(&DB, &LookStream.vt, &g_Alloc, &g_Alloc);
} }
SRes Extract(UInt32 file_index, char *buffer) SRes Extract(UInt32 file_index, char *buffer)
{ {
size_t offset, out_size_processed; size_t offset, out_size_processed;
SRes res = SzArEx_Extract(&DB, &LookStream.s, file_index, SRes res = SzArEx_Extract(&DB, &LookStream.vt, file_index,
&BlockIndex, &OutBuffer, &OutBufferSize, &BlockIndex, &OutBuffer, &OutBufferSize,
&offset, &out_size_processed, &offset, &out_size_processed,
&g_Alloc, &g_Alloc); &g_Alloc, &g_Alloc);

View file

@ -53,6 +53,7 @@
#include "serializer.h" #include "serializer.h"
#include "v_text.h" #include "v_text.h"
#include "g_levellocals.h" #include "g_levellocals.h"
#include "vm.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -491,6 +492,12 @@ unsigned int S_GetMSLength(FSoundID sound)
else return 0; else return 0;
} }
DEFINE_ACTION_FUNCTION(DObject,S_GetLength)
{
PARAM_PROLOGUE;
PARAM_SOUND(sound_id);
ACTION_RETURN_FLOAT(S_GetMSLength(sound_id)/1000.0);
}
//========================================================================== //==========================================================================
// //

View file

@ -9378,6 +9378,13 @@ FxExpression *FxStrLen::Resolve(FCompileContext &ctx)
{ {
SAFE_RESOLVE(Self, ctx); SAFE_RESOLVE(Self, ctx);
assert(Self->ValueType == TypeString); assert(Self->ValueType == TypeString);
if (Self->isConstant())
{
auto constself = static_cast<FxConstant *>(Self);
auto constlen = new FxConstant((int)constself->GetValue().GetString().Len(), Self->ScriptPosition);
delete this;
return constlen->Resolve(ctx);
}
ValueType = TypeUInt32; ValueType = TypeUInt32;
return this; return this;
} }

View file

@ -494,6 +494,7 @@ static FFlagDef DynLightFlagDefs[] =
DEFINE_FLAG(LF, ATTENUATE, ADynamicLight, lightflags), DEFINE_FLAG(LF, ATTENUATE, ADynamicLight, lightflags),
DEFINE_FLAG(LF, NOSHADOWMAP, ADynamicLight, lightflags), DEFINE_FLAG(LF, NOSHADOWMAP, ADynamicLight, lightflags),
DEFINE_FLAG(LF, DONTLIGHTACTORS, ADynamicLight, lightflags), DEFINE_FLAG(LF, DONTLIGHTACTORS, ADynamicLight, lightflags),
DEFINE_FLAG(LF, SPOT, ADynamicLight, lightflags),
}; };
static FFlagDef PowerSpeedFlagDefs[] = static FFlagDef PowerSpeedFlagDefs[] =

View file

@ -230,6 +230,15 @@ DEFINE_ACTION_FUNCTION(_Screen, GetClipRect)
return MIN(numret, 4); return MIN(numret, 4);
} }
DEFINE_ACTION_FUNCTION(_Screen, GetViewWindow)
{
PARAM_PROLOGUE;
if (numret > 0) ret[0].SetInt(viewwindowx);
if (numret > 1) ret[1].SetInt(viewwindowy);
if (numret > 2) ret[2].SetInt(viewwidth);
if (numret > 3) ret[3].SetInt(viewheight);
return MIN(numret, 4);
}
bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const
{ {

View file

@ -226,8 +226,8 @@ int copy_zip_file(FILE *zip, file_entry_t *file, FILE *ozip, CentralDirectoryEnt
// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } static void *SzAlloc(ISzAllocPtr p, size_t size) { p = p; return malloc(size); }
static void SzFree(void *p, void *address) { p = p; free(address); } static void SzFree(ISzAllocPtr p, void *address) { p = p; free(address); }
// EXTERNAL DATA DECLARATIONS ---------------------------------------------- // EXTERNAL DATA DECLARATIONS ----------------------------------------------

View file

@ -109,6 +109,26 @@ DoomEdNums
9832 = PointLightFlickerAttenuated 9832 = PointLightFlickerAttenuated
9833 = SectorPointLightAttenuated 9833 = SectorPointLightAttenuated
9834 = PointLightFlickerRandomAttenuated 9834 = PointLightFlickerRandomAttenuated
9840 = SpotLight
9841 = SpotLightPulse
9842 = SpotLightFlicker
9843 = SectorSpotLight
9844 = SpotLightFlickerRandom
9850 = SpotLightAdditive
9851 = SpotLightPulseAdditive
9852 = SpotLightFlickerAdditive
9853 = SectorSpotLightAdditive
9854 = SpotLightFlickerRandomSubtractive
9860 = SpotLightSubtractive
9861 = SpotLightPulseSubtractive
9862 = SpotLightFlickerSubtractive
9863 = SectorSpotLightSubtractive
9864 = SpotLightFlickerRandomSubtractive
9870 = SpotLightAttenuated
9871 = SpotLightPulseAttenuated
9872 = SpotLightFlickerAttenuated
9873 = SectorSpotLightAttenuated
9874 = SpotLightFlickerRandomAttenuated
9982 = SecActEyesAboveC 9982 = SecActEyesAboveC
9983 = SecActEyesBelowC 9983 = SecActEyesBelowC
9988 = CustomSprite 9988 = CustomSprite

View file

@ -278,6 +278,13 @@ float pointLightAttenuation(vec4 lightpos, float lightcolorA)
} }
} }
float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle, float lightCosOuterAngle)
{
vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz);
float cosDir = dot(lightDirection, spotdir);
return smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir);
}
//=========================================================================== //===========================================================================
// //
// Calculate light // Calculate light
@ -348,23 +355,33 @@ vec4 getLightColor(float fogdist, float fogfactor)
// //
// modulated lights // modulated lights
// //
for(int i=lightRange.x; i<lightRange.y; i+=2) for(int i=lightRange.x; i<lightRange.y; i+=4)
{ {
vec4 lightpos = lights[i]; vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1]; vec4 lightcolor = lights[i+1];
vec4 lightspot1 = lights[i+2];
vec4 lightspot2 = lights[i+3];
lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); float attenuation = pointLightAttenuation(lightpos, lightcolor.a);
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
lightcolor.rgb *= attenuation;
dynlight.rgb += lightcolor.rgb; dynlight.rgb += lightcolor.rgb;
} }
// //
// subtractive lights // subtractive lights
// //
for(int i=lightRange.y; i<lightRange.z; i+=2) for(int i=lightRange.y; i<lightRange.z; i+=4)
{ {
vec4 lightpos = lights[i]; vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1]; vec4 lightcolor = lights[i+1];
vec4 lightspot1 = lights[i+2];
vec4 lightspot2 = lights[i+3];
lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); float attenuation = pointLightAttenuation(lightpos, lightcolor.a);
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
lightcolor.rgb *= attenuation;
dynlight.rgb -= lightcolor.rgb; dynlight.rgb -= lightcolor.rgb;
} }
} }
@ -467,12 +484,17 @@ void main()
// //
// additive lights - these can be done after the alpha test. // additive lights - these can be done after the alpha test.
// //
for(int i=lightRange.z; i<lightRange.w; i+=2) for(int i=lightRange.z; i<lightRange.w; i+=4)
{ {
vec4 lightpos = lights[i]; vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1]; vec4 lightcolor = lights[i+1];
vec4 lightspot1 = lights[i+2];
vec4 lightspot2 = lights[i+3];
lightcolor.rgb *= pointLightAttenuation(lightpos, lightcolor.a); float attenuation = pointLightAttenuation(lightpos, lightcolor.a);
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
lightcolor.rgb *= attenuation;
addlight.rgb += lightcolor.rgb; addlight.rgb += lightcolor.rgb;
} }
frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0); frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0);

View file

@ -29,6 +29,32 @@ struct FCheckPosition
native void ClearLastRipped(); native void ClearLastRipped();
} }
struct FLineTraceData
{
enum ETraceResult
{
TRACE_HitNone,
TRACE_HitFloor,
TRACE_HitCeiling,
TRACE_HitWall,
TRACE_HitActor,
TRACE_CrossingPortal
};
Actor HitActor;
Line HitLine;
Sector HitSector;
F3DFloor Hit3DFloor;
TextureID HitTexture;
Vector3 HitLocation;
double Distance;
int NumPortals;
int LineSide;
int LinePart;
int SectorPlane;
int HitType;
}
struct LinkContext struct LinkContext
{ {
voidptr sector_list; // really msecnode but that's not exported yet. voidptr sector_list; // really msecnode but that's not exported yet.
@ -602,6 +628,7 @@ class Actor : Thinker native
native void PoisonMobj (Actor inflictor, Actor source, int damage, int duration, int period, Name type); native void PoisonMobj (Actor inflictor, Actor source, int damage, int duration, int period, Name type);
native double AimLineAttack(double angle, double distance, out FTranslatedLineTarget pLineTarget = null, double vrange = 0., int flags = 0, Actor target = null, Actor friender = null); native double AimLineAttack(double angle, double distance, out FTranslatedLineTarget pLineTarget = null, double vrange = 0., int flags = 0, Actor target = null, Actor friender = null);
native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class<Actor> pufftype, int flags = 0, out FTranslatedLineTarget victim = null, double offsetz = 0., double offsetforward = 0., double offsetside = 0.); native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class<Actor> pufftype, int flags = 0, out FTranslatedLineTarget victim = null, double offsetz = 0., double offsetforward = 0., double offsetside = 0.);
native bool LineTrace(double angle, double distance, double pitch, int flags = 0, double offsetz = 0., double offsetforward = 0., double offsetside = 0., out FLineTraceData data = null);
native bool CheckSight(Actor target, int flags = 0); native bool CheckSight(Actor target, int flags = 0);
native bool IsVisible(Actor other, bool allaround, LookExParams params = null); native bool IsVisible(Actor other, bool allaround, LookExParams params = null);
native bool HitFriend(); native bool HitFriend();
@ -1061,6 +1088,7 @@ class Actor : Thinker native
native void A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0); native void A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0);
native void A_RadiusDamageSelf(int damage = 128, double distance = 128, int flags = 0, class<Actor> flashtype = null); native void A_RadiusDamageSelf(int damage = 128, double distance = 128, int flags = 0, class<Actor> flashtype = null);
native int A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff", name damagetype = "none"); native int A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff", name damagetype = "none");
native int GetRadiusDamage(Actor thing, int damage, int distance, int fulldmgdistance = 0, bool oldradiusdmg = false);
native void A_Stop(); native void A_Stop();
native void A_Respawn(int flags = 1); native void A_Respawn(int flags = 1);
native void A_RestoreSpecialPosition(); native void A_RestoreSpecialPosition();

View file

@ -175,6 +175,7 @@ struct Screen native
native static void SetClipRect(int x, int y, int w, int h); native static void SetClipRect(int x, int y, int w, int h);
native static void ClearClipRect(); native static void ClearClipRect();
native static int, int, int, int GetClipRect(); native static int, int, int, int GetClipRect();
native static int, int, int, int GetViewWindow();
// This is a leftover of the abandoned Inventory.DrawPowerup method. // This is a leftover of the abandoned Inventory.DrawPowerup method.
@ -354,6 +355,7 @@ class Object native
native static void S_PauseSound (bool notmusic, bool notsfx); native static void S_PauseSound (bool notmusic, bool notsfx);
native static void S_ResumeSound (bool notsfx); native static void S_ResumeSound (bool notsfx);
native static bool S_ChangeMusic(String music_name, int order = 0, bool looping = true, bool force = false); native static bool S_ChangeMusic(String music_name, int order = 0, bool looping = true, bool force = false);
native static float S_GetLength(Sound sound_id);
native static uint BAM(double angle); native static uint BAM(double angle);
native static void SetMusicVolume(float vol); native static void SetMusicVolume(float vol);
native static uint MSTime(); native static uint MSTime();
@ -458,6 +460,87 @@ class BlockLinesIterator : Object native
native bool Next(); native bool Next();
} }
enum ETraceStatus
{
TRACE_Stop, // stop the trace, returning this hit
TRACE_Continue, // continue the trace, returning this hit if there are none further along
TRACE_Skip, // continue the trace; do not return this hit
TRACE_Abort // stop the trace, returning no hits
}
enum ETraceFlags
{
TRACE_NoSky = 1, // Hitting the sky returns TRACE_HitNone
//TRACE_PCross = 2, // Trigger SPAC_PCROSS lines
//TRACE_Impact = 4, // Trigger SPAC_IMPACT lines
TRACE_PortalRestrict = 8, // Cannot go through portals without a static link offset.
TRACE_ReportPortals = 16 // Report any portal crossing to the TraceCallback
}
enum ETraceResult
{
TRACE_HitNone,
TRACE_HitFloor,
TRACE_HitCeiling,
TRACE_HitWall,
TRACE_HitActor,
TRACE_CrossingPortal
}
enum ELineTier
{
TIER_Middle,
TIER_Upper,
TIER_Lower,
TIER_FFloor
}
struct TraceResults native
{
native Sector HitSector; // originally called "Sector". cannot be named like this in ZScript.
native TextureID HitTexture;
native vector3 HitPos;
native vector3 HitVector;
native vector3 SrcFromTarget;
native double SrcAngleFromTarget;
native double Distance;
native double Fraction;
native Actor HitActor; // valid if hit an actor. // originally called "Actor".
native Line HitLine; // valid if hit a line // originally called "Line".
native uint8 Side;
native uint8 Tier; // see Tracer.ELineTier
native bool unlinked; // passed through a portal without static offset.
native ETraceResult HitType;
// F3DFloor *ffloor;
native Sector CrossedWater; // For Boom-style, Transfer_Heights-based deep water
native vector3 CrossedWaterPos; // remember the position so that we can use it for spawning the splash
native Sector Crossed3DWater; // For 3D floor-based deep water
native vector3 Crossed3DWaterPos;
}
class Tracer : Object native
{
native @TraceResults Results;
native bool Trace(vector3 start, Sector sec, vector3 direction, double maxDist, ETraceFlags traceFlags);
virtual ETraceStatus TraceCallback()
{
// Normally you would examine Results.HitType (for ETraceResult), and determine either:
// - stop tracing and return the entity that was found (return TRACE_Stop)
// - ignore some object, like noclip, e.g. only count solid walls and floors, and ignore actors (return TRACE_Skip)
// - find last object of some type (return TRACE_Continue)
// - stop tracing entirely and assume we found nothing (return TRACE_Abort)
// TRACE_Abort and TRACE_Continue are of limited use in scripting.
return TRACE_Stop; // default callback returns first hit, whatever it is.
}
}
struct DropItem native struct DropItem native
{ {

View file

@ -897,6 +897,18 @@ enum ELineAttackFlags
LAF_ABSPOSITION = 1 << 7, LAF_ABSPOSITION = 1 << 7,
} }
enum ELineTraceFlags
{
TRF_ABSPOSITION = 1,
TRF_ABSOFFSET = 2,
TRF_THRUSPECIES = 4,
TRF_THRUACTORS = 8,
TRF_THRUBLOCK = 16,
TRF_THRUHITSCAN = 32,
TRF_NOSKY = 64,
TRF_ALLACTORS = 128,
}
const DEFMELEERANGE = 64; const DEFMELEERANGE = 64;
const SAWRANGE = (64.+(1./65536.)); // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) const SAWRANGE = (64.+(1./65536.)); // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states)
const MISSILERANGE = (32*64); const MISSILERANGE = (32*64);

View file

@ -1,5 +1,11 @@
class DynamicLight : Actor native class DynamicLight : Actor native
{ {
native double SpotInnerAngle;
native double SpotOuterAngle;
property SpotInnerAngle: SpotInnerAngle;
property SpotOuterAngle: SpotOuterAngle;
enum EArgs enum EArgs
{ {
LIGHT_RED = 0, LIGHT_RED = 0,
@ -17,7 +23,7 @@ class DynamicLight : Actor native
FlickerLight, FlickerLight,
RandomFlickerLight, RandomFlickerLight,
SectorLight, SectorLight,
SpotLight, DummyLight,
ColorPulseLight, ColorPulseLight,
ColorFlickerLight, ColorFlickerLight,
RandomColorFlickerLight RandomColorFlickerLight
@ -199,6 +205,166 @@ class PointLightFlickerRandomAttenuated :PointLightFlickerRandom
} }
} }
class SpotLight : DynamicLight
{
Default
{
DynamicLight.Type "Point";
+DYNAMICLIGHT.SPOT
}
}
class SpotLightPulse : SpotLight
{
Default
{
DynamicLight.Type "Pulse";
}
}
class SpotLightFlicker : SpotLight
{
Default
{
DynamicLight.Type "Flicker";
}
}
class SectorSpotLight : SpotLight
{
Default
{
DynamicLight.Type "Sector";
}
}
class SpotLightFlickerRandom : SpotLight
{
Default
{
DynamicLight.Type "RandomFlicker";
}
}
class SpotLightAdditive : SpotLight
{
Default
{
+DYNAMICLIGHT.ADDITIVE
}
}
class SpotLightPulseAdditive : SpotLightPulse
{
Default
{
+DYNAMICLIGHT.ADDITIVE
}
}
class SpotLightFlickerAdditive : SpotLightFlicker
{
Default
{
+DYNAMICLIGHT.ADDITIVE
}
}
class SectorSpotLightAdditive : SectorSpotLight
{
Default
{
+DYNAMICLIGHT.ADDITIVE
}
}
class SpotLightFlickerRandomAdditive : SpotLightFlickerRandom
{
Default
{
+DYNAMICLIGHT.ADDITIVE
}
}
class SpotLightSubtractive : SpotLight
{
Default
{
+DYNAMICLIGHT.SUBTRACTIVE
}
}
class SpotLightPulseSubtractive : SpotLightPulse
{
Default
{
+DYNAMICLIGHT.SUBTRACTIVE
}
}
class SpotLightFlickerSubtractive : SpotLightFlicker
{
Default
{
+DYNAMICLIGHT.SUBTRACTIVE
}
}
class SectorSpotLightSubtractive : SectorSpotLight
{
Default
{
+DYNAMICLIGHT.SUBTRACTIVE
}
}
class SpotLightFlickerRandomSubtractive : SpotLightFlickerRandom
{
Default
{
+DYNAMICLIGHT.SUBTRACTIVE
}
}
class SpotLightAttenuated : SpotLight
{
Default
{
+DYNAMICLIGHT.ATTENUATE
}
}
class SpotLightPulseAttenuated : SpotLightPulse
{
Default
{
+DYNAMICLIGHT.ATTENUATE
}
}
class SpotLightFlickerAttenuated : SpotLightFlicker
{
Default
{
+DYNAMICLIGHT.ATTENUATE
}
}
class SectorSpotLightAttenuated : SectorSpotLight
{
Default
{
+DYNAMICLIGHT.ATTENUATE
}
}
class SpotLightFlickerRandomAttenuated : SpotLightFlickerRandom
{
Default
{
+DYNAMICLIGHT.ATTENUATE
}
}
class VavoomLight : DynamicLight class VavoomLight : DynamicLight
{ {