**1.圧縮の原理 [#e7f0ea57]
~
原理は単純でデータが連続で続いていたら、そやつらを符号化するだけです。~
#ref("./gazou1.jpg",70%);~
~
ここで注意しておきたいのはデータが連続しないときも符号をつかないといけないということです。~
でないとプログラム側がデータか符号かがわかりませんから。~
つまりこの圧縮方法だとよほどデータが連続してないと圧縮前よりデータ量が増えてしまうということです。~
これは次回に解消します。~
~
~
**2.解凍の原理 [#s09e0873]
~
符号どうりにデータを展開します。~
~
~
**3.圧縮結果 [#b9489437]
1.ACジャパン あいさつの魔法.mp3
 1.15MB → 2.21MB  圧縮率191.69%
増えた!
増えた!~
~
2.[[はいから亭 メニュー.txt]]
 1.86KB → 3.68KB  圧縮率198.11%
増えた!~
~
3.[[どーなつ先輩の亡骸.JPG]]
 595KB → 1.14MB  圧縮率196.82%
増えた!~
~
4.どーなつ先輩の亡骸.bmp  256色
 3.23MB → 699KB 圧縮率21.10%
~
5.どーなつ先輩の亡骸.bmp  16色
 1.61MB → 136KB 圧縮率5.89%
~
5.どーなつ先輩の亡骸.bmp  白黒
 417KB →  40.4KB 圧縮率9.69%
~
***総評 [#ka87ba28]
普通のデータでは連続しているデータは少なく、連続していない場合符号化の時点で1byteが2byteぶんのデータサイズになるのでほぼ2倍のデータ量になります。~
画像ファイルで白黒より16色のほうが圧縮率がいいのは白黒ではデータが連続し過ぎているというのがひとつの理由です。~
あるデータが何回続くのかを1byteで記録しているので255回の連続までしか記録できません。~
また白黒は文字通り白と黒しかありませんから1ドットを1bitで表現できます。~
これを利用するとさらに圧縮率が高まります。~
~
~
**Sample [#w618d0d2]
~
~
 #include<stdio.h>
 #include<stdlib.h>
 #include<conio.h>
 #include<string.h>
 
 #define EXP_DATA   0
 #define EXP_SYMBOL 1
 
 void RLECompressFile(char *read_file_name);
 void RLEDecompressFile(char *read_file_name);
 
 int main(int argc, char *argv[])
 {
 	int input;
 
 	//コマンドライン引数の例外
 	if((argc - 1) != 1) {
 		printf("ファイルを指定してください\n");
 		return 0;
 	}
 
 	//圧縮or解凍
 	do {
 		printf("圧縮→'c' 解凍→'t' 終了→'q'\n");
 		input = getch();
 		switch(input) {
 			case 'c':
 				printf("ファイルを圧縮します\n\n");
 				printf("%s\n", argv[1]);
 				RLECompressFile(argv[1]);
 				break;
 			case 't':
 				printf("ファイルを解凍します\n");
 				printf("%s\n", argv[1]);
 				RLEDecompressFile(argv[1]);
 				break;
 			case 'q':
 				printf("終了します\n");
 				return 0;
 			default:
 				printf("もう一度入力してください\n");
 		}
 	}while((input != 'c') && input != 't');
 
 	return 0;
 }
 
 //ファイルを圧縮する関数
 //引数1:ファイルの名前
 void RLECompressFile(char *read_file_name)
 {
 	FILE *read_fp;
 	FILE *write_fp;
 	fpos_t rfile_size = 0;
 	fpos_t wfile_size = 0;
 	fpos_t file_pos = 0;
 
 	unsigned char *read_data;
 	unsigned char write_data[2];	//write_data[0] → データ   write_data[1] → 何回続くか
 	fpos_t i;
 	unsigned char equ_counter = 1;
 	char write_file_name[_MAX_PATH];
 
 
 	//読み込みファイル
 	if((read_fp = fopen(read_file_name, "rb")) == NULL) {
 		printf("ファイルが開けません(read)\n");
 		exit(0);
 	}
 
 	//新規ファイル
 	strcpy(write_file_name, read_file_name);
 	strcat(write_file_name, ".rrr");	//拡張子をrrrに
 	if((write_fp = fopen(write_file_name, "wb")) == NULL) {
 		printf("ファイルが開けません(write)\n");
 		exit(0);
 	}
 
 	//ファイルサイズ取得
 	file_pos = fseek(read_fp, 0, SEEK_END);
 	fgetpos(read_fp, &rfile_size);
 	fseek(read_fp, file_pos, SEEK_SET); 
 	printf("圧縮前 %dbyte\n", rfile_size);
 
 
 	//メモリ確保
 	read_data = (unsigned char*)malloc(rfile_size);
 
 	//読み込み
 	fread(read_data, sizeof(unsigned char), rfile_size, read_fp);
 
 
 	//圧縮と書き込み
 	for(i = 1; i < rfile_size + 1; i++) {
 		for(equ_counter = 1; equ_counter < 256; equ_counter++) {
 			if(read_data[i] == read_data[i - 1]) {
 				i++;
 				continue;
 			}else {
 				break;
 			}
 		}
 
 		write_data[EXP_DATA] = read_data[i - 1];
 		write_data[EXP_SYMBOL] = equ_counter;
 		fwrite(write_data, sizeof(unsigned char), 2, write_fp);
 	}
 
 	fgetpos(write_fp, &wfile_size);
 	printf("圧縮後 %dbyte\n", wfile_size);
 	printf("圧縮率 %f%%\n\n", ((float)wfile_size / (float)rfile_size) * 100.0);
 
 	fclose(read_fp);
 	fclose(write_fp);
 
 	free(read_data);
 }
 
 //ファイルを解凍する関数
 //引数1:ファイルの名前
 void RLEDecompressFile(char *read_file_name)
 {
 	FILE *read_fp;
 	FILE *write_fp;
 	fpos_t rfile_size = 0;
 	fpos_t wfile_size = 0;
 	fpos_t file_pos = 0;
 
 	unsigned char *read_data;
 	fpos_t i, j;
 	unsigned char equ_counter = 1;
 	char write_file_name[_MAX_PATH];
 
 
 	//読み込みファイル
 	if((read_fp = fopen(read_file_name, "rb")) == NULL) {
 		printf("ファイルが開けません(read)\n");
 		exit(0);
 	}
 
 	//新規ファイル
 	strcpy(write_file_name, read_file_name);
 	write_file_name[strlen(write_file_name) - 4] = '\0';
 	if((write_fp = fopen(write_file_name, "wb")) == NULL) {
 		printf("ファイルが開けません(write)\n");
 		exit(0);
 	}
 
 	//ファイルサイズ取得
 	file_pos = fseek(read_fp, 0, SEEK_END);
 	fgetpos(read_fp, &rfile_size);
 	fseek(read_fp, file_pos, SEEK_SET); 
 
 	//メモリ確保
 	read_data = (unsigned char*)malloc(rfile_size);
 
 	//読み込み
 	fread(read_data, sizeof(unsigned char), rfile_size, read_fp);
 
 
 	//解答と書き込み
 	for(i = 0; i < rfile_size; i += 2) {
 		for(j = 0; j < read_data[i + 1]; j++) {
 			fwrite(&read_data[i], sizeof(char), 1, write_fp);
 		}
 	}
 
 	fclose(read_fp);
 	fclose(write_fp);
 
 	free(read_data);
 }

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS