| |

VerySource

 Forgot password?
 Register
Search
View: 834|Reply: 5

C language file compression code

[Copy link]

1

Threads

2

Posts

3.00

Credits

Newbie

Rank: 1

Credits
3.00

 China

Post time: 2020-3-7 16:30:01
| Show all posts |Read mode
C source code for compressed files, thank you
Reply

Use magic Report

0

Threads

25

Posts

19.00

Credits

Newbie

Rank: 1

Credits
19.00

 China

Post time: 2020-5-27 23:15:01
| Show all posts
zlib
Reply

Use magic Report

0

Threads

78

Posts

29.00

Credits

Newbie

Rank: 1

Credits
29.00

 China

Post time: 2020-5-28 10:00:01
| Show all posts
Source code of lzss:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define N 4096 / * size of ring buffer * /
#define F 18 / * upper limit for match_length * /
#define THRESHOLD 2 / * encode string into position and length
                                                   if match_length is greate
r thhan this * /
#define NIL N / * index for root of binary search t
rees
* /
unsigned long int
                textsize = 0, / * text size counter * /
                codesize = 0, / * code size counter * /
                printcount = 0; / * counter for reporting progress every 1K b
ytes
* /
unsigned char
                text_buf [N + F-1]; / * ring buffer of size N,
                        with extra F-1 bytes to facilitate string comparison
* /
int match_position, match_length, / * of longest match. These a
re
                        set by the InsertNode () procedure. * /
                lson [N + 1], rson [N + 257], dad [N + 1]; / * left&right chi
ldre
&
                        parents-These constitute binary search trees. * /
FILE * infile, * outfile; / * input&output files * /
void InitTree (void) / * initialize trees * /
{
        int i;
        / * For i = 0 to N-1, rson [i] and lson [i] will be the right and
           left children of node i. These nodes need not be initialized.
           Also, dad [i] is the parent of node i. These are initialized to
           NIL (= N), which stands for 'not used.'
           For i = 0 to 255, rson [N + i + 1] is the root of the tree
           for strings that begin with character i. These are initialized
           to NIL. Note there are 256 trees. * /
        for (i = N + 1; i <= N + 256; i ++) rson [i] = NIL;
        for (i = 0; i <N; i ++) dad [i] = NIL;
}
void InsertNode (int r)
        / * Inserts string of length F, text_buf [r..r + F-1], into one of the
           trees (text_buf [r] 'th tree) and returns the longest-match positio
n
           and length via the global variables match_position and
match_length.
           If match_length = F, then removes the old node in favor of the ne
w
           one, because the old one will be deleted sooner.
           Note r plays double role, as tree node and position in buffer. * /
{
        int i, p, cmp;
        unsigned char * key;
        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> match_length) {
                        match_position = p;
                        if ((match_length = i)> = F) break;
                }
        }
        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 DeleteNode (int p) / * deletes node p from tree * /
{
        int q;
        if (dad [p] == NIL) return; / * not in tree * /
        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;
}
Reply

Use magic Report

0

Threads

78

Posts

29.00

Credits

Newbie

Rank: 1

Credits
29.00

 China

Post time: 2020-5-28 11:00:02
| Show all posts
void Encode (void)
{
        int i, c, len, r, s, last_match_length, code_buf_ptr;
        unsigned char code_buf [17], mask;
        InitTree (); / * initialize trees * /
        code_buf [0] = 0; / * code_buf [1..16] saves eight units of code, and
                code_buf [0] works as eight flags, "1" representing that the
unit
                is an unencoded letter (1 byte), "0" a position-and-length p
air
                (2 bytes). Thus, eight units require at most 16 bytes of co
de.
/
        code_buf_ptr = mask = 1;
        s = 0; r = N-F;
        for (i = s; i <r; i ++) text_buf [i] = ''; / * Clear the buffer with
                any character that will appear often. * /
        for (len = 0; len <F&&(c = getc (infile))! = EOF; len ++)
                text_buf [r + len] = c; / * Read F bytes into the last F byte
s of
                        the buffer * /
        if ((textsize = len) == 0) return; / * text of size zero * /
        for (i = 1; i <= F; i ++) InsertNode (r-i); / * Insert the F strings
,
                each of which begins with one or more 'space' characters. N
ote
                the order in which these strings are inserted. This way,
                degenerate trees will be less likely to occur. * /
        InsertNode (r); / * Finally, insert the whole string just read. The
                global variables match_length and match_position are set. * /
        do {
                if (match_length> len) match_length = len; / * match_length
                        may be spuriously long near the end of text. * /
                if (match_length <= THRESHOLD) {
                        match_length = 1; / * Not long enough match. Send o
ne b
te. * /
                        code_buf [0] | = mask; / * 'send one byte' flag * /
                        code_buf [code_buf_ptr ++] = text_buf [r]; / * Send unc
oded
* /
                } else {
                        code_buf [code_buf_ptr ++] = (unsigned char) match_pos
itio
;
                        code_buf [code_buf_ptr ++] = (unsigned char)
                                (((match_position >> 4)&0xf0)
                          | (match_length-(THRESHOLD + 1))); / * Send posi
tion
and
                                        length pair. Note match_length> THR
ESHO
D. * /
                }
                if ((mask << = 1) == 0) {/ * Shift mask left one bit. * /
                        for (i = 0; i <code_buf_ptr; i ++) / * Send at most
8 un
ts of * /
                                putc (code_buf [i], outfile); / * code toge
ther
* /
                        codesize + = code_buf_ptr;
                        code_buf [0] = 0; code_buf_ptr = mask = 1;
                }
                last_match_length = match_length;
                for (i = 0; i <last_match_length&&
                                (c = getc (infile))! = EOF; i ++) {
                        DeleteNode (s); / * Delete old strings and * /
                        text_buf [s] = c; / * read new bytes * /
                        if (s <F-1) text_buf [s + N] = c; / * If the posit
ion
s
                                near the end of buffer, extend the buffer to
mak
                                string comparison easier. * /
                        s = (s + 1)&(N-1); r = (r + 1)&(N-1);
                                / * Since this is a ring buffer, increment th
e po
ition
                                   modulo N. * /
                        InsertNode (r); / * Register the string in text_buf [r
..r +
-1] */
                }
                if ((textsize + = i)> printcount) {
                        printf ("% 12ld\r", textsize); printcount + = 1024;
                                / * Reports progress each time the textsize e
xcee
s
                                   multiples of 1024. * /
                }
                while (i ++ <last_match_length) {/ * After the end of
text
* /
                        DeleteNode (s); / * n
o ne
d to read, but * /
                        s = (s + 1)&(N-1); r = (r + 1)&(N-1);
                        if (--len) InsertNode (r); / * buffer ma
y no
be empty. * /
                }
        } while (len> 0); / * until length of string to be processed is
zer
* /
        if (code_buf_ptr> 1) {/ * Send remaining code. * /
                for (i = 0; i <code_buf_ptr; i ++) putc (code_buf [i], outfile
);
                codesize + = code_buf_ptr;
        }
        printf ("In:% ld bytes\n", textsize); / * Encoding is done. * /
        printf ("Out:% ld bytes\n", codesize);
        printf ("Out / In:% .3f\n", (double) codesize / textsize);
}
void Decode (void) / * Just the reverse of Encode (). * /
{
        int i, j, k, r, c;
        unsigned int flags;
        for (i = 0; i <N-F; i ++) text_buf [i] = '';
        r = N-F; flags = 0;
        for (;;) {
                if (((flags >> = 1)&256) == 0) {
                        if ((c = getc (infile)) == EOF) break;
                        flags = c | 0xff00; / * uses higher byte
clev
rly * /
                } / * t
o co
nt eight * /
                if (flags&1) {
                        if ((c = getc (infile)) == EOF) break;
                        putc (c, outfile); text_buf [r ++] = c; r&= (N-1);
                } else {
                        if ((i = getc (infile)) == EOF) break;
                        if ((j = getc (infile)) == EOF) break;
                        i | = ((j&0xf0) << 4); j = (j&0x0f) + THRESHOLD;
                        for (k = 0; k <= j; k ++) {
                                c = text_buf [(i + k)&(N-1)];
                                putc (c, outfile); text_buf [r ++] = c; r&=
(N-
1);
                        }
                }
        }
}
int main (int argc, char * argv [])
{
        char * s;
        if (argc! = 4) {
                printf ("'lzss e file1 file2' encodes file1 into file2.\n"
                           "'lzss d file2 file1' decodes file2 into file1.\n
");
                return EXIT_FAILURE;
        }
        if ((s = argv [1], s [1] || strpbrk (s, "DEde") == NULL)
         || (s = argv [2], (infile = fopen (s, "rb")) == NULL)
         || (s = argv [3], (outfile = fopen (s, "wb")) == NULL)) {
                printf ("???% s\n", s); return EXIT_FAILURE;
        }
        if (toupper (* argv [1]) == 'E') Encode (); else Decode ();
        fclose (infile); fclose (outfile);
        return EXIT_SUCCESS;
}
Reply

Use magic Report

0

Threads

78

Posts

29.00

Credits

Newbie

Rank: 1

Credits
29.00

 United States

Post time: 2020-5-28 17:30:01
| Show all posts
It is also possible to call zlib sample code ~~
Reply

Use magic Report

1

Threads

2

Posts

3.00

Credits

Newbie

Rank: 1

Credits
3.00

 China

 Author| Post time: 2020-5-29 11:45:02
| Show all posts
OK, thank you! I look down!
Reply

Use magic Report

You have to log in before you can reply Login | Register

Points Rules

Contact us|Archive|Mobile|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

Quick Reply To Top Return to the list