mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-30 10:50:13 +02:00
Update to v095r11 release.
byuu says: Changelog: - SFC: "uint8 read(uint addr)" -> "uint8 read(uint addr, uint8 data)" - hiro: mHorizontalLayout::setGeometry() return value - hiro/GTK: ListView,TreeView::setFocused() does not grab focus of first item Notes: - nall/windows/utf8.hpp needs using uint = unsigned; at the top to compile - sfc/balanced, sfc/performance won't compile yet Seems Cx4 games broke a while back. Not from this WIP, either. I'll go back and find out what's wrong now.
This commit is contained in:
@@ -7,52 +7,55 @@
|
||||
namespace nall { namespace Decode {
|
||||
|
||||
struct GZIP {
|
||||
string filename;
|
||||
uint8_t* data = nullptr;
|
||||
unsigned size = 0;
|
||||
|
||||
inline bool decompress(const string& filename);
|
||||
inline bool decompress(const uint8_t* data, unsigned size);
|
||||
|
||||
inline GZIP();
|
||||
inline ~GZIP();
|
||||
|
||||
inline auto decompress(const string& filename) -> bool;
|
||||
inline auto decompress(const uint8* data, uint size) -> bool;
|
||||
|
||||
string filename;
|
||||
uint8* data = nullptr;
|
||||
uint size = 0;
|
||||
};
|
||||
|
||||
bool GZIP::decompress(const string& filename) {
|
||||
GZIP::~GZIP() {
|
||||
if(data) delete[] data;
|
||||
}
|
||||
|
||||
auto GZIP::decompress(const string& filename) -> bool {
|
||||
if(auto memory = file::read(filename)) {
|
||||
return decompress(memory.data(), memory.size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GZIP::decompress(const uint8_t* data, unsigned size) {
|
||||
auto GZIP::decompress(const uint8* data, uint size) -> bool {
|
||||
if(size < 18) return false;
|
||||
if(data[0] != 0x1f) return false;
|
||||
if(data[1] != 0x8b) return false;
|
||||
unsigned cm = data[2];
|
||||
unsigned flg = data[3];
|
||||
unsigned mtime = data[4];
|
||||
uint cm = data[2];
|
||||
uint flg = data[3];
|
||||
uint mtime = data[4];
|
||||
mtime |= data[5] << 8;
|
||||
mtime |= data[6] << 16;
|
||||
mtime |= data[7] << 24;
|
||||
unsigned xfl = data[8];
|
||||
unsigned os = data[9];
|
||||
unsigned p = 10;
|
||||
unsigned isize = data[size - 4];
|
||||
uint xfl = data[8];
|
||||
uint os = data[9];
|
||||
uint p = 10;
|
||||
uint isize = data[size - 4];
|
||||
isize |= data[size - 3] << 8;
|
||||
isize |= data[size - 2] << 16;
|
||||
isize |= data[size - 1] << 24;
|
||||
filename = "";
|
||||
|
||||
if(flg & 0x04) { //FEXTRA
|
||||
unsigned xlen = data[p + 0];
|
||||
uint xlen = data[p + 0];
|
||||
xlen |= data[p + 1] << 8;
|
||||
p += 2 + xlen;
|
||||
}
|
||||
|
||||
if(flg & 0x08) { //FNAME
|
||||
char buffer[PATH_MAX];
|
||||
for(unsigned n = 0; n < PATH_MAX; n++, p++) {
|
||||
for(uint n = 0; n < PATH_MAX; n++, p++) {
|
||||
buffer[n] = data[p];
|
||||
if(data[p] == 0) break;
|
||||
}
|
||||
@@ -73,13 +76,6 @@ bool GZIP::decompress(const uint8_t* data, unsigned size) {
|
||||
return inflate(this->data, this->size, data + p, size - p - 8);
|
||||
}
|
||||
|
||||
GZIP::GZIP() {
|
||||
}
|
||||
|
||||
GZIP::~GZIP() {
|
||||
if(data) delete[] data;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
@@ -6,16 +6,16 @@
|
||||
namespace nall { namespace Decode {
|
||||
|
||||
namespace puff {
|
||||
inline int puff(
|
||||
inline auto puff(
|
||||
unsigned char* dest, unsigned long* destlen,
|
||||
unsigned char* source, unsigned long* sourcelen
|
||||
);
|
||||
) -> int;
|
||||
}
|
||||
|
||||
inline bool inflate(
|
||||
uint8_t* target, unsigned targetLength,
|
||||
const uint8_t* source, unsigned sourceLength
|
||||
) {
|
||||
inline auto inflate(
|
||||
uint8* target, uint targetLength,
|
||||
const uint8* source, uint sourceLength
|
||||
) -> bool {
|
||||
unsigned long tl = targetLength, sl = sourceLength;
|
||||
int result = puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl);
|
||||
return result == 0;
|
||||
@@ -23,7 +23,7 @@ inline bool inflate(
|
||||
|
||||
namespace puff {
|
||||
|
||||
enum {
|
||||
enum : uint {
|
||||
MAXBITS = 15,
|
||||
MAXLCODES = 286,
|
||||
MAXDCODES = 30,
|
||||
@@ -50,7 +50,7 @@ struct huffman {
|
||||
short* symbol;
|
||||
};
|
||||
|
||||
inline int bits(state* s, int need) {
|
||||
inline auto bits(state* s, int need) -> int {
|
||||
long val;
|
||||
|
||||
val = s->bitbuf;
|
||||
@@ -66,8 +66,8 @@ inline int bits(state* s, int need) {
|
||||
return (int)(val & ((1L << need) - 1));
|
||||
}
|
||||
|
||||
inline int stored(state* s) {
|
||||
unsigned len;
|
||||
inline auto stored(state* s) -> int {
|
||||
uint len;
|
||||
|
||||
s->bitbuf = 0;
|
||||
s->bitcnt = 0;
|
||||
@@ -91,7 +91,7 @@ inline int stored(state* s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int decode(state* s, huffman* h) {
|
||||
inline auto decode(state* s, huffman* h) -> int {
|
||||
int len, code, first, count, index, bitbuf, left;
|
||||
short* next;
|
||||
|
||||
@@ -126,7 +126,7 @@ inline int decode(state* s, huffman* h) {
|
||||
return -10;
|
||||
}
|
||||
|
||||
inline int construct(huffman* h, short* length, int n) {
|
||||
inline auto construct(huffman* h, short* length, int n) -> int {
|
||||
int symbol, len, left;
|
||||
short offs[MAXBITS + 1];
|
||||
|
||||
@@ -151,9 +151,9 @@ inline int construct(huffman* h, short* length, int n) {
|
||||
return left;
|
||||
}
|
||||
|
||||
inline int codes(state* s, huffman* lencode, huffman* distcode) {
|
||||
inline auto codes(state* s, huffman* lencode, huffman* distcode) -> int {
|
||||
int symbol, len;
|
||||
unsigned dist;
|
||||
uint dist;
|
||||
static const short lens[29] = {
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
|
||||
@@ -213,7 +213,7 @@ inline int codes(state* s, huffman* lencode, huffman* distcode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int fixed(state* s) {
|
||||
inline auto fixed(state* s) -> int {
|
||||
static int virgin = 1;
|
||||
static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
|
||||
static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
|
||||
@@ -243,7 +243,7 @@ inline int fixed(state* s) {
|
||||
return codes(s, &lencode, &distcode);
|
||||
}
|
||||
|
||||
inline int dynamic(state* s) {
|
||||
inline auto dynamic(state* s) -> int {
|
||||
int nlen, ndist, ncode, index, err;
|
||||
short lengths[MAXCODES];
|
||||
short lencnt[MAXBITS + 1], lensym[MAXLCODES];
|
||||
@@ -303,10 +303,10 @@ inline int dynamic(state* s) {
|
||||
return codes(s, &lencode, &distcode);
|
||||
}
|
||||
|
||||
inline int puff(
|
||||
inline auto puff(
|
||||
unsigned char* dest, unsigned long* destlen,
|
||||
unsigned char* source, unsigned long* sourcelen
|
||||
) {
|
||||
) -> int {
|
||||
state s;
|
||||
int last, type, err;
|
||||
|
||||
|
@@ -7,75 +7,83 @@
|
||||
namespace nall { namespace Decode {
|
||||
|
||||
struct PNG {
|
||||
inline PNG();
|
||||
inline ~PNG();
|
||||
|
||||
inline auto load(const string& filename) -> bool;
|
||||
inline auto load(const uint8* sourceData, uint sourceSize) -> bool;
|
||||
inline auto readbits(const uint8*& data) -> uint;
|
||||
|
||||
struct Info {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned bitDepth;
|
||||
uint width;
|
||||
uint height;
|
||||
uint bitDepth;
|
||||
//colorType:
|
||||
//0 = L (luma)
|
||||
//2 = R,G,B
|
||||
//3 = P (palette)
|
||||
//4 = L,A
|
||||
//6 = R,G,B,A
|
||||
unsigned colorType;
|
||||
unsigned compressionMethod;
|
||||
unsigned filterType;
|
||||
unsigned interlaceMethod;
|
||||
uint colorType;
|
||||
uint compressionMethod;
|
||||
uint filterType;
|
||||
uint interlaceMethod;
|
||||
|
||||
unsigned bytesPerPixel;
|
||||
unsigned pitch;
|
||||
uint bytesPerPixel;
|
||||
uint pitch;
|
||||
|
||||
uint8_t palette[256][3];
|
||||
uint8 palette[256][3];
|
||||
} info;
|
||||
|
||||
uint8_t* data = nullptr;
|
||||
unsigned size = 0;
|
||||
uint8* data = nullptr;
|
||||
uint size = 0;
|
||||
|
||||
inline bool load(const string& filename);
|
||||
inline bool load(const uint8_t* sourceData, unsigned sourceSize);
|
||||
inline unsigned readbits(const uint8_t*& data);
|
||||
unsigned bitpos = 0;
|
||||
|
||||
inline PNG();
|
||||
inline ~PNG();
|
||||
uint bitpos = 0;
|
||||
|
||||
protected:
|
||||
enum class FourCC : unsigned {
|
||||
enum class FourCC : uint {
|
||||
IHDR = 0x49484452,
|
||||
PLTE = 0x504c5445,
|
||||
IDAT = 0x49444154,
|
||||
IEND = 0x49454e44,
|
||||
};
|
||||
|
||||
inline unsigned interlace(unsigned pass, unsigned index);
|
||||
inline unsigned inflateSize();
|
||||
inline bool deinterlace(const uint8_t*& inputData, unsigned pass);
|
||||
inline bool filter(uint8_t* outputData, const uint8_t* inputData, unsigned width, unsigned height);
|
||||
inline unsigned read(const uint8_t* data, unsigned length);
|
||||
inline auto interlace(uint pass, uint index) -> uint;
|
||||
inline auto inflateSize() -> uint;
|
||||
inline auto deinterlace(const uint8*& inputData, uint pass) -> bool;
|
||||
inline auto filter(uint8* outputData, const uint8* inputData, uint width, uint height) -> bool;
|
||||
inline auto read(const uint8* data, uint length) -> uint;
|
||||
};
|
||||
|
||||
bool PNG::load(const string& filename) {
|
||||
PNG::PNG() {
|
||||
}
|
||||
|
||||
PNG::~PNG() {
|
||||
if(data) delete[] data;
|
||||
}
|
||||
|
||||
auto PNG::load(const string& filename) -> bool {
|
||||
if(auto memory = file::read(filename)) {
|
||||
return load(memory.data(), memory.size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PNG::load(const uint8_t* sourceData, unsigned sourceSize) {
|
||||
auto PNG::load(const uint8* sourceData, uint sourceSize) -> bool {
|
||||
if(sourceSize < 8) return false;
|
||||
if(read(sourceData + 0, 4) != 0x89504e47) return false;
|
||||
if(read(sourceData + 4, 4) != 0x0d0a1a0a) return false;
|
||||
|
||||
uint8_t* compressedData = nullptr;
|
||||
unsigned compressedSize = 0;
|
||||
uint8* compressedData = nullptr;
|
||||
uint compressedSize = 0;
|
||||
|
||||
unsigned offset = 8;
|
||||
uint offset = 8;
|
||||
while(offset < sourceSize) {
|
||||
unsigned length = read(sourceData + offset + 0, 4);
|
||||
unsigned fourCC = read(sourceData + offset + 4, 4);
|
||||
unsigned checksum = read(sourceData + offset + 8 + length, 4);
|
||||
uint length = read(sourceData + offset + 0, 4);
|
||||
uint fourCC = read(sourceData + offset + 4, 4);
|
||||
uint checksum = read(sourceData + offset + 8 + length, 4);
|
||||
|
||||
if(fourCC == (unsigned)FourCC::IHDR) {
|
||||
if(fourCC == (uint)FourCC::IHDR) {
|
||||
info.width = read(sourceData + offset + 8, 4);
|
||||
info.height = read(sourceData + offset + 12, 4);
|
||||
info.bitDepth = read(sourceData + offset + 16, 1);
|
||||
@@ -108,30 +116,30 @@ bool PNG::load(const uint8_t* sourceData, unsigned sourceSize) {
|
||||
info.pitch = (int)info.width * info.bytesPerPixel;
|
||||
}
|
||||
|
||||
if(fourCC == (unsigned)FourCC::PLTE) {
|
||||
if(fourCC == (uint)FourCC::PLTE) {
|
||||
if(length % 3) return false;
|
||||
for(unsigned n = 0, p = offset + 8; n < length / 3; n++) {
|
||||
for(uint n = 0, p = offset + 8; n < length / 3; n++) {
|
||||
info.palette[n][0] = sourceData[p++];
|
||||
info.palette[n][1] = sourceData[p++];
|
||||
info.palette[n][2] = sourceData[p++];
|
||||
}
|
||||
}
|
||||
|
||||
if(fourCC == (unsigned)FourCC::IDAT) {
|
||||
compressedData = (uint8_t*)realloc(compressedData, compressedSize + length);
|
||||
if(fourCC == (uint)FourCC::IDAT) {
|
||||
compressedData = (uint8*)realloc(compressedData, compressedSize + length);
|
||||
memcpy(compressedData + compressedSize, sourceData + offset + 8, length);
|
||||
compressedSize += length;
|
||||
}
|
||||
|
||||
if(fourCC == (unsigned)FourCC::IEND) {
|
||||
if(fourCC == (uint)FourCC::IEND) {
|
||||
break;
|
||||
}
|
||||
|
||||
offset += 4 + 4 + length + 4;
|
||||
}
|
||||
|
||||
unsigned interlacedSize = inflateSize();
|
||||
uint8_t *interlacedData = new uint8_t[interlacedSize];
|
||||
uint interlacedSize = inflateSize();
|
||||
uint8 *interlacedData = new uint8[interlacedSize];
|
||||
|
||||
bool result = inflate(interlacedData, interlacedSize, compressedData + 2, compressedSize - 6);
|
||||
free(compressedData);
|
||||
@@ -142,7 +150,7 @@ bool PNG::load(const uint8_t* sourceData, unsigned sourceSize) {
|
||||
}
|
||||
|
||||
size = info.width * info.height * info.bytesPerPixel;
|
||||
data = new uint8_t[size];
|
||||
data = new uint8[size];
|
||||
|
||||
if(info.interlaceMethod == 0) {
|
||||
if(filter(data, interlacedData, info.width, info.height) == false) {
|
||||
@@ -152,8 +160,8 @@ bool PNG::load(const uint8_t* sourceData, unsigned sourceSize) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
const uint8_t *passData = interlacedData;
|
||||
for(unsigned pass = 0; pass < 7; pass++) {
|
||||
const uint8* passData = interlacedData;
|
||||
for(uint pass = 0; pass < 7; pass++) {
|
||||
if(deinterlace(passData, pass) == false) {
|
||||
delete[] interlacedData;
|
||||
delete[] data;
|
||||
@@ -167,8 +175,8 @@ bool PNG::load(const uint8_t* sourceData, unsigned sourceSize) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned PNG::interlace(unsigned pass, unsigned index) {
|
||||
static const unsigned data[7][4] = {
|
||||
auto PNG::interlace(uint pass, uint index) -> uint {
|
||||
static const uint data[7][4] = {
|
||||
//x-distance, y-distance, x-origin, y-origin
|
||||
{8, 8, 0, 0},
|
||||
{8, 8, 4, 0},
|
||||
@@ -181,39 +189,39 @@ unsigned PNG::interlace(unsigned pass, unsigned index) {
|
||||
return data[pass][index];
|
||||
}
|
||||
|
||||
unsigned PNG::inflateSize() {
|
||||
auto PNG::inflateSize() -> uint {
|
||||
if(info.interlaceMethod == 0) {
|
||||
return info.width * info.height * info.bytesPerPixel + info.height;
|
||||
}
|
||||
|
||||
unsigned size = 0;
|
||||
for(unsigned pass = 0; pass < 7; pass++) {
|
||||
unsigned xd = interlace(pass, 0), yd = interlace(pass, 1);
|
||||
unsigned xo = interlace(pass, 2), yo = interlace(pass, 3);
|
||||
unsigned width = (info.width + (xd - xo - 1)) / xd;
|
||||
unsigned height = (info.height + (yd - yo - 1)) / yd;
|
||||
uint size = 0;
|
||||
for(uint pass = 0; pass < 7; pass++) {
|
||||
uint xd = interlace(pass, 0), yd = interlace(pass, 1);
|
||||
uint xo = interlace(pass, 2), yo = interlace(pass, 3);
|
||||
uint width = (info.width + (xd - xo - 1)) / xd;
|
||||
uint height = (info.height + (yd - yo - 1)) / yd;
|
||||
if(width == 0 || height == 0) continue;
|
||||
size += width * height * info.bytesPerPixel + height;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool PNG::deinterlace(const uint8_t*& inputData, unsigned pass) {
|
||||
unsigned xd = interlace(pass, 0), yd = interlace(pass, 1);
|
||||
unsigned xo = interlace(pass, 2), yo = interlace(pass, 3);
|
||||
unsigned width = (info.width + (xd - xo - 1)) / xd;
|
||||
unsigned height = (info.height + (yd - yo - 1)) / yd;
|
||||
auto PNG::deinterlace(const uint8*& inputData, uint pass) -> bool {
|
||||
uint xd = interlace(pass, 0), yd = interlace(pass, 1);
|
||||
uint xo = interlace(pass, 2), yo = interlace(pass, 3);
|
||||
uint width = (info.width + (xd - xo - 1)) / xd;
|
||||
uint height = (info.height + (yd - yo - 1)) / yd;
|
||||
if(width == 0 || height == 0) return true;
|
||||
|
||||
unsigned outputSize = width * height * info.bytesPerPixel;
|
||||
uint8_t* outputData = new uint8_t[outputSize];
|
||||
uint outputSize = width * height * info.bytesPerPixel;
|
||||
uint8* outputData = new uint8[outputSize];
|
||||
bool result = filter(outputData, inputData, width, height);
|
||||
|
||||
const uint8_t* rd = outputData;
|
||||
for(unsigned y = yo; y < info.height; y += yd) {
|
||||
uint8_t* wr = data + y * info.pitch;
|
||||
for(unsigned x = xo; x < info.width; x += xd) {
|
||||
for(unsigned b = 0; b < info.bytesPerPixel; b++) {
|
||||
const uint8* rd = outputData;
|
||||
for(uint y = yo; y < info.height; y += yd) {
|
||||
uint8* wr = data + y * info.pitch;
|
||||
for(uint x = xo; x < info.width; x += xd) {
|
||||
for(uint b = 0; b < info.bytesPerPixel; b++) {
|
||||
wr[x * info.bytesPerPixel + b] = *rd++;
|
||||
}
|
||||
}
|
||||
@@ -224,12 +232,12 @@ bool PNG::deinterlace(const uint8_t*& inputData, unsigned pass) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PNG::filter(uint8_t* outputData, const uint8_t* inputData, unsigned width, unsigned height) {
|
||||
uint8_t* wr = outputData;
|
||||
const uint8_t* rd = inputData;
|
||||
auto PNG::filter(uint8* outputData, const uint8* inputData, uint width, uint height) -> bool {
|
||||
uint8* wr = outputData;
|
||||
const uint8* rd = inputData;
|
||||
int bpp = info.bytesPerPixel, pitch = width * bpp;
|
||||
for(int y = 0; y < height; y++) {
|
||||
uint8_t filter = *rd++;
|
||||
uint8 filter = *rd++;
|
||||
|
||||
switch(filter) {
|
||||
case 0x00: //None
|
||||
@@ -255,7 +263,7 @@ bool PNG::filter(uint8_t* outputData, const uint8_t* inputData, unsigned width,
|
||||
short a = x - bpp < 0 ? 0 : wr[x - bpp];
|
||||
short b = y - 1 < 0 ? 0 : wr[x - pitch];
|
||||
|
||||
wr[x] = rd[x] + (uint8_t)((a + b) / 2);
|
||||
wr[x] = rd[x] + (uint8)((a + b) / 2);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -270,7 +278,7 @@ bool PNG::filter(uint8_t* outputData, const uint8_t* inputData, unsigned width,
|
||||
short pb = p > b ? p - b : b - p;
|
||||
short pc = p > c ? p - c : c - p;
|
||||
|
||||
uint8_t paeth = (uint8_t)((pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c);
|
||||
uint8 paeth = (uint8)((pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c);
|
||||
|
||||
wr[x] = rd[x] + paeth;
|
||||
}
|
||||
@@ -287,14 +295,14 @@ bool PNG::filter(uint8_t* outputData, const uint8_t* inputData, unsigned width,
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned PNG::read(const uint8_t* data, unsigned length) {
|
||||
unsigned result = 0;
|
||||
auto PNG::read(const uint8* data, uint length) -> uint {
|
||||
uint result = 0;
|
||||
while(length--) result = (result << 8) | (*data++);
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned PNG::readbits(const uint8_t*& data) {
|
||||
unsigned result = 0;
|
||||
auto PNG::readbits(const uint8*& data) -> uint {
|
||||
uint result = 0;
|
||||
switch(info.bitDepth) {
|
||||
case 1:
|
||||
result = (*data >> bitpos) & 1;
|
||||
@@ -322,13 +330,6 @@ unsigned PNG::readbits(const uint8_t*& data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
PNG::PNG() {
|
||||
}
|
||||
|
||||
PNG::~PNG() {
|
||||
if(data) delete[] data;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
@@ -11,14 +11,18 @@ namespace nall { namespace Decode {
|
||||
struct ZIP {
|
||||
struct File {
|
||||
string name;
|
||||
const uint8_t* data;
|
||||
unsigned size;
|
||||
unsigned csize;
|
||||
unsigned cmode; //0 = uncompressed, 8 = deflate
|
||||
unsigned crc32;
|
||||
const uint8* data;
|
||||
uint size;
|
||||
uint csize;
|
||||
uint cmode; //0 = uncompressed, 8 = deflate
|
||||
uint crc32;
|
||||
};
|
||||
|
||||
inline bool open(const string& filename) {
|
||||
~ZIP() {
|
||||
close();
|
||||
}
|
||||
|
||||
auto open(const string& filename) -> bool {
|
||||
close();
|
||||
if(fm.open(filename, filemap::mode::read) == false) return false;
|
||||
if(open(fm.data(), fm.size()) == false) {
|
||||
@@ -28,7 +32,7 @@ struct ZIP {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool open(const uint8_t* data, unsigned size) {
|
||||
auto open(const uint8* data, uint size) -> bool {
|
||||
if(size < 22) return false;
|
||||
|
||||
filedata = data;
|
||||
@@ -36,19 +40,19 @@ struct ZIP {
|
||||
|
||||
file.reset();
|
||||
|
||||
const uint8_t* footer = data + size - 22;
|
||||
const uint8* footer = data + size - 22;
|
||||
while(true) {
|
||||
if(footer <= data + 22) return false;
|
||||
if(read(footer, 4) == 0x06054b50) {
|
||||
unsigned commentlength = read(footer + 20, 2);
|
||||
uint commentlength = read(footer + 20, 2);
|
||||
if(footer + 22 + commentlength == data + size) break;
|
||||
}
|
||||
footer--;
|
||||
}
|
||||
const uint8_t* directory = data + read(footer + 16, 4);
|
||||
const uint8* directory = data + read(footer + 16, 4);
|
||||
|
||||
while(true) {
|
||||
unsigned signature = read(directory + 0, 4);
|
||||
uint signature = read(directory + 0, 4);
|
||||
if(signature != 0x02014b50) break;
|
||||
|
||||
File file;
|
||||
@@ -57,9 +61,9 @@ struct ZIP {
|
||||
file.csize = read(directory + 20, 4);
|
||||
file.size = read(directory + 24, 4);
|
||||
|
||||
unsigned namelength = read(directory + 28, 2);
|
||||
unsigned extralength = read(directory + 30, 2);
|
||||
unsigned commentlength = read(directory + 32, 2);
|
||||
uint namelength = read(directory + 28, 2);
|
||||
uint extralength = read(directory + 30, 2);
|
||||
uint commentlength = read(directory + 32, 2);
|
||||
|
||||
char* filename = new char[namelength + 1];
|
||||
memcpy(filename, directory + 46, namelength);
|
||||
@@ -67,9 +71,9 @@ struct ZIP {
|
||||
file.name = filename;
|
||||
delete[] filename;
|
||||
|
||||
unsigned offset = read(directory + 42, 4);
|
||||
unsigned offsetNL = read(data + offset + 26, 2);
|
||||
unsigned offsetEL = read(data + offset + 28, 2);
|
||||
uint offset = read(directory + 42, 4);
|
||||
uint offsetNL = read(data + offset + 26, 2);
|
||||
uint offsetEL = read(data + offset + 28, 2);
|
||||
file.data = data + offset + 30 + offsetNL + offsetEL;
|
||||
|
||||
directory += 46 + namelength + extralength + commentlength;
|
||||
@@ -80,8 +84,8 @@ struct ZIP {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline vector<uint8_t> extract(File& file) {
|
||||
vector<uint8_t> buffer;
|
||||
auto extract(File& file) -> vector<uint8> {
|
||||
vector<uint8> buffer;
|
||||
|
||||
if(file.cmode == 0) {
|
||||
buffer.resize(file.size);
|
||||
@@ -98,21 +102,17 @@ struct ZIP {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline void close() {
|
||||
auto close() -> void {
|
||||
if(fm.open()) fm.close();
|
||||
}
|
||||
|
||||
~ZIP() {
|
||||
close();
|
||||
}
|
||||
|
||||
protected:
|
||||
filemap fm;
|
||||
const uint8_t* filedata;
|
||||
unsigned filesize;
|
||||
const uint8* filedata;
|
||||
uint filesize;
|
||||
|
||||
unsigned read(const uint8_t* data, unsigned size) {
|
||||
unsigned result = 0, shift = 0;
|
||||
auto read(const uint8* data, uint size) -> uint {
|
||||
uint result = 0, shift = 0;
|
||||
while(size--) { result |= *data++ << shift; shift += 8; }
|
||||
return result;
|
||||
}
|
||||
|
Reference in New Issue
Block a user