From 3bbadd5a093eb87e9c22c95df563be242b0d6738 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Fri, 3 Feb 2017 16:29:50 +0100 Subject: [PATCH] Removed obsolete files, relocated 7-zip 7z archive files are now in the same folder Removed obsolete gles files Updated Makefile --- .gitignore | 3 + Makefile | 12 +- src/archivers/7z/{Archive/7z => }/7zAlloc.cpp | 154 +- src/archivers/7z/{Archive/7z => }/7zAlloc.h | 30 +- .../7z/{Archive/7z => }/7zDecode.cpp | 508 ++-- src/archivers/7z/{Archive/7z => }/7zDecode.h | 26 +- .../7z/{Archive/7z => }/7zExtract.cpp | 186 +- src/archivers/7z/{Archive/7z => }/7zExtract.h | 82 +- .../7z/{Archive/7z => }/7zHeader.cpp | 12 +- src/archivers/7z/{Archive/7z => }/7zHeader.h | 114 +- src/archivers/7z/{Archive/7z => }/7zIn.cpp | 2408 ++++++++--------- src/archivers/7z/{Archive/7z => }/7zIn.h | 82 +- src/archivers/7z/{Archive/7z => }/7zItem.cpp | 254 +- src/archivers/7z/{Archive/7z => }/7zItem.h | 168 +- src/od-gles/gl.cpp | 324 --- src/od-gles/gl.h | 35 - src/od-gles/gl_platform.cpp | 156 -- src/od-gles/gl_platform.h | 2 - src/od-gles/gles_gfx.cpp | 748 ----- src/od-gles/shader_stuff.cpp | 490 ---- src/od-gles/shader_stuff.h | 12 - 21 files changed, 2021 insertions(+), 3785 deletions(-) rename src/archivers/7z/{Archive/7z => }/7zAlloc.cpp (94%) rename src/archivers/7z/{Archive/7z => }/7zAlloc.h (95%) rename src/archivers/7z/{Archive/7z => }/7zDecode.cpp (96%) rename src/archivers/7z/{Archive/7z => }/7zDecode.h (96%) rename src/archivers/7z/{Archive/7z => }/7zExtract.cpp (96%) rename src/archivers/7z/{Archive/7z => }/7zExtract.h (97%) rename src/archivers/7z/{Archive/7z => }/7zHeader.cpp (96%) rename src/archivers/7z/{Archive/7z => }/7zHeader.h (90%) rename src/archivers/7z/{Archive/7z => }/7zIn.cpp (96%) rename src/archivers/7z/{Archive/7z => }/7zIn.h (95%) rename src/archivers/7z/{Archive/7z => }/7zItem.cpp (95%) rename src/archivers/7z/{Archive/7z => }/7zItem.h (93%) delete mode 100644 src/od-gles/gl.cpp delete mode 100644 src/od-gles/gl.h delete mode 100644 src/od-gles/gl_platform.cpp delete mode 100644 src/od-gles/gl_platform.h delete mode 100644 src/od-gles/gles_gfx.cpp delete mode 100644 src/od-gles/shader_stuff.cpp delete mode 100644 src/od-gles/shader_stuff.h diff --git a/.gitignore b/.gitignore index 94d52561..2f45c791 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ Amiberry/VisualGDB/Release-rpi2/Amiberry *.db-shm *.db-wal *.TMP +VSLinux/obj/ARM/Debug/Amiberry.tlog/unsuccessfulbuild +*.lastbuildstate +*.tlog diff --git a/Makefile b/Makefile index addb4b0c..822b48e0 100644 --- a/Makefile +++ b/Makefile @@ -110,12 +110,12 @@ OBJS = \ src/uaeresource.o \ src/zfile.o \ src/zfile_archive.o \ - src/archivers/7z/Archive/7z/7zAlloc.o \ - src/archivers/7z/Archive/7z/7zDecode.o \ - src/archivers/7z/Archive/7z/7zExtract.o \ - src/archivers/7z/Archive/7z/7zHeader.o \ - src/archivers/7z/Archive/7z/7zIn.o \ - src/archivers/7z/Archive/7z/7zItem.o \ + src/archivers/7z/7zAlloc.o \ + src/archivers/7z/7zDecode.o \ + src/archivers/7z/7zExtract.o \ + src/archivers/7z/7zHeader.o \ + src/archivers/7z/7zIn.o \ + src/archivers/7z/7zItem.o \ src/archivers/7z/7zBuf.o \ src/archivers/7z/7zCrc.o \ src/archivers/7z/7zStream.o \ diff --git a/src/archivers/7z/Archive/7z/7zAlloc.cpp b/src/archivers/7z/7zAlloc.cpp similarity index 94% rename from src/archivers/7z/Archive/7z/7zAlloc.cpp rename to src/archivers/7z/7zAlloc.cpp index 0c9448fd..71131161 100644 --- a/src/archivers/7z/Archive/7z/7zAlloc.cpp +++ b/src/archivers/7z/7zAlloc.cpp @@ -1,77 +1,77 @@ -/* 7zAlloc.c -- Allocation functions -2008-10-04 : Igor Pavlov : Public domain */ - -#include -#include "7zAlloc.h" - -/* #define _SZ_ALLOC_DEBUG */ -/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ - -#ifdef _SZ_ALLOC_DEBUG - -#ifdef _WIN32 -#include -#endif - -#include -int g_allocCount = 0; -int g_allocCountTemp = 0; - -#endif - -void *SzAlloc(void *p, size_t size) -{ - p = p; - if (size == 0) - return 0; -#ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); - g_allocCount++; -#endif - return malloc(size); -} - -void SzFree(void *p, void *address) -{ - p = p; -#ifdef _SZ_ALLOC_DEBUG - if (address != 0) - { - g_allocCount--; - fprintf(stderr, "\nFree; count = %10d", g_allocCount); - } -#endif - free(address); -} - -void *SzAllocTemp(void *p, size_t size) -{ - p = p; - if (size == 0) - return 0; -#ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); - g_allocCountTemp++; -#ifdef _WIN32 - return HeapAlloc(GetProcessHeap(), 0, size); -#endif -#endif - return malloc(size); -} - -void SzFreeTemp(void *p, void *address) -{ - p = p; -#ifdef _SZ_ALLOC_DEBUG - if (address != 0) - { - g_allocCountTemp--; - fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); - } -#ifdef _WIN32 - HeapFree(GetProcessHeap(), 0, address); - return; -#endif -#endif - free(address); -} +/* 7zAlloc.c -- Allocation functions +2008-10-04 : Igor Pavlov : Public domain */ + +#include +#include "7zAlloc.h" + +/* #define _SZ_ALLOC_DEBUG */ +/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ + +#ifdef _SZ_ALLOC_DEBUG + +#ifdef _WIN32 +#include +#endif + +#include +int g_allocCount = 0; +int g_allocCountTemp = 0; + +#endif + +void *SzAlloc(void *p, size_t size) +{ + p = p; + if (size == 0) + return 0; +#ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); + g_allocCount++; +#endif + return malloc(size); +} + +void SzFree(void *p, void *address) +{ + p = p; +#ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCount--; + fprintf(stderr, "\nFree; count = %10d", g_allocCount); + } +#endif + free(address); +} + +void *SzAllocTemp(void *p, size_t size) +{ + p = p; + if (size == 0) + return 0; +#ifdef _SZ_ALLOC_DEBUG + fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); + g_allocCountTemp++; +#ifdef _WIN32 + return HeapAlloc(GetProcessHeap(), 0, size); +#endif +#endif + return malloc(size); +} + +void SzFreeTemp(void *p, void *address) +{ + p = p; +#ifdef _SZ_ALLOC_DEBUG + if (address != 0) + { + g_allocCountTemp--; + fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); + } +#ifdef _WIN32 + HeapFree(GetProcessHeap(), 0, address); + return; +#endif +#endif + free(address); +} diff --git a/src/archivers/7z/Archive/7z/7zAlloc.h b/src/archivers/7z/7zAlloc.h similarity index 95% rename from src/archivers/7z/Archive/7z/7zAlloc.h rename to src/archivers/7z/7zAlloc.h index 91505d00..e752ef18 100644 --- a/src/archivers/7z/Archive/7z/7zAlloc.h +++ b/src/archivers/7z/7zAlloc.h @@ -1,15 +1,15 @@ -/* 7zAlloc.h -- Allocation functions -2008-10-04 : Igor Pavlov : Public domain */ - -#ifndef __7Z_ALLOC_H -#define __7Z_ALLOC_H - -#include - -void *SzAlloc(void *p, size_t size); -void SzFree(void *p, void *address); - -void *SzAllocTemp(void *p, size_t size); -void SzFreeTemp(void *p, void *address); - -#endif +/* 7zAlloc.h -- Allocation functions +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __7Z_ALLOC_H +#define __7Z_ALLOC_H + +#include + +void *SzAlloc(void *p, size_t size); +void SzFree(void *p, void *address); + +void *SzAllocTemp(void *p, size_t size); +void SzFreeTemp(void *p, void *address); + +#endif diff --git a/src/archivers/7z/Archive/7z/7zDecode.cpp b/src/archivers/7z/7zDecode.cpp similarity index 96% rename from src/archivers/7z/Archive/7z/7zDecode.cpp rename to src/archivers/7z/7zDecode.cpp index 93673377..91f3cfd8 100644 --- a/src/archivers/7z/Archive/7z/7zDecode.cpp +++ b/src/archivers/7z/7zDecode.cpp @@ -1,254 +1,254 @@ -/* 7zDecode.c -- Decoding from 7z folder -2008-11-23 : Igor Pavlov : Public domain */ - -#include - -#include "../../Bcj2.h" -#include "../../Bra.h" -#include "../../LzmaDec.h" -#include "7zDecode.h" - -#define k_Copy 0 -#define k_LZMA 0x30101 -#define k_BCJ 0x03030103 -#define k_BCJ2 0x0303011B - -static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) -{ - CLzmaDec state; - SRes res = SZ_OK; - - LzmaDec_Construct(&state); - RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); - state.dic = outBuffer; - state.dicBufSize = outSize; - LzmaDec_Init(&state); - - for (;;) - { - Byte *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; - ELzmaStatus status; - res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) - { - if (state.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - LzmaDec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) -{ - while (inSize > 0) - { - void *inBuf; - size_t curSize = (1 << 18); - if (curSize > inSize) - curSize = (size_t)inSize; - RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize)); - if (curSize == 0) - return SZ_ERROR_INPUT_EOF; - memcpy(outBuffer, inBuf, curSize); - outBuffer += curSize; - inSize -= curSize; - RINOK(inStream->Skip((void *)inStream, curSize)); - } - return SZ_OK; -} - -#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) -#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) -#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) -#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) - -SRes CheckSupportedFolder(const CSzFolder *f) -{ - if (f->NumCoders < 1 || f->NumCoders > 4) - return SZ_ERROR_UNSUPPORTED; - if (IS_UNSUPPORTED_CODER(f->Coders[0])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumCoders == 1) - { - if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - if (f->NumCoders == 2) - { - if (IS_NO_BCJ(f->Coders[1]) || - f->NumPackStreams != 1 || f->PackStreams[0] != 0 || - f->NumBindPairs != 1 || - f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - if (f->NumCoders == 4) - { - if (IS_UNSUPPORTED_CODER(f->Coders[1]) || - IS_UNSUPPORTED_CODER(f->Coders[2]) || - IS_NO_BCJ2(f->Coders[3])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumPackStreams != 4 || - f->PackStreams[0] != 2 || - f->PackStreams[1] != 6 || - f->PackStreams[2] != 1 || - f->PackStreams[3] != 0 || - f->NumBindPairs != 3 || - f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || - f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || - f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - return SZ_ERROR_UNSUPPORTED; -} - -UInt64 GetSum(const UInt64 *values, UInt32 index) -{ - UInt64 sum = 0; - UInt32 i; - for (i = 0; i < index; i++) - sum += values[i]; - return sum; -} - -SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, - Byte *tempBuf[]) -{ - UInt32 ci; - SizeT tempSizes[3] = { 0, 0, 0}; - SizeT tempSize3 = 0; - Byte *tempBuf3 = 0; - - RINOK(CheckSupportedFolder(folder)); - - for (ci = 0; ci < folder->NumCoders; ci++) - { - CSzCoderInfo *coder = &folder->Coders[ci]; - - if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) - { - UInt32 si = 0; - UInt64 offset; - UInt64 inSize; - Byte *outBufCur = outBuffer; - SizeT outSizeCur = outSize; - if (folder->NumCoders == 4) - { - UInt32 indices[] = { 3, 2, 0 }; - UInt64 unpackSize = folder->UnpackSizes[ci]; - si = indices[ci]; - if (ci < 2) - { - Byte *temp; - outSizeCur = (SizeT)unpackSize; - if (outSizeCur != unpackSize) - return SZ_ERROR_MEM; - temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); - if (temp == 0 && outSizeCur != 0) - return SZ_ERROR_MEM; - outBufCur = tempBuf[1 - ci] = temp; - tempSizes[1 - ci] = outSizeCur; - } - else if (ci == 2) - { - if (unpackSize > outSize) /* check it */ - return SZ_ERROR_PARAM; - tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); - tempSize3 = outSizeCur = (SizeT)unpackSize; - } - else - return SZ_ERROR_UNSUPPORTED; - } - offset = GetSum(packSizes, si); - inSize = packSizes[si]; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - - if (coder->MethodID == k_Copy) - { - if (inSize != outSizeCur) /* check it */ - return SZ_ERROR_DATA; - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); - } - else - { - RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - } - else if (coder->MethodID == k_BCJ) - { - UInt32 state; - if (ci != 1) - return SZ_ERROR_UNSUPPORTED; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); - } - else if (coder->MethodID == k_BCJ2) - { - UInt64 offset = GetSum(packSizes, 1); - UInt64 s3Size = packSizes[1]; - SRes res; - if (ci != 3) - return SZ_ERROR_UNSUPPORTED; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - tempSizes[2] = (SizeT)s3Size; - if (tempSizes[2] != s3Size) - return SZ_ERROR_MEM; - tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); - if (tempBuf[2] == 0 && tempSizes[2] != 0) - return SZ_ERROR_MEM; - res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); - RINOK(res) - - res = Bcj2_Decode( - tempBuf3, tempSize3, - tempBuf[0], tempSizes[0], - tempBuf[1], tempSizes[1], - tempBuf[2], tempSizes[2], - outBuffer, outSize); - RINOK(res) - } - else - return SZ_ERROR_UNSUPPORTED; - } - return SZ_OK; -} - -SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, - ILookInStream *inStream, UInt64 startPos, - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - Byte *tempBuf[3] = { 0, 0, 0}; - int i; - SRes res = SzDecode2(packSizes, folder, inStream, startPos, - outBuffer, (SizeT)outSize, allocMain, tempBuf); - for (i = 0; i < 3; i++) - IAlloc_Free(allocMain, tempBuf[i]); - return res; -} +/* 7zDecode.c -- Decoding from 7z folder +2008-11-23 : Igor Pavlov : Public domain */ + +#include + +#include "Bcj2.h" +#include "Bra.h" +#include "LzmaDec.h" +#include "7zDecode.h" + +#define k_Copy 0 +#define k_LZMA 0x30101 +#define k_BCJ 0x03030103 +#define k_BCJ2 0x0303011B + +static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) +{ + CLzmaDec state; + SRes res = SZ_OK; + + LzmaDec_Construct(&state); + RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); + state.dic = outBuffer; + state.dicBufSize = outSize; + LzmaDec_Init(&state); + + for (;;) + { + Byte *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; + ELzmaStatus status; + res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) + { + if (state.dicBufSize != outSize || lookahead != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) + res = SZ_ERROR_DATA; + break; + } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + LzmaDec_FreeProbs(&state, allocMain); + return res; +} + +static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) +{ + while (inSize > 0) + { + void *inBuf; + size_t curSize = (1 << 18); + if (curSize > inSize) + curSize = (size_t)inSize; + RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize)); + if (curSize == 0) + return SZ_ERROR_INPUT_EOF; + memcpy(outBuffer, inBuf, curSize); + outBuffer += curSize; + inSize -= curSize; + RINOK(inStream->Skip((void *)inStream, curSize)); + } + return SZ_OK; +} + +#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA) +#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1) +#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1) +#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1) + +SRes CheckSupportedFolder(const CSzFolder *f) +{ + if (f->NumCoders < 1 || f->NumCoders > 4) + return SZ_ERROR_UNSUPPORTED; + if (IS_UNSUPPORTED_CODER(f->Coders[0])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumCoders == 1) + { + if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + if (f->NumCoders == 2) + { + if (IS_NO_BCJ(f->Coders[1]) || + f->NumPackStreams != 1 || f->PackStreams[0] != 0 || + f->NumBindPairs != 1 || + f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + if (f->NumCoders == 4) + { + if (IS_UNSUPPORTED_CODER(f->Coders[1]) || + IS_UNSUPPORTED_CODER(f->Coders[2]) || + IS_NO_BCJ2(f->Coders[3])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumPackStreams != 4 || + f->PackStreams[0] != 2 || + f->PackStreams[1] != 6 || + f->PackStreams[2] != 1 || + f->PackStreams[3] != 0 || + f->NumBindPairs != 3 || + f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || + f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || + f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + return SZ_ERROR_UNSUPPORTED; +} + +UInt64 GetSum(const UInt64 *values, UInt32 index) +{ + UInt64 sum = 0; + UInt32 i; + for (i = 0; i < index; i++) + sum += values[i]; + return sum; +} + +SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, + Byte *tempBuf[]) +{ + UInt32 ci; + SizeT tempSizes[3] = { 0, 0, 0}; + SizeT tempSize3 = 0; + Byte *tempBuf3 = 0; + + RINOK(CheckSupportedFolder(folder)); + + for (ci = 0; ci < folder->NumCoders; ci++) + { + CSzCoderInfo *coder = &folder->Coders[ci]; + + if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) + { + UInt32 si = 0; + UInt64 offset; + UInt64 inSize; + Byte *outBufCur = outBuffer; + SizeT outSizeCur = outSize; + if (folder->NumCoders == 4) + { + UInt32 indices[] = { 3, 2, 0 }; + UInt64 unpackSize = folder->UnpackSizes[ci]; + si = indices[ci]; + if (ci < 2) + { + Byte *temp; + outSizeCur = (SizeT)unpackSize; + if (outSizeCur != unpackSize) + return SZ_ERROR_MEM; + temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); + if (temp == 0 && outSizeCur != 0) + return SZ_ERROR_MEM; + outBufCur = tempBuf[1 - ci] = temp; + tempSizes[1 - ci] = outSizeCur; + } + else if (ci == 2) + { + if (unpackSize > outSize) /* check it */ + return SZ_ERROR_PARAM; + tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); + tempSize3 = outSizeCur = (SizeT)unpackSize; + } + else + return SZ_ERROR_UNSUPPORTED; + } + offset = GetSum(packSizes, si); + inSize = packSizes[si]; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + + if (coder->MethodID == k_Copy) + { + if (inSize != outSizeCur) /* check it */ + return SZ_ERROR_DATA; + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + } + else + { + RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + } + else if (coder->MethodID == k_BCJ) + { + UInt32 state; + if (ci != 1) + return SZ_ERROR_UNSUPPORTED; + x86_Convert_Init(state); + x86_Convert(outBuffer, outSize, 0, &state, 0); + } + else if (coder->MethodID == k_BCJ2) + { + UInt64 offset = GetSum(packSizes, 1); + UInt64 s3Size = packSizes[1]; + SRes res; + if (ci != 3) + return SZ_ERROR_UNSUPPORTED; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + tempSizes[2] = (SizeT)s3Size; + if (tempSizes[2] != s3Size) + return SZ_ERROR_MEM; + tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); + if (tempBuf[2] == 0 && tempSizes[2] != 0) + return SZ_ERROR_MEM; + res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); + RINOK(res) + + res = Bcj2_Decode( + tempBuf3, tempSize3, + tempBuf[0], tempSizes[0], + tempBuf[1], tempSizes[1], + tempBuf[2], tempSizes[2], + outBuffer, outSize); + RINOK(res) + } + else + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; +} + +SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, + ILookInStream *inStream, UInt64 startPos, + Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) +{ + Byte *tempBuf[3] = { 0, 0, 0}; + int i; + SRes res = SzDecode2(packSizes, folder, inStream, startPos, + outBuffer, (SizeT)outSize, allocMain, tempBuf); + for (i = 0; i < 3; i++) + IAlloc_Free(allocMain, tempBuf[i]); + return res; +} diff --git a/src/archivers/7z/Archive/7z/7zDecode.h b/src/archivers/7z/7zDecode.h similarity index 96% rename from src/archivers/7z/Archive/7z/7zDecode.h rename to src/archivers/7z/7zDecode.h index ce81f40f..ba0b2da9 100644 --- a/src/archivers/7z/Archive/7z/7zDecode.h +++ b/src/archivers/7z/7zDecode.h @@ -1,13 +1,13 @@ -/* 7zDecode.h -- Decoding from 7z folder -2008-11-23 : Igor Pavlov : Public domain */ - -#ifndef __7Z_DECODE_H -#define __7Z_DECODE_H - -#include "7zItem.h" - -SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, - ILookInStream *stream, UInt64 startPos, - Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); - -#endif +/* 7zDecode.h -- Decoding from 7z folder +2008-11-23 : Igor Pavlov : Public domain */ + +#ifndef __7Z_DECODE_H +#define __7Z_DECODE_H + +#include "7zItem.h" + +SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder, + ILookInStream *stream, UInt64 startPos, + Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); + +#endif diff --git a/src/archivers/7z/Archive/7z/7zExtract.cpp b/src/archivers/7z/7zExtract.cpp similarity index 96% rename from src/archivers/7z/Archive/7z/7zExtract.cpp rename to src/archivers/7z/7zExtract.cpp index 10fb57b5..89cb1216 100644 --- a/src/archivers/7z/Archive/7z/7zExtract.cpp +++ b/src/archivers/7z/7zExtract.cpp @@ -1,93 +1,93 @@ -/* 7zExtract.c -- Extracting from 7z archive -2008-11-23 : Igor Pavlov : Public domain */ - -#include "../../7zCrc.h" -#include "7zDecode.h" -#include "7zExtract.h" - -SRes SzAr_Extract( - const CSzArEx *p, - ILookInStream *inStream, - UInt32 fileIndex, - UInt32 *blockIndex, - Byte **outBuffer, - size_t *outBufferSize, - size_t *offset, - size_t *outSizeProcessed, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; - SRes res = SZ_OK; - *offset = 0; - *outSizeProcessed = 0; - if (folderIndex == (UInt32)-1) - { - IAlloc_Free(allocMain, *outBuffer); - *blockIndex = folderIndex; - *outBuffer = 0; - *outBufferSize = 0; - return SZ_OK; - } - - if (*outBuffer == 0 || *blockIndex != folderIndex) - { - CSzFolder *folder = p->db.Folders + folderIndex; - UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); - size_t unpackSize = (size_t)unpackSizeSpec; - UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); - - if (unpackSize != unpackSizeSpec) - return SZ_ERROR_MEM; - *blockIndex = folderIndex; - IAlloc_Free(allocMain, *outBuffer); - *outBuffer = 0; - - RINOK(LookInStream_SeekTo(inStream, startOffset)); - - if (res == SZ_OK) - { - *outBufferSize = unpackSize; - if (unpackSize != 0) - { - *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); - if (*outBuffer == 0) - res = SZ_ERROR_MEM; - } - if (res == SZ_OK) - { - res = SzDecode(p->db.PackSizes + - p->FolderStartPackStreamIndex[folderIndex], folder, - inStream, startOffset, - *outBuffer, unpackSize, allocTemp); - if (res == SZ_OK) - { - if (folder->UnpackCRCDefined) - { - if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) - res = SZ_ERROR_CRC; - } - } - } - } - } - if (res == SZ_OK) - { - UInt32 i; - CSzFileItem *fileItem = p->db.Files + fileIndex; - *offset = 0; - for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) - *offset += (UInt32)p->db.Files[i].Size; - *outSizeProcessed = (size_t)fileItem->Size; - if (*offset + *outSizeProcessed > *outBufferSize) - return SZ_ERROR_FAIL; - { - if (fileItem->FileCRCDefined) - { - if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) - res = SZ_ERROR_CRC; - } - } - } - return res; -} +/* 7zExtract.c -- Extracting from 7z archive +2008-11-23 : Igor Pavlov : Public domain */ + +#include "7zCrc.h" +#include "7zDecode.h" +#include "7zExtract.h" + +SRes SzAr_Extract( + const CSzArEx *p, + ILookInStream *inStream, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **outBuffer, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; + SRes res = SZ_OK; + *offset = 0; + *outSizeProcessed = 0; + if (folderIndex == (UInt32)-1) + { + IAlloc_Free(allocMain, *outBuffer); + *blockIndex = folderIndex; + *outBuffer = 0; + *outBufferSize = 0; + return SZ_OK; + } + + if (*outBuffer == 0 || *blockIndex != folderIndex) + { + CSzFolder *folder = p->db.Folders + folderIndex; + UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder); + size_t unpackSize = (size_t)unpackSizeSpec; + UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); + + if (unpackSize != unpackSizeSpec) + return SZ_ERROR_MEM; + *blockIndex = folderIndex; + IAlloc_Free(allocMain, *outBuffer); + *outBuffer = 0; + + RINOK(LookInStream_SeekTo(inStream, startOffset)); + + if (res == SZ_OK) + { + *outBufferSize = unpackSize; + if (unpackSize != 0) + { + *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize); + if (*outBuffer == 0) + res = SZ_ERROR_MEM; + } + if (res == SZ_OK) + { + res = SzDecode(p->db.PackSizes + + p->FolderStartPackStreamIndex[folderIndex], folder, + inStream, startOffset, + *outBuffer, unpackSize, allocTemp); + if (res == SZ_OK) + { + if (folder->UnpackCRCDefined) + { + if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) + res = SZ_ERROR_CRC; + } + } + } + } + } + if (res == SZ_OK) + { + UInt32 i; + CSzFileItem *fileItem = p->db.Files + fileIndex; + *offset = 0; + for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (UInt32)p->db.Files[i].Size; + *outSizeProcessed = (size_t)fileItem->Size; + if (*offset + *outSizeProcessed > *outBufferSize) + return SZ_ERROR_FAIL; + { + if (fileItem->FileCRCDefined) + { + if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) + res = SZ_ERROR_CRC; + } + } + } + return res; +} diff --git a/src/archivers/7z/Archive/7z/7zExtract.h b/src/archivers/7z/7zExtract.h similarity index 97% rename from src/archivers/7z/Archive/7z/7zExtract.h rename to src/archivers/7z/7zExtract.h index e171f4ab..5f78415f 100644 --- a/src/archivers/7z/Archive/7z/7zExtract.h +++ b/src/archivers/7z/7zExtract.h @@ -1,41 +1,41 @@ -/* 7zExtract.h -- Extracting from 7z archive -2008-11-23 : Igor Pavlov : Public domain */ - -#ifndef __7Z_EXTRACT_H -#define __7Z_EXTRACT_H - -#include "7zIn.h" - -/* - SzExtract extracts file from archive - - *outBuffer must be 0 before first call for each new archive. - - Extracting cache: - If you need to decompress more than one file, you can send - these values from previous call: - *blockIndex, - *outBuffer, - *outBufferSize - You can consider "*outBuffer" as cache of solid block. If your archive is solid, - it will increase decompression speed. - - If you use external function, you can declare these 3 cache variables - (blockIndex, outBuffer, outBufferSize) as static in that external function. - - Free *outBuffer and set *outBuffer to 0, if you want to flush cache. -*/ - -SRes SzAr_Extract( - const CSzArEx *db, - ILookInStream *inStream, - UInt32 fileIndex, /* index of file */ - UInt32 *blockIndex, /* index of solid block */ - Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ - size_t *outBufferSize, /* buffer size for output buffer */ - size_t *offset, /* offset of stream for required file in *outBuffer */ - size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); - -#endif +/* 7zExtract.h -- Extracting from 7z archive +2008-11-23 : Igor Pavlov : Public domain */ + +#ifndef __7Z_EXTRACT_H +#define __7Z_EXTRACT_H + +#include "7zIn.h" + +/* + SzExtract extracts file from archive + + *outBuffer must be 0 before first call for each new archive. + + Extracting cache: + If you need to decompress more than one file, you can send + these values from previous call: + *blockIndex, + *outBuffer, + *outBufferSize + You can consider "*outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + If you use external function, you can declare these 3 cache variables + (blockIndex, outBuffer, outBufferSize) as static in that external function. + + Free *outBuffer and set *outBuffer to 0, if you want to flush cache. +*/ + +SRes SzAr_Extract( + const CSzArEx *db, + ILookInStream *inStream, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + +#endif diff --git a/src/archivers/7z/Archive/7z/7zHeader.cpp b/src/archivers/7z/7zHeader.cpp similarity index 96% rename from src/archivers/7z/Archive/7z/7zHeader.cpp rename to src/archivers/7z/7zHeader.cpp index c44ff4a4..e48faa48 100644 --- a/src/archivers/7z/Archive/7z/7zHeader.cpp +++ b/src/archivers/7z/7zHeader.cpp @@ -1,6 +1,6 @@ -/* 7zHeader.c -- 7z Headers -2008-10-04 : Igor Pavlov : Public domain */ - -#include "7zHeader.h" - -Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; +/* 7zHeader.c -- 7z Headers +2008-10-04 : Igor Pavlov : Public domain */ + +#include "7zHeader.h" + +Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; diff --git a/src/archivers/7z/Archive/7z/7zHeader.h b/src/archivers/7z/7zHeader.h similarity index 90% rename from src/archivers/7z/Archive/7z/7zHeader.h rename to src/archivers/7z/7zHeader.h index 91b9d0dd..c44819fe 100644 --- a/src/archivers/7z/Archive/7z/7zHeader.h +++ b/src/archivers/7z/7zHeader.h @@ -1,57 +1,57 @@ -/* 7zHeader.h -- 7z Headers -2008-10-04 : Igor Pavlov : Public domain */ - -#ifndef __7Z_HEADER_H -#define __7Z_HEADER_H - -#include "../../Types.h" - -#define k7zSignatureSize 6 -extern Byte k7zSignature[k7zSignatureSize]; - -#define k7zMajorVersion 0 - -#define k7zStartHeaderSize 0x20 - -enum EIdEnum -{ - k7zIdEnd, - - k7zIdHeader, - - k7zIdArchiveProperties, - - k7zIdAdditionalStreamsInfo, - k7zIdMainStreamsInfo, - k7zIdFilesInfo, - - k7zIdPackInfo, - k7zIdUnpackInfo, - k7zIdSubStreamsInfo, - - k7zIdSize, - k7zIdCRC, - - k7zIdFolder, - - k7zIdCodersUnpackSize, - k7zIdNumUnpackStream, - - k7zIdEmptyStream, - k7zIdEmptyFile, - k7zIdAnti, - - k7zIdName, - k7zIdCTime, - k7zIdATime, - k7zIdMTime, - k7zIdWinAttributes, - k7zIdComment, - - k7zIdEncodedHeader, - - k7zIdStartPos, - k7zIdDummy -}; - -#endif +/* 7zHeader.h -- 7z Headers +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __7Z_HEADER_H +#define __7Z_HEADER_H + +#include "Types.h" + +#define k7zSignatureSize 6 +extern Byte k7zSignature[k7zSignatureSize]; + +#define k7zMajorVersion 0 + +#define k7zStartHeaderSize 0x20 + +enum EIdEnum +{ + k7zIdEnd, + + k7zIdHeader, + + k7zIdArchiveProperties, + + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + + k7zIdPackInfo, + k7zIdUnpackInfo, + k7zIdSubStreamsInfo, + + k7zIdSize, + k7zIdCRC, + + k7zIdFolder, + + k7zIdCodersUnpackSize, + k7zIdNumUnpackStream, + + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + + k7zIdName, + k7zIdCTime, + k7zIdATime, + k7zIdMTime, + k7zIdWinAttributes, + k7zIdComment, + + k7zIdEncodedHeader, + + k7zIdStartPos, + k7zIdDummy +}; + +#endif diff --git a/src/archivers/7z/Archive/7z/7zIn.cpp b/src/archivers/7z/7zIn.cpp similarity index 96% rename from src/archivers/7z/Archive/7z/7zIn.cpp rename to src/archivers/7z/7zIn.cpp index e23e3fe0..d3e1c783 100644 --- a/src/archivers/7z/Archive/7z/7zIn.cpp +++ b/src/archivers/7z/7zIn.cpp @@ -1,1204 +1,1204 @@ -/* 7zIn.c -- 7z Input functions -2008-12-31 : Igor Pavlov : Public domain */ - -#include "../../7zCrc.h" -#include "../../CpuArch.h" - -#include "7zDecode.h" -#include "7zIn.h" - -#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } - -#define NUM_FOLDER_CODERS_MAX 32 -#define NUM_CODER_STREAMS_MAX 32 - -void SzArEx_Init(CSzArEx *p) -{ - SzAr_Init(&p->db); - p->FolderStartPackStreamIndex = 0; - p->PackStreamStartPositions = 0; - p->FolderStartFileIndex = 0; - p->FileIndexToFolderIndexMap = 0; -} - -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->FolderStartPackStreamIndex); - IAlloc_Free(alloc, p->PackStreamStartPositions); - IAlloc_Free(alloc, p->FolderStartFileIndex); - IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); - SzAr_Free(&p->db, alloc); - SzArEx_Init(p); -} - -/* -UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const -{ - return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; -} - -UInt64 GetFilePackSize(int fileIndex) const -{ - int folderIndex = FileIndexToFolderIndexMap[fileIndex]; - if (folderIndex >= 0) - { - const CSzFolder &folderInfo = Folders[folderIndex]; - if (FolderStartFileIndex[folderIndex] == fileIndex) - return GetFolderFullPackSize(folderIndex); - } - return 0; -} -*/ - -#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ - if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } - -static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) -{ - UInt32 startPos = 0; - UInt64 startPosSize = 0; - UInt32 i; - UInt32 folderIndex = 0; - UInt32 indexInFolder = 0; - MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); - for (i = 0; i < p->db.NumFolders; i++) - { - p->FolderStartPackStreamIndex[i] = startPos; - startPos += p->db.Folders[i].NumPackStreams; - } - - MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); - - for (i = 0; i < p->db.NumPackStreams; i++) - { - p->PackStreamStartPositions[i] = startPosSize; - startPosSize += p->db.PackSizes[i]; - } - - MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); - MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); - - for (i = 0; i < p->db.NumFiles; i++) - { - CSzFileItem *file = p->db.Files + i; - int emptyStream = !file->HasStream; - if (emptyStream && indexInFolder == 0) - { - p->FileIndexToFolderIndexMap[i] = (UInt32)-1; - continue; - } - if (indexInFolder == 0) - { - /* - v3.13 incorrectly worked with empty folders - v4.07: Loop for skipping empty folders - */ - for (;;) - { - if (folderIndex >= p->db.NumFolders) - return SZ_ERROR_ARCHIVE; - p->FolderStartFileIndex[folderIndex] = i; - if (p->db.Folders[folderIndex].NumUnpackStreams != 0) - break; - folderIndex++; - } - } - p->FileIndexToFolderIndexMap[i] = folderIndex; - if (emptyStream) - continue; - indexInFolder++; - if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) - { - folderIndex++; - indexInFolder = 0; - } - } - return SZ_OK; -} - - -UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) -{ - return p->dataPos + - p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; -} - -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) -{ - UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; - CSzFolder *folder = p->db.Folders + folderIndex; - UInt64 size = 0; - UInt32 i; - for (i = 0; i < folder->NumPackStreams; i++) - { - UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; - if (t < size) /* check it */ - return SZ_ERROR_FAIL; - size = t; - } - *resSize = size; - return SZ_OK; -} - - -/* -SRes SzReadTime(const CObjectVector &dataVector, - CObjectVector &files, UInt64 type) -{ - CBoolVector boolVector; - RINOK(ReadBoolVector2(files.Size(), boolVector)) - - CStreamSwitch streamSwitch; - RINOK(streamSwitch.Set(this, &dataVector)); - - for (int i = 0; i < files.Size(); i++) - { - CSzFileItem &file = files[i]; - CArchiveFileTime fileTime; - bool defined = boolVector[i]; - if (defined) - { - UInt32 low, high; - RINOK(SzReadUInt32(low)); - RINOK(SzReadUInt32(high)); - fileTime.dwLowDateTime = low; - fileTime.dwHighDateTime = high; - } - switch(type) - { - case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; - case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; - case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; - } - } - return SZ_OK; -} -*/ - -static int TestSignatureCandidate(Byte *testBytes) -{ - size_t i; - for (i = 0; i < k7zSignatureSize; i++) - if (testBytes[i] != k7zSignature[i]) - return 0; - return 1; -} - -typedef struct _CSzState -{ - Byte *Data; - size_t Size; -} CSzData; - -static SRes SzReadByte(CSzData *sd, Byte *b) -{ - if (sd->Size == 0) - return SZ_ERROR_ARCHIVE; - sd->Size--; - *b = *sd->Data++; - return SZ_OK; -} - -static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) -{ - size_t i; - for (i = 0; i < size; i++) - { - RINOK(SzReadByte(sd, data + i)); - } - return SZ_OK; -} - -static SRes SzReadUInt32(CSzData *sd, UInt32 *value) -{ - int i; - *value = 0; - for (i = 0; i < 4; i++) - { - Byte b; - RINOK(SzReadByte(sd, &b)); - *value |= ((UInt32)(b) << (8 * i)); - } - return SZ_OK; -} - -static SRes SzReadNumber(CSzData *sd, UInt64 *value) -{ - Byte firstByte; - Byte mask = 0x80; - int i; - RINOK(SzReadByte(sd, &firstByte)); - *value = 0; - for (i = 0; i < 8; i++) - { - Byte b; - if ((firstByte & mask) == 0) - { - UInt64 highPart = firstByte & (mask - 1); - *value += (highPart << (8 * i)); - return SZ_OK; - } - RINOK(SzReadByte(sd, &b)); - *value |= ((UInt64)b << (8 * i)); - mask >>= 1; - } - return SZ_OK; -} - -static SRes SzReadNumber32(CSzData *sd, UInt32 *value) -{ - UInt64 value64; - RINOK(SzReadNumber(sd, &value64)); - if (value64 >= 0x80000000) - return SZ_ERROR_UNSUPPORTED; - if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) - return SZ_ERROR_UNSUPPORTED; - *value = (UInt32)value64; - return SZ_OK; -} - -static SRes SzReadID(CSzData *sd, UInt64 *value) -{ - return SzReadNumber(sd, value); -} - -static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) -{ - if (size > sd->Size) - return SZ_ERROR_ARCHIVE; - sd->Size -= (size_t)size; - sd->Data += (size_t)size; - return SZ_OK; -} - -static SRes SzSkeepData(CSzData *sd) -{ - UInt64 size; - RINOK(SzReadNumber(sd, &size)); - return SzSkeepDataSize(sd, size); -} - -static SRes SzReadArchiveProperties(CSzData *sd) -{ - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - SzSkeepData(sd); - } - return SZ_OK; -} - -static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) -{ - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == attribute) - return SZ_OK; - if (type == k7zIdEnd) - return SZ_ERROR_ARCHIVE; - RINOK(SzSkeepData(sd)); - } -} - -static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) -{ - Byte b = 0; - Byte mask = 0; - size_t i; - MY_ALLOC(Byte, *v, numItems, alloc); - for (i = 0; i < numItems; i++) - { - if (mask == 0) - { - RINOK(SzReadByte(sd, &b)); - mask = 0x80; - } - (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); - mask >>= 1; - } - return SZ_OK; -} - -static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) -{ - Byte allAreDefined; - size_t i; - RINOK(SzReadByte(sd, &allAreDefined)); - if (allAreDefined == 0) - return SzReadBoolVector(sd, numItems, v, alloc); - MY_ALLOC(Byte, *v, numItems, alloc); - for (i = 0; i < numItems; i++) - (*v)[i] = 1; - return SZ_OK; -} - -static SRes SzReadHashDigests( - CSzData *sd, - size_t numItems, - Byte **digestsDefined, - UInt32 **digests, - ISzAlloc *alloc) -{ - size_t i; - RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); - MY_ALLOC(UInt32, *digests, numItems, alloc); - for (i = 0; i < numItems; i++) - if ((*digestsDefined)[i]) - { - RINOK(SzReadUInt32(sd, (*digests) + i)); - } - return SZ_OK; -} - -static SRes SzReadPackInfo( - CSzData *sd, - UInt64 *dataOffset, - UInt32 *numPackStreams, - UInt64 **packSizes, - Byte **packCRCsDefined, - UInt32 **packCRCs, - ISzAlloc *alloc) -{ - UInt32 i; - RINOK(SzReadNumber(sd, dataOffset)); - RINOK(SzReadNumber32(sd, numPackStreams)); - - RINOK(SzWaitAttribute(sd, k7zIdSize)); - - MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); - - for (i = 0; i < *numPackStreams; i++) - { - RINOK(SzReadNumber(sd, (*packSizes) + i)); - } - - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - if (type == k7zIdCRC) - { - RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); - continue; - } - RINOK(SzSkeepData(sd)); - } - if (*packCRCsDefined == 0) - { - MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); - MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); - for (i = 0; i < *numPackStreams; i++) - { - (*packCRCsDefined)[i] = 0; - (*packCRCs)[i] = 0; - } - } - return SZ_OK; -} - -static SRes SzReadSwitch(CSzData *sd) -{ - Byte external; - RINOK(SzReadByte(sd, &external)); - return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; -} - -static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) -{ - UInt32 numCoders, numBindPairs, numPackStreams, i; - UInt32 numInStreams = 0, numOutStreams = 0; - - RINOK(SzReadNumber32(sd, &numCoders)); - if (numCoders > NUM_FOLDER_CODERS_MAX) - return SZ_ERROR_UNSUPPORTED; - folder->NumCoders = numCoders; - - MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); - - for (i = 0; i < numCoders; i++) - SzCoderInfo_Init(folder->Coders + i); - - for (i = 0; i < numCoders; i++) - { - Byte mainByte; - CSzCoderInfo *coder = folder->Coders + i; - { - unsigned idSize, j; - Byte longID[15]; - RINOK(SzReadByte(sd, &mainByte)); - idSize = (unsigned)(mainByte & 0xF); - RINOK(SzReadBytes(sd, longID, idSize)); - if (idSize > sizeof(coder->MethodID)) - return SZ_ERROR_UNSUPPORTED; - coder->MethodID = 0; - for (j = 0; j < idSize; j++) - coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); - - if ((mainByte & 0x10) != 0) - { - RINOK(SzReadNumber32(sd, &coder->NumInStreams)); - RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); - if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || - coder->NumOutStreams > NUM_CODER_STREAMS_MAX) - return SZ_ERROR_UNSUPPORTED; - } - else - { - coder->NumInStreams = 1; - coder->NumOutStreams = 1; - } - if ((mainByte & 0x20) != 0) - { - UInt64 propertiesSize = 0; - RINOK(SzReadNumber(sd, &propertiesSize)); - if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) - return SZ_ERROR_MEM; - RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); - } - } - while ((mainByte & 0x80) != 0) - { - RINOK(SzReadByte(sd, &mainByte)); - RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); - if ((mainByte & 0x10) != 0) - { - UInt32 n; - RINOK(SzReadNumber32(sd, &n)); - RINOK(SzReadNumber32(sd, &n)); - } - if ((mainByte & 0x20) != 0) - { - UInt64 propertiesSize = 0; - RINOK(SzReadNumber(sd, &propertiesSize)); - RINOK(SzSkeepDataSize(sd, propertiesSize)); - } - } - numInStreams += coder->NumInStreams; - numOutStreams += coder->NumOutStreams; - } - - if (numOutStreams == 0) - return SZ_ERROR_UNSUPPORTED; - - folder->NumBindPairs = numBindPairs = numOutStreams - 1; - MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); - - for (i = 0; i < numBindPairs; i++) - { - CBindPair *bp = folder->BindPairs + i; - RINOK(SzReadNumber32(sd, &bp->InIndex)); - RINOK(SzReadNumber32(sd, &bp->OutIndex)); - } - - if (numInStreams < numBindPairs) - return SZ_ERROR_UNSUPPORTED; - - folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; - MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); - - if (numPackStreams == 1) - { - for (i = 0; i < numInStreams ; i++) - if (SzFolder_FindBindPairForInStream(folder, i) < 0) - break; - if (i == numInStreams) - return SZ_ERROR_UNSUPPORTED; - folder->PackStreams[0] = i; - } - else - for (i = 0; i < numPackStreams; i++) - { - RINOK(SzReadNumber32(sd, folder->PackStreams + i)); - } - return SZ_OK; -} - -static SRes SzReadUnpackInfo( - CSzData *sd, - UInt32 *numFolders, - CSzFolder **folders, /* for alloc */ - ISzAlloc *alloc, - ISzAlloc *allocTemp) -{ - UInt32 i; - RINOK(SzWaitAttribute(sd, k7zIdFolder)); - RINOK(SzReadNumber32(sd, numFolders)); - { - RINOK(SzReadSwitch(sd)); - - MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); - - for (i = 0; i < *numFolders; i++) - SzFolder_Init((*folders) + i); - - for (i = 0; i < *numFolders; i++) - { - RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); - } - } - - RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); - - for (i = 0; i < *numFolders; i++) - { - UInt32 j; - CSzFolder *folder = (*folders) + i; - UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); - - MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); - - for (j = 0; j < numOutStreams; j++) - { - RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); - } - } - - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - return SZ_OK; - if (type == k7zIdCRC) - { - SRes res; - Byte *crcsDefined = 0; - UInt32 *crcs = 0; - res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); - if (res == SZ_OK) - { - for (i = 0; i < *numFolders; i++) - { - CSzFolder *folder = (*folders) + i; - folder->UnpackCRCDefined = crcsDefined[i]; - folder->UnpackCRC = crcs[i]; - } - } - IAlloc_Free(allocTemp, crcs); - IAlloc_Free(allocTemp, crcsDefined); - RINOK(res); - continue; - } - RINOK(SzSkeepData(sd)); - } -} - -static SRes SzReadSubStreamsInfo( - CSzData *sd, - UInt32 numFolders, - CSzFolder *folders, - UInt32 *numUnpackStreams, - UInt64 **unpackSizes, - Byte **digestsDefined, - UInt32 **digests, - ISzAlloc *allocTemp) -{ - UInt64 type = 0; - UInt32 i; - UInt32 si = 0; - UInt32 numDigests = 0; - - for (i = 0; i < numFolders; i++) - folders[i].NumUnpackStreams = 1; - *numUnpackStreams = numFolders; - - for (;;) - { - RINOK(SzReadID(sd, &type)); - if (type == k7zIdNumUnpackStream) - { - *numUnpackStreams = 0; - for (i = 0; i < numFolders; i++) - { - UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); - folders[i].NumUnpackStreams = numStreams; - *numUnpackStreams += numStreams; - } - continue; - } - if (type == k7zIdCRC || type == k7zIdSize) - break; - if (type == k7zIdEnd) - break; - RINOK(SzSkeepData(sd)); - } - - if (*numUnpackStreams == 0) - { - *unpackSizes = 0; - *digestsDefined = 0; - *digests = 0; - } - else - { - *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); - RINOM(*unpackSizes); - *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); - RINOM(*digestsDefined); - *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); - RINOM(*digests); - } - - for (i = 0; i < numFolders; i++) - { - /* - v3.13 incorrectly worked with empty folders - v4.07: we check that folder is empty - */ - UInt64 sum = 0; - UInt32 j; - UInt32 numSubstreams = folders[i].NumUnpackStreams; - if (numSubstreams == 0) - continue; - if (type == k7zIdSize) - for (j = 1; j < numSubstreams; j++) - { - UInt64 size; - RINOK(SzReadNumber(sd, &size)); - (*unpackSizes)[si++] = size; - sum += size; - } - (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; - } - if (type == k7zIdSize) - { - RINOK(SzReadID(sd, &type)); - } - - for (i = 0; i < *numUnpackStreams; i++) - { - (*digestsDefined)[i] = 0; - (*digests)[i] = 0; - } - - - for (i = 0; i < numFolders; i++) - { - UInt32 numSubstreams = folders[i].NumUnpackStreams; - if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) - numDigests += numSubstreams; - } - - - si = 0; - for (;;) - { - if (type == k7zIdCRC) - { - int digestIndex = 0; - Byte *digestsDefined2 = 0; - UInt32 *digests2 = 0; - SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); - if (res == SZ_OK) - { - for (i = 0; i < numFolders; i++) - { - CSzFolder *folder = folders + i; - UInt32 numSubstreams = folder->NumUnpackStreams; - if (numSubstreams == 1 && folder->UnpackCRCDefined) - { - (*digestsDefined)[si] = 1; - (*digests)[si] = folder->UnpackCRC; - si++; - } - else - { - UInt32 j; - for (j = 0; j < numSubstreams; j++, digestIndex++) - { - (*digestsDefined)[si] = digestsDefined2[digestIndex]; - (*digests)[si] = digests2[digestIndex]; - si++; - } - } - } - } - IAlloc_Free(allocTemp, digestsDefined2); - IAlloc_Free(allocTemp, digests2); - RINOK(res); - } - else if (type == k7zIdEnd) - return SZ_OK; - else - { - RINOK(SzSkeepData(sd)); - } - RINOK(SzReadID(sd, &type)); - } -} - - -static SRes SzReadStreamsInfo( - CSzData *sd, - UInt64 *dataOffset, - CSzAr *p, - UInt32 *numUnpackStreams, - UInt64 **unpackSizes, /* allocTemp */ - Byte **digestsDefined, /* allocTemp */ - UInt32 **digests, /* allocTemp */ - ISzAlloc *alloc, - ISzAlloc *allocTemp) -{ - for (;;) - { - UInt64 type; - RINOK(SzReadID(sd, &type)); - if ((UInt64)(int)type != type) - return SZ_ERROR_UNSUPPORTED; - switch((int)type) - { - case k7zIdEnd: - return SZ_OK; - case k7zIdPackInfo: - { - RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, - &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); - break; - } - case k7zIdUnpackInfo: - { - RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); - break; - } - case k7zIdSubStreamsInfo: - { - RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, - numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); - break; - } - default: - return SZ_ERROR_UNSUPPORTED; - } - } -} - -Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc) -{ - UInt32 i; - for (i = 0; i < numFiles; i++) - { - UInt32 len = 0; - UInt32 pos = 0; - CSzFileItem *file = files + i; - while (pos + 2 <= sd->Size) - { - int numAdds; - UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); - pos += 2; - len++; - if (value == 0) - break; - if (value < 0x80) - continue; - if (value >= 0xD800 && value < 0xE000) - { - UInt32 c2; - if (value >= 0xDC00) - return SZ_ERROR_ARCHIVE; - if (pos + 2 > sd->Size) - return SZ_ERROR_ARCHIVE; - c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); - pos += 2; - if (c2 < 0xDC00 || c2 >= 0xE000) - return SZ_ERROR_ARCHIVE; - value = ((value - 0xD800) << 10) | (c2 - 0xDC00); - } - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((UInt32)1) << (numAdds * 5 + 6))) - break; - len += numAdds; - } - - MY_ALLOC(char, file->Name, (size_t)len, alloc); - - len = 0; - while (2 <= sd->Size) - { - int numAdds; - UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); - SzSkeepDataSize(sd, 2); - if (value < 0x80) - { - file->Name[len++] = (char)value; - if (value == 0) - break; - continue; - } - if (value >= 0xD800 && value < 0xE000) - { - UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); - SzSkeepDataSize(sd, 2); - value = ((value - 0xD800) << 10) | (c2 - 0xDC00); - } - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((UInt32)1) << (numAdds * 5 + 6))) - break; - file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); - do - { - numAdds--; - file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); - } - while (numAdds > 0); - - len += numAdds; - } - } - return SZ_OK; -} - -static SRes SzReadHeader2( - CSzArEx *p, /* allocMain */ - CSzData *sd, - UInt64 **unpackSizes, /* allocTemp */ - Byte **digestsDefined, /* allocTemp */ - UInt32 **digests, /* allocTemp */ - Byte **emptyStreamVector, /* allocTemp */ - Byte **emptyFileVector, /* allocTemp */ - Byte **lwtVector, /* allocTemp */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt64 type; - UInt32 numUnpackStreams = 0; - UInt32 numFiles = 0; - CSzFileItem *files = 0; - UInt32 numEmptyStreams = 0; - UInt32 i; - - RINOK(SzReadID(sd, &type)); - - if (type == k7zIdArchiveProperties) - { - RINOK(SzReadArchiveProperties(sd)); - RINOK(SzReadID(sd, &type)); - } - - - if (type == k7zIdMainStreamsInfo) - { - RINOK(SzReadStreamsInfo(sd, - &p->dataPos, - &p->db, - &numUnpackStreams, - unpackSizes, - digestsDefined, - digests, allocMain, allocTemp)); - p->dataPos += p->startPosAfterHeader; - RINOK(SzReadID(sd, &type)); - } - - if (type == k7zIdEnd) - return SZ_OK; - if (type != k7zIdFilesInfo) - return SZ_ERROR_ARCHIVE; - - RINOK(SzReadNumber32(sd, &numFiles)); - p->db.NumFiles = numFiles; - - MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); - - p->db.Files = files; - for (i = 0; i < numFiles; i++) - SzFile_Init(files + i); - - for (;;) - { - UInt64 type; - UInt64 size; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - RINOK(SzReadNumber(sd, &size)); - - if ((UInt64)(int)type != type) - { - RINOK(SzSkeepDataSize(sd, size)); - } - else - switch((int)type) - { - case k7zIdName: - { - RINOK(SzReadSwitch(sd)); - RINOK(SzReadFileNames(sd, numFiles, files, allocMain)) - break; - } - case k7zIdEmptyStream: - { - RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); - numEmptyStreams = 0; - for (i = 0; i < numFiles; i++) - if ((*emptyStreamVector)[i]) - numEmptyStreams++; - break; - } - case k7zIdEmptyFile: - { - RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); - break; - } - case k7zIdMTime: - { - RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); - RINOK(SzReadSwitch(sd)); - for (i = 0; i < numFiles; i++) - { - CSzFileItem *f = &files[i]; - Byte defined = (*lwtVector)[i]; - f->MTimeDefined = defined; - f->MTime.Low = f->MTime.High = 0; - if (defined) - { - RINOK(SzReadUInt32(sd, &f->MTime.Low)); - RINOK(SzReadUInt32(sd, &f->MTime.High)); - } - } - break; - } - default: - { - RINOK(SzSkeepDataSize(sd, size)); - } - } - } - - { - UInt32 emptyFileIndex = 0; - UInt32 sizeIndex = 0; - for (i = 0; i < numFiles; i++) - { - CSzFileItem *file = files + i; - file->IsAnti = 0; - if (*emptyStreamVector == 0) - file->HasStream = 1; - else - file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); - if (file->HasStream) - { - file->IsDir = 0; - file->Size = (*unpackSizes)[sizeIndex]; - file->FileCRC = (*digests)[sizeIndex]; - file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; - sizeIndex++; - } - else - { - if (*emptyFileVector == 0) - file->IsDir = 1; - else - file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); - emptyFileIndex++; - file->Size = 0; - file->FileCRCDefined = 0; - } - } - } - return SzArEx_Fill(p, allocMain); -} - -static SRes SzReadHeader( - CSzArEx *p, - CSzData *sd, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - UInt64 *unpackSizes = 0; - Byte *digestsDefined = 0; - UInt32 *digests = 0; - Byte *emptyStreamVector = 0; - Byte *emptyFileVector = 0; - Byte *lwtVector = 0; - SRes res = SzReadHeader2(p, sd, - &unpackSizes, &digestsDefined, &digests, - &emptyStreamVector, &emptyFileVector, &lwtVector, - allocMain, allocTemp); - IAlloc_Free(allocTemp, unpackSizes); - IAlloc_Free(allocTemp, digestsDefined); - IAlloc_Free(allocTemp, digests); - IAlloc_Free(allocTemp, emptyStreamVector); - IAlloc_Free(allocTemp, emptyFileVector); - IAlloc_Free(allocTemp, lwtVector); - return res; -} - -static SRes SzReadAndDecodePackedStreams2( - ILookInStream *inStream, - CSzData *sd, - CBuf *outBuffer, - UInt64 baseOffset, - CSzAr *p, - UInt64 **unpackSizes, - Byte **digestsDefined, - UInt32 **digests, - ISzAlloc *allocTemp) -{ - - UInt32 numUnpackStreams = 0; - UInt64 dataStartPos; - CSzFolder *folder; - UInt64 unpackSize; - SRes res; - - RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, - &numUnpackStreams, unpackSizes, digestsDefined, digests, - allocTemp, allocTemp)); - - dataStartPos += baseOffset; - if (p->NumFolders != 1) - return SZ_ERROR_ARCHIVE; - - folder = p->Folders; - unpackSize = SzFolder_GetUnpackSize(folder); - - RINOK(LookInStream_SeekTo(inStream, dataStartPos)); - - if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) - return SZ_ERROR_MEM; - - res = SzDecode(p->PackSizes, folder, - inStream, dataStartPos, - outBuffer->data, (size_t)unpackSize, allocTemp); - RINOK(res); - if (folder->UnpackCRCDefined) - if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) - return SZ_ERROR_CRC; - return SZ_OK; -} - -static SRes SzReadAndDecodePackedStreams( - ILookInStream *inStream, - CSzData *sd, - CBuf *outBuffer, - UInt64 baseOffset, - ISzAlloc *allocTemp) -{ - CSzAr p; - UInt64 *unpackSizes = 0; - Byte *digestsDefined = 0; - UInt32 *digests = 0; - SRes res; - SzAr_Init(&p); - res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, - &p, &unpackSizes, &digestsDefined, &digests, - allocTemp); - SzAr_Free(&p, allocTemp); - IAlloc_Free(allocTemp, unpackSizes); - IAlloc_Free(allocTemp, digestsDefined); - IAlloc_Free(allocTemp, digests); - return res; -} - -static SRes SzArEx_Open2( - CSzArEx *p, - ILookInStream *inStream, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - Byte header[k7zStartHeaderSize]; - UInt64 nextHeaderOffset, nextHeaderSize; - size_t nextHeaderSizeT; - UInt32 nextHeaderCRC; - CBuf buffer; - SRes res; - - RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); - - if (!TestSignatureCandidate(header)) - return SZ_ERROR_NO_ARCHIVE; - if (header[6] != k7zMajorVersion) - return SZ_ERROR_UNSUPPORTED; - - nextHeaderOffset = GetUi64(header + 12); - nextHeaderSize = GetUi64(header + 20); - nextHeaderCRC = GetUi32(header + 28); - - p->startPosAfterHeader = k7zStartHeaderSize; - - if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) - return SZ_ERROR_CRC; - - nextHeaderSizeT = (size_t)nextHeaderSize; - if (nextHeaderSizeT != nextHeaderSize) - return SZ_ERROR_MEM; - if (nextHeaderSizeT == 0) - return SZ_OK; - if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || - nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) - return SZ_ERROR_NO_ARCHIVE; - - { - Int64 pos = 0; - RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); - if ((UInt64)pos < nextHeaderOffset || - (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || - (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) - return SZ_ERROR_INPUT_EOF; - } - - RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); - - if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) - return SZ_ERROR_MEM; - - res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); - if (res == SZ_OK) - { - res = SZ_ERROR_ARCHIVE; - if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) - { - CSzData sd; - UInt64 type; - sd.Data = buffer.data; - sd.Size = buffer.size; - res = SzReadID(&sd, &type); - if (res == SZ_OK) - { - if (type == k7zIdEncodedHeader) - { - CBuf outBuffer; - Buf_Init(&outBuffer); - res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); - if (res != SZ_OK) - Buf_Free(&outBuffer, allocTemp); - else - { - Buf_Free(&buffer, allocTemp); - buffer.data = outBuffer.data; - buffer.size = outBuffer.size; - sd.Data = buffer.data; - sd.Size = buffer.size; - res = SzReadID(&sd, &type); - } - } - } - if (res == SZ_OK) - { - if (type == k7zIdHeader) - res = SzReadHeader(p, &sd, allocMain, allocTemp); - else - res = SZ_ERROR_UNSUPPORTED; - } - } - } - Buf_Free(&buffer, allocTemp); - return res; -} - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) -{ - SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); - if (res != SZ_OK) - SzArEx_Free(p, allocMain); - return res; -} +/* 7zIn.c -- 7z Input functions +2008-12-31 : Igor Pavlov : Public domain */ + +#include "7zCrc.h" +#include "CpuArch.h" + +#include "7zDecode.h" +#include "7zIn.h" + +#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } + +#define NUM_FOLDER_CODERS_MAX 32 +#define NUM_CODER_STREAMS_MAX 32 + +void SzArEx_Init(CSzArEx *p) +{ + SzAr_Init(&p->db); + p->FolderStartPackStreamIndex = 0; + p->PackStreamStartPositions = 0; + p->FolderStartFileIndex = 0; + p->FileIndexToFolderIndexMap = 0; +} + +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) +{ + IAlloc_Free(alloc, p->FolderStartPackStreamIndex); + IAlloc_Free(alloc, p->PackStreamStartPositions); + IAlloc_Free(alloc, p->FolderStartFileIndex); + IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); + SzAr_Free(&p->db, alloc); + SzArEx_Init(p); +} + +/* +UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const +{ + return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; +} + +UInt64 GetFilePackSize(int fileIndex) const +{ + int folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex >= 0) + { + const CSzFolder &folderInfo = Folders[folderIndex]; + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + } + return 0; +} +*/ + +#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ + if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } + +static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) +{ + UInt32 startPos = 0; + UInt64 startPosSize = 0; + UInt32 i; + UInt32 folderIndex = 0; + UInt32 indexInFolder = 0; + MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); + for (i = 0; i < p->db.NumFolders; i++) + { + p->FolderStartPackStreamIndex[i] = startPos; + startPos += p->db.Folders[i].NumPackStreams; + } + + MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); + + for (i = 0; i < p->db.NumPackStreams; i++) + { + p->PackStreamStartPositions[i] = startPosSize; + startPosSize += p->db.PackSizes[i]; + } + + MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc); + MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); + + for (i = 0; i < p->db.NumFiles; i++) + { + CSzFileItem *file = p->db.Files + i; + int emptyStream = !file->HasStream; + if (emptyStream && indexInFolder == 0) + { + p->FileIndexToFolderIndexMap[i] = (UInt32)-1; + continue; + } + if (indexInFolder == 0) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: Loop for skipping empty folders + */ + for (;;) + { + if (folderIndex >= p->db.NumFolders) + return SZ_ERROR_ARCHIVE; + p->FolderStartFileIndex[folderIndex] = i; + if (p->db.Folders[folderIndex].NumUnpackStreams != 0) + break; + folderIndex++; + } + } + p->FileIndexToFolderIndexMap[i] = folderIndex; + if (emptyStream) + continue; + indexInFolder++; + if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) + { + folderIndex++; + indexInFolder = 0; + } + } + return SZ_OK; +} + + +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder) +{ + return p->dataPos + + p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; +} + +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize) +{ + UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; + CSzFolder *folder = p->db.Folders + folderIndex; + UInt64 size = 0; + UInt32 i; + for (i = 0; i < folder->NumPackStreams; i++) + { + UInt64 t = size + p->db.PackSizes[packStreamIndex + i]; + if (t < size) /* check it */ + return SZ_ERROR_FAIL; + size = t; + } + *resSize = size; + return SZ_OK; +} + + +/* +SRes SzReadTime(const CObjectVector &dataVector, + CObjectVector &files, UInt64 type) +{ + CBoolVector boolVector; + RINOK(ReadBoolVector2(files.Size(), boolVector)) + + CStreamSwitch streamSwitch; + RINOK(streamSwitch.Set(this, &dataVector)); + + for (int i = 0; i < files.Size(); i++) + { + CSzFileItem &file = files[i]; + CArchiveFileTime fileTime; + bool defined = boolVector[i]; + if (defined) + { + UInt32 low, high; + RINOK(SzReadUInt32(low)); + RINOK(SzReadUInt32(high)); + fileTime.dwLowDateTime = low; + fileTime.dwHighDateTime = high; + } + switch(type) + { + case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break; + case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break; + case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break; + } + } + return SZ_OK; +} +*/ + +static int TestSignatureCandidate(Byte *testBytes) +{ + size_t i; + for (i = 0; i < k7zSignatureSize; i++) + if (testBytes[i] != k7zSignature[i]) + return 0; + return 1; +} + +typedef struct _CSzState +{ + Byte *Data; + size_t Size; +} CSzData; + +static SRes SzReadByte(CSzData *sd, Byte *b) +{ + if (sd->Size == 0) + return SZ_ERROR_ARCHIVE; + sd->Size--; + *b = *sd->Data++; + return SZ_OK; +} + +static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size) +{ + size_t i; + for (i = 0; i < size; i++) + { + RINOK(SzReadByte(sd, data + i)); + } + return SZ_OK; +} + +static SRes SzReadUInt32(CSzData *sd, UInt32 *value) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + Byte b; + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt32)(b) << (8 * i)); + } + return SZ_OK; +} + +static SRes SzReadNumber(CSzData *sd, UInt64 *value) +{ + Byte firstByte; + Byte mask = 0x80; + int i; + RINOK(SzReadByte(sd, &firstByte)); + *value = 0; + for (i = 0; i < 8; i++) + { + Byte b; + if ((firstByte & mask) == 0) + { + UInt64 highPart = firstByte & (mask - 1); + *value += (highPart << (8 * i)); + return SZ_OK; + } + RINOK(SzReadByte(sd, &b)); + *value |= ((UInt64)b << (8 * i)); + mask >>= 1; + } + return SZ_OK; +} + +static SRes SzReadNumber32(CSzData *sd, UInt32 *value) +{ + UInt64 value64; + RINOK(SzReadNumber(sd, &value64)); + if (value64 >= 0x80000000) + return SZ_ERROR_UNSUPPORTED; + if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2))) + return SZ_ERROR_UNSUPPORTED; + *value = (UInt32)value64; + return SZ_OK; +} + +static SRes SzReadID(CSzData *sd, UInt64 *value) +{ + return SzReadNumber(sd, value); +} + +static SRes SzSkeepDataSize(CSzData *sd, UInt64 size) +{ + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + sd->Size -= (size_t)size; + sd->Data += (size_t)size; + return SZ_OK; +} + +static SRes SzSkeepData(CSzData *sd) +{ + UInt64 size; + RINOK(SzReadNumber(sd, &size)); + return SzSkeepDataSize(sd, size); +} + +static SRes SzReadArchiveProperties(CSzData *sd) +{ + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + SzSkeepData(sd); + } + return SZ_OK; +} + +static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute) +{ + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == attribute) + return SZ_OK; + if (type == k7zIdEnd) + return SZ_ERROR_ARCHIVE; + RINOK(SzSkeepData(sd)); + } +} + +static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) +{ + Byte b = 0; + Byte mask = 0; + size_t i; + MY_ALLOC(Byte, *v, numItems, alloc); + for (i = 0; i < numItems; i++) + { + if (mask == 0) + { + RINOK(SzReadByte(sd, &b)); + mask = 0x80; + } + (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0); + mask >>= 1; + } + return SZ_OK; +} + +static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc) +{ + Byte allAreDefined; + size_t i; + RINOK(SzReadByte(sd, &allAreDefined)); + if (allAreDefined == 0) + return SzReadBoolVector(sd, numItems, v, alloc); + MY_ALLOC(Byte, *v, numItems, alloc); + for (i = 0; i < numItems; i++) + (*v)[i] = 1; + return SZ_OK; +} + +static SRes SzReadHashDigests( + CSzData *sd, + size_t numItems, + Byte **digestsDefined, + UInt32 **digests, + ISzAlloc *alloc) +{ + size_t i; + RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); + MY_ALLOC(UInt32, *digests, numItems, alloc); + for (i = 0; i < numItems; i++) + if ((*digestsDefined)[i]) + { + RINOK(SzReadUInt32(sd, (*digests) + i)); + } + return SZ_OK; +} + +static SRes SzReadPackInfo( + CSzData *sd, + UInt64 *dataOffset, + UInt32 *numPackStreams, + UInt64 **packSizes, + Byte **packCRCsDefined, + UInt32 **packCRCs, + ISzAlloc *alloc) +{ + UInt32 i; + RINOK(SzReadNumber(sd, dataOffset)); + RINOK(SzReadNumber32(sd, numPackStreams)); + + RINOK(SzWaitAttribute(sd, k7zIdSize)); + + MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc); + + for (i = 0; i < *numPackStreams; i++) + { + RINOK(SzReadNumber(sd, (*packSizes) + i)); + } + + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + if (type == k7zIdCRC) + { + RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); + continue; + } + RINOK(SzSkeepData(sd)); + } + if (*packCRCsDefined == 0) + { + MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc); + MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc); + for (i = 0; i < *numPackStreams; i++) + { + (*packCRCsDefined)[i] = 0; + (*packCRCs)[i] = 0; + } + } + return SZ_OK; +} + +static SRes SzReadSwitch(CSzData *sd) +{ + Byte external; + RINOK(SzReadByte(sd, &external)); + return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; +} + +static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) +{ + UInt32 numCoders, numBindPairs, numPackStreams, i; + UInt32 numInStreams = 0, numOutStreams = 0; + + RINOK(SzReadNumber32(sd, &numCoders)); + if (numCoders > NUM_FOLDER_CODERS_MAX) + return SZ_ERROR_UNSUPPORTED; + folder->NumCoders = numCoders; + + MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); + + for (i = 0; i < numCoders; i++) + SzCoderInfo_Init(folder->Coders + i); + + for (i = 0; i < numCoders; i++) + { + Byte mainByte; + CSzCoderInfo *coder = folder->Coders + i; + { + unsigned idSize, j; + Byte longID[15]; + RINOK(SzReadByte(sd, &mainByte)); + idSize = (unsigned)(mainByte & 0xF); + RINOK(SzReadBytes(sd, longID, idSize)); + if (idSize > sizeof(coder->MethodID)) + return SZ_ERROR_UNSUPPORTED; + coder->MethodID = 0; + for (j = 0; j < idSize; j++) + coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j); + + if ((mainByte & 0x10) != 0) + { + RINOK(SzReadNumber32(sd, &coder->NumInStreams)); + RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); + if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || + coder->NumOutStreams > NUM_CODER_STREAMS_MAX) + return SZ_ERROR_UNSUPPORTED; + } + else + { + coder->NumInStreams = 1; + coder->NumOutStreams = 1; + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) + return SZ_ERROR_MEM; + RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize)); + } + } + while ((mainByte & 0x80) != 0) + { + RINOK(SzReadByte(sd, &mainByte)); + RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); + if ((mainByte & 0x10) != 0) + { + UInt32 n; + RINOK(SzReadNumber32(sd, &n)); + RINOK(SzReadNumber32(sd, &n)); + } + if ((mainByte & 0x20) != 0) + { + UInt64 propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + RINOK(SzSkeepDataSize(sd, propertiesSize)); + } + } + numInStreams += coder->NumInStreams; + numOutStreams += coder->NumOutStreams; + } + + if (numOutStreams == 0) + return SZ_ERROR_UNSUPPORTED; + + folder->NumBindPairs = numBindPairs = numOutStreams - 1; + MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); + + for (i = 0; i < numBindPairs; i++) + { + CBindPair *bp = folder->BindPairs + i; + RINOK(SzReadNumber32(sd, &bp->InIndex)); + RINOK(SzReadNumber32(sd, &bp->OutIndex)); + } + + if (numInStreams < numBindPairs) + return SZ_ERROR_UNSUPPORTED; + + folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; + MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc); + + if (numPackStreams == 1) + { + for (i = 0; i < numInStreams ; i++) + if (SzFolder_FindBindPairForInStream(folder, i) < 0) + break; + if (i == numInStreams) + return SZ_ERROR_UNSUPPORTED; + folder->PackStreams[0] = i; + } + else + for (i = 0; i < numPackStreams; i++) + { + RINOK(SzReadNumber32(sd, folder->PackStreams + i)); + } + return SZ_OK; +} + +static SRes SzReadUnpackInfo( + CSzData *sd, + UInt32 *numFolders, + CSzFolder **folders, /* for alloc */ + ISzAlloc *alloc, + ISzAlloc *allocTemp) +{ + UInt32 i; + RINOK(SzWaitAttribute(sd, k7zIdFolder)); + RINOK(SzReadNumber32(sd, numFolders)); + { + RINOK(SzReadSwitch(sd)); + + MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); + + for (i = 0; i < *numFolders; i++) + SzFolder_Init((*folders) + i); + + for (i = 0; i < *numFolders; i++) + { + RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); + } + } + + RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); + + for (i = 0; i < *numFolders; i++) + { + UInt32 j; + CSzFolder *folder = (*folders) + i; + UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder); + + MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc); + + for (j = 0; j < numOutStreams; j++) + { + RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); + } + } + + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + SRes res; + Byte *crcsDefined = 0; + UInt32 *crcs = 0; + res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); + if (res == SZ_OK) + { + for (i = 0; i < *numFolders; i++) + { + CSzFolder *folder = (*folders) + i; + folder->UnpackCRCDefined = crcsDefined[i]; + folder->UnpackCRC = crcs[i]; + } + } + IAlloc_Free(allocTemp, crcs); + IAlloc_Free(allocTemp, crcsDefined); + RINOK(res); + continue; + } + RINOK(SzSkeepData(sd)); + } +} + +static SRes SzReadSubStreamsInfo( + CSzData *sd, + UInt32 numFolders, + CSzFolder *folders, + UInt32 *numUnpackStreams, + UInt64 **unpackSizes, + Byte **digestsDefined, + UInt32 **digests, + ISzAlloc *allocTemp) +{ + UInt64 type = 0; + UInt32 i; + UInt32 si = 0; + UInt32 numDigests = 0; + + for (i = 0; i < numFolders; i++) + folders[i].NumUnpackStreams = 1; + *numUnpackStreams = numFolders; + + for (;;) + { + RINOK(SzReadID(sd, &type)); + if (type == k7zIdNumUnpackStream) + { + *numUnpackStreams = 0; + for (i = 0; i < numFolders; i++) + { + UInt32 numStreams; + RINOK(SzReadNumber32(sd, &numStreams)); + folders[i].NumUnpackStreams = numStreams; + *numUnpackStreams += numStreams; + } + continue; + } + if (type == k7zIdCRC || type == k7zIdSize) + break; + if (type == k7zIdEnd) + break; + RINOK(SzSkeepData(sd)); + } + + if (*numUnpackStreams == 0) + { + *unpackSizes = 0; + *digestsDefined = 0; + *digests = 0; + } + else + { + *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64)); + RINOM(*unpackSizes); + *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte)); + RINOM(*digestsDefined); + *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32)); + RINOM(*digests); + } + + for (i = 0; i < numFolders; i++) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: we check that folder is empty + */ + UInt64 sum = 0; + UInt32 j; + UInt32 numSubstreams = folders[i].NumUnpackStreams; + if (numSubstreams == 0) + continue; + if (type == k7zIdSize) + for (j = 1; j < numSubstreams; j++) + { + UInt64 size; + RINOK(SzReadNumber(sd, &size)); + (*unpackSizes)[si++] = size; + sum += size; + } + (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; + } + if (type == k7zIdSize) + { + RINOK(SzReadID(sd, &type)); + } + + for (i = 0; i < *numUnpackStreams; i++) + { + (*digestsDefined)[i] = 0; + (*digests)[i] = 0; + } + + + for (i = 0; i < numFolders; i++) + { + UInt32 numSubstreams = folders[i].NumUnpackStreams; + if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) + numDigests += numSubstreams; + } + + + si = 0; + for (;;) + { + if (type == k7zIdCRC) + { + int digestIndex = 0; + Byte *digestsDefined2 = 0; + UInt32 *digests2 = 0; + SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); + if (res == SZ_OK) + { + for (i = 0; i < numFolders; i++) + { + CSzFolder *folder = folders + i; + UInt32 numSubstreams = folder->NumUnpackStreams; + if (numSubstreams == 1 && folder->UnpackCRCDefined) + { + (*digestsDefined)[si] = 1; + (*digests)[si] = folder->UnpackCRC; + si++; + } + else + { + UInt32 j; + for (j = 0; j < numSubstreams; j++, digestIndex++) + { + (*digestsDefined)[si] = digestsDefined2[digestIndex]; + (*digests)[si] = digests2[digestIndex]; + si++; + } + } + } + } + IAlloc_Free(allocTemp, digestsDefined2); + IAlloc_Free(allocTemp, digests2); + RINOK(res); + } + else if (type == k7zIdEnd) + return SZ_OK; + else + { + RINOK(SzSkeepData(sd)); + } + RINOK(SzReadID(sd, &type)); + } +} + + +static SRes SzReadStreamsInfo( + CSzData *sd, + UInt64 *dataOffset, + CSzAr *p, + UInt32 *numUnpackStreams, + UInt64 **unpackSizes, /* allocTemp */ + Byte **digestsDefined, /* allocTemp */ + UInt32 **digests, /* allocTemp */ + ISzAlloc *alloc, + ISzAlloc *allocTemp) +{ + for (;;) + { + UInt64 type; + RINOK(SzReadID(sd, &type)); + if ((UInt64)(int)type != type) + return SZ_ERROR_UNSUPPORTED; + switch((int)type) + { + case k7zIdEnd: + return SZ_OK; + case k7zIdPackInfo: + { + RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, + &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); + break; + } + case k7zIdUnpackInfo: + { + RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); + break; + } + case k7zIdSubStreamsInfo: + { + RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, + numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); + break; + } + default: + return SZ_ERROR_UNSUPPORTED; + } + } +} + +Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc) +{ + UInt32 i; + for (i = 0; i < numFiles; i++) + { + UInt32 len = 0; + UInt32 pos = 0; + CSzFileItem *file = files + i; + while (pos + 2 <= sd->Size) + { + int numAdds; + UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); + pos += 2; + len++; + if (value == 0) + break; + if (value < 0x80) + continue; + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2; + if (value >= 0xDC00) + return SZ_ERROR_ARCHIVE; + if (pos + 2 > sd->Size) + return SZ_ERROR_ARCHIVE; + c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); + pos += 2; + if (c2 < 0xDC00 || c2 >= 0xE000) + return SZ_ERROR_ARCHIVE; + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + len += numAdds; + } + + MY_ALLOC(char, file->Name, (size_t)len, alloc); + + len = 0; + while (2 <= sd->Size) + { + int numAdds; + UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); + SzSkeepDataSize(sd, 2); + if (value < 0x80) + { + file->Name[len++] = (char)value; + if (value == 0) + break; + continue; + } + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8)); + SzSkeepDataSize(sd, 2); + value = ((value - 0xD800) << 10) | (c2 - 0xDC00); + } + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + do + { + numAdds--; + file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + } + while (numAdds > 0); + + len += numAdds; + } + } + return SZ_OK; +} + +static SRes SzReadHeader2( + CSzArEx *p, /* allocMain */ + CSzData *sd, + UInt64 **unpackSizes, /* allocTemp */ + Byte **digestsDefined, /* allocTemp */ + UInt32 **digests, /* allocTemp */ + Byte **emptyStreamVector, /* allocTemp */ + Byte **emptyFileVector, /* allocTemp */ + Byte **lwtVector, /* allocTemp */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt64 type; + UInt32 numUnpackStreams = 0; + UInt32 numFiles = 0; + CSzFileItem *files = 0; + UInt32 numEmptyStreams = 0; + UInt32 i; + + RINOK(SzReadID(sd, &type)); + + if (type == k7zIdArchiveProperties) + { + RINOK(SzReadArchiveProperties(sd)); + RINOK(SzReadID(sd, &type)); + } + + + if (type == k7zIdMainStreamsInfo) + { + RINOK(SzReadStreamsInfo(sd, + &p->dataPos, + &p->db, + &numUnpackStreams, + unpackSizes, + digestsDefined, + digests, allocMain, allocTemp)); + p->dataPos += p->startPosAfterHeader; + RINOK(SzReadID(sd, &type)); + } + + if (type == k7zIdEnd) + return SZ_OK; + if (type != k7zIdFilesInfo) + return SZ_ERROR_ARCHIVE; + + RINOK(SzReadNumber32(sd, &numFiles)); + p->db.NumFiles = numFiles; + + MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); + + p->db.Files = files; + for (i = 0; i < numFiles; i++) + SzFile_Init(files + i); + + for (;;) + { + UInt64 type; + UInt64 size; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + RINOK(SzReadNumber(sd, &size)); + + if ((UInt64)(int)type != type) + { + RINOK(SzSkeepDataSize(sd, size)); + } + else + switch((int)type) + { + case k7zIdName: + { + RINOK(SzReadSwitch(sd)); + RINOK(SzReadFileNames(sd, numFiles, files, allocMain)) + break; + } + case k7zIdEmptyStream: + { + RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); + numEmptyStreams = 0; + for (i = 0; i < numFiles; i++) + if ((*emptyStreamVector)[i]) + numEmptyStreams++; + break; + } + case k7zIdEmptyFile: + { + RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); + break; + } + case k7zIdMTime: + { + RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); + RINOK(SzReadSwitch(sd)); + for (i = 0; i < numFiles; i++) + { + CSzFileItem *f = &files[i]; + Byte defined = (*lwtVector)[i]; + f->MTimeDefined = defined; + f->MTime.Low = f->MTime.High = 0; + if (defined) + { + RINOK(SzReadUInt32(sd, &f->MTime.Low)); + RINOK(SzReadUInt32(sd, &f->MTime.High)); + } + } + break; + } + default: + { + RINOK(SzSkeepDataSize(sd, size)); + } + } + } + + { + UInt32 emptyFileIndex = 0; + UInt32 sizeIndex = 0; + for (i = 0; i < numFiles; i++) + { + CSzFileItem *file = files + i; + file->IsAnti = 0; + if (*emptyStreamVector == 0) + file->HasStream = 1; + else + file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1); + if (file->HasStream) + { + file->IsDir = 0; + file->Size = (*unpackSizes)[sizeIndex]; + file->FileCRC = (*digests)[sizeIndex]; + file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex]; + sizeIndex++; + } + else + { + if (*emptyFileVector == 0) + file->IsDir = 1; + else + file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); + emptyFileIndex++; + file->Size = 0; + file->FileCRCDefined = 0; + } + } + } + return SzArEx_Fill(p, allocMain); +} + +static SRes SzReadHeader( + CSzArEx *p, + CSzData *sd, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt64 *unpackSizes = 0; + Byte *digestsDefined = 0; + UInt32 *digests = 0; + Byte *emptyStreamVector = 0; + Byte *emptyFileVector = 0; + Byte *lwtVector = 0; + SRes res = SzReadHeader2(p, sd, + &unpackSizes, &digestsDefined, &digests, + &emptyStreamVector, &emptyFileVector, &lwtVector, + allocMain, allocTemp); + IAlloc_Free(allocTemp, unpackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); + IAlloc_Free(allocTemp, emptyStreamVector); + IAlloc_Free(allocTemp, emptyFileVector); + IAlloc_Free(allocTemp, lwtVector); + return res; +} + +static SRes SzReadAndDecodePackedStreams2( + ILookInStream *inStream, + CSzData *sd, + CBuf *outBuffer, + UInt64 baseOffset, + CSzAr *p, + UInt64 **unpackSizes, + Byte **digestsDefined, + UInt32 **digests, + ISzAlloc *allocTemp) +{ + + UInt32 numUnpackStreams = 0; + UInt64 dataStartPos; + CSzFolder *folder; + UInt64 unpackSize; + SRes res; + + RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, + &numUnpackStreams, unpackSizes, digestsDefined, digests, + allocTemp, allocTemp)); + + dataStartPos += baseOffset; + if (p->NumFolders != 1) + return SZ_ERROR_ARCHIVE; + + folder = p->Folders; + unpackSize = SzFolder_GetUnpackSize(folder); + + RINOK(LookInStream_SeekTo(inStream, dataStartPos)); + + if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) + return SZ_ERROR_MEM; + + res = SzDecode(p->PackSizes, folder, + inStream, dataStartPos, + outBuffer->data, (size_t)unpackSize, allocTemp); + RINOK(res); + if (folder->UnpackCRCDefined) + if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) + return SZ_ERROR_CRC; + return SZ_OK; +} + +static SRes SzReadAndDecodePackedStreams( + ILookInStream *inStream, + CSzData *sd, + CBuf *outBuffer, + UInt64 baseOffset, + ISzAlloc *allocTemp) +{ + CSzAr p; + UInt64 *unpackSizes = 0; + Byte *digestsDefined = 0; + UInt32 *digests = 0; + SRes res; + SzAr_Init(&p); + res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, + &p, &unpackSizes, &digestsDefined, &digests, + allocTemp); + SzAr_Free(&p, allocTemp); + IAlloc_Free(allocTemp, unpackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); + return res; +} + +static SRes SzArEx_Open2( + CSzArEx *p, + ILookInStream *inStream, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + Byte header[k7zStartHeaderSize]; + UInt64 nextHeaderOffset, nextHeaderSize; + size_t nextHeaderSizeT; + UInt32 nextHeaderCRC; + CBuf buffer; + SRes res; + + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); + + if (!TestSignatureCandidate(header)) + return SZ_ERROR_NO_ARCHIVE; + if (header[6] != k7zMajorVersion) + return SZ_ERROR_UNSUPPORTED; + + nextHeaderOffset = GetUi64(header + 12); + nextHeaderSize = GetUi64(header + 20); + nextHeaderCRC = GetUi32(header + 28); + + p->startPosAfterHeader = k7zStartHeaderSize; + + if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) + return SZ_ERROR_CRC; + + nextHeaderSizeT = (size_t)nextHeaderSize; + if (nextHeaderSizeT != nextHeaderSize) + return SZ_ERROR_MEM; + if (nextHeaderSizeT == 0) + return SZ_OK; + if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || + nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) + return SZ_ERROR_NO_ARCHIVE; + + { + Int64 pos = 0; + RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); + if ((UInt64)pos < nextHeaderOffset || + (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset || + (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) + return SZ_ERROR_INPUT_EOF; + } + + RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset)); + + if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) + return SZ_ERROR_MEM; + + res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); + if (res == SZ_OK) + { + res = SZ_ERROR_ARCHIVE; + if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) + { + CSzData sd; + UInt64 type; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); + if (res == SZ_OK) + { + if (type == k7zIdEncodedHeader) + { + CBuf outBuffer; + Buf_Init(&outBuffer); + res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); + if (res != SZ_OK) + Buf_Free(&outBuffer, allocTemp); + else + { + Buf_Free(&buffer, allocTemp); + buffer.data = outBuffer.data; + buffer.size = outBuffer.size; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); + } + } + } + if (res == SZ_OK) + { + if (type == k7zIdHeader) + res = SzReadHeader(p, &sd, allocMain, allocTemp); + else + res = SZ_ERROR_UNSUPPORTED; + } + } + } + Buf_Free(&buffer, allocTemp); + return res; +} + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) +{ + SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); + if (res != SZ_OK) + SzArEx_Free(p, allocMain); + return res; +} diff --git a/src/archivers/7z/Archive/7z/7zIn.h b/src/archivers/7z/7zIn.h similarity index 95% rename from src/archivers/7z/Archive/7z/7zIn.h rename to src/archivers/7z/7zIn.h index 5cbbbf85..e9c635b4 100644 --- a/src/archivers/7z/Archive/7z/7zIn.h +++ b/src/archivers/7z/7zIn.h @@ -1,41 +1,41 @@ -/* 7zIn.h -- 7z Input functions -2008-11-23 : Igor Pavlov : Public domain */ - -#ifndef __7Z_IN_H -#define __7Z_IN_H - -#include "7zHeader.h" -#include "7zItem.h" - -typedef struct -{ - CSzAr db; - - UInt64 startPosAfterHeader; - UInt64 dataPos; - - UInt32 *FolderStartPackStreamIndex; - UInt64 *PackStreamStartPositions; - UInt32 *FolderStartFileIndex; - UInt32 *FileIndexToFolderIndexMap; -} CSzArEx; - -void SzArEx_Init(CSzArEx *p); -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); -UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); - -/* -Errors: -SZ_ERROR_NO_ARCHIVE -SZ_ERROR_ARCHIVE -SZ_ERROR_UNSUPPORTED -SZ_ERROR_MEM -SZ_ERROR_CRC -SZ_ERROR_INPUT_EOF -SZ_ERROR_FAIL -*/ - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); - -#endif +/* 7zIn.h -- 7z Input functions +2008-11-23 : Igor Pavlov : Public domain */ + +#ifndef __7Z_IN_H +#define __7Z_IN_H + +#include "7zHeader.h" +#include "7zItem.h" + +typedef struct +{ + CSzAr db; + + UInt64 startPosAfterHeader; + UInt64 dataPos; + + UInt32 *FolderStartPackStreamIndex; + UInt64 *PackStreamStartPositions; + UInt32 *FolderStartFileIndex; + UInt32 *FileIndexToFolderIndexMap; +} CSzArEx; + +void SzArEx_Init(CSzArEx *p); +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); + +/* +Errors: +SZ_ERROR_NO_ARCHIVE +SZ_ERROR_ARCHIVE +SZ_ERROR_UNSUPPORTED +SZ_ERROR_MEM +SZ_ERROR_CRC +SZ_ERROR_INPUT_EOF +SZ_ERROR_FAIL +*/ + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); + +#endif diff --git a/src/archivers/7z/Archive/7z/7zItem.cpp b/src/archivers/7z/7zItem.cpp similarity index 95% rename from src/archivers/7z/Archive/7z/7zItem.cpp rename to src/archivers/7z/7zItem.cpp index 213f35f6..eadf57ec 100644 --- a/src/archivers/7z/Archive/7z/7zItem.cpp +++ b/src/archivers/7z/7zItem.cpp @@ -1,127 +1,127 @@ -/* 7zItem.c -- 7z Items -2008-10-04 : Igor Pavlov : Public domain */ - -#include "7zItem.h" - -void SzCoderInfo_Init(CSzCoderInfo *p) -{ - Buf_Init(&p->Props); -} - -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) -{ - Buf_Free(&p->Props, alloc); - SzCoderInfo_Init(p); -} - -void SzFolder_Init(CSzFolder *p) -{ - p->Coders = 0; - p->BindPairs = 0; - p->PackStreams = 0; - p->UnpackSizes = 0; - p->NumCoders = 0; - p->NumBindPairs = 0; - p->NumPackStreams = 0; - p->UnpackCRCDefined = 0; - p->UnpackCRC = 0; - p->NumUnpackStreams = 0; -} - -void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) -{ - UInt32 i; - if (p->Coders) - for (i = 0; i < p->NumCoders; i++) - SzCoderInfo_Free(&p->Coders[i], alloc); - IAlloc_Free(alloc, p->Coders); - IAlloc_Free(alloc, p->BindPairs); - IAlloc_Free(alloc, p->PackStreams); - IAlloc_Free(alloc, p->UnpackSizes); - SzFolder_Init(p); -} - -UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) -{ - UInt32 result = 0; - UInt32 i; - for (i = 0; i < p->NumCoders; i++) - result += p->Coders[i].NumOutStreams; - return result; -} - -int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) -{ - UInt32 i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].InIndex == inStreamIndex) - return i; - return -1; -} - - -int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) -{ - UInt32 i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].OutIndex == outStreamIndex) - return i; - return -1; -} - -UInt64 SzFolder_GetUnpackSize(CSzFolder *p) -{ - int i = (int)SzFolder_GetNumOutStreams(p); - if (i == 0) - return 0; - for (i--; i >= 0; i--) - if (SzFolder_FindBindPairForOutStream(p, i) < 0) - return p->UnpackSizes[i]; - /* throw 1; */ - return 0; -} - -void SzFile_Init(CSzFileItem *p) -{ - p->HasStream = 1; - p->IsDir = 0; - p->IsAnti = 0; - p->FileCRCDefined = 0; - p->MTimeDefined = 0; - p->Name = 0; -} - -static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->Name); - SzFile_Init(p); -} - -void SzAr_Init(CSzAr *p) -{ - p->PackSizes = 0; - p->PackCRCsDefined = 0; - p->PackCRCs = 0; - p->Folders = 0; - p->Files = 0; - p->NumPackStreams = 0; - p->NumFolders = 0; - p->NumFiles = 0; -} - -void SzAr_Free(CSzAr *p, ISzAlloc *alloc) -{ - UInt32 i; - if (p->Folders) - for (i = 0; i < p->NumFolders; i++) - SzFolder_Free(&p->Folders[i], alloc); - if (p->Files) - for (i = 0; i < p->NumFiles; i++) - SzFile_Free(&p->Files[i], alloc); - IAlloc_Free(alloc, p->PackSizes); - IAlloc_Free(alloc, p->PackCRCsDefined); - IAlloc_Free(alloc, p->PackCRCs); - IAlloc_Free(alloc, p->Folders); - IAlloc_Free(alloc, p->Files); - SzAr_Init(p); -} +/* 7zItem.c -- 7z Items +2008-10-04 : Igor Pavlov : Public domain */ + +#include "7zItem.h" + +void SzCoderInfo_Init(CSzCoderInfo *p) +{ + Buf_Init(&p->Props); +} + +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) +{ + Buf_Free(&p->Props, alloc); + SzCoderInfo_Init(p); +} + +void SzFolder_Init(CSzFolder *p) +{ + p->Coders = 0; + p->BindPairs = 0; + p->PackStreams = 0; + p->UnpackSizes = 0; + p->NumCoders = 0; + p->NumBindPairs = 0; + p->NumPackStreams = 0; + p->UnpackCRCDefined = 0; + p->UnpackCRC = 0; + p->NumUnpackStreams = 0; +} + +void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) +{ + UInt32 i; + if (p->Coders) + for (i = 0; i < p->NumCoders; i++) + SzCoderInfo_Free(&p->Coders[i], alloc); + IAlloc_Free(alloc, p->Coders); + IAlloc_Free(alloc, p->BindPairs); + IAlloc_Free(alloc, p->PackStreams); + IAlloc_Free(alloc, p->UnpackSizes); + SzFolder_Init(p); +} + +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p) +{ + UInt32 result = 0; + UInt32 i; + for (i = 0; i < p->NumCoders; i++) + result += p->Coders[i].NumOutStreams; + return result; +} + +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex) +{ + UInt32 i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; +} + + +int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex) +{ + UInt32 i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; +} + +UInt64 SzFolder_GetUnpackSize(CSzFolder *p) +{ + int i = (int)SzFolder_GetNumOutStreams(p); + if (i == 0) + return 0; + for (i--; i >= 0; i--) + if (SzFolder_FindBindPairForOutStream(p, i) < 0) + return p->UnpackSizes[i]; + /* throw 1; */ + return 0; +} + +void SzFile_Init(CSzFileItem *p) +{ + p->HasStream = 1; + p->IsDir = 0; + p->IsAnti = 0; + p->FileCRCDefined = 0; + p->MTimeDefined = 0; + p->Name = 0; +} + +static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc) +{ + IAlloc_Free(alloc, p->Name); + SzFile_Init(p); +} + +void SzAr_Init(CSzAr *p) +{ + p->PackSizes = 0; + p->PackCRCsDefined = 0; + p->PackCRCs = 0; + p->Folders = 0; + p->Files = 0; + p->NumPackStreams = 0; + p->NumFolders = 0; + p->NumFiles = 0; +} + +void SzAr_Free(CSzAr *p, ISzAlloc *alloc) +{ + UInt32 i; + if (p->Folders) + for (i = 0; i < p->NumFolders; i++) + SzFolder_Free(&p->Folders[i], alloc); + if (p->Files) + for (i = 0; i < p->NumFiles; i++) + SzFile_Free(&p->Files[i], alloc); + IAlloc_Free(alloc, p->PackSizes); + IAlloc_Free(alloc, p->PackCRCsDefined); + IAlloc_Free(alloc, p->PackCRCs); + IAlloc_Free(alloc, p->Folders); + IAlloc_Free(alloc, p->Files); + SzAr_Init(p); +} diff --git a/src/archivers/7z/Archive/7z/7zItem.h b/src/archivers/7z/7zItem.h similarity index 93% rename from src/archivers/7z/Archive/7z/7zItem.h rename to src/archivers/7z/7zItem.h index 56abff8f..2e630676 100644 --- a/src/archivers/7z/Archive/7z/7zItem.h +++ b/src/archivers/7z/7zItem.h @@ -1,84 +1,84 @@ -/* 7zItem.h -- 7z Items -2008-10-04 : Igor Pavlov : Public domain */ - -#ifndef __7Z_ITEM_H -#define __7Z_ITEM_H - -#include "../../7zBuf.h" - -typedef struct -{ - UInt32 NumInStreams; - UInt32 NumOutStreams; - UInt64 MethodID; - CBuf Props; -} CSzCoderInfo; - -void SzCoderInfo_Init(CSzCoderInfo *p); -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); - -typedef struct -{ - UInt32 InIndex; - UInt32 OutIndex; -} CBindPair; - -typedef struct -{ - CSzCoderInfo *Coders; - CBindPair *BindPairs; - UInt32 *PackStreams; - UInt64 *UnpackSizes; - UInt32 NumCoders; - UInt32 NumBindPairs; - UInt32 NumPackStreams; - int UnpackCRCDefined; - UInt32 UnpackCRC; - - UInt32 NumUnpackStreams; -} CSzFolder; - -void SzFolder_Init(CSzFolder *p); -UInt64 SzFolder_GetUnpackSize(CSzFolder *p); -int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); -UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); -UInt64 SzFolder_GetUnpackSize(CSzFolder *p); - -typedef struct -{ - UInt32 Low; - UInt32 High; -} CNtfsFileTime; - -typedef struct -{ - CNtfsFileTime MTime; - UInt64 Size; - char *Name; - UInt32 FileCRC; - - Byte HasStream; - Byte IsDir; - Byte IsAnti; - Byte FileCRCDefined; - Byte MTimeDefined; -} CSzFileItem; - -void SzFile_Init(CSzFileItem *p); - -typedef struct -{ - UInt64 *PackSizes; - Byte *PackCRCsDefined; - UInt32 *PackCRCs; - CSzFolder *Folders; - CSzFileItem *Files; - UInt32 NumPackStreams; - UInt32 NumFolders; - UInt32 NumFiles; -} CSzAr; - -void SzAr_Init(CSzAr *p); -void SzAr_Free(CSzAr *p, ISzAlloc *alloc); - -#endif +/* 7zItem.h -- 7z Items +2008-10-04 : Igor Pavlov : Public domain */ + +#ifndef __7Z_ITEM_H +#define __7Z_ITEM_H + +#include "7zBuf.h" + +typedef struct +{ + UInt32 NumInStreams; + UInt32 NumOutStreams; + UInt64 MethodID; + CBuf Props; +} CSzCoderInfo; + +void SzCoderInfo_Init(CSzCoderInfo *p); +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); + +typedef struct +{ + UInt32 InIndex; + UInt32 OutIndex; +} CBindPair; + +typedef struct +{ + CSzCoderInfo *Coders; + CBindPair *BindPairs; + UInt32 *PackStreams; + UInt64 *UnpackSizes; + UInt32 NumCoders; + UInt32 NumBindPairs; + UInt32 NumPackStreams; + int UnpackCRCDefined; + UInt32 UnpackCRC; + + UInt32 NumUnpackStreams; +} CSzFolder; + +void SzFolder_Init(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); +int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); +UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); +UInt64 SzFolder_GetUnpackSize(CSzFolder *p); + +typedef struct +{ + UInt32 Low; + UInt32 High; +} CNtfsFileTime; + +typedef struct +{ + CNtfsFileTime MTime; + UInt64 Size; + char *Name; + UInt32 FileCRC; + + Byte HasStream; + Byte IsDir; + Byte IsAnti; + Byte FileCRCDefined; + Byte MTimeDefined; +} CSzFileItem; + +void SzFile_Init(CSzFileItem *p); + +typedef struct +{ + UInt64 *PackSizes; + Byte *PackCRCsDefined; + UInt32 *PackCRCs; + CSzFolder *Folders; + CSzFileItem *Files; + UInt32 NumPackStreams; + UInt32 NumFolders; + UInt32 NumFiles; +} CSzAr; + +void SzAr_Init(CSzAr *p); +void SzAr_Free(CSzAr *p, ISzAlloc *alloc); + +#endif diff --git a/src/od-gles/gl.cpp b/src/od-gles/gl.cpp deleted file mode 100644 index 83d4f0d3..00000000 --- a/src/od-gles/gl.cpp +++ /dev/null @@ -1,324 +0,0 @@ -#include -#include - -#include - -#include -#include - -#include "gl_platform.h" -#include "gl.h" - -#include "shader_stuff.h" - - -static EGLDisplay edpy; -static EGLSurface esfc; -static EGLContext ectxt; - -/* for external flips */ -void *gl_es_display; -void *gl_es_surface; - - -static float vertex_coords[] = { - -1.0f, 1.0f, 0.0f, // 0 0 1 - 1.0f, 1.0f, 0.0f, // 1 ^ - -1.0f, - -1.0f, 0.0f, // 2 | 2 3 - 1.0f, - -1.0f, 0.0f, // 3 +--> -}; - -static float orig_texture_coords[] = { - -0.5f, - -0.5f, - 0.5f, - -0.5f, - -0.5f, - 0.5f, - 0.5f, - 0.5f, -}; - -static float texture_coords[] = { - 0.0f, - 0.0f, // we flip this: - 1.0f, - 0.0f, // v^ - 0.0f, - 1.0f, // | u - 1.0f, - 1.0f, // +--> -}; - - -static int gl_have_error(const char *name) -{ - GLenum e = glGetError(); - if (e != GL_NO_ERROR) { - printf("GL error: %s %x\n", name, e); - return 1; - } - return 0; -} - -static int gles_have_error(const char *name) -{ - EGLint e = eglGetError(); - if (e != EGL_SUCCESS) { - printf("%s %x\n", name, e); - return 1; - } - return 0; -} - -int gl_init(void *display, void *window, int *quirks) -{ - EGLConfig ecfg = NULL; - GLuint texture_name = 0; - void *tmp_texture_mem = NULL; - EGLint num_config; - int retval = -1; - int ret; - - static const EGLint config_attributes[] = - { - EGL_RED_SIZE, - 8, - EGL_GREEN_SIZE, - 8, - EGL_BLUE_SIZE, - 8, - EGL_ALPHA_SIZE, - 8, - EGL_SURFACE_TYPE, - EGL_WINDOW_BIT, - EGL_NONE - }; - - static const EGLint context_attributes[] = - { -#ifdef SHADER_SUPPORT - EGL_CONTEXT_CLIENT_VERSION, - 2, -#else - EGL_CONTEXT_CLIENT_VERSION, - 1, -#endif - EGL_NONE - }; - - - // gl_platform_init() does Raspi-specific stuff like bcm_host_init() - ret = gl_platform_init(&display, &window, quirks); - if (ret != 0) { - printf("gl_platform_init failed with %d\n", ret); - goto out; - } - - tmp_texture_mem = calloc(1, 1024 * 512 * 2); - if (tmp_texture_mem == NULL) { - printf("OOM\n"); - goto out; - } - - edpy = eglGetDisplay((EGLNativeDisplayType)display); - if (edpy == EGL_NO_DISPLAY) { - printf("Failed to get EGL display\n"); - goto out; - } - - if (!eglInitialize(edpy, NULL, NULL)) { - printf("Failed to initialize EGL\n"); - goto out; - } - - if (!eglChooseConfig(edpy, config_attributes, &ecfg, 1, &num_config)) { - printf("Failed to choose config (%x)\n", eglGetError()); - goto out; - } - - if (ecfg == NULL || num_config == 0) { - printf("No EGL configs available\n"); - goto out; - } - - esfc = eglCreateWindowSurface(edpy, - ecfg, - (EGLNativeWindowType)window, - NULL); - if (esfc == EGL_NO_SURFACE) { - printf("Unable to create EGL surface (%x)\n", - eglGetError()); - goto out; - } - - ectxt = eglCreateContext(edpy, ecfg, EGL_NO_CONTEXT, context_attributes); - if (ectxt == EGL_NO_CONTEXT) { - printf("Unable to create EGL context (%x)\n", - eglGetError()); - goto out; - } - - eglMakeCurrent(edpy, esfc, esfc, ectxt); -#ifndef SHADER_SUPPORT - glEnable(GL_TEXTURE_2D); // for old fixed-function pipeline -#endif - //if (gl_have_error("glEnable(GL_TEXTURE_2D)")) goto out; - - glGenTextures(1, &texture_name); - if (gl_have_error("glGenTextures")) goto out; - - - - glBindTexture(GL_TEXTURE_2D, texture_name); - if (gl_have_error("glBindTexture")) goto out; - - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGB, - 1024, - 512, - 0, - GL_RGB, - GL_UNSIGNED_SHORT_5_6_5, - tmp_texture_mem); - if (gl_have_error("glTexImage2D")) goto out; - - // no mipmaps - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - //glViewport(0, 0, 512, 512); - glLoadIdentity(); - glFrontFace(GL_CW); - glEnable(GL_CULL_FACE); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - - if (gl_have_error("init")) - goto out; - - gl_es_display = (void *)edpy; - gl_es_surface = (void *)esfc; - retval = 0; - - int shader_stuff_result; -#ifdef SHADER_SUPPORT - shader_stuff_result = shader_stuff_init(); - shader_stuff_result = shader_stuff_reload_shaders(); - shader_stuff_result = shader_stuff_set_data(vertex_coords, texture_coords, texture_name); -#endif -out: - free(tmp_texture_mem); - return retval; -} - -static int framecount = 0; - -int gl_flip(const void *fb, int w, int h) -{ - static int old_w, old_h; - -#ifdef SHADER_SUPPORT - if (framecount % 60 == 0) - { -// printf("gl_flip() w: %d, h: %d\n", w, h); - } - - if (framecount % 30 == 0) - { - if (shader_stuff_shader_needs_reload()) { - shader_stuff_reload_shaders(); - // shader_stuff_set_data(vertex_coords, texture_coords, texture_name); - - } - } -#endif - - framecount++; - float floattime = (framecount * 0.04f); - - if (fb != NULL) { - if (w != old_w || h != old_h) { - float f_w = (float)w / 1024.0f; - float f_h = (float)h / 512.0f; - texture_coords[1 * 2 + 0] = f_w; - texture_coords[2 * 2 + 1] = f_h; - texture_coords[3 * 2 + 0] = f_w; - texture_coords[3 * 2 + 1] = f_h; - old_w = w; - old_h = h; - } -/* - float rotmat[4]; // 2d rotation matrix - rotmat[0] = cos(floattime); - rotmat[1] = sin(floattime); - rotmat[2] = -sin(floattime); - rotmat[3] = cos(floattime); - - for (int i=0; i<4; i++) { - float f_w = (float)w / 1024.0f; - float f_h = (float)h / 512.0f; - float x = orig_texture_coords[i*2 + 0] * f_w; - float y = orig_texture_coords[i*2 + 1] * f_h; - texture_coords[i*2 + 0] = - f_w * 0.5f + (x * rotmat[0] + y * rotmat[1]); - texture_coords[i*2 + 1] = - f_h * 0.5f + (x * rotmat[2] + y * rotmat[3]); - - } -*/ - - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - w, - h, - GL_RGB, - GL_UNSIGNED_SHORT_5_6_5, - fb); - if (gl_have_error("glTexSubImage2D")) - return -1; - } // if (fb != NULL) - -#ifdef SHADER_SUPPORT - shader_stuff_frame(framecount, w, h, 800, 480); // TODO! hard-coded output size - if (gl_have_error("use program")) return -1; -#else - glVertexPointer(3, GL_FLOAT, 0, vertex_coords); - if (gl_have_error("glVertexPointer")) return -1; - - glTexCoordPointer(2, GL_FLOAT, 0, texture_coords); - if (gl_have_error("glTexCoordPointer")) return -1; -#endif - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); -// glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - if (gl_have_error("glDrawArrays")) return -1; - - eglSwapBuffers(edpy, esfc); - if (gles_have_error("eglSwapBuffers")) return -1; - - return 0; -} - -void gl_finish(void) -{ - eglMakeCurrent(edpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroyContext(edpy, ectxt); - ectxt = EGL_NO_CONTEXT; - eglDestroySurface(edpy, esfc); - esfc = EGL_NO_SURFACE; - eglTerminate(edpy); - edpy = EGL_NO_DISPLAY; - - gl_es_display = (void *)edpy; - gl_es_surface = (void *)esfc; - - gl_platform_finish(); -} diff --git a/src/od-gles/gl.h b/src/od-gles/gl.h deleted file mode 100644 index cb480710..00000000 --- a/src/od-gles/gl.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef LIBPICOFE_GL_H -#define LIBPICOFE_GL_H - -#ifdef HAVE_GLES - -int gl_init(void *display, void *window, int *quirks); -int gl_flip(const void *fb, int w, int h); -void gl_finish(void); - -/* for external flips */ -extern void *gl_es_display; -extern void *gl_es_surface; - -#else - -static __inline int gl_init(void *display, void *window, int *quirks) -{ - return -1; -} -static __inline int gl_flip(const void *fb, int w, int h) -{ - return -1; -} -static __inline void gl_finish(void) -{ -} - -#define gl_es_display (void *)0 -#define gl_es_surface (void *)0 - -#endif - -#define GL_QUIRK_ACTIVATE_RECREATE 1 - -#endif // LIBPICOFE_GL_H diff --git a/src/od-gles/gl_platform.cpp b/src/od-gles/gl_platform.cpp deleted file mode 100644 index 391b67d5..00000000 --- a/src/od-gles/gl_platform.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include -#include - -#include "gl.h" -#include "gl_platform.h" - -#ifdef VCOS_VERSION - -/* - * hacks for Broadcom VideoCore / Raspberry Pi.. - * Why do I have to do this proprietary API stuff, - * couldn't they implement EGL properly? D: - */ -#include -#include -#include - -static Display *x11display; -static Window x11window; -static DISPMANX_DISPLAY_HANDLE_T m_dispmanDisplay; -static EGL_DISPMANX_WINDOW_T m_nativeWindow; - -static void *x11lib; -#define FPTR(f) typeof(f) * p##f -static FPTR(XGetGeometry); -static FPTR(XGetWindowAttributes); -static FPTR(XTranslateCoordinates); - -static void get_window_rect(VC_RECT_T *rect) -{ - XWindowAttributes xattrs_root; - uint32_t disp_w = 0, disp_h = 0; - int dx = 0, dy = 0; - unsigned int dw = 0, dh = 0, dummy; - Window root, dummyw; - - graphics_get_display_size(0, &disp_w, &disp_h); - if (disp_w == 0 || disp_h == 0) - fprintf(stderr, "ERROR: graphics_get_display_size is broken\n"); - - // default to fullscreen - // Chips: rpi cut border when full screen... - #if 1 - rect->x = (disp_w*2)/100; - rect->y = 0; - rect->width = disp_w - (disp_w*2)/100; - rect->height = disp_h - (disp_h*2)/100; - #else - rect->x = rect->y = 0; - rect->width = disp_w; - rect->height = disp_h; - #endif - - if (x11display == NULL || x11window == 0) - return; // use fullscreen - - pXGetGeometry(x11display, x11window, &root, &dx, &dy, &dw, &dh, - &dummy, &dummy); - pXGetWindowAttributes(x11display, root, &xattrs_root); - - if (dw == xattrs_root.width && dh == xattrs_root.height) - return; // use fullscreen - - pXTranslateCoordinates(x11display, x11window, root, - dx, dy, &dx, &dy, &dummyw); - - // how to deal with that weird centering thing? - // this is not quite right.. - dx += (disp_w - xattrs_root.width) / 2; - dy += (disp_h - xattrs_root.height) / 2; - - rect->x = dx; - rect->y = dy; - rect->width = dw; - rect->height = dh; -} - -static void submit_rect(void) -{ - DISPMANX_UPDATE_HANDLE_T m_dispmanUpdate; - DISPMANX_ELEMENT_HANDLE_T m_dispmanElement; - VC_RECT_T srcRect = { 0, }; // unused, but we segfault without passing it?? - VC_RECT_T dstRect; - - get_window_rect(&dstRect); - - m_dispmanDisplay = vc_dispmanx_display_open(0); - m_dispmanUpdate = vc_dispmanx_update_start(0); - - m_dispmanElement = vc_dispmanx_element_add(m_dispmanUpdate, - m_dispmanDisplay, 0, &dstRect, 0, &srcRect, - DISPMANX_PROTECTION_NONE, 0, 0, DISPMANX_NO_ROTATE); - - m_nativeWindow.element = m_dispmanElement; - m_nativeWindow.width = dstRect.width; - m_nativeWindow.height = dstRect.height; - - vc_dispmanx_update_submit_sync(m_dispmanUpdate); -} - -int gl_platform_init(void **display, void **window, int *quirks) -{ - x11display = NULL; - x11window = 0; - - x11lib = dlopen("libX11.so.6", RTLD_LAZY); - if (x11lib != NULL) { - pXGetGeometry = dlsym(x11lib, "XGetGeometry"); - pXGetWindowAttributes = dlsym(x11lib, "XGetWindowAttributes"); - pXTranslateCoordinates = dlsym(x11lib, "XTranslateCoordinates"); - if (pXGetGeometry != NULL && pXGetWindowAttributes != NULL - && pXTranslateCoordinates != NULL) - { - x11display = *display; - x11window = (Window)*window; - } - } - - bcm_host_init(); - submit_rect(); - - *display = EGL_DEFAULT_DISPLAY; - *window = &m_nativeWindow; - *quirks |= GL_QUIRK_ACTIVATE_RECREATE; - - return 0; -} - -void gl_platform_finish(void) -{ - vc_dispmanx_display_close(m_dispmanDisplay); - bcm_host_deinit(); - - if (x11lib) { - dlclose(x11lib); - x11lib = NULL; - } - - x11display = NULL; - x11window = 0; -} - -#else - -int gl_platform_init(void **display, void **window, int *quirks) -{ - return 0; -} - -void gl_platform_finish(void) -{ -} - -#endif diff --git a/src/od-gles/gl_platform.h b/src/od-gles/gl_platform.h deleted file mode 100644 index 3e0bbb14..00000000 --- a/src/od-gles/gl_platform.h +++ /dev/null @@ -1,2 +0,0 @@ -int gl_platform_init(void **display, void **window, int *quirks); -void gl_platform_finish(void); diff --git a/src/od-gles/gles_gfx.cpp b/src/od-gles/gles_gfx.cpp deleted file mode 100644 index ca38dccd..00000000 --- a/src/od-gles/gles_gfx.cpp +++ /dev/null @@ -1,748 +0,0 @@ -#include "sysconfig.h" -#include "sysdeps.h" -#include "config.h" -#include "uae.h" -#include "options.h" -#include "gui.h" -#include "memory.h" -#include "newcpu.h" -#include "inputdevice.h" -#include "custom.h" -#include "xwin.h" -#include "drawing.h" -#include "savestate.h" -#include "picasso96.h" - -#include -#include -#include -#include -#ifdef ANDROIDSDL -#include -#endif -#include "gl.h" -#include - -/* SDL surface variable for output of emulation */ -SDL_Surface *prSDLScreen = NULL; -/* Dummy SDL variable for screen init */ -SDL_Surface *Dummy_prSDLScreen = NULL; -static SDL_Surface *current_screenshot = NULL; -/* Possible screen modes (x and y resolutions) */ -#define MAX_SCREEN_MODES 6 -static int x_size_table[MAX_SCREEN_MODES] = { 640, 640, 800, 1024, 1152, 1280 }; -static int y_size_table[MAX_SCREEN_MODES] = { 400, 480, 480, 768, 864, 960 }; - -static int red_bits, green_bits, blue_bits; -static int red_shift, green_shift, blue_shift; - -struct PicassoResolution *DisplayModes; -struct MultiDisplay Displays[MAX_DISPLAYS]; - -int screen_is_picasso = 0; - -static int curr_layer_width = 0; - -static char vid_drv_name[32]; -static void *display, *window; -static int gl_quirks; - -static char screenshot_filename_default[255]={ - '/', 't', 'm', 'p', '/', 'n', 'u', 'l', 'l', '.', 'p', 'n', 'g', '\0' -}; -char *screenshot_filename=(char *)&screenshot_filename_default[0]; -FILE *screenshot_file=NULL; -static void CreateScreenshot(void); -static int save_thumb(char *path); -int delay_savestate_frame = 0; - -int justClicked = 0; -int mouseMoving = 0; -int fcounter = 0; -int doStylusRightClick = 0; - -static long next_synctime = 0; - - -unsigned char current_resource_amigafb = 0; - - -int graphics_setup (void) -{ -#ifdef PICASSO96 - picasso_InitResolutions(); - InitPicasso96(); -#endif - - return 1; -} - - -void InitAmigaVidMode(struct uae_prefs *p) -{ - /* Initialize structure for Amiga video modes */ - gfxvidinfo.pixbytes = 2; - gfxvidinfo.bufmem = (uae_u8 *)prSDLScreen->pixels; - gfxvidinfo.outwidth = p->gfx_size.width; - gfxvidinfo.outheight = p->gfx_size.height; -#ifdef PICASSO96 - if(screen_is_picasso) - { - gfxvidinfo.outwidth = picasso_vidinfo.width; - //gfxvidinfo.outheight = picasso_vidinfo.height; - } -#endif - gfxvidinfo.rowbytes = prSDLScreen->pitch; - //gfxvidinfo.rowbytes = blit_rect.width * 2; -} - -void graphics_dispmanshutdown (void) -{ - printf("dispmanshutdown\n"); -} - - -void graphics_subshutdown (void) -{ - gl_finish(); - // Dunno if below lines are usefull for Rpi... - //SDL_FreeSurface(prSDLScreen); - //prSDLScreen = NULL; -} - - - - - -static void open_screen(struct uae_prefs *p) -{ - int width; - int height; - SDL_SysWMinfo wminfo; - int ret; - int gl_works = 0; - - -#ifdef PICASSO96 - if (screen_is_picasso) - { - width = picasso_vidinfo.width; - height = picasso_vidinfo.height; - } else -#endif - { - p->gfx_resolution = p->gfx_size.width > 600 ? 1 : 0; - width = p->gfx_size.width; - height = p->gfx_size.height; - } - - - if(Dummy_prSDLScreen) - { // y.f. 2016-10-13 : free the previous screen surface every time, - // so we can have fullscreen while running and windowed while in config window. - // Apparently, something somewhere is resetting the screen. - SDL_FreeSurface(Dummy_prSDLScreen); - Dummy_prSDLScreen = NULL; - } - - if(Dummy_prSDLScreen == NULL ) - { - const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo (); - printf("Current resolution: %d x %d %d bpp\n",videoInfo->current_w, videoInfo->current_h, videoInfo->vfmt->BitsPerPixel); - //Dummy_prSDLScreen = SDL_SetVideoMode(videoInfo->current_w,videoInfo->current_h,16,SDL_SWSURFACE |SDL_FULLSCREEN); - Dummy_prSDLScreen = SDL_SetVideoMode(width, height, 16, SDL_SWSURFACE); - } - - SDL_ShowCursor(SDL_DISABLE); - - printf("Emulation resolution: Width %i Height: %i\n",width,height); - prSDLScreen = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,16, - Dummy_prSDLScreen->format->Rmask, - Dummy_prSDLScreen->format->Gmask, - Dummy_prSDLScreen->format->Bmask, - Dummy_prSDLScreen->format->Amask); - - - // get x11 display/window for GL - SDL_VideoDriverName(vid_drv_name, sizeof(vid_drv_name)); -#ifdef SDL_VIDEO_DRIVER_X11 - if (strcmp(vid_drv_name, "x11") == 0) { - SDL_VERSION(&wminfo.version); - ret = SDL_GetWMInfo(&wminfo); - if (ret > 0) { - display = wminfo.info.x11.display; - window = (void *)wminfo.info.x11.window; - } - } -#else - (void)wminfo; -#endif - ret = gl_init(display, window, &gl_quirks); - if (ret == 0) { - gl_works = 1; - } - - - if(prSDLScreen != NULL) - { - InitAmigaVidMode(p); - init_row_map(); - } - //framecnt = 1; // Don't draw frame before reset done -} - - -void update_display(struct uae_prefs *p) -{ - open_screen(p); - - SDL_ShowCursor(SDL_DISABLE); - - framecnt = 1; // Don't draw frame before reset done -} - - -int check_prefs_changed_gfx (void) -{ - int changed = 0; - - if(currprefs.gfx_size.height != changed_prefs.gfx_size.height || - currprefs.gfx_size.width != changed_prefs.gfx_size.width || - currprefs.gfx_size_fs.width != changed_prefs.gfx_size_fs.width || - currprefs.gfx_resolution != changed_prefs.gfx_resolution) - { - cfgfile_configuration_change(1); - currprefs.gfx_size.height = changed_prefs.gfx_size.height; - currprefs.gfx_size.width = changed_prefs.gfx_size.width; - currprefs.gfx_size_fs.width = changed_prefs.gfx_size_fs.width; - currprefs.gfx_resolution = changed_prefs.gfx_resolution; - update_display(&currprefs); - changed = 1; - } - if (currprefs.leds_on_screen != changed_prefs.leds_on_screen || - currprefs.pandora_hide_idle_led != changed_prefs.pandora_hide_idle_led || - currprefs.pandora_vertical_offset != changed_prefs.pandora_vertical_offset) - { - currprefs.leds_on_screen = changed_prefs.leds_on_screen; - currprefs.pandora_hide_idle_led = changed_prefs.pandora_hide_idle_led; - currprefs.pandora_vertical_offset = changed_prefs.pandora_vertical_offset; - changed = 1; - } - if (currprefs.chipset_refreshrate != changed_prefs.chipset_refreshrate) - { - currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate; - init_hz_full (); - changed = 1; - } - - return changed; -} - - -int lockscr (void) -{ - //SDL_LockSurface(prSDLScreen); - return 1; -} - - -void unlockscr (void) -{ - //SDL_UnlockSurface(prSDLScreen); -} - -void wait_for_vsync(void) -{ - // Temporary -} - -void flush_screen () -{ - //SDL_UnlockSurface (prSDLScreen); - - - if (savestate_state == STATE_DOSAVE) - { - if(delay_savestate_frame > 0) - --delay_savestate_frame; - else - { - CreateScreenshot(); - save_thumb(screenshot_filename); - savestate_state = 0; - } - } - - long start = read_processor_time(); - //if(start < next_synctime && next_synctime - start > time_per_frame - 1000) - // usleep((next_synctime - start) - 1000); - - gl_flip(gfxvidinfo.bufmem, currprefs.gfx_size.width, currprefs.gfx_size.height); - - - last_synctime = read_processor_time(); - - if(last_synctime - next_synctime > time_per_frame * (1 + currprefs.gfx_framerate) - (long)1000) - adjust_idletime(-1); - else - adjust_idletime(last_synctime - start); - - next_synctime = last_synctime + time_per_frame * (1 + currprefs.gfx_framerate); - - init_row_map(); - -} - - -void black_screen_now(void) -{ - SDL_FillRect(Dummy_prSDLScreen,NULL,0); - SDL_Flip(Dummy_prSDLScreen); -} - - -static void graphics_subinit (void) -{ - if (prSDLScreen == NULL) - { - fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError()); - return; - } - else - { - SDL_ShowCursor(SDL_DISABLE); - - InitAmigaVidMode(&currprefs); - } -} - -STATIC_INLINE int bitsInMask (unsigned long mask) -{ - /* count bits in mask */ - int n = 0; - while (mask) - { - n += mask & 1; - mask >>= 1; - } - return n; -} - - -STATIC_INLINE int maskShift (unsigned long mask) -{ - /* determine how far mask is shifted */ - int n = 0; - while (!(mask & 1)) - { - n++; - mask >>= 1; - } - return n; -} - - -static int init_colors (void) -{ - int i; - int red_bits, green_bits, blue_bits; - int red_shift, green_shift, blue_shift; - - /* Truecolor: */ - red_bits = bitsInMask(prSDLScreen->format->Rmask); - green_bits = bitsInMask(prSDLScreen->format->Gmask); - blue_bits = bitsInMask(prSDLScreen->format->Bmask); - red_shift = maskShift(prSDLScreen->format->Rmask); - green_shift = maskShift(prSDLScreen->format->Gmask); - blue_shift = maskShift(prSDLScreen->format->Bmask); - alloc_colors64k (red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, 0); - notice_new_xcolors(); - for (i = 0; i < 4096; i++) - xcolors[i] = xcolors[i] * 0x00010001; - - return 1; -} - - -/* - * Find the colour depth of the display - */ -static int get_display_depth (void) -{ - const SDL_VideoInfo *vid_info; - int depth = 0; - - if ((vid_info = SDL_GetVideoInfo())) { - depth = vid_info->vfmt->BitsPerPixel; - - /* Don't trust the answer if it's 16 bits; the display - * could actually be 15 bits deep. We'll count the bits - * ourselves */ - if (depth == 16) - depth = bitsInMask (vid_info->vfmt->Rmask) + bitsInMask (vid_info->vfmt->Gmask) + bitsInMask (vid_info->vfmt->Bmask); - } - return depth; -} - -int GetSurfacePixelFormat(void) -{ - int depth = get_display_depth(); - int unit = (depth + 1) & 0xF8; - - return (unit == 8 ? RGBFB_CHUNKY - : depth == 15 && unit == 16 ? RGBFB_R5G5B5 - : depth == 16 && unit == 16 ? RGBFB_R5G6B5 - : unit == 24 ? RGBFB_B8G8R8 - : unit == 32 ? RGBFB_R8G8B8A8 - : RGBFB_NONE); -} - - -int graphics_init (bool mousecapture) -{ - int i,j; - - //uae_sem_init (&vsync_wait_sem, 0, 1); - - graphics_subinit (); - - - if (!init_colors ()) - return 0; - - //buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; - //keyboard_init(); - - return 1; -} - -void graphics_leave (void) -{ - graphics_subshutdown (); - SDL_FreeSurface(Dummy_prSDLScreen); - SDL_VideoQuit(); -} - - -#define systemRedShift (prSDLScreen->format->Rshift) -#define systemGreenShift (prSDLScreen->format->Gshift) -#define systemBlueShift (prSDLScreen->format->Bshift) -#define systemRedMask (prSDLScreen->format->Rmask) -#define systemGreenMask (prSDLScreen->format->Gmask) -#define systemBlueMask (prSDLScreen->format->Bmask) - -static int save_png(SDL_Surface* surface, char *path) -{ - int w = surface->w; - int h = surface->h; - unsigned char * pix = (unsigned char *)surface->pixels; - unsigned char writeBuffer[1024 * 3]; - FILE *f = fopen(path,"wb"); - if(!f) return 0; - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, - NULL, - NULL, - NULL); - if(!png_ptr) { - fclose(f); - return 0; - } - - png_infop info_ptr = png_create_info_struct(png_ptr); - - if(!info_ptr) { - png_destroy_write_struct(&png_ptr,NULL); - fclose(f); - return 0; - } - - png_init_io(png_ptr,f); - - png_set_IHDR(png_ptr, - info_ptr, - w, - h, - 8, - PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - png_write_info(png_ptr,info_ptr); - - unsigned char *b = writeBuffer; - - int sizeX = w; - int sizeY = h; - int y; - int x; - - unsigned short *p = (unsigned short *)pix; - for(y = 0; y < sizeY; y++) - { - for(x = 0; x < sizeX; x++) - { - unsigned short v = p[x]; - - *b++ = ((v & systemRedMask ) >> systemRedShift ) << 3; // R - *b++ = ((v & systemGreenMask) >> systemGreenShift) << 2; // G - *b++ = ((v & systemBlueMask ) >> systemBlueShift ) << 3; // B - } - p += surface->pitch / 2; - png_write_row(png_ptr,writeBuffer); - b = writeBuffer; - } - - png_write_end(png_ptr, info_ptr); - - png_destroy_write_struct(&png_ptr, &info_ptr); - - fclose(f); - return 1; -} - - -static void CreateScreenshot(void) -{ - int w, h; - - if(current_screenshot != NULL) - { - SDL_FreeSurface(current_screenshot); - current_screenshot = NULL; - } - - w=prSDLScreen->w; - h=prSDLScreen->h; - - current_screenshot = SDL_CreateRGBSurface(prSDLScreen->flags,w,h,prSDLScreen->format->BitsPerPixel,prSDLScreen->format->Rmask,prSDLScreen->format->Gmask,prSDLScreen->format->Bmask,prSDLScreen->format->Amask); - SDL_BlitSurface(prSDLScreen, NULL, current_screenshot, NULL); -} - - -static int save_thumb(char *path) -{ - int ret = 0; - if(current_screenshot != NULL) - { - ret = save_png(current_screenshot, path); - SDL_FreeSurface(current_screenshot); - current_screenshot = NULL; - } - return ret; -} - -bool vsync_switchmode (int hz) -{ - int changed_height = changed_prefs.gfx_size.height; - - if (hz >= 55) - hz = 60; - else - hz = 50; - - if(hz == 50 && currVSyncRate == 60) - { - // Switch from NTSC -> PAL - switch(changed_height) { - case 200: changed_height = 240; break; - case 216: changed_height = 262; break; - case 240: changed_height = 270; break; - case 256: changed_height = 270; break; - case 262: changed_height = 270; break; - case 270: changed_height = 270; break; - } - } - else if(hz == 60 && currVSyncRate == 50) - { - // Switch from PAL -> NTSC - switch(changed_height) { - case 200: changed_height = 200; break; - case 216: changed_height = 200; break; - case 240: changed_height = 200; break; - case 256: changed_height = 216; break; - case 262: changed_height = 216; break; - case 270: changed_height = 240; break; - } - } - - if(changed_height == currprefs.gfx_size.height && hz == currprefs.chipset_refreshrate) - return true; - - changed_prefs.gfx_size.height = changed_height; - - return true; -} - -bool target_graphics_buffer_update (void) -{ - bool rate_changed = 0; - //bool rate_changed = SetVSyncRate(currprefs.chipset_refreshrate); - - if(currprefs.gfx_size.height != changed_prefs.gfx_size.height) - { - update_display(&changed_prefs); - rate_changed = true; - } - - if(rate_changed) - { - black_screen_now(); - fpscounter_reset(); - time_per_frame = 1000 * 1000 / (currprefs.chipset_refreshrate); - } - - return true; -} - - - -#ifdef PICASSO96 - - -static int resolution_compare (const void *a, const void *b) -{ - struct PicassoResolution *ma = (struct PicassoResolution *)a; - struct PicassoResolution *mb = (struct PicassoResolution *)b; - if (ma->res.width < mb->res.width) - return -1; - if (ma->res.width > mb->res.width) - return 1; - if (ma->res.height < mb->res.height) - return -1; - if (ma->res.height > mb->res.height) - return 1; - return ma->depth - mb->depth; -} -static void sortmodes (void) -{ - int i = 0, idx = -1; - int pw = -1, ph = -1; - while (DisplayModes[i].depth >= 0) - i++; - qsort (DisplayModes, i, sizeof (struct PicassoResolution), resolution_compare); - for (i = 0; DisplayModes[i].depth >= 0; i++) { - if (DisplayModes[i].res.height != ph || DisplayModes[i].res.width != pw) { - ph = DisplayModes[i].res.height; - pw = DisplayModes[i].res.width; - idx++; - } - DisplayModes[i].residx = idx; - } -} - -static void modesList (void) -{ - int i, j; - - i = 0; - while (DisplayModes[i].depth >= 0) { - write_log("%d: %s (", i, DisplayModes[i].name); - j = 0; - while (DisplayModes[i].refresh[j] > 0) { - if (j > 0) - write_log(","); - write_log("%d", DisplayModes[i].refresh[j]); - j++; - } - write_log(")\n"); - i++; - } -} - -void picasso_InitResolutions (void) -{ - struct MultiDisplay *md1; - int i, count = 0; - char tmp[200]; - int bitdepth; - - Displays[0].primary = 1; - Displays[0].disabled = 0; - Displays[0].rect.left = 0; - Displays[0].rect.top = 0; - Displays[0].rect.right = 800; - Displays[0].rect.bottom = 640; - sprintf (tmp, "%s (%d*%d)", "Display", Displays[0].rect.right, Displays[0].rect.bottom); - Displays[0].name = my_strdup(tmp); - Displays[0].name2 = my_strdup("Display"); - - md1 = Displays; - DisplayModes = md1->DisplayModes = xmalloc(struct PicassoResolution, MAX_PICASSO_MODES); - for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++) { - for(bitdepth = 16; bitdepth <= 32; bitdepth += 16) { - int bit_unit = (bitdepth + 1) & 0xF8; - int rgbFormat = (bitdepth == 16 ? RGBFB_R5G6B5 : RGBFB_R8G8B8A8); - int pixelFormat = 1 << rgbFormat; - pixelFormat |= RGBFF_CHUNKY; - - if (SDL_VideoModeOK (x_size_table[i], y_size_table[i], bitdepth, SDL_SWSURFACE)) - { - DisplayModes[count].res.width = x_size_table[i]; - DisplayModes[count].res.height = y_size_table[i]; - DisplayModes[count].depth = bit_unit >> 3; - DisplayModes[count].refresh[0] = 50; - DisplayModes[count].refresh[1] = 60; - DisplayModes[count].refresh[2] = 0; - DisplayModes[count].colormodes = pixelFormat; - sprintf(DisplayModes[count].name, "%dx%d, %d-bit", - DisplayModes[count].res.width, DisplayModes[count].res.height, DisplayModes[count].depth * 8); - - count++; - } - } - } - DisplayModes[count].depth = -1; - sortmodes(); - modesList(); - DisplayModes = Displays[0].DisplayModes; -} - - -void gfx_set_picasso_modeinfo (uae_u32 w, uae_u32 h, uae_u32 depth, RGBFTYPE rgbfmt) -{ - depth >>= 3; - if( ((unsigned)picasso_vidinfo.width == w ) && - ( (unsigned)picasso_vidinfo.height == h ) && - ( (unsigned)picasso_vidinfo.depth == depth ) && - ( picasso_vidinfo.selected_rgbformat == rgbfmt) ) - return; - - picasso_vidinfo.selected_rgbformat = rgbfmt; - picasso_vidinfo.width = w; - picasso_vidinfo.height = h; - picasso_vidinfo.depth = depth; - picasso_vidinfo.extra_mem = 1; - - picasso_vidinfo.pixbytes = depth; - if (screen_is_picasso) - { - open_screen(&currprefs); - picasso_vidinfo.rowbytes = prSDLScreen->pitch; - } -} - - -void gfx_set_picasso_state (int on) -{ - if (on == screen_is_picasso) - return; - - screen_is_picasso = on; - open_screen(&currprefs); - picasso_vidinfo.rowbytes = prSDLScreen->pitch; -} - -uae_u8 *gfx_lock_picasso (void) -{ - // We lock the surface directly after create and flip - picasso_vidinfo.rowbytes = prSDLScreen->pitch; - return (uae_u8 *)prSDLScreen->pixels; -} - -void gfx_unlock_picasso (void) -{ - // We lock the surface directly after create and flip, so no unlock here -} - -#endif // PICASSO96 diff --git a/src/od-gles/shader_stuff.cpp b/src/od-gles/shader_stuff.cpp deleted file mode 100644 index 3012ffd2..00000000 --- a/src/od-gles/shader_stuff.cpp +++ /dev/null @@ -1,490 +0,0 @@ - -#include -#include - -#include - -#include - -#include "shader_stuff.h" - - -typedef struct -{ - // Handle to a program object - GLuint programObject; - - // Attribute locations - GLint positionLoc; - GLint texCoordLoc; - - // Sampler location - GLint samplerLoc; - - // Other locations - GLint frameCountLoc; - GLint emulatorFrameSizeLoc; - GLint outputFrameSizeLoc; - - // Texture handle - GLuint textureId; - -} UserData; - -typedef struct STATE_T -{ - uint32_t width; - uint32_t height; - - EGLDisplay display; - EGLSurface surface; - EGLContext context; -#ifdef VCOS_VERSION - EGL_DISPMANX_WINDOW_T nativewindow; -#endif - UserData *user_data; - void (*draw_func) (struct STATE_T* ); -} STATE_T; - - - -// for checking if file has changed -#include -#include - - -time_t get_file_date(const char *path) -{ - struct stat file_stat; - int err = stat(path, &file_stat); - if (err) - return 0; - else - return file_stat.st_mtime; -} - - -void showlog(GLint shader) -{ - char log[1024]; - - glGetShaderInfoLog(shader,sizeof log,NULL,log); - printf("%d:shader:\n%s\n", shader, log); -} - -static void showprogramlog(GLint shader) -{ - char log[1024]; - glGetProgramInfoLog(shader,sizeof log,NULL,log); - printf("%d:program:\n%s\n", shader, log); -} - -//static char fshader_file_name[10000]; -static char fshader_file_name[] = "fshader.glsl"; -static time_t fshader_file_date=0; -static GLchar *fshader_source = NULL; - - -static GLchar default_vShaderStr[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - -static GLchar default_fShaderStr[] = - "precision mediump float;\n" - "varying vec2 v_texCoord;\n" - "uniform sampler2D s_texture;\n" - "uniform float u_framecount;\n" - "uniform vec2 u_emulator_frame_size;\n" - "uniform vec2 u_output_frame_size;\n" - "void main()\n" - "{\n" -// " gl_FragColor = texture2D( s_texture, v_texCoord );\n" - " gl_FragColor = texture2D( s_texture, v_texCoord )\n" -// " * (cos(gl_FragCoord.y * 3.14159) * 0.5 + 0.5); \n" -// " * (cos(v_texCoord.y * 3.14159 * 262.0 * 2.0 * 2.0) * 0.45 + 0.55); \n" - " * (cos(gl_FragCoord.y * 3.1415926) * 0.35 + 0.65); \n" - "}\n"; - - -/* -void set_fshader_file_name(char *shaderdir) -{ - strcpy(fshader_file_name,shaderdir); - if(shaderdir[strlen(shaderdir)-1]!='/') - strcat(fshader_file_name,"/"); - strcat(fshader_file_name,"fshader.glsl"); -} -*/ - -/* Returns non-zero, if the fragment shaders should be reloaded. - * Because the file has been changed or deleted or something. - * Returns zero, if the shader doesn't need to be reloaded. - */ -int shader_stuff_shader_needs_reload() -{ - if ((fshader_file_name == NULL) || (fshader_source == default_fShaderStr)) - return 0; - - return (get_file_date(fshader_file_name) != fshader_file_date); -} - - -/* Tries to load file named file_name. - * - * If opening the file succeeds: - * Allocates memory for *file_data with malloc() and loads the file - * contents in the allocated buffer. An extra terminator char is added. - * Previous pointer value is overwritten. - * - * *file_date is set to the time/date stamp of the file. - * - * Returns 0. - * - * If opening the file fails: - * *file_data and *file_date are left untouched. - * Returns -1. - * - */ -int load_file(char *file_name, GLchar **file_data, time_t *file_date) -{ - GLchar *data = NULL; - - FILE *f = fopen(file_name, "rb"); - if(f!=NULL) - { - fseek(f, 0, SEEK_END); - int len = ftell(f); - *file_data = (GLchar *)malloc(len+1); - fseek(f, 0, SEEK_SET); - fread(*file_data, 1, len, f); - fclose(f); - (*file_data)[len] = 0; // String terminator - - *file_date = get_file_date(file_name); - } - else { - printf("Fragment shader file %s won't open\n", file_name); - return -1; - } - - return 0; -} - -void free_fshader_source() -{ - if ((fshader_source != NULL) && (fshader_source != default_fShaderStr)) { - free(fshader_source); - fshader_source = NULL; - } -} - -/// -// Create a shader object, load the shader source, and -// compile the shader. -// -GLuint LoadShader(GLenum type, const GLchar *shaderSrc) -{ - GLuint shader; - GLint compiled; - // Create the shader object - shader = glCreateShader(type); - if(shader == 0) - return 0; - // Load the shader source - glShaderSource(shader, 1, &shaderSrc, NULL); - // Compile the shader - glCompileShader(shader); - // Check the compile status - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if(!compiled) - { - GLint infoLen = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); - if(infoLen > 1) - { - char* infoLog = (char *)malloc(sizeof(char) * infoLen); - glGetShaderInfoLog(shader, infoLen, NULL, infoLog); - fprintf(stderr, "Error compiling shader:\n%s\n", infoLog); - free(infoLog); - } - glDeleteShader(shader); - return 0; - } - return shader; -} - -GLuint LoadProgram ( const GLchar *vertShaderSrc, const GLchar *fragShaderSrc ) -{ - GLuint vertexShader; - GLuint fragmentShader; - GLuint programObject; - GLint linked; - - // Load the vertex/fragment shaders - vertexShader = LoadShader ( GL_VERTEX_SHADER, vertShaderSrc ); - if ( vertexShader == 0 ) - return 0; - - fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fragShaderSrc ); - // if it didn't compile, let's try the default shader - if ((fragmentShader == 0) && (fshader_source != default_fShaderStr)) { - fshader_source = default_fShaderStr; - fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, default_fShaderStr ); - } - - if ( fragmentShader == 0 ) - { - glDeleteShader( vertexShader ); - return 0; - } - - // Create the program object - programObject = glCreateProgram ( ); - - if ( programObject == 0 ) - return 0; - - glAttachShader ( programObject, vertexShader ); - glAttachShader ( programObject, fragmentShader ); - - // Link the program - glLinkProgram ( programObject ); - - // Check the link status - glGetProgramiv ( programObject, GL_LINK_STATUS, &linked ); - - if ( !linked ) - { - GLint infoLen = 0; - glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen ); - - if ( infoLen > 1 ) - { - char* infoLog = (char *)malloc (sizeof(char) * infoLen ); - - glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog ); - fprintf (stderr, "Error linking program:\n%s\n", infoLog ); - - free ( infoLog ); - } - - glDeleteProgram ( programObject ); - return 0; - } - - // Free up no longer needed shader resources - glDeleteShader ( vertexShader ); - glDeleteShader ( fragmentShader ); - - return programObject; -} - -static STATE_T shader_stuff_state; - -int shader_stuff_init() -{ - STATE_T *p_state = &shader_stuff_state; - p_state->user_data = (UserData *)malloc(sizeof(UserData)); - return GL_TRUE; -} - -/// -// Initialize the shader and program object -// -int shader_stuff_reload_shaders() -{ - STATE_T *p_state = &shader_stuff_state; - UserData *userData = p_state->user_data; - -// ----- these lines could be moved to a separate "delete program" routine - - free_fshader_source(); - - // If there was an existing program object, delete it. - if (userData->programObject != 0) { - glDeleteProgram(userData->programObject); - userData->programObject = 0; - } -// ----- - - - if (load_file(fshader_file_name, &fshader_source, &fshader_file_date) != 0) { - printf("Cannot open %s. Using built-in default fragment shader.", fshader_file_name); - fshader_source = default_fShaderStr; - } - - // Load the shaders and get a linked program object - userData->programObject = LoadProgram ( default_vShaderStr, fshader_source ); - - - return GL_TRUE; -} - -int shader_stuff_set_data(GLfloat *vertex_coords_3f, GLfloat *texture_coords_2f, GLuint texture_name) -{ - STATE_T *p_state = &shader_stuff_state; - UserData *userData = p_state->user_data; - - glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f ); - - // Get the attribute locations - userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" ); - userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" ); - - // Get the sampler location - userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" ); - - // Get the sampler location - userData->frameCountLoc = glGetUniformLocation ( userData->programObject, "u_framecount" ); - printf("frameCountLoc = %d\n", userData->frameCountLoc); - userData->emulatorFrameSizeLoc = glGetUniformLocation ( userData->programObject, "u_emulator_frame_size" ); - printf("emulatorFrameSizeLoc = %d\n", userData->emulatorFrameSizeLoc); - userData->outputFrameSizeLoc = glGetUniformLocation ( userData->programObject, "u_output_frame_size" ); - - // Load the texture - userData->textureId = texture_name; - - // Load the vertex position - glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT, - GL_FALSE, 3 * sizeof(GLfloat), vertex_coords_3f ); - // Load the texture coordinate - glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(GLfloat), texture_coords_2f ); - - glEnableVertexAttribArray ( userData->positionLoc ); - glEnableVertexAttribArray ( userData->texCoordLoc ); - - // Bind the texture - glActiveTexture ( GL_TEXTURE0 ); - glBindTexture ( GL_TEXTURE_2D, userData->textureId ); - - // Set the sampler texture unit to 0 - glUniform1i ( userData->samplerLoc, 0 ); - - - return GL_TRUE; -} - -// call this for every frame -// todo: merge all this "stuff" properly to gl.cpp -int shader_stuff_frame(int framecount, int emu_width, int emu_height, int out_width, int out_height) -{ - STATE_T *p_state = &shader_stuff_state; - UserData *userData = p_state->user_data; - - glUseProgram ( userData->programObject ); - - glUniform1f ( userData->frameCountLoc, (GLfloat)(framecount) ); - glUniform2f( userData->emulatorFrameSizeLoc, (GLfloat)(emu_width), (GLfloat)(emu_height)); - glUniform2f ( userData->outputFrameSizeLoc, (GLfloat)(out_width), (GLfloat)(out_height)); - -} - - -/* - -// for checking if file has changed -#include -#include - - -void showlog(GLint shader) -{ - char log[1024]; - - glGetShaderInfoLog(shader,sizeof log,NULL,log); - printf("%d:shader:\n%s\n", shader, log); -} - -static void showprogramlog(GLint shader) -{ - char log[1024]; - glGetProgramInfoLog(shader,sizeof log,NULL,log); - printf("%d:program:\n%s\n", shader, log); -} - -static char fshader_file_name[10000]; -static time_t fshader_file_date=0; - -void set_fshader_file_name(char *shaderdir) -{ - strcpy(fshader_file_name,shaderdir); - if(shaderdir[strlen(shaderdir)-1]!='/') - strcat(fshader_file_name,"/"); - strcat(fshader_file_name,"fshader.glsl"); -} - -static int init_shader() -{ - FILE *f; - int len; - static GLchar *fsource=NULL,*vsource= - "attribute vec2 vertex;" - "void main(void) {" - " gl_Position = vec4(vertex.x,vertex.y,0.0,1.0);" - "}"; - - f=fopen(fshader_file_name,"rb"); - if(f==NULL) - { - printf("Fragment shader won't open\n"); - return -1; - } - fseek(f,0,SEEK_END); - len=ftell(f); - if(fsource!=NULL) - free(fsource); - fsource=malloc(len+1); - fseek(f,0,SEEK_SET); - fread(fsource,1,len,f); - fclose(f); - fsource[len]=0; // Need to terminate! - - fshader_file_date = get_file_date(fshader_file_name); - - vshader=glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vshader,1,(const GLchar **)&vsource,0); - glCompileShader(vshader); - showlog(vshader); - - fshader=glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fshader,1,(const GLchar **)&fsource,0); - glCompileShader(fshader); - showlog(fshader); - - program=glCreateProgram(); - glAttachShader(program,vshader); - glAttachShader(program,fshader); - glLinkProgram(program); - - return 0; -} - -void delete_shader() -{ - glDetachShader(program, fshader); - glDetachShader(program, vshader); - glDeleteShader(fshader); - glDeleteShader(vshader); - glUseProgram(0); - glDeleteProgram(program); - glUseProgram(0); -} - -void koelli_reload_shader() -{ - delete_shader(); - init_shader(); -} -* -int koelli_fshader_file_changed(void) -{ - return (get_file_date(fshader_file_name) != fshader_file_date); -} -*/ diff --git a/src/od-gles/shader_stuff.h b/src/od-gles/shader_stuff.h deleted file mode 100644 index b245e55a..00000000 --- a/src/od-gles/shader_stuff.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __SHADER_STUFF_H -#define __SHADER_STUFF_H - -#include - -extern int shader_stuff_init(); -extern int shader_stuff_shader_needs_reload(); -extern int shader_stuff_reload_shaders(); -extern int shader_stuff_set_data(GLfloat *vertex_coords_3f, GLfloat *texture_coords_2f, GLuint texture_name); -extern int shader_stuff_frame(int framecount, int emu_width, int emu_height, int out_width, int out_height); - -#endif