このディレクトリの索引

# 出典 :: C/C++の宿題片付けます 130代目 #715 # 1] 授業単元: プログラミング # [2] 問題文(含コード&リンク): # http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9970.txt# 1)Raw形式PGMファイルから,画像を読み込む関数を実装せよ. # 2)画像データをRaw形式PGMファイルへ書き出す関数を実装せよ. # 3)実装した読み込み,書き出し関数を用いて,任意のRaw形式PGMファイルを読み込み,別の名前のRaw形式PGMファイルとして書き出すプログラムを作成せよ. # 作成するプログラムの要求仕様は以下の通りである. # 実行ファイル名 任意の名前(自分で決めて良い)仮に ReadWrite とする # # 実行書式 ReadWrite [入力ファイル] [出力ファイル] 入力ファイル名,出力ファイル名とも省略不可 # # ソースファイル名 実行ファイル名.c(例では ReadWrite.c となる) # プログラムに要求される動作 [入力ファイル]で示されたPGM形式ファイルを読み込み,[出力ファイル]に示されるPGM形式ファイルに出力する. # 備考 このプログラムのmain関数が置かれるソースファイル(ReadWrite.c)にファイル入出力関数を記述することは, # 以下に示す「再利用性」の観点から好ましくない.すなわち,本課題では,少なくとも # 1)ReadWrite.c(main関数を記述),2)ファイル入出力を行う関数を実装したソースファイル,の2ファイルを作成する必要がある. # 関数プロトタイプ宣言は共通ヘッダファイルに記述しても良い. # 解説 http://nojiriko.asia/data/t753.txt # 1. Raw形式PGMファイルから,画像データを読み込む関数を実装せよ. # 任意の名前のRaw形式PGMファイルから画像データを読み込み,第1週で実装した画像用構造体に格納する関数を作成せよ. # 画像の縦横サイズは画像ファイルから取得するとし,いかなるサイズの画像でも読み込める関数とすること. # # C言語では,テキストファイルとバイナリファイルとのそれぞれに対して利用するファイル入出力関数が異なる. # # Raw形式PGMファイルは,ファイル中にヘッダとデータをそれぞれ「テキスト」,「バイナリ」として含んでいるので,それぞれの読み込みに利用する関数が異なる. # ファイルのオープン・クローズはそれぞれ1回でよい.UNIX(厳密には“POSIX企画に準拠したOS”)ではテキストファイル・バイナリファイルの区別を行わないので, # 実引数 mode の指定における 'b' はあってもなくても良い. # # 2.画像データをRaw形式PGMファイルへ書き出す関数を実装せよ. # 第1週で設計・実装したデータ構造に格納されている画像データを任意の名前のRaw形式PGMファイルへ出力する関数を作成せよ.注意点は1)と同様である. # # 実装についての注意点 # データ構造や各種関数は,再利用性を充分に考慮して実装すること.例えば, # 設計・実装したデータ構造はヘッダファイルにテンプレート宣言を記述する. # 2,3で実装した画像入出力関数は,本演習における画像処理の基本となり何度も利 # 用する関数であるので,分割コンパイルを利用して今後作成するプログラムから容易に # 再利用できるよう実装せよ.【図書2pp.224-239】が参考になる. # # # # # # 第1週で実装した画像用構造体 # typedef struct{ # int width; # int height; # unsigned char *p; # }image_t; # # P2 # # Shows the word "FEEP" (example from Netpbm man page on PGM) # 24 7 # 15 t753(_入力ファイル,_出力ファイル) :- abolish(画像構造/2), 'PGMファイルを低水準に読み出す'(_入力ファイル,_出力ファイル). 'PGMファイルを低水準に読み出す'(_入力ファイル,_画像構造ならび) :- 頭部を読み取る(_入力ファイル,_頭部の文字数), 画像データの読み込み(_入力ファイル,_頭部の文字数,_画像データ), assertz(画像構造(画像データ,_画像データ)). headerを読み取る(_入力ファイル,_型,_行,_深さ,_頭部の文字数) :- open(_入力ファイル,read,_入力), '型・行・深さを得る'(_入力,_型,_行,_深さ,_頭部の文字数), close(_入力). '型・行・深さを得る'(_入力,_型,_行,_深さ,_頭部の文字数) :- 行入力(_入力,_行), '型・行・深さを得る'(_入力,_行,[],0,_型,_行,_深さ,_頭部の文字数). '型・行・深さを得る'(_入力,_行,[_深さ,_行,_型],_頭部の文字数,[_型,_行,_深さ],_頭部の文字数) :- !. '型・行・深さを得る'(_入力,_行,L1,_頭部の文字数_1,_型,_行,_深さ,_頭部の文字数) :- 'コメント行は無視して、_頭部の文字数だけ更新'(_入力,_行,L1,_頭部の文字数_1,_型,_行,_深さ,_頭部の文字数),!. '型・行・深さを得る'(_入力,_行,L1,_頭部の文字数_1,_型,_行,_深さ,_頭部の文字数) :- '型・行・深さを埋めていく'(_入力,_行,L1,_頭部の文字数_1,_型,_行,_深さ,_頭部の文字数). 'コメント行は無視して、_頭部の文字数だけ更新'(_入力,_行,L1,_頭部の文字数_1,_型,_行,_深さ,_頭部の文字数) :- sub_atom(_行,0,1,_,'#'), '改行を含むコメント行の文字数を求めて_頭部文字数を更新する'(_行,_頭部文字数_1,_頭部文字数_2), 行入力(_入力,_行2), '型・行・深さを得る'(_入力,_行2,L1,_頭部の文字数_2,_型,_行,_深さ,_頭部の文字数). '改行を含むコメント行の文字数を求めて_頭部文字数を更新する'(_行,_頭部文字数_1,_頭部文字数_2) :- atom_length(_行,_行の文字数), _頭部の文字数_2 is _頭部の文字数 + _行の文字数 + 1. '型・行・深さを埋めていく'(_入力,_行,L1,_頭部の文字数_1,_型,_行,_深さ,_頭部の文字数) :- 行入力(_入力,_行_2), atom_length(_行,_行の文字数), _頭部の文字数_2 is _頭部の文字数_1 + _行の文字数 + 1, '型・行・深さを得る'(_入力,_行_2,_頭部の文字数_2,[_行|L1],_型,_行,_深さ,_頭部の文字数). 画像データの読み込み(_入力ファイル,_頭部の文字数,_画像データ) :- open(_入力ファイル,read,_入力,[type(binary)]), 頭部部分を空読み(_入力,_頭部の文字数), 画像データ部分の読み取り(_入力,_画像データ), close(_入力). 頭部部分を空読み(_入力,_頭部の文字数) :- between(1,_頭部の文字数,N), get_byte(_入力,_), N = _頭部の文字数,!. 画像データ部分の読み取り(_入力,_画像データ) :- findall(_コード,( '1バイトずつ読み出す'(_コード), (_コード = -1,!,fail;true)),_画像データ). '1バイトずつ読み出す'(_入力,_コード) :- repeat, get_byte(_入力,_コード). 行入力(_入力,_行) :- read_line_to_codes(_入力,_コードならび), atom_codes(_行,_コードならび).