annotate src/zlib-1.2.7/contrib/minizip/mztools.c @ 4:e13257ea84a4

Add bzip2, zlib, liblo, portaudio sources
author Chris Cannam
date Wed, 20 Mar 2013 13:59:52 +0000
parents
children
rev   line source
Chris@4 1 /*
Chris@4 2 Additional tools for Minizip
Chris@4 3 Code: Xavier Roche '2004
Chris@4 4 License: Same as ZLIB (www.gzip.org)
Chris@4 5 */
Chris@4 6
Chris@4 7 /* Code */
Chris@4 8 #include <stdio.h>
Chris@4 9 #include <stdlib.h>
Chris@4 10 #include <string.h>
Chris@4 11 #include "zlib.h"
Chris@4 12 #include "unzip.h"
Chris@4 13
Chris@4 14 #define READ_8(adr) ((unsigned char)*(adr))
Chris@4 15 #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
Chris@4 16 #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
Chris@4 17
Chris@4 18 #define WRITE_8(buff, n) do { \
Chris@4 19 *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
Chris@4 20 } while(0)
Chris@4 21 #define WRITE_16(buff, n) do { \
Chris@4 22 WRITE_8((unsigned char*)(buff), n); \
Chris@4 23 WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
Chris@4 24 } while(0)
Chris@4 25 #define WRITE_32(buff, n) do { \
Chris@4 26 WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
Chris@4 27 WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
Chris@4 28 } while(0)
Chris@4 29
Chris@4 30 extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
Chris@4 31 const char* file;
Chris@4 32 const char* fileOut;
Chris@4 33 const char* fileOutTmp;
Chris@4 34 uLong* nRecovered;
Chris@4 35 uLong* bytesRecovered;
Chris@4 36 {
Chris@4 37 int err = Z_OK;
Chris@4 38 FILE* fpZip = fopen(file, "rb");
Chris@4 39 FILE* fpOut = fopen(fileOut, "wb");
Chris@4 40 FILE* fpOutCD = fopen(fileOutTmp, "wb");
Chris@4 41 if (fpZip != NULL && fpOut != NULL) {
Chris@4 42 int entries = 0;
Chris@4 43 uLong totalBytes = 0;
Chris@4 44 char header[30];
Chris@4 45 char filename[1024];
Chris@4 46 char extra[1024];
Chris@4 47 int offset = 0;
Chris@4 48 int offsetCD = 0;
Chris@4 49 while ( fread(header, 1, 30, fpZip) == 30 ) {
Chris@4 50 int currentOffset = offset;
Chris@4 51
Chris@4 52 /* File entry */
Chris@4 53 if (READ_32(header) == 0x04034b50) {
Chris@4 54 unsigned int version = READ_16(header + 4);
Chris@4 55 unsigned int gpflag = READ_16(header + 6);
Chris@4 56 unsigned int method = READ_16(header + 8);
Chris@4 57 unsigned int filetime = READ_16(header + 10);
Chris@4 58 unsigned int filedate = READ_16(header + 12);
Chris@4 59 unsigned int crc = READ_32(header + 14); /* crc */
Chris@4 60 unsigned int cpsize = READ_32(header + 18); /* compressed size */
Chris@4 61 unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
Chris@4 62 unsigned int fnsize = READ_16(header + 26); /* file name length */
Chris@4 63 unsigned int extsize = READ_16(header + 28); /* extra field length */
Chris@4 64 filename[0] = extra[0] = '\0';
Chris@4 65
Chris@4 66 /* Header */
Chris@4 67 if (fwrite(header, 1, 30, fpOut) == 30) {
Chris@4 68 offset += 30;
Chris@4 69 } else {
Chris@4 70 err = Z_ERRNO;
Chris@4 71 break;
Chris@4 72 }
Chris@4 73
Chris@4 74 /* Filename */
Chris@4 75 if (fnsize > 0) {
Chris@4 76 if (fnsize < sizeof(filename)) {
Chris@4 77 if (fread(filename, 1, fnsize, fpZip) == fnsize) {
Chris@4 78 if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
Chris@4 79 offset += fnsize;
Chris@4 80 } else {
Chris@4 81 err = Z_ERRNO;
Chris@4 82 break;
Chris@4 83 }
Chris@4 84 } else {
Chris@4 85 err = Z_ERRNO;
Chris@4 86 break;
Chris@4 87 }
Chris@4 88 } else {
Chris@4 89 err = Z_ERRNO;
Chris@4 90 break;
Chris@4 91 }
Chris@4 92 } else {
Chris@4 93 err = Z_STREAM_ERROR;
Chris@4 94 break;
Chris@4 95 }
Chris@4 96
Chris@4 97 /* Extra field */
Chris@4 98 if (extsize > 0) {
Chris@4 99 if (extsize < sizeof(extra)) {
Chris@4 100 if (fread(extra, 1, extsize, fpZip) == extsize) {
Chris@4 101 if (fwrite(extra, 1, extsize, fpOut) == extsize) {
Chris@4 102 offset += extsize;
Chris@4 103 } else {
Chris@4 104 err = Z_ERRNO;
Chris@4 105 break;
Chris@4 106 }
Chris@4 107 } else {
Chris@4 108 err = Z_ERRNO;
Chris@4 109 break;
Chris@4 110 }
Chris@4 111 } else {
Chris@4 112 err = Z_ERRNO;
Chris@4 113 break;
Chris@4 114 }
Chris@4 115 }
Chris@4 116
Chris@4 117 /* Data */
Chris@4 118 {
Chris@4 119 int dataSize = cpsize;
Chris@4 120 if (dataSize == 0) {
Chris@4 121 dataSize = uncpsize;
Chris@4 122 }
Chris@4 123 if (dataSize > 0) {
Chris@4 124 char* data = malloc(dataSize);
Chris@4 125 if (data != NULL) {
Chris@4 126 if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
Chris@4 127 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
Chris@4 128 offset += dataSize;
Chris@4 129 totalBytes += dataSize;
Chris@4 130 } else {
Chris@4 131 err = Z_ERRNO;
Chris@4 132 }
Chris@4 133 } else {
Chris@4 134 err = Z_ERRNO;
Chris@4 135 }
Chris@4 136 free(data);
Chris@4 137 if (err != Z_OK) {
Chris@4 138 break;
Chris@4 139 }
Chris@4 140 } else {
Chris@4 141 err = Z_MEM_ERROR;
Chris@4 142 break;
Chris@4 143 }
Chris@4 144 }
Chris@4 145 }
Chris@4 146
Chris@4 147 /* Central directory entry */
Chris@4 148 {
Chris@4 149 char header[46];
Chris@4 150 char* comment = "";
Chris@4 151 int comsize = (int) strlen(comment);
Chris@4 152 WRITE_32(header, 0x02014b50);
Chris@4 153 WRITE_16(header + 4, version);
Chris@4 154 WRITE_16(header + 6, version);
Chris@4 155 WRITE_16(header + 8, gpflag);
Chris@4 156 WRITE_16(header + 10, method);
Chris@4 157 WRITE_16(header + 12, filetime);
Chris@4 158 WRITE_16(header + 14, filedate);
Chris@4 159 WRITE_32(header + 16, crc);
Chris@4 160 WRITE_32(header + 20, cpsize);
Chris@4 161 WRITE_32(header + 24, uncpsize);
Chris@4 162 WRITE_16(header + 28, fnsize);
Chris@4 163 WRITE_16(header + 30, extsize);
Chris@4 164 WRITE_16(header + 32, comsize);
Chris@4 165 WRITE_16(header + 34, 0); /* disk # */
Chris@4 166 WRITE_16(header + 36, 0); /* int attrb */
Chris@4 167 WRITE_32(header + 38, 0); /* ext attrb */
Chris@4 168 WRITE_32(header + 42, currentOffset);
Chris@4 169 /* Header */
Chris@4 170 if (fwrite(header, 1, 46, fpOutCD) == 46) {
Chris@4 171 offsetCD += 46;
Chris@4 172
Chris@4 173 /* Filename */
Chris@4 174 if (fnsize > 0) {
Chris@4 175 if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
Chris@4 176 offsetCD += fnsize;
Chris@4 177 } else {
Chris@4 178 err = Z_ERRNO;
Chris@4 179 break;
Chris@4 180 }
Chris@4 181 } else {
Chris@4 182 err = Z_STREAM_ERROR;
Chris@4 183 break;
Chris@4 184 }
Chris@4 185
Chris@4 186 /* Extra field */
Chris@4 187 if (extsize > 0) {
Chris@4 188 if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
Chris@4 189 offsetCD += extsize;
Chris@4 190 } else {
Chris@4 191 err = Z_ERRNO;
Chris@4 192 break;
Chris@4 193 }
Chris@4 194 }
Chris@4 195
Chris@4 196 /* Comment field */
Chris@4 197 if (comsize > 0) {
Chris@4 198 if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
Chris@4 199 offsetCD += comsize;
Chris@4 200 } else {
Chris@4 201 err = Z_ERRNO;
Chris@4 202 break;
Chris@4 203 }
Chris@4 204 }
Chris@4 205
Chris@4 206
Chris@4 207 } else {
Chris@4 208 err = Z_ERRNO;
Chris@4 209 break;
Chris@4 210 }
Chris@4 211 }
Chris@4 212
Chris@4 213 /* Success */
Chris@4 214 entries++;
Chris@4 215
Chris@4 216 } else {
Chris@4 217 break;
Chris@4 218 }
Chris@4 219 }
Chris@4 220
Chris@4 221 /* Final central directory */
Chris@4 222 {
Chris@4 223 int entriesZip = entries;
Chris@4 224 char header[22];
Chris@4 225 char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
Chris@4 226 int comsize = (int) strlen(comment);
Chris@4 227 if (entriesZip > 0xffff) {
Chris@4 228 entriesZip = 0xffff;
Chris@4 229 }
Chris@4 230 WRITE_32(header, 0x06054b50);
Chris@4 231 WRITE_16(header + 4, 0); /* disk # */
Chris@4 232 WRITE_16(header + 6, 0); /* disk # */
Chris@4 233 WRITE_16(header + 8, entriesZip); /* hack */
Chris@4 234 WRITE_16(header + 10, entriesZip); /* hack */
Chris@4 235 WRITE_32(header + 12, offsetCD); /* size of CD */
Chris@4 236 WRITE_32(header + 16, offset); /* offset to CD */
Chris@4 237 WRITE_16(header + 20, comsize); /* comment */
Chris@4 238
Chris@4 239 /* Header */
Chris@4 240 if (fwrite(header, 1, 22, fpOutCD) == 22) {
Chris@4 241
Chris@4 242 /* Comment field */
Chris@4 243 if (comsize > 0) {
Chris@4 244 if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
Chris@4 245 err = Z_ERRNO;
Chris@4 246 }
Chris@4 247 }
Chris@4 248
Chris@4 249 } else {
Chris@4 250 err = Z_ERRNO;
Chris@4 251 }
Chris@4 252 }
Chris@4 253
Chris@4 254 /* Final merge (file + central directory) */
Chris@4 255 fclose(fpOutCD);
Chris@4 256 if (err == Z_OK) {
Chris@4 257 fpOutCD = fopen(fileOutTmp, "rb");
Chris@4 258 if (fpOutCD != NULL) {
Chris@4 259 int nRead;
Chris@4 260 char buffer[8192];
Chris@4 261 while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
Chris@4 262 if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
Chris@4 263 err = Z_ERRNO;
Chris@4 264 break;
Chris@4 265 }
Chris@4 266 }
Chris@4 267 fclose(fpOutCD);
Chris@4 268 }
Chris@4 269 }
Chris@4 270
Chris@4 271 /* Close */
Chris@4 272 fclose(fpZip);
Chris@4 273 fclose(fpOut);
Chris@4 274
Chris@4 275 /* Wipe temporary file */
Chris@4 276 (void)remove(fileOutTmp);
Chris@4 277
Chris@4 278 /* Number of recovered entries */
Chris@4 279 if (err == Z_OK) {
Chris@4 280 if (nRecovered != NULL) {
Chris@4 281 *nRecovered = entries;
Chris@4 282 }
Chris@4 283 if (bytesRecovered != NULL) {
Chris@4 284 *bytesRecovered = totalBytes;
Chris@4 285 }
Chris@4 286 }
Chris@4 287 } else {
Chris@4 288 err = Z_STREAM_ERROR;
Chris@4 289 }
Chris@4 290 return err;
Chris@4 291 }