⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzw.c

📁 lua脚本语言调用allegro游戏程序库的接口-跨平台
💻 C
字号:
#include "lzw.h"static intread_code (PACKFILE * file, char *buf, int *bit_pos, int bit_size){    int i;    int code = 0;    int pos = 1;    for (i = 0; i < bit_size; i++)    {        int byte_pos = (*bit_pos >> 3) & 255;        if (byte_pos == 0)        {            int data_len = pack_getc (file);            if (data_len == 0)            {                //printf ("Fatal. Errorneous GIF stream.\n");                //abort ();                return -1;            }            pack_fread (buf + 256 - data_len, data_len, file);            byte_pos = 256 - data_len;            *bit_pos = byte_pos << 3;        }        if (buf[byte_pos] & (1 << (*bit_pos & 7)))            code += pos;        pos += pos;        (*bit_pos)++;    }    return code;}static voidwrite_code (PACKFILE * file, char *buf, int *bit_pos, int bit_size, int code){    int i;    int pos = 1;    for (i = 0; i < bit_size; i++)    {        int byte_pos = *bit_pos >> 3;        if (code & pos)            buf[byte_pos] |= (1 << (*bit_pos & 7));        else            buf[byte_pos] &= ~(1 << (*bit_pos & 7));        (*bit_pos)++;        if (*bit_pos == 2040)        {            pack_putc (byte_pos + 1, file);            pack_fwrite (buf, byte_pos + 1, file);            *bit_pos = 0;        }        pos += pos;    }}static intread_pixel (BITMAP *bmp, int pos){    return getpixel (bmp, pos % bmp->w, pos / bmp->w);}static voidwrite_pixel (BITMAP *bmp, int pos, int code){    putpixel (bmp, pos % bmp->w, pos / bmp->w, code);}intLZW_decode (PACKFILE * file, BITMAP *bmp){    int orig_bit_size;    char buf[256];    int bit_size;    int bit_pos;    int clear_marker;    int end_marker;    struct    {        int prefix;        int c;        int len;    }    codes[4096];                /* Maximum bit size is 12. */    int n;    int i, prev, code, c;    int out_pos = 0;    orig_bit_size = pack_getc (file);    n = 2 + (1 << orig_bit_size);    for (i = 0; i < n; i++)    {        codes[i].c = i;        codes[i].len = 0;    }    clear_marker = n - 2;    end_marker = n - 1;    bit_size = orig_bit_size + 1;    bit_pos = 0;    /* Expect to read clear code as first code here. */    prev = read_code (file, buf, &bit_pos, bit_size);    if (prev == -1)        return -1;    do    {        code = read_code (file, buf, &bit_pos, bit_size);        if (code == -1)            return -1;        if (code == clear_marker)        {            bit_size = orig_bit_size;            n = 1 << bit_size;            n += 2;            bit_size++;            prev = code;            continue;        }        if (code == end_marker)            break;        /* Known code: ok. Else: must be doubled char. */        if (code < n)            c = code;        else            c = prev;        /* Output the code. */        out_pos += codes[c].len;        i = 0;        do        {            write_pixel (bmp, out_pos - i, codes[c].c);            if (codes[c].len)                c = codes[c].prefix;            else                break;            i++;        }        while (1);        out_pos++;        /* Unknown code -> must be double char. */        if (code >= n)        {            write_pixel (bmp, out_pos, codes[c].c);            out_pos++;        }        /* Except after clear marker, build new code. */        if (prev != clear_marker)        {            codes[n].prefix = prev;            codes[n].len = codes[prev].len + 1;            codes[n].c = codes[c].c;            n++;        }        /* Out of bits? Increase. */        if (n == (1 << bit_size))        {            if (bit_size < 12)                bit_size++;        }        prev = code;    }    while (1);    return 0;}static intget_minimum_bitsize (BITMAP *bmp){    int x, y, max = 0, b = 2;    for (y = 0; y < bmp->h; y++)    {        for (x = 0; x < bmp->w; x++)        {            int c = getpixel (bmp, x, y);            if (c > max)                max = c;        }    }    while ((1 << b) <= max)    {        b++;    }    return b;}voidLZW_encode (PACKFILE * file, BITMAP *bmp){    int orig_bit_size;    int bit_size;    char buf[256];    int bit_pos;    int clear_marker;    int end_marker;    struct    {        int prefix;        int c;        int len;    }    codes[4096];                /* Maximum bit size is 12. */    int code, prev;    int in_pos;    int n, i;    orig_bit_size = get_minimum_bitsize (bmp);    n = 2 + (1 << orig_bit_size);    for (i = 0; i < n; i++)    {        codes[i].c = i;        codes[i].len = 0;    }    clear_marker = n - 2;    end_marker = n - 1;    pack_putc (orig_bit_size, file);    bit_size = orig_bit_size + 1;    bit_pos = 0;    /* Play fair and put a clear marker at the start. */    write_code (file, buf, &bit_pos, bit_size, clear_marker);    prev = read_pixel (bmp, 0);    for (in_pos = 1; in_pos < bmp->w * bmp->h; in_pos++)    {        code = read_pixel (bmp, in_pos);        if (prev != clear_marker)        {            /* Search for the code. */            for (i = end_marker + 1; i < n; i++)            {                if (codes[i].prefix == prev && codes[i].c == code)                {                    code = i;                    break;                }            }            /* If not found, add it, and write previous code. */            if (i == n)            {                codes[n].prefix = prev;                codes[n].len = codes[prev].len + 1;                codes[n].c = code;                n++;                write_code (file, buf, &bit_pos, bit_size, prev);            }        }        /* Out of bits? Increase. */        if (n == 1 + (1 << bit_size))        {            if (bit_size < 12)                bit_size++;        }        /* Too big table? Clear and start over. */        if (n == 4096)        {            write_code (file, buf, &bit_pos, bit_size, clear_marker);            bit_size = orig_bit_size + 1;            n = end_marker + 1;        }        prev = code;    }    write_code (file, buf, &bit_pos, bit_size, prev);    write_code (file, buf, &bit_pos, bit_size, end_marker);    if (bit_pos)    {        int byte_pos = (bit_pos + 7) / 8;        pack_putc (byte_pos, file);        pack_fwrite (buf, byte_pos, file);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -