/*********************************************************** * * rle3.c * * ランレングス符号化のテスト * ラン長部分をマーク符号で識別する * ***********************************************************/ #include #include #include #define BUF_SIZE 0x1000 /* 4KByteまで */ #define MINLEN 4 #define LIMIT1 240 #define LIMIT2 (256 * (256 - LIMIT1) + LIMIT1 - 1) typedef unsigned char Uchar; /* バッファ定義 */ Uchar buffer[BUF_SIZE]; Uchar encbuf[BUF_SIZE]; Uchar decbuf[BUF_SIZE]; Uchar mch = 'Z'; /* マーク符号 */ /* 符号化 */ int rl3_encode(Uchar *out, Uchar *in, int size) { int rpos = 0, wpos = 0; while (rpos < size) { int c = in[rpos++]; int i, le = 1; /* 文字列のラン長を調べる */ while (rpos < size && le < 1 + LIMIT2) { if (in[rpos] != c) break; le++; rpos++; } if (le >= MINLEN) { /* マーク符号を出力 */ out[wpos++] = mch; le--; /* ラン長を出力 */ if (le < LIMIT1) { out[wpos++] = le; } else { le -= LIMIT1; out[wpos++] = (le >> 8) + LIMIT1; out[wpos++] = le & 0xff; } out[wpos++] = c; } else { if (c == mch) { out[wpos++] = mch; out[wpos++] = le - 1; } else { for (i = 0; i < le; i++) out[wpos++] = c; } } } return wpos; } /* 復号 */ int rl3_decode(Uchar *out, Uchar *in, int size) { int rpos = 0, wpos = 0; while (rpos < size) { int c = in[rpos++]; int i, le; if (c == mch) { /* ラン長を入力 */ int le = in[rpos++]; if (le >= LIMIT1) { le = ((le - LIMIT1) << 8) + in[rpos++] + LIMIT1; } le++; if (le >= MINLEN) c = in[rpos++]; for (i = 0; i < le; i++) out[wpos++] = c; } else { out[wpos++] = c; } } return wpos; } /* バッファの内容を 16 進数で表示する */ void print_buffer(Uchar *buff, int size) { int i; for (i = 0; i < size; i++) { printf("%02x ", buff[i]); } printf("\n"); } /* メイン関数 */ int main() { int size, encsize, decsize; printf("\n文字列を入力して下さい :\n"); if (fgets((char *)buffer, BUF_SIZE, stdin) == NULL) { exit(0); } size = strlen(buffer); if (size > 0 && buffer[size - 1] == '\n') size--; /* 改行削除 */ printf("* %d byte\n", size); printf("----- RunLength Encode (Hex code)-----\n"); encsize = rl3_encode(encbuf, buffer, size); print_buffer(encbuf, encsize); printf("* %d byte\n", encsize); printf("----- RunLength Decode -----\n"); decsize = rl3_decode(decbuf, encbuf, encsize); fwrite(decbuf, decsize, 1, stdout); printf("\n"); printf("* %d byte\n", decsize); /* check */ if (size != decsize) { printf("NG !!\n"); exit(1); } if (memcmp(buffer, decbuf, size)) { printf("NG !!\n"); exit(1); } return 0; } /* end of file */