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
);