mirror of
https://github.com/QuasarApp/zip.git
synced 2025-04-28 13:24:33 +00:00
API to set custom global CRC-32 function (#191)
* API to set custom global CRC-32 function
This commit is contained in:
parent
f02a47dee0
commit
de71d577e0
15
README.md
15
README.md
@ -245,7 +245,7 @@ void zip_walk(struct zip_t *zip, const char *path) {
|
||||
}
|
||||
```
|
||||
|
||||
* Deletes zip archive entries.
|
||||
* Delete zip archive entries.
|
||||
```c
|
||||
char *entries[] = {"unused.txt", "remove.ini", "delete.me"};
|
||||
|
||||
@ -256,6 +256,19 @@ struct zip_t *zip = zip_open("foo.zip", 0, 'd');
|
||||
zip_close(zip);
|
||||
```
|
||||
|
||||
* Use custom CRC-32 function.
|
||||
```c
|
||||
unsigned long my_crc32(unsigned long crc, const void *buf, size_t bufsize) {
|
||||
uint32_t c = crc32_16bytes_prefetch(buf, bufsize, (uint32_t)crc);
|
||||
return (unsigned long)c;
|
||||
}
|
||||
|
||||
//...
|
||||
zip_crc32_func(my_crc32);
|
||||
|
||||
zip_extract("foo.zip", "/tmp", NULL, NULL);
|
||||
```
|
||||
|
||||
# Bindings
|
||||
Compile zip library as a dynamic library.
|
||||
```shell
|
||||
|
205
src/miniz.h
205
src/miniz.h
@ -345,7 +345,7 @@ mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
|
||||
#define MZ_CRC32_INIT (0)
|
||||
// mz_crc32() returns the initial CRC-32 value to use when called with
|
||||
// ptr==NULL.
|
||||
mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
|
||||
mz_ulong mz_crc32(mz_ulong crc, const void *ptr, size_t buf_len);
|
||||
|
||||
// Compression strategies.
|
||||
enum {
|
||||
@ -781,7 +781,6 @@ typedef struct {
|
||||
void *m_pIO_opaque;
|
||||
|
||||
mz_zip_internal_state *m_pState;
|
||||
|
||||
} mz_zip_archive;
|
||||
|
||||
typedef enum {
|
||||
@ -1166,26 +1165,6 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len,
|
||||
const void *pSrc_buf, size_t src_buf_len,
|
||||
int flags);
|
||||
|
||||
// Compresses an image to a compressed PNG file in memory.
|
||||
// On entry:
|
||||
// pImage, w, h, and num_chans describe the image to compress. num_chans may be
|
||||
// 1, 2, 3, or 4. The image pitch in bytes per scanline will be w*num_chans.
|
||||
// The leftmost pixel on the top scanline is stored first in memory. level may
|
||||
// range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED,
|
||||
// MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL If flip is
|
||||
// true, the image will be flipped on the Y axis (useful for OpenGL apps).
|
||||
// On return:
|
||||
// Function returns a pointer to the compressed data, or NULL on failure.
|
||||
// *pLen_out will be set to the size of the PNG image file.
|
||||
// The caller must mz_free() the returned heap block (which will typically be
|
||||
// larger than *pLen_out) when it's no longer needed.
|
||||
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w,
|
||||
int h, int num_chans,
|
||||
size_t *pLen_out,
|
||||
mz_uint level, mz_bool flip);
|
||||
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||
int num_chans, size_t *pLen_out);
|
||||
|
||||
// Output stream interface. The compressor uses this interface to write
|
||||
// compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
|
||||
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len,
|
||||
@ -1417,11 +1396,12 @@ mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) {
|
||||
// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C
|
||||
// implementation that balances processor cache usage against speed":
|
||||
// http://www.geocities.com/malbrain/
|
||||
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) {
|
||||
mz_ulong mz_crc32(mz_ulong crc, const void *buf, size_t buf_len) {
|
||||
static const mz_uint32 s_crc32[16] = {
|
||||
0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4,
|
||||
0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c};
|
||||
const mz_uint8 *ptr = (const mz_uint8 *)buf;
|
||||
mz_uint32 crcu32 = (mz_uint32)crc;
|
||||
if (!ptr)
|
||||
return MZ_CRC32_INIT;
|
||||
@ -1434,6 +1414,10 @@ mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) {
|
||||
return ~crcu32;
|
||||
}
|
||||
|
||||
typedef mz_ulong (*mz_crc32_func)(mz_ulong, const void *, size_t);
|
||||
|
||||
static volatile mz_crc32_func def_crc32_func = mz_crc32;
|
||||
|
||||
void mz_free(void *p) { MZ_FREE(p); }
|
||||
|
||||
#ifndef MINIZ_NO_ZLIB_APIS
|
||||
@ -2816,8 +2800,9 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num,
|
||||
{ \
|
||||
if (rle_repeat_count) { \
|
||||
if (rle_repeat_count < 3) { \
|
||||
d->m_huff_count[2][prev_code_size] = (mz_uint16)( \
|
||||
d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
|
||||
d->m_huff_count[2][prev_code_size] = \
|
||||
(mz_uint16)(d->m_huff_count[2][prev_code_size] + \
|
||||
rle_repeat_count); \
|
||||
while (rle_repeat_count--) \
|
||||
packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
|
||||
} else { \
|
||||
@ -3400,12 +3385,13 @@ static mz_bool tdefl_compress_fast(tdefl_compressor *d) {
|
||||
|
||||
if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <=
|
||||
dict_size) &&
|
||||
((mz_uint32)(
|
||||
*(d->m_dict + (probe_pos & TDEFL_LZ_DICT_SIZE_MASK)) |
|
||||
(*(d->m_dict + ((probe_pos & TDEFL_LZ_DICT_SIZE_MASK) + 1))
|
||||
<< 8) |
|
||||
(*(d->m_dict + ((probe_pos & TDEFL_LZ_DICT_SIZE_MASK) + 2))
|
||||
<< 16)) == first_trigram)) {
|
||||
((mz_uint32)(*(d->m_dict + (probe_pos & TDEFL_LZ_DICT_SIZE_MASK)) |
|
||||
(*(d->m_dict +
|
||||
((probe_pos & TDEFL_LZ_DICT_SIZE_MASK) + 1))
|
||||
<< 8) |
|
||||
(*(d->m_dict +
|
||||
((probe_pos & TDEFL_LZ_DICT_SIZE_MASK) + 2))
|
||||
<< 16)) == first_trigram)) {
|
||||
const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
|
||||
const mz_uint16 *q =
|
||||
(const mz_uint16 *)(d->m_dict +
|
||||
@ -3976,129 +3962,6 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits,
|
||||
// C and C99, so no big deal)
|
||||
#endif
|
||||
|
||||
// Simple PNG writer function by Alex Evans, 2011. Released into the public
|
||||
// domain: https://gist.github.com/908299, more context at
|
||||
// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
|
||||
// This is actually a modification of Alex's original code so PNG files
|
||||
// generated by this function pass pngcheck.
|
||||
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w,
|
||||
int h, int num_chans,
|
||||
size_t *pLen_out,
|
||||
mz_uint level, mz_bool flip) {
|
||||
// Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was
|
||||
// defined.
|
||||
static const mz_uint s_tdefl_png_num_probes[11] = {
|
||||
0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500};
|
||||
tdefl_compressor *pComp =
|
||||
(tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
|
||||
tdefl_output_buffer out_buf;
|
||||
int i, bpl = w * num_chans, y, z;
|
||||
mz_uint32 c;
|
||||
*pLen_out = 0;
|
||||
if (!pComp)
|
||||
return NULL;
|
||||
MZ_CLEAR_OBJ(out_buf);
|
||||
out_buf.m_expandable = MZ_TRUE;
|
||||
out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
|
||||
if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) {
|
||||
MZ_FREE(pComp);
|
||||
return NULL;
|
||||
}
|
||||
// write dummy header
|
||||
for (z = 41; z; --z)
|
||||
tdefl_output_buffer_putter(&z, 1, &out_buf);
|
||||
// compress image data
|
||||
tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf,
|
||||
s_tdefl_png_num_probes[MZ_MIN(10, level)] |
|
||||
TDEFL_WRITE_ZLIB_HEADER);
|
||||
for (y = 0; y < h; ++y) {
|
||||
tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
|
||||
tdefl_compress_buffer(pComp,
|
||||
(mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl,
|
||||
bpl, TDEFL_NO_FLUSH);
|
||||
}
|
||||
if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) !=
|
||||
TDEFL_STATUS_DONE) {
|
||||
MZ_FREE(pComp);
|
||||
MZ_FREE(out_buf.m_pBuf);
|
||||
return NULL;
|
||||
}
|
||||
// write real header
|
||||
*pLen_out = out_buf.m_size - 41;
|
||||
{
|
||||
static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06};
|
||||
mz_uint8 pnghdr[41] = {0x89,
|
||||
0x50,
|
||||
0x4e,
|
||||
0x47,
|
||||
0x0d,
|
||||
0x0a,
|
||||
0x1a,
|
||||
0x0a,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x0d,
|
||||
0x49,
|
||||
0x48,
|
||||
0x44,
|
||||
0x52,
|
||||
0,
|
||||
0,
|
||||
(mz_uint8)(w >> 8),
|
||||
(mz_uint8)w,
|
||||
0,
|
||||
0,
|
||||
(mz_uint8)(h >> 8),
|
||||
(mz_uint8)h,
|
||||
8,
|
||||
chans[num_chans],
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
(mz_uint8)(*pLen_out >> 24),
|
||||
(mz_uint8)(*pLen_out >> 16),
|
||||
(mz_uint8)(*pLen_out >> 8),
|
||||
(mz_uint8)*pLen_out,
|
||||
0x49,
|
||||
0x44,
|
||||
0x41,
|
||||
0x54};
|
||||
c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
|
||||
for (i = 0; i < 4; ++i, c <<= 8)
|
||||
((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
|
||||
memcpy(out_buf.m_pBuf, pnghdr, 41);
|
||||
}
|
||||
// write footer (IDAT CRC-32, followed by IEND chunk)
|
||||
if (!tdefl_output_buffer_putter(
|
||||
"\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) {
|
||||
*pLen_out = 0;
|
||||
MZ_FREE(pComp);
|
||||
MZ_FREE(out_buf.m_pBuf);
|
||||
return NULL;
|
||||
}
|
||||
c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4,
|
||||
*pLen_out + 4);
|
||||
for (i = 0; i < 4; ++i, c <<= 8)
|
||||
(out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
|
||||
// compute final size of file, grab compressed data buffer and return
|
||||
*pLen_out += 57;
|
||||
MZ_FREE(pComp);
|
||||
return out_buf.m_pBuf;
|
||||
}
|
||||
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||
int num_chans, size_t *pLen_out) {
|
||||
// Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we
|
||||
// can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's
|
||||
// where #defined out)
|
||||
return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans,
|
||||
pLen_out, 6, MZ_FALSE);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
@ -4119,7 +3982,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||
|
||||
static wchar_t *str2wstr(const char *str) {
|
||||
int len = strlen(str) + 1;
|
||||
wchar_t *wstr = (wchar_t*)malloc(len * sizeof(wchar_t));
|
||||
wchar_t *wstr = (wchar_t *)malloc(len * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, str, len * sizeof(char), wstr, len);
|
||||
return wstr;
|
||||
}
|
||||
@ -5359,8 +5222,9 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
|
||||
(size_t)needed_size) != needed_size)
|
||||
return MZ_FALSE;
|
||||
return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) ||
|
||||
(mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf,
|
||||
(size_t)file_stat.m_uncomp_size) == file_stat.m_crc32);
|
||||
(def_crc32_func(MZ_CRC32_INIT, pBuf,
|
||||
(size_t)file_stat.m_uncomp_size) ==
|
||||
file_stat.m_crc32);
|
||||
}
|
||||
|
||||
// Decompress the file either directly from memory or from a file input
|
||||
@ -5421,8 +5285,8 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
|
||||
if (status == TINFL_STATUS_DONE) {
|
||||
// Make sure the entire file was decompressed, and check its CRC.
|
||||
if ((out_buf_ofs != file_stat.m_uncomp_size) ||
|
||||
(mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf,
|
||||
(size_t)file_stat.m_uncomp_size) != file_stat.m_crc32))
|
||||
(def_crc32_func(MZ_CRC32_INIT, pBuf, (size_t)file_stat.m_uncomp_size) !=
|
||||
file_stat.m_crc32))
|
||||
status = TINFL_STATUS_FAILED;
|
||||
}
|
||||
|
||||
@ -5582,9 +5446,8 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
|
||||
(size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
|
||||
status = TINFL_STATUS_FAILED;
|
||||
else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
file_crc32 =
|
||||
(mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf,
|
||||
(size_t)file_stat.m_comp_size);
|
||||
file_crc32 = (mz_uint32)def_crc32_func(file_crc32, pRead_buf,
|
||||
(size_t)file_stat.m_comp_size);
|
||||
// cur_file_ofs += file_stat.m_comp_size;
|
||||
out_buf_ofs += file_stat.m_comp_size;
|
||||
// comp_remaining = 0;
|
||||
@ -5598,7 +5461,7 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
|
||||
}
|
||||
|
||||
if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
file_crc32 = (mz_uint32)mz_crc32(
|
||||
file_crc32 = (mz_uint32)def_crc32_func(
|
||||
file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
|
||||
|
||||
if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
|
||||
@ -5651,8 +5514,8 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
|
||||
status = TINFL_STATUS_FAILED;
|
||||
break;
|
||||
}
|
||||
file_crc32 =
|
||||
(mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
|
||||
file_crc32 = (mz_uint32)def_crc32_func(
|
||||
file_crc32, (const void *)pWrite_buf_cur, out_buf_size);
|
||||
if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) {
|
||||
status = TINFL_STATUS_FAILED;
|
||||
break;
|
||||
@ -6220,8 +6083,8 @@ mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip,
|
||||
cur_archive_file_ofs += archive_name_size;
|
||||
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) {
|
||||
uncomp_crc32 =
|
||||
(mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
|
||||
uncomp_crc32 = (mz_uint32)def_crc32_func(MZ_CRC32_INIT,
|
||||
(const mz_uint8 *)pBuf, buf_size);
|
||||
uncomp_size = buf_size;
|
||||
if (uncomp_size <= 3) {
|
||||
level = 0;
|
||||
@ -6402,8 +6265,8 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
|
||||
MZ_FCLOSE(pSrc_file);
|
||||
return MZ_FALSE;
|
||||
}
|
||||
uncomp_crc32 =
|
||||
(mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
|
||||
uncomp_crc32 = (mz_uint32)def_crc32_func(
|
||||
uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
|
||||
uncomp_remaining -= n;
|
||||
cur_archive_file_ofs += n;
|
||||
}
|
||||
@ -6441,8 +6304,8 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
|
||||
if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
|
||||
break;
|
||||
|
||||
uncomp_crc32 = (mz_uint32)mz_crc32(
|
||||
uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
|
||||
uncomp_crc32 =
|
||||
(mz_uint32)def_crc32_func(uncomp_crc32, pRead_buf, in_buf_size);
|
||||
uncomp_remaining -= in_buf_size;
|
||||
|
||||
status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size,
|
||||
|
12
src/zip.c
12
src/zip.c
@ -1219,8 +1219,8 @@ int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) {
|
||||
pzip = &(zip->archive);
|
||||
if (buf && bufsize > 0) {
|
||||
zip->entry.uncomp_size += bufsize;
|
||||
zip->entry.uncomp_crc32 = (mz_uint32)mz_crc32(
|
||||
zip->entry.uncomp_crc32, (const mz_uint8 *)buf, bufsize);
|
||||
zip->entry.uncomp_crc32 =
|
||||
(mz_uint32)def_crc32_func(zip->entry.uncomp_crc32, buf, bufsize);
|
||||
|
||||
level = zip->level & 0xF;
|
||||
if (!level) {
|
||||
@ -1620,3 +1620,11 @@ int zip_extract(const char *zipname, const char *dir,
|
||||
|
||||
return zip_archive_extract(&zip_archive, dir, on_extract, arg);
|
||||
}
|
||||
|
||||
void zip_crc32_func(unsigned long (*crc32_func)(unsigned long crc,
|
||||
const void *buf,
|
||||
size_t bufsize)) {
|
||||
if (crc32_func) {
|
||||
def_crc32_func = crc32_func;
|
||||
}
|
||||
}
|
||||
|
32
src/zip.h
32
src/zip.h
@ -16,17 +16,17 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef ZIP_SHARED
|
||||
# define ZIP_EXPORT
|
||||
#define ZIP_EXPORT
|
||||
#else
|
||||
# ifdef _WIN32
|
||||
# ifdef ZIP_BUILD_SHARED
|
||||
# define ZIP_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define ZIP_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define ZIP_EXPORT __attribute__ ((visibility ("default")))
|
||||
# endif
|
||||
#ifdef _WIN32
|
||||
#ifdef ZIP_BUILD_SHARED
|
||||
#define ZIP_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define ZIP_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define ZIP_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -286,7 +286,8 @@ extern ZIP_EXPORT ssize_t zip_entry_read(struct zip_t *zip, void **buf,
|
||||
* For large entries, please take a look at zip_entry_extract function.
|
||||
*
|
||||
* @return the return code - the number of bytes actually read on success.
|
||||
* Otherwise a negative number (< 0) on error (e.g. bufsize is not large enough).
|
||||
* Otherwise a negative number (< 0) on error (e.g. bufsize is not large
|
||||
* enough).
|
||||
*/
|
||||
extern ZIP_EXPORT ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf,
|
||||
size_t bufsize);
|
||||
@ -425,6 +426,15 @@ extern ZIP_EXPORT int zip_extract(const char *zipname, const char *dir,
|
||||
void *arg),
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* Sets global CRC-32 checksum function.
|
||||
*
|
||||
* @param crc32_func crc32 function (init value, buffer, buffer size)
|
||||
*/
|
||||
extern ZIP_EXPORT void
|
||||
zip_crc32_func(unsigned long (*crc32_func)(unsigned long crc, const void *buf,
|
||||
size_t bufsize));
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user