「ゲームプログラミング/画像ファイルの作成プログラム」の版間の差分

削除された内容 追加された内容
→‎ランレングス圧縮: コードミスを修正。
→‎PackBits: コードを謎のバグ対応ずみのものに変更。
1,269 行
}
 
unsigned char str1[70]; // 表示結果を短くするために数値を微妙に小さくした
printf("機械語を読み取っています。\n"); // 「文字列」ではなく機械語
 
fread(str1, sizeof(unsigned char), 50150, fp1);
char str2[70]; // 表示結果を短くするために数値を微妙に小さくした
int endCount ;
for (int i = 0; i < sizeof(str1) / sizeof(str1[0]); i = i + 1) {
if (str1[i] > 0 && str1[i] < 256 ) {
str2[i] = str1[i] ;
}
else { endCount = i;
str2[i] = 0x00 ;
break; }
}
 
printf("\nファイルに書いてある機械語\n");
 
for (int i = 0; i < sizeof(str1) / sizeof(str1[0]); i = i + 1) {
printf("%02x ", str1[i]); // 最低でも2桁を表示、の意味
}
 
 
printf("\nファイルに書いてある機械語2\n");
 
for (int i = 0; i < sizeof(str2) / sizeof(str2[0]); i = i + 1) {
printf("%02x ", str2[i]); // 最低でも2桁を表示、の意味
}
 
 
printf("\n文字の繰り返しを検出しようとしています...\n");
1,295 ⟶ 1,321行目:
 
int temp = 0;
int breakLoopbreakFor = 0; // for から抜けるためのフラグ
 
for (temp = 0; temp <= 12; temp = temp + 1) {
1,308 ⟶ 1,334行目:
press1[1] = bufRep[0];
preCount = +2;
breakLoopbreakFor = 1;
break;
} else if (str1[temp] == 0) {
breakLoopbreakFor = 1;
// ヌルが来たら文末などと判断し、他に何もせずに抜け出す
break;
} // else if
 
if (breakLoopbreakFor == 1) {
break;
}
1,340 ⟶ 1,366行目:
int hokan = temp; // 次のforの開始番号用
 
int loopNumloop = 1;
 
int count ;
breakLoopbreakFor = 0; // 下記 while のbreak フラグ用
while (breakLoopbreakFor == 0) {
if(loop == endCount ) {
 
repFlag = 0;
breakFor = 1;
break;
}
hokan = temp;
bufWord[loopNumloop] = str1[hokan + 1];
bufRep[loopNumloop] = 1;
 
press1[preCount + 0] = bufWord[loopNumloop];
press1[preCount + 1] = bufRep[loopNumloop];
 
repFlag = 1; // 次のループ用に再セット
for (temp = hokan + 1; temp <= 255; temp = temp + 1) {
if (repFlag == 1) {
 
if (str1[temp + 1] == str1[temp] && str1[temp] != 0) {
bufRep[loopNumloop] = bufRep[loopNumloop] + 1;
repFlag = 1;
 
1,363 ⟶ 1,402行目:
 
repFlag = 0;
press1[preCount + 0] = bufWord[loopNumloop];
press1[preCount + 1] = bufRep[loopNumloop];
preCount = preCount + 2;
 
break;
} else if (str1[temp] == 0) {
breakLoopbreakFor = 1; // ヌルが来たら文末などと判断し ループから break
break;
1,375 ⟶ 1,414行目:
 
else {
breakLoopbreakFor = 1; // 無限ループ防止のため 想定外の自体はループから break
 
break;
} // else if
} else {
breakLoopbreakFor = 1; // 無限ループ防止のため 想定外の自体はループから break
 
break;
1,388 ⟶ 1,427行目:
} // for
 
printf("loop: %02x \n", loopNumloop); // 最低でも2桁を表示、
 
printf("記録する文字%dの機械語: %02x \n", loopNumloop,
bufWord[loopNumloop]); // 最低でも2桁を表示、の意味
printf("その文字の現在の回数: %02x \n",
bufRep[loopNumloop]); // 最低でも2桁を表示、の意味
 
printf("圧縮する文字%dの機械語: %02x ", loopNumloop,
press1[2 * loopNumloop]); // 最低でも2桁を表示、の意味
printf("その文字の現在の回数: %02x ",
press1[2 * loopNumloop + 1]); // 最低でも2桁を表示、の意味
 
printf("\n次の書き込みカウンター位置: %02x \n",
preCount); // 最低でも2桁を表示、の意味
 
loopNumloop = loopNumloop + 1;
} // while
 
printf("\nランレングス的に圧縮のシミュレーション...\n");
 
for (int i = 0; i < preCount + 20; i = i + 1) {
printf("%02x ", press1[i]); // 最低でも2桁を表示、の意味
}
 
printf("\nファイルに書いてある機械語1\n");
fclose(fp1);
 
for (int i = 0; i < endCount; i = i + 1) {
printf("%02x ", str1[i]); // 最低でも2桁を表示、の意味
}
printf("\nファイルに書いてある機械語2\n");
 
for (int i = 0; i < endCount; i = i + 1) {
printf("%02x ", str2[i]); // 最低でも2桁を表示、の意味
}
 
fclose(fp1);
printf("\nファイルをクローズしました。\n");
}
1,421 ⟶ 1,473行目:
ファイルをオープンしました。
機械語を読み取っています。
 
ファイルに書いてある機械語
61 61 61 61 61 62 63 64 65 65 65 65 65 65 00 00 ffffff9800 5500 5100 000 00 00 00 00 00 00 00
ffffb4 00 00 ffffffeb00 fffffffe00 fffffffe00 98 55 49 00 00 00 00 00 b4 00 69 fe fe 07 00 00 ffffffc020 191c 40 00 00 0
fffff9a 2c ffffffc40 00 00 0073 008b 50b1 fffffff2ce 5300 00 00 00 c0 f1 4b 00 00 1000
ファイルに書いてある機械語2
00 00 00 00 00 00 00 00
61 61 61 61 61 62 63 64 65 65 65 65 65 65 00 00 10 3a 30 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 11 00 01 10 fffffffe 07 00 00 00 00 00 0
0 00 00 00 00 ffffffca 12 ffffff82 77 00 00 00 00 40 15 40 00 00 00
文字の繰り返しを検出しようとしています...
記録する文字1の機械語: 61
1,459 ⟶ 1,515行目:
 
ランレングス的に圧縮のシミュレーション...
61 05 62 01 63 01 64 01 65 06 00 01
ファイルに書いてある機械語1
61 61 61 61 61 62 63 64 65 65 65 65 65 65
ファイルに書いてある機械語2
01 00 00 00 06 00 00 00 01 00 00 00 65 65
ファイルをクローズしました。
 
</pre>
 
1,466 ⟶ 1,527行目:
 
あとはこのコードを、PackBitsになるように改良していけばいいだけである。
 
 
上記コードで機械語を格納する配列を2種類(str1 と str2)用意している理由は、なぜか最後に書き込みした機械語を格納している配列が書き換わってしまうバグ的な現象があるため、それを波及させないように2つ配列を用意しているという理由にもとづく。(「機械語1」と「機械語2」の結果がなぜか違っている。)
 
=== ASCII文字の英文の圧縮の原理 ===