how to compress a file in c

Solutions on MaxInterview for how to compress a file in c by the best coders in the world

showing results for - "how to compress a file in c"
Henri
13 Nov 2018
1#include <stdio.h>
2#include <string.h>
3
4//comp()
5void Compress(unsigned char *szOut, const char *szMessage) {
6	unsigned long long nBuffer = 0; //This is enough to store 8 uncompressed characters or 9 compressed. We will only use 8 tho.
7	char nBitsInBuffer = 0;
8	while (*szMessage != 0) {
9		nBuffer |= (unsigned long long)(*szMessage++ & 0x7F) << nBitsInBuffer;
10		nBitsInBuffer += 7;
11		if (nBitsInBuffer == 7 * 8) { //We have 8 chars in the buffer, dump them
12			while (nBitsInBuffer > 0) {
13				*szOut++ = nBuffer & 0xFF;
14				nBuffer >>= 8;
15				nBitsInBuffer -= 8;
16			}
17			//The following should be redundant, but just to be safe
18			nBitsInBuffer = 0;
19			nBuffer = 0;
20		}
21	}
22	//Write out whatever is left in the buffer
23	while (nBitsInBuffer > 0) {
24		*szOut++ = nBuffer & 0xFF;
25		nBuffer >>= 8;
26		nBitsInBuffer -= 8;
27	}
28}
29
30//uncomp()
31//nCompressedLen is the number of bytes in the compressed buffer.
32//NOTE: the compressed buffer does not have a NULL terminating character
33void Uncompress(char *szOut, const unsigned char *szCompressed, unsigned nCompressedLen) {
34	unsigned long long nBuffer = 0; //This is enough to store 8 uncompressed characters or 9 compressed. We will only use 8 tho.
35	char nBitsInBuffer = 0;
36	while (nCompressedLen) {
37		while (nCompressedLen && nBitsInBuffer < 7 * 8) {
38			nBuffer |= (unsigned long long)*szCompressed++ << nBitsInBuffer;
39			nBitsInBuffer += 8;
40			--nCompressedLen;
41		}
42		while (nBitsInBuffer > 0) {
43			*szOut++ = nBuffer & 0x7F;
44			nBuffer >>= 7;
45			nBitsInBuffer -= 7;
46		}
47		//The following should be redundant, but just to be safe
48		nBitsInBuffer = 0;
49		nBuffer = 0;
50	}
51}
52
53int main() {
54	//char szMessage[] = "\x53\x7F\x63\x4B";
55	char szMessage[] = "hello world. this is a compressed long string";
56	static const unsigned nCompressedSize = sizeof(szMessage) * 7 / 8; //This does not include the NULL terminating character from the string
57	unsigned char pCompressedBytes[nCompressedSize];
58	char szUncompressed[sizeof(szMessage)];
59	printf("     Message: %s\n", szMessage);
60	Compress(pCompressedBytes, szMessage);
61	printf("  Compressed: ");
62	for (int nByte = 0; nByte < nCompressedSize; ++nByte) {
63		printf("%02X ", pCompressedBytes[nByte]);
64	}
65	printf("\n");
66	Uncompress(szUncompressed, pCompressedBytes, nCompressedSize);
67	szUncompressed[sizeof(szMessage) - 1] = 0; //We need to terminate the string. The NULL terminator is not stored in the compressed bytes
68	printf("Uncompressed: %s\n", szUncompressed);
69	//Now just verify that we ended up with the same message we started with
70	if (strcmp(szMessage, szUncompressed) == 0) {
71		printf("Compression works\n");
72	} else {
73		printf("Compression failed\n");
74	}
75	return 0;
76}
Angela
22 Feb 2020
1#include <stdint.h>
2
3uint32_t lz77_compress (uint8_t *uncompressed_text, uint32_t uncompressed_size, uint8_t *compressed_text)
4{
5    uint8_t pointer_length, temp_pointer_length;
6    uint16_t pointer_pos, temp_pointer_pos, output_pointer;
7    uint32_t compressed_pointer, output_size, coding_pos, output_lookahead_ref, look_behind, look_ahead;
8    
9    *((uint32_t *) compressed_text) = uncompressed_size;
10    compressed_pointer = output_size = 4;
11    
12    for(coding_pos = 0; coding_pos < uncompressed_size; ++coding_pos)
13    {
14        pointer_pos = 0;
15        pointer_length = 0;
16        for(temp_pointer_pos = 1; (temp_pointer_pos < 4096) && (temp_pointer_pos <= coding_pos); ++temp_pointer_pos)
17        {
18            look_behind = coding_pos - temp_pointer_pos;
19            look_ahead = coding_pos;
20            for(temp_pointer_length = 0; uncompressed_text[look_ahead++] == uncompressed_text[look_behind++]; ++temp_pointer_length)
21                if(temp_pointer_length == 15)
22                    break;
23            if(temp_pointer_length > pointer_length)
24            {
25                pointer_pos = temp_pointer_pos;
26                pointer_length = temp_pointer_length;
27                if(pointer_length == 15)
28                    break;
29            }
30        }
31        coding_pos += pointer_length;
32        if(pointer_length && (coding_pos == uncompressed_size))
33        {
34            output_pointer = (pointer_pos << 4) | (pointer_length - 1);
35            output_lookahead_ref = coding_pos - 1;
36        }
37        else
38        {
39            output_pointer = (pointer_pos << 4) | pointer_length;
40            output_lookahead_ref = coding_pos;
41        }
42        *((uint32_t *) (compressed_text + compressed_pointer)) = output_pointer;
43        compressed_pointer += 2;
44        *(compressed_text + compressed_pointer++) = *(uncompressed_text + output_lookahead_ref);
45        output_size += 3;
46    }
47    
48    return output_size;
49}
50
51uint32_t lz77_decompress (uint8_t *compressed_text, uint8_t *uncompressed_text)
52{
53    uint8_t pointer_length;
54    uint16_t input_pointer, pointer_pos;
55    uint32_t compressed_pointer, coding_pos, pointer_offset, uncompressed_size;
56    
57    uncompressed_size = *((uint32_t *) compressed_text);
58    compressed_pointer = 4;
59    
60    for(coding_pos = 0; coding_pos < uncompressed_size; ++coding_pos)
61    {
62        input_pointer = *((uint32_t *) (compressed_text + compressed_pointer));
63        compressed_pointer += 2;
64        pointer_pos = input_pointer >> 4;
65        pointer_length = input_pointer & 15;
66        if(pointer_pos)
67            for(pointer_offset = coding_pos - pointer_pos; pointer_length > 0; --pointer_length)
68                uncompressed_text[coding_pos++] = uncompressed_text[pointer_offset++];
69        *(uncompressed_text + coding_pos) = *(compressed_text + compressed_pointer++);
70    }
71    
72    return coding_pos;
73}
74