Commit af20c8c87ba9b1c80ba02190393be183cf454719

Authored by Imanol-Mikel Barba Sabariego
1 parent 3f906bc9

Moved decompression function outside and changed it to work with buffers. Added compression function

compression.c 0 → 100644
  1 +#include "compression.h"
  2 +
  3 +ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData) {
  4 + unsigned int increase = compDataLen/2;
  5 + unsigned int uncompLength = compDataLen; // Later to be increased
  6 +
  7 + char* uncomp = (char*)calloc(uncompLength, sizeof(char));
  8 +
  9 + z_stream strm;
  10 + strm.next_in = (Bytef*) compData;
  11 + strm.avail_in = compDataLen;
  12 + strm.total_out = 0;
  13 + strm.zalloc = Z_NULL;
  14 + strm.zfree = Z_NULL;
  15 +
  16 + if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) {
  17 + fprintf(stderr, "Unable to initialize zlib zstream for decompression\n");
  18 + free(uncomp);
  19 + return -1;
  20 + }
  21 +
  22 + int err = Z_OK;
  23 + do {
  24 + // If our output buffer is too small
  25 + if(strm.total_out >= uncompLength ) {
  26 + // Increase size of output buffer
  27 + void* newptr = realloc(uncomp,uncompLength + increase);
  28 + if(newptr == NULL) {
  29 + fprintf(stderr,"Unable to request memory realloc\n");
  30 + inflateEnd(&strm);
  31 + free(uncomp);
  32 + return -2;
  33 + }
  34 + uncomp = newptr;
  35 + uncompLength += increase;
  36 + }
  37 +
  38 + strm.next_out = (Bytef *) (uncomp + strm.total_out);
  39 + strm.avail_out = uncompLength - strm.total_out;
  40 +
  41 + // Inflate another chunk.
  42 + err = inflate (&strm, Z_SYNC_FLUSH);
  43 + if(err != Z_OK && err != Z_STREAM_END) {
  44 + fprintf(stderr, "zlib error: %d.\n", err);
  45 + inflateEnd(&strm);
  46 + free(uncomp);
  47 + return -3;
  48 + }
  49 + } while(err != Z_STREAM_END);
  50 + uncompLength = strm.total_out;
  51 +
  52 + if(inflateEnd(&strm) != Z_OK) {
  53 + fprintf(stderr,"Error while deallocating libz zstream\n");
  54 + free(uncomp);
  55 + return -4;
  56 + }
  57 +
  58 + *unCompData = uncomp;
  59 + return uncompLength;
  60 +}
  61 +
  62 +ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData) {
  63 + unsigned int compLength = unCompDataLen;
  64 + unsigned int increase = compLength/4;
  65 + char* comp = (char*)calloc(compLength, sizeof(char));
  66 +
  67 + z_stream strm;
  68 + strm.next_in = (Bytef*) unCompData;
  69 + strm.avail_in = unCompDataLen;
  70 + strm.total_out = 0;
  71 + strm.zalloc = Z_NULL;
  72 + strm.zfree = Z_NULL;
  73 +
  74 + if(deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16+MAX_WBITS),8 , Z_DEFAULT_STRATEGY) != Z_OK) {
  75 + fprintf(stderr, "Unable to initialize zlib zstream for compression\n");
  76 + free(comp);
  77 + return -1;
  78 + }
  79 +
  80 + int err = Z_OK;
  81 + do {
  82 + // If our output buffer is too small
  83 + if (strm.total_out >= compLength) {
  84 + // Increase size of output buffer
  85 + void* newptr = realloc(comp, compLength + increase);
  86 + if(newptr == NULL) {
  87 + fprintf(stderr,"Unable to request memory realloc\n");
  88 + deflateEnd(&strm);
  89 + free(comp);
  90 + return -2;
  91 + }
  92 + comp = newptr;
  93 + compLength += increase;
  94 + }
  95 +
  96 + strm.next_out = (Bytef*) (comp + strm.total_out);
  97 + strm.avail_out = compLength - strm.total_out;
  98 +
  99 + // deflate another chunk
  100 + err = deflate(&strm, Z_FINISH);
  101 + if(err != Z_OK && err != Z_STREAM_END) {
  102 + fprintf(stderr, "Error while deflating buffer\n");
  103 + deflateEnd(&strm);
  104 + free(comp);
  105 + return -3;
  106 + }
  107 + } while(err != Z_STREAM_END);
  108 + compLength = strm.total_out;
  109 +
  110 + if(deflateEnd(&strm) != Z_OK) {
  111 + fprintf(stderr,"Error while deallocating libz zstream\n");
  112 + free(comp);
  113 + return -4;
  114 + }
  115 +
  116 + // Set OS Flag to 0x00: "FAT filesystem (MS-DOS, OS/2, NT/Win32)"
  117 + comp[OS_FLAG_OFFSET] = 0x00;
  118 +
  119 + *compData = comp;
  120 + return compLength;
  121 +}
0 \ No newline at end of file 122 \ No newline at end of file
compression.h 0 → 100644
  1 +#ifndef _COMPRESSION_H
  2 +#define _COMPRESSION_H
  3 +
  4 +#include <stdlib.h>
  5 +#include <zlib.h>
  6 +#include <stdio.h>
  7 +
  8 +#define OS_FLAG_OFFSET 0x9
  9 +
  10 +ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData);
  11 +ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData);
  12 +
  13 +#endif
0 \ No newline at end of file 14 \ No newline at end of file
1 #include "nbt.h" 1 #include "nbt.h"
  2 +#include "compression.h"
  3 +#include "chunk.h"
2 4
3 ssize_t loadDB(const char* filename, void** data); 5 ssize_t loadDB(const char* filename, void** data);
4 void destroyTag(Tag* t); 6 void destroyTag(Tag* t);
@@ -26,67 +28,31 @@ ssize_t loadDB(const char* filename, void** data) { @@ -26,67 +28,31 @@ ssize_t loadDB(const char* filename, void** data) {
26 } 28 }
27 fstat(fd, &sb); 29 fstat(fd, &sb);
28 30
29 - uint16_t header = 0;  
30 - if(pread(fd,&header,sizeof(uint16_t),0) == -1) {  
31 - perror("Unable to read header");  
32 - close(fd);  
33 - return -3;  
34 - }  
35 -  
36 void* filedata; 31 void* filedata;
37 ssize_t filesize = sb.st_size; 32 ssize_t filesize = sb.st_size;
38 33
39 - if(header == GZIP_MAGIC) {  
40 - close(fd);  
41 - filedata = calloc(GZIP_BUFFER,sizeof(char));  
42 - gzFile file = gzopen(filename,"r");  
43 - if(!file) {  
44 - perror("Failed to gzopen() file");  
45 - free(filedata);  
46 - return -4;  
47 - }  
48 - int err;  
49 - int nRead;  
50 - size_t totalBytes = 0;  
51 - while((nRead = gzread(file, filedata+totalBytes, GZIP_BUFFER)) != 0) {  
52 - totalBytes += nRead;  
53 - if(!(totalBytes % GZIP_BUFFER)) {  
54 - void* newptr = realloc(filedata,totalBytes + GZIP_BUFFER);  
55 - if(newptr == NULL) {  
56 - perror("Unable to realloc for decompression");  
57 - gzclose(file);  
58 - free(filedata);  
59 - return -6;  
60 - }  
61 - filedata = newptr;  
62 - }  
63 - }  
64 - if(!gzeof(file)) {  
65 - const char * errorStr;  
66 - errorStr = gzerror(file, &err);  
67 - fprintf(stderr, "libz error: %s.\n", errorStr);  
68 - gzclose(file);  
69 - free(filedata);  
70 - return -5;  
71 - }  
72 - filesize = totalBytes;  
73 - gzclose (file);  
74 - } else {  
75 - filedata = malloc(filesize);  
76 - ssize_t nRead = 0;  
77 - size_t totalRead = 0;  
78 -  
79 - while((nRead = read(fd,filedata+totalRead,filesize-totalRead))) {  
80 - if(nRead == -1) {  
81 - if(errno == EINTR) {  
82 - continue;  
83 - }  
84 - perror("Error reading file");  
85 - return -7; 34 + filedata = malloc(filesize);
  35 + ssize_t nRead = 0;
  36 + size_t totalRead = 0;
  37 +
  38 + while((nRead = read(fd,filedata+totalRead,filesize-totalRead))) {
  39 + if(nRead == -1) {
  40 + if(errno == EINTR) {
  41 + continue;
86 } 42 }
87 - totalRead += nRead; 43 + perror("Error reading file");
  44 + return -7;
88 } 45 }
  46 + totalRead += nRead;
89 } 47 }
  48 +
  49 + if(*(uint16_t*)filedata == GZIP_MAGIC) {
  50 + void* decompressedFileData;
  51 + filesize = inflateGzip(filedata,filesize,&decompressedFileData);
  52 + free(filedata);
  53 + filedata = decompressedFileData;
  54 + }
  55 +
90 *data = filedata; 56 *data = filedata;
91 return filesize; 57 return filesize;
92 } 58 }
@@ -190,6 +156,12 @@ unsigned int parseCompound(void* addr, TagCompound* tc) { @@ -190,6 +156,12 @@ unsigned int parseCompound(void* addr, TagCompound* tc) {
190 pos += parseTag(pos,&list[numTags]); 156 pos += parseTag(pos,&list[numTags]);
191 } while(list[numTags++].type != TAG_END); 157 } while(list[numTags++].type != TAG_END);
192 158
  159 + void* newptr = reallocarray(list, numTags, sizeof(Tag));
  160 + if(!newptr) {
  161 + fprintf(stderr,"Unable to request memory realloc\n");
  162 + }
  163 + list = newptr;
  164 +
193 tc->list = list; 165 tc->list = list;
194 tc->numTags = numTags-1; 166 tc->numTags = numTags-1;
195 return pos - addr; 167 return pos - addr;