/****************************************************************** * * * Nest version 2 - 3D Wasp Nest Simulator * * Copyright (C) 1997 Sylvain GUERIN * * LIASC, ENST Bretagne & Santa Fe Institute * * * ****************************************************************** E-mail: Sylvain.Guerin@enst-bretagne.fr or: Sylvain Guerin 13 rue des Monts Lorgeaux, 51460 L'EPINE, FRANCE ****************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ****************************************************************** Name : compress.c Component : compressing algorithm Fonctionality : contains code refering to file compressing (extracted from lzhuf.c written by Haruyasu Yoshizaki 20/11/88) ****************************************************************** lzhuf.c written by Haruyasu Yoshizaki 1988/11/20 some minor changes 1989/04/06 comments translated by Haruhiko Okumura 1989/04/07 getbit and getbyte modified 1990/03/23 by Paul Edwards so that they would work on machines where integers are not necessarily 16 bits (although ANSI guarantees a minimum of 16). This program has compiled and run with no errors under Turbo C 2.0, Power C, and SAS/C 4.5 (running on an IBM mainframe under MVS/XA 2.2). Could people please use YYYY/MM/DD date format so that everyone in the world can know what format the date is in? external storage of filesize changed 1990/04/18 by Paul Edwards to Intel's "little endian" rather than a machine-dependant style so that files produced on one machine with lzhuf can be decoded on any other. "little endian" style was chosen since lzhuf originated on PC's, and therefore they should dictate the standard. initialization of something predicting spaces changed 1990/04/22 by Paul Edwards so that when the compressed file is taken somewhere else, it will decode properly, without changing ascii spaces to ebcdic spaces. This was done by changing the ' ' (space literal) to 0x20 (which is the far most likely character to occur, if you don't know what environment it will be running on. ******************************************************************/ #include "compress.h" #include /* let's use zlib instead of system("gzip") */ #include #include #include #include #include #include CompressAlgorithm::CompressAlgorithm () { textsize = 0; codesize = 0; printcount = 0; strcpy (wterr, "Can't write."); /* table for encoding and decoding the upper 6 bits of position */ /* for encoding */ p_len = new uchar[64] = { 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }; p_code = new uchar[64] = { 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; /* for decoding */ d_code = new uchar[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, }; d_len = new uchar[256] = { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; getbuf = 0; getlen = 0; putbuf = 0; putlen = 0; } CompressAlgorithm::~CompressAlgorithm () { delete[] p_len; delete[] p_code; delete[] d_len; delete[] d_code; } void CompressAlgorithm::Error(char *message) { printf("\n%s\n", message); exit(EXIT_FAILURE); } void CompressAlgorithm::InitTree(void) /* initialize trees */ { int i; for (i = N + 1; i <= N + 256; i++) rson[i] = NIL; /* root */ for (i = 0; i < N; i++) dad[i] = NIL; /* node */ } void CompressAlgorithm::InsertNode(int r) /* insert to tree */ { int i, p, cmp; unsigned char *key; unsigned c; cmp = 1; key = &text_buf[r]; p = N + 1 + key[0]; rson[r] = lson[r] = NIL; match_length = 0; for ( ; ; ) { if (cmp >= 0) { if (rson[p] != NIL) p = rson[p]; else { rson[p] = r; dad[r] = p; return; } } else { if (lson[p] != NIL) p = lson[p]; else { lson[p] = r; dad[r] = p; return; } } for (i = 1; i < F; i++) if ((cmp = key[i] - text_buf[p + i]) != 0) break; if (i > THRESHOLD) { if (i > match_length) { match_position = ((r - p) & (N - 1)) - 1; if ((match_length = i) >= F) break; } if (i == match_length) { if ((c = ((r - p) & (N-1)) - 1) < (unsigned)match_position) { match_position = c; } } } } dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p]; dad[lson[p]] = r; dad[rson[p]] = r; if (rson[dad[p]] == p) rson[dad[p]] = r; else lson[dad[p]] = r; dad[p] = NIL; /* remove p */ } void CompressAlgorithm::DeleteNode(int p) /* remove from tree */ { int q; if (dad[p] == NIL) return; /* not registered */ if (rson[p] == NIL) q = lson[p]; else if (lson[p] == NIL) q = rson[p]; else { q = lson[p]; if (rson[q] != NIL) { do { q = rson[q]; } while (rson[q] != NIL); rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q]; lson[q] = lson[p]; dad[lson[p]] = q; } rson[q] = rson[p]; dad[rson[p]] = q; } dad[q] = dad[p]; if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q; dad[p] = NIL; } int CompressAlgorithm::GetBit(void) /* get one bit */ { unsigned i; while (getlen <= 8) { if ((int)(i = getc(infile)) < 0) i = 0; getbuf |= i << (8 - getlen); getlen += 8; } i = getbuf; getbuf <<= 1; getlen--; return (int)((i & 0x8000) >> 15); } int CompressAlgorithm::GetByte(void) /* get one byte */ { unsigned i; while (getlen <= 8) { if ((int)(i = getc(infile)) < 0) i = 0; getbuf |= i << (8 - getlen); getlen += 8; } i = getbuf; getbuf <<= 8; getlen -= 8; return (int)((i & 0xff00) >> 8); } void CompressAlgorithm::Putcode(int l, unsigned c) /* output c bits of code */ { putbuf |= c >> putlen; if ((putlen += l) >= 8) { if (putc(putbuf >> 8, outfile) == EOF) { Error(wterr); } if ((putlen -= 8) >= 8) { if (putc(putbuf, outfile) == EOF) { Error(wterr); } codesize += 2; putlen -= 8; putbuf = c << (l - putlen); } else { putbuf <<= 8; codesize++; } } } /* initialization of tree */ void CompressAlgorithm::StartHuff(void) { int i, j; for (i = 0; i < N_CHAR; i++) { freq[i] = 1; son[i] = i + T; prnt[i + T] = i; } i = 0; j = N_CHAR; while (j <= R) { freq[j] = freq[i] + freq[i + 1]; son[j] = i; prnt[i] = prnt[i + 1] = j; i += 2; j++; } freq[T] = 0xffff; prnt[R] = 0; } /* reconstruction of tree */ void CompressAlgorithm::reconst(void) { int i, j, k; unsigned f, l; /* collect leaf nodes in the first half of the table */ /* and replace the freq by (freq + 1) / 2. */ j = 0; for (i = 0; i < T; i++) { if (son[i] >= T) { freq[j] = (freq[i] + 1) / 2; son[j] = son[i]; j++; } } /* begin constructing tree by connecting sons */ for (i = 0, j = N_CHAR; j < T; i += 2, j++) { k = i + 1; f = freq[j] = freq[i] + freq[k]; for (k = j - 1; f < freq[k]; k--); k++; l = (j - k) * 2; memmove(&freq[k + 1], &freq[k], l); freq[k] = f; memmove(&son[k + 1], &son[k], l); son[k] = i; } /* connect prnt */ for (i = 0; i < T; i++) { if ((k = son[i]) >= T) { prnt[k] = i; } else { prnt[k] = prnt[k + 1] = i; } } } /* increment frequency of given code by one, and update tree */ void CompressAlgorithm::update(int c) { int i, j, k, l; if (freq[R] == MAX_FREQ) { reconst(); } c = prnt[c + T]; do { k = ++freq[c]; /* if the order is disturbed, exchange nodes */ if ((unsigned)k > freq[l = c + 1]) { while ((unsigned)k > freq[++l]); l--; freq[c] = freq[l]; freq[l] = k; i = son[c]; prnt[i] = l; if (i < T) prnt[i + 1] = l; j = son[l]; son[l] = i; prnt[j] = c; if (j < T) prnt[j + 1] = c; son[c] = j; c = l; } } while ((c = prnt[c]) != 0); /* repeat up to root */ } void CompressAlgorithm::EncodeChar(unsigned c) { unsigned i; int j, k; i = 0; j = 0; k = prnt[c + T]; /* travel from leaf to root */ do { i >>= 1; /* if node's address is odd-numbered, choose bigger brother node */ if (k & 1) i += 0x8000; j++; } while ((k = prnt[k]) != R); Putcode(j, i); code = i; len = j; update(c); } void CompressAlgorithm::EncodePosition(unsigned c) { unsigned i; /* output upper 6 bits by table lookup */ i = c >> 6; Putcode(p_len[i], (unsigned)p_code[i] << 8); /* output lower 6 bits verbatim */ Putcode(6, (c & 0x3f) << 10); } void CompressAlgorithm::EncodeEnd(void) { if (putlen) { if (putc(putbuf >> 8, outfile) == EOF) { Error(wterr); } codesize++; } } int CompressAlgorithm::DecodeChar(void) { unsigned c; c = son[R]; /* travel from root to leaf, */ /* choosing the smaller child node (son[]) if the read bit is 0, */ /* the bigger (son[]+1} if 1 */ while (c < T) { c += GetBit(); c = son[c]; } c -= T; update(c); return (int)c; } int CompressAlgorithm::DecodePosition(void) { unsigned i, j, c; /* recover upper 6 bits from table */ i = GetByte(); c = (unsigned)d_code[i] << 6; j = d_len[i]; /* read lower 6 bits verbatim */ j -= 2; while (j--) { i = (i << 1) + GetBit(); } return (int)(c | (i & 0x3f)); } /* compression */ void CompressAlgorithm::Encode(void) /* compression */ { int i, c, len, r, s, last_match_length; fseek(infile, 0L, 2); textsize = ftell(infile); fputc((int)((textsize & 0xff)),outfile); fputc((int)((textsize & 0xff00) >> 8),outfile); fputc((int)((textsize & 0xff0000L) >> 16),outfile); fputc((int)((textsize & 0xff000000L) >> 24),outfile); if (ferror(outfile)) Error(wterr); /* output size of text */ if (textsize == 0) return; rewind(infile); textsize = 0; /* rewind and re-read */ StartHuff(); InitTree(); s = 0; r = N - F; for (i = s; i < r; i++) text_buf[i] = 0x20; for (len = 0; len < F && (c = getc(infile)) != EOF; len++) text_buf[r + len] = (unsigned char)c; textsize = len; for (i = 1; i <= F; i++) InsertNode(r - i); InsertNode(r); do { if (match_length > len) match_length = len; if (match_length <= THRESHOLD) { match_length = 1; EncodeChar(text_buf[r]); } else { EncodeChar(255 - THRESHOLD + match_length); EncodePosition(match_position); } last_match_length = match_length; for (i = 0; i < last_match_length && (c = getc(infile)) != EOF; i++) { DeleteNode(s); text_buf[s] = (unsigned char)c; if (s < F - 1) text_buf[s + N] = (unsigned char)c; s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); InsertNode(r); } if ((textsize += i) > printcount) { // printf("%12ld\r", textsize); printcount += 1024; } while (i++ < last_match_length) { DeleteNode(s); s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); if (--len) InsertNode(r); } } while (len > 0); EncodeEnd(); // printf("In : %ld bytes\n", textsize); // printf("Out: %ld bytes\n", codesize); // printf("Out/In: %.3f\n", 1.0 * codesize / textsize); } void CompressAlgorithm::Decode(void) /* recover */ { int i, j, k, r, c; unsigned long int count; textsize = (fgetc(infile)); textsize |= (fgetc(infile) << 8); textsize |= (fgetc(infile) << 16); textsize |= (fgetc(infile) << 24); if (ferror(infile)) Error("Can't read"); /* read size of text */ if (textsize == 0) return; StartHuff(); for (i = 0; i < N - F; i++) text_buf[i] = 0x20; r = N - F; for (count = 0; count < textsize; ) { c = DecodeChar(); if (c < 256) { if (putc(c, outfile) == EOF) { Error(wterr); } text_buf[r++] = (unsigned char)c; r &= (N - 1); count++; } else { i = (r - DecodePosition() - 1) & (N - 1); j = c - 255 + THRESHOLD; for (k = 0; k < j; k++) { c = text_buf[(i + k) & (N - 1)]; if (putc(c, outfile) == EOF) { Error(wterr); } text_buf[r++] = (unsigned char)c; r &= (N - 1); count++; } } if (count > printcount) { // printf("%12ld\r", count); printcount += 1024; } } // printf("%12ld\n", count); } /* cette methode prend le fichier, l'encode, et le sauve avec le suffixe .zhuf en effacant le fichier original */ int CompressAlgorithm::compress2 (char* inputPath, char* inputFile) { char inputName[256]; char outputName[256]; // printf ("Compress\n"); strcpy (inputName, inputPath); if (inputPath[strlen (inputPath)-1] != '/') { strcat (inputName, "/"); } strcat (inputName, inputFile); strcpy (outputName, inputName); strcat (outputName, ".zhuf"); // printf ("Input: %s\n", inputName); // printf ("Output: %s\n", outputName); if (openFiles (inputName, outputName) == 0) { Encode (); closeFiles (); // printf ("fin\n"); return remove (inputName); } else { // printf ("ERROR: unable to encode file\n"); return -1; } } /* cette methode prend le fichier .zhuf, le decode, et le sauve sans le suffixe .zhuf en effacant le fichier original */ int CompressAlgorithm::decompress2 (char* inputPath, char* inputFile) { char inputName[256]; char outputName[256]; int lenght; // printf ("Decompress\n"); lenght = strlen (inputFile); if ( (inputFile[lenght-5] == '.') && (inputFile[lenght-4] == 'z') && (inputFile[lenght-3] == 'h') && (inputFile[lenght-2] == 'u') && (inputFile[lenght-1] == 'f')) { /* ok, right format */ strcpy (inputName, inputPath); if (inputPath[strlen (inputPath)-1] != '/') { strcat (inputName, "/"); } strcat (inputName, inputFile); lenght = strlen (inputName); strcpy (outputName, inputName); outputName[lenght-5] = '\0'; // printf ("Input: %s\n", inputName); // printf ("Output: %s\n", outputName); if (openFiles (inputName, outputName) == 0) { Decode (); closeFiles (); // printf ("fin\n"); return remove (inputName); } else { return -1; } } else { // printf ("ERROR: unable to decode file: wrong format or already done\n"); return -1; } } int CompressAlgorithm::openFiles (char* inFile, char* outFile) { if ((infile = fopen(inFile, "rb")) == NULL) { return -1; } else if ((outfile = fopen(outFile, "wb")) == NULL) { fclose (infile); return -1; } else { return 0; } } void CompressAlgorithm::closeFiles () { fclose(infile); fclose(outfile); } int CompressAlgorithm::compress2 (char* inputPath, char* inputFile, char* outputFile) { char inputName[256]; char outputName[256]; // printf ("Compress\n"); strcpy (inputName, inputPath); if (inputPath[strlen (inputPath)-1] != '/') { strcat (inputName, "/"); } strcat (inputName, inputFile); strcpy (outputName, inputPath); if (inputPath[strlen (inputPath)-1] != '/') { strcat (outputName, "/"); } strcat (outputName, outputFile); // printf ("Input: %s\n", inputName); // printf ("Output: %s\n", outputName); if (openFiles (inputName, outputName) == 0) { Encode (); closeFiles (); // printf ("Fin\n"); return 0; } else { // printf ("ERROR: unable to encode file\n"); return -1; } } int CompressAlgorithm::decompress2 (char* inputPath, char* inputFile, char* outputFile) { char inputName[256]; char outputName[256]; // printf ("Decompress\n"); strcpy (inputName, inputPath); if (inputPath[strlen (inputPath)-1] != '/') { strcat (inputName, "/"); } strcat (inputName, inputFile); strcpy (outputName, inputPath); if (inputPath[strlen (inputPath)-1] != '/') { strcat (outputName, "/"); } strcat (outputName, outputFile); // printf ("Input: %s\n", inputName); // printf ("Output: %s\n", outputName); if (openFiles (inputName, outputName) == 0) { Decode (); closeFiles (); // printf ("Fin\n"); return 0; } else { // printf ("ERROR: unable to decode file\n"); return -1; } } int CompressAlgorithm::compress (char* inputPath, char* inputFile) { int res; char *fname = (char *) malloc (sizeof (char) * (strlen (inputPath)+strlen (inputFile))); char *outputFile = (char *) malloc (sizeof (char) * (strlen (inputFile)+5)); strcpy (outputFile, inputFile); strcat (outputFile, ".zhuf"); /* suffix : .zhuf */ strcpy (fname, inputPath); strcat (fname, inputFile); res = compress (inputPath, inputFile, outputFile); if (res == -1) { return -1; /* if compression has failed, we don't delete original file :) */ } else { unlink (fname); return 0; } } int CompressAlgorithm::decompress (char* inputPath, char* inputFile) { int res; char *fname = (char *) malloc (sizeof (char) * (strlen (inputPath)+strlen (inputFile))); char *outputFile = (char *) malloc (sizeof (char) * (strlen (inputFile)-5)); strncpy (outputFile, inputFile, strlen (inputFile)-5); strcpy (fname, inputPath); strcat (fname, inputFile); res = decompress (inputPath, inputFile, outputFile); if (res == -1) { return -1; /* if compression has failed, we don't delete original file :) */ } else { unlink (fname); return 0; } } int CompressAlgorithm::compress (char* inputPath, char* inputFile, char* outputFile) { char *fname, *zfname; gzFile zfile; int file; char buffer [512]; int len; fname = (char *) malloc (sizeof (char) * (strlen (inputPath)+strlen (inputFile))); strcpy (fname, inputPath); strcat (fname, inputFile); file = open (fname, O_RDONLY); if (file == -1) return -1; zfname = (char *) malloc (sizeof (char) * (strlen (inputPath)+strlen (outputFile))); strcpy (zfname, inputPath); strcat (zfname, outputFile); zfile = gzopen (zfname, "wb9"); if (zfile == NULL) return -1; while ((len = read (file , buffer, sizeof(buffer)-1)) > 0) gzwrite (zfile, buffer, len); gzclose (zfile); close (file); return 0; } int CompressAlgorithm::decompress (char* inputPath, char* inputFile, char* outputFile) { char *fname, *zfname; gzFile zfile; int file; char buffer [512]; int len; zfname = (char *) malloc (sizeof (char) * (strlen (inputPath)+strlen (inputFile))); strcpy (zfname, inputPath); strcat (zfname, inputFile); zfile = gzopen (zfname, "rb"); if (zfile == NULL) return -1; fname = (char *) malloc (sizeof (char) * (strlen (inputPath)+strlen (outputFile))); strcpy (fname, inputPath); strcat (fname, outputFile); file = open (fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (file == -1) return -1; while ((len = gzread (zfile , buffer, sizeof(buffer)-1)) > 0) write (file, buffer, len); gzclose (zfile); close (file); return 0; }