3 // This is here to simplify interfacing to zlib, as zlib does NO zip file handling
6 // (C) 2012 Underground Software
8 // JLH = James Hammons <jlhamm@acm.org>
11 // --- ---------- -------------------------------------------------------------
12 // JLH 01/16/2010 Created this log ;-)
13 // JLH 02/28/2010 Removed unnecessary cruft
14 // JLH 05/31/2012 Rewrote everything and removed all MAME code
25 uint32_t GetLong(FILE * fp)
27 uint32_t n = ((uint32_t)fgetc(fp));
28 n |= ((uint32_t)fgetc(fp)) << 8;
29 n |= ((uint32_t)fgetc(fp)) << 16;
30 n |= ((uint32_t)fgetc(fp)) << 24;
36 uint16_t GetWord(FILE * fp)
38 uint16_t n = ((uint16_t)fgetc(fp));
39 n |= ((uint16_t)fgetc(fp)) << 8;
45 bool GetZIPHeader(FILE * fp, ZipFileEntry & ze)
47 ze.signature = GetLong(fp);
48 ze.version = GetWord(fp);
49 ze.flags = GetWord(fp);
50 ze.method = GetWord(fp);
51 ze.modifiedTime = GetWord(fp);
52 ze.modifiedDate = GetWord(fp);
53 ze.crc32 = GetLong(fp);
54 ze.compressedSize = GetLong(fp);
55 ze.uncompressedSize = GetLong(fp);
56 ze.filenameLength = GetWord(fp);
57 ze.extraLength = GetWord(fp);
59 // This handling is really ungraceful; but if someone is going to feed us
60 // shit, then why eat it? :-)
61 if (ze.filenameLength < 512)
63 fread(ze.filename, 1, ze.filenameLength, fp);
64 ze.filename[ze.filenameLength] = 0;
68 fseek(fp, ze.filenameLength, SEEK_CUR);
72 // Skip the "extra" header
73 fseek(fp, ze.extraLength, SEEK_CUR);
75 return (ze.signature == 0x04034B50 ? true : false);
80 // Uncompress a file from a ZIP file filestream
81 // NOTE: The passed in buffer *must* be fully allocated before calling this!
83 #define CHUNKSIZE 16384
84 int UncompressFileFromZIP(FILE * fp, ZipFileEntry ze, uint8_t * buffer)
87 unsigned char inBuffer[CHUNKSIZE];
88 uint32_t remaining = ze.compressedSize;
90 // Set up z_stream for inflating
97 int ret = inflateInit2(&zip, -MAX_WBITS); // -MAX_WBITS tells it there's no header
99 // Bail if can't initialize the z_stream...
103 zip.avail_out = ze.uncompressedSize;
104 zip.next_out = buffer;
106 // Decompress until deflate stream ends or we hit end of file
109 zip.avail_in = fread(inBuffer, 1, (remaining < CHUNKSIZE ? remaining : CHUNKSIZE), fp);
110 zip.next_in = inBuffer;
111 remaining -= CHUNKSIZE;
119 if (zip.avail_in == 0)
122 ret = inflate(&zip, Z_NO_FLUSH);
124 if ((ret == Z_NEED_DICT) || (ret == Z_DATA_ERROR) || (ret == Z_MEM_ERROR))
131 while (ret != Z_STREAM_END);
135 return (ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR);