プログラミング演習Ⅱ 課題4第3週

プログラミング演習Ⅱ
課題4第3週
iioLoadFile()と
iioMallocImageBuffer()の補足
iioLoadFile()
/*
int iioLoadFile(IMAGE *pImage, const char *fname)
画像ファイルをオープンし,
適切なサイズの画像バッファを確保し
IMAGE構造体に割り当てた後に,
画像バッファにデータをロードする.
Image *pImage
const char *fname
戻り値
:
:
:
IMAGE構造体へのポインタ
入力ファイル名
0(ファイルのロード成功)
1(ファイルのロード失敗)
*/
int iioLoadFile(IMAGE *pImage, const char *fname)
{
FILE *fpr;
char
lineBuffer[LINEMAX];
int
i;
/* ファイルオープン */
if ((fpr = fopen(fname, "rb")) == NULL) {
perror(fname);
return 1;
}
/* ヘッダ部読み込み開始 */
fgets(lineBuffer, LINEMAX, fpr);
if (strcmp(lineBuffer, "P6\n")) {
// ERROR
fclose(fpr);
return 1;
}
ヘ
ッ
ダ
ー
fgets(lineBuffer, LINEMAX, fpr);
デ
ー
タ
長さ
2バイト
1バイト
不定
不定
不定
1バイト
不定
1バイト
不定
不定
…
/* コメント行の読み飛ばし */
while (lineBuffer[0] == '#')
fgets(lineBuffer, LINEMAX, fpr);
"rb"は、read biinary
内容
P6
改行コード
横幅を示すアスキー文字列
セパレーター(空白)
縦幅を示すアスキー文字列
改行コード
最大輝度を表すアスキー文字
改行コード
輝度を示す値(バイナリ)
輝度を示す値(バイナリ)
…
/* IMAGE構造体のメンバ変数に,画像の幅,高さをセット.*/
sscanf(lineBuffer, "%d %d\n", &pImage->xsize, &pImage->ysize);
fgets(lineBuffer, LINEMAX, fpr);
/* IMAGE構造体のメンバ変数に,画像の最大輝度をセット.*/
sscanf(lineBuffer, "%d", &pImage->level);
/* ヘッダ部読み込み終了 */
/* バッファ用メモリ確保 */
iioMallocImageBuffer(pImage);
/* バッファに画像データを格納 */
freadを画像の行数分だけ繰り返す
for (i = 0; i < pImage->ysize; i++){
fread(pImage->pBuffer[i], sizeof(PIXEL), pImage->xsize, fpr);
}
fwriteも使い方は同じ
/* ファイルクローズ */
fclose(fpr);
return 0;
}
iioSaveFile()の作り方
int iioSaveFile(IMAGE *pImage, const char *fname)
{
FILE *fpw; ←ファイル出力用ファイルポインタ
int i; ←画像の行数だけ繰り返すループ変数
/* ファイルオープン*/ ←iioLoadFileと同じ。但し、"rb"⇒"wb"
fpr⇒fpw
/* ヘッダ出力 */
fprintf(fpw,"P6\n%d %d\n%d\n",
pImage->xsize,pImage->ysize,pImage->level);
P6
xsize ysize
level
/* 画像データをファイルへ出力 */ ←iioLoadFileと同じ。
但し、fread⇒fwrite
fpr⇒fpw
fclose(fpw);
return 0;
}
iioMallocImageBuffer()
void iioMallocImageBuffer(IMAGE *pImage)
{
int i; ←画像の行数だけ繰り返すループ変数
pImage->pBuffer = malloc(pImage->ysize*sizeof(PPIXEL));
ysize個のPPIXEL
の配列を確保
malloc(ysize * sizeof(PPIXEL));
for (i = 0; i < pImage->ysize; i++){
pImage->pBuffer[i] = malloc(pImage->xsize * sizeof(PIXEL));
}
}
xsize個のPIXEL
の配列を確保
pImage->pBuffer
malloc(xsize * sizeof(PIXEL));
iioFreeImageBuffer()の作り方
void iioFreeImageBuffer(IMAGE *pImage)
{
int i; ←画像の行数だけ繰り返すループ変数
方針:Bを開放してからAを開放する
pImage->pBuffer
A
B
Bを開放
for (i = 0; i < pImage->ysize; i++){
pImage->pBuffer[i] = malloc(pImage->xsize * sizeof(PIXEL));
free( /* mallocで確保した1行分のBの領域を解放*/ );
}
Aを開放
free( /* mallocで確保したAの領域を解放*/ );
pImage->pBuffer
A
B
メモリリークの確認方法(1)
freeで正しく解放されていない場合,メモリリークが起こる.
デバッグ時のコマンドライン引数の設定
ツールバーのプロジェクト(P)→ex4_2のプロパティ→構成プロパティ → デバッグ
作業ディレクトリに.\Debug ,コマンド引数に img01.ppm result.ppm と記述
デバッグ実行し,出力ウィンドウを見る
メモリリークの確認方法(2)
OK
NG
~省略~
(他に, _CrtDumpMemoryLeaks();の戻り値をチェックしてもよい)