このディレクトリの索引

# 【質問テンプレ】 
# [1] 授業単元 C言語 
# [2] 問題文(含コード&リンク): 
# 二つのバイナリファイルの中身を比較して等しいか、等しくないかを 
# 比較して結果を返す関数を作る 

二つのバイナリファイルの中身を比較(_ファイル1,_ファイル2,_診断) :- 
open(ファイル1,read,_ストリーム1,[type(binary)]), 
    open(ファイル2,read,_ストリーム2,[type(binary)]), 
    get_byte(_ストリーム1,A), 
    get_byte(_ストリーム2,B), 
    二つのバイナリファイルの中身を比較(_ストリーム1,_ストリーム2,A,B,_診断), 
    close(_ストリーム1), 
    close(_ストリーム2). 

二つのバイナリファイルの中身を比較(_,_,-1,-1,等しい) :- !. 
二つのバイナリファイルの中身を比較(_,_,A,B,等しくない) :- not(A=B),!. 
二つのバイナリファイルの中身を比較(_ストリーム1,_ストリーム2,A,A,_診断) :- 
    get_byte(_ストリーム1,C), 
    get_byte(_ストリーム2,D), 
    二つのバイナリファイルの中身を比較(_ストリーム1,_ストリーム2,C,D,_診断).

#  1] 授業単元: プログラミング  
#  [2] 問題文(含コード&リンク):  
# 2)画像データをRaw形式PGMファイルへ書き出す関数を実装せよ.
# 3)実装した読み込み,書き出し関数を用いて,任意のRaw形式PGMファイルを読み込み,別の名前のRaw形式PGMファイルとして書き出すプログラムを作成せよ.
#     作成するプログラムの要求仕様は以下の通りである.
# 実行ファイル名             任意の名前(自分で決めて良い)仮に ReadWrite とする 
# 
# 実行書式                   ReadWrite [入力ファイル] [出力ファイル] 入力ファイル名,出力ファイル名とも省略不可
# 
# ソースファイル名           実行ファイル名.c(例では ReadWrite.c となる)
# プログラムに要求される動作 [入力ファイル]で示されたPGM形式ファイルを読み込み,[出力ファイル]に示されるPGM形式ファイルに出力する.
# 備考                       このプログラムのmain関数が置かれるソースファイル(ReadWrite.c)にファイル入出力関数を記述することは,
#                            以下に示す「再利用性」の観点から好ましくない.すなわち,本課題では,少なくとも
#                           1)ReadWrite.c(main関数を記述),2)ファイル入出力を行う関数を実装したソースファイル,の2ファイルを作成する必要がある.
#                            関数プロトタイプ宣言は共通ヘッダファイルに記述しても良い.

# 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;

t753(_入力ファイル,_出力ファイル) :-
    abolish(画像構造/2),
    raw_read_pgm(_入力ファイル,_出力ファイル).

raw_read_pgm(_入力ファイル,_画像構造ならび,_画像rawmodeデータ) :-    
    headerを読み取る(_入力ファイル,_headerの文字数),
    画像データの読み込み(_入力ファイル,_画像データ),
    assertz(画像構造(画像データ,_画像データ)).

headerの解析(_header,[_行|R]) :-
    sub_atom(_行,0,1,_残り文字,'#'),
    _残り文字の二 is _残り文字 - 1,
    sub_atom(_行,1,_残り文字2,_,_コメント),
    assertz(画像構造(コメント,_コメント)).

headerを読み取る(_入力ファイル,_headerの文字数) :-
    open(_入力ファイル,read,Input),
    get_line(Input,_型),
    get_line(Input,_行),
    atomic_length(_型,Len1),
    atomic_length(_行,Len2),
    headerを読み取る(Input,_行,_headerの文字数2),
    _headerの文字数 is _headerの文字数2 + Len1 + Len2 + 2,
    close(Input).

headerを読み取る(Input,'',_文字数) :-
    get_line(Input,_行),
    split(_行,[' '],[X,Y]),
    get_line(Input,_深さ文字列),
    atom_to_term(_深さ文字列,_深さ,_),
    atomic_length(_行,Len1),
    atomic_length(_深さ,Len2),
    _文字数 is 1 + Len1 + 1 + Len2 + 1,
    assertz(画像構造(画面サイズ,[X,Y])),
    assertz(画像構造(色深度,_深さ)),!.
headerを読み取る(Input,_行,_文字数) :-
    header解析(_行),
    atomic_length(_行,Len),
    get_line(Input,_行2),
    headerを読み取る(Input,_行2,_文字数2),
    _文字数 is _文字数2 + Len + 1.

画像データの読み込み(_入力ファイル,_headerサイズ) :-
    open(_入力ファイル,read,Input,[type(binary]),
    for(1,N,_headerサイズ),
    get_byte(Input,_),
    N = _headerサイズ,
    画像データ部分の読み取り(Input,_画像データ),
    close(input2),
    assertz(画像構造(画像データ,_画像データ)),!.

画像データ部分の読み取り(Input,_画像データ) :-
    findall(U,(repeat,get_byte(Input,C),(C = -1,!,fail;true)),_画像データ).
#  [1] 授業単元:卒業研究 
#  [2] 問題文:白黒濃淡画像をガンマ補正するプログラムを作る 

ガンマ補正(_画像ファイル,_Headerの長さ,_ガンマ補正,_補正された画像ファイル) :- 
    open(_画像ファイル,read,Input,[type(binary)]), 
    open(_補正された画像フィル,write,Output,[type(binary)]), 
    for(1,N,_Headerの長さ), 
    get_byte(Input,C), 
    put_byte(Output,C), 
    N=_Headerの長さ, 
    get_byte(Input,C2), 
    ガンマ補正の一(C2,Input,Output,_ガンマ補正), 
    close(Output), 
    close(Input),!. 

ガンマ補正の一(-1,_,_,_) :- !.
ガンマ補正の一(C,Input,Output,_ガンマ補正) :- 
    _補正された値 is truncate(floor((( C / 255 ) ^ (1 / _ガンマ補正)) * 255 + 0.5)), 
    put_byte(Output,_補正された値), 
    get_byte(Input,C2), 
    ガンマ補正の一(C2,Input,Output,_ガンマ補正).

# 1] 授業単元: プログラミング
# ★演習問題3
# 氏名,年齢,性別が5人分書かれた次のようなテキストファイルを読み
# 込んで、両面に表示するプログラムを作成せよ.このとき,構造体を利用
# せよ.
#  (入力ファイル:test.txtの中身)
#
# Tanaka 31 Man
# Kawai 24 Man
# Suzuki 22 Woman
# ltoh 40 Woman
# Sugita 37 Man 

'テキストファイルの内容を,別のテキストファイルにコピーする'(_コピー元ファイル,_コピー先ファイル) :-
    open(_コピー元ファイル,read,Input,[type(binary)]),
    open(_コピー先ファイル,write,Output,[type(binary)]),
    repeat,
    一文字読む(Input,C),
    一文字書き出す(Output,C),
    close(Input),
    close(Output),!.

一文字読む(Input,C) :- get_byte(C).

一文字書き出す(Output,-1) :- !.
一文字書き出す(Output,C) :- put_byte(Output,C),fail.!.

テキストファイルの中身の内容を画面に出力(_コピー元ファイル,_コピー先ファイル) :-
    get_lines(_コピー元ファイル,Lines1),
    get_lines(_コピー先ファイル,Lines2),
    '2テキストを並べて行表示'(Lines1,Lines2),!.

'2テキストを並べて行表示'([],[]) :- !.
'2テキストを並べて行表示'([A|R1],[B|R2]) :-
    write_formatted('%t %t\n',[A,B]),
    '2テキストを並べて行表示'(R1,R2).


# 1] 授業単元: プログラミング
#
# ★演習問題2
# fgetc関数とfputc関数を使って,テキストファイルの内容を,別のテキ
# ストファイルにコピーするプログラムを作成しなさい.確認のため,元の
# ファイルとコピーされたテキストファイルの中身の内容を画面にそれぞれ
# 出力せよ

'テキストファイルの内容を,別のテキストファイルにコピーする'(_コピー元ファイル,_コピー先ファイル) :-
    open(_コピー元ファイル,read,Input,[type(binary)]),
    open(_コピー先ファイル,write,Output,[type(binary)]),
    repeat,
    一文字読む(Input,C),
    一文字書き出す(Output,C),
    close(Input),
    close(Output),!.

一文字読む(Input,C) :- get_byte(C).

一文字書き出す(Output,-1) :- !.
一文字書き出す(Output,C) :- put_byte(Output,C),fail.!.

テキストファイルの中身の内容を画面に出力(_コピー元ファイル,_コピー先ファイル) :-
    get_lines(_コピー元ファイル,Lines1),
    get_lines(_コピー先ファイル,Lines2),
    '2テキストを並べて行表示'(Lines1,Lines2),!.

'2テキストを並べて行表示'([],[]) :- !.
'2テキストを並べて行表示'([A|R1],[B|R2]) :-
    write_formatted('%t %t\n',[A,B]),
    '2テキストを並べて行表示'(R1,R2).

#  ../test/read.cgi/tech/1263824755/361 
#  ≪問題と条件≫ 
#  第1引数に指定したファイルからバイナリーモードで1バイトずつファイルを読み込み、 
#  ファイルの内容を16進数で示したものを第2引数に指定したファイルに書き込むプログラムを作成せよ。ただし、16バイトごとに改行を入れること。 
#  (実行) 
#  >free1.exe test.txt test2.txt 
#   
#  でしょ? 
# 
# 

program :-
  user_parameters([FileIn,FileOut]),
  open(FileIn,read,Input,[type(binary)]),
  open(FileOut,write,Output),
  get_byte(Input,C),
  free1(0,Input,Output,C),
  close(Output),
  close(Input).

free1(_,_,_,-1) :- !.
free1(16,Input,Output,C) :-
  write(Output,'\n'),
  free1(0,Input,Output,C),!.
free1(M,Input,Output,C) :-
  free1(M,Input,Output,C) :-
  N進数(16,C,A),
  write(Output,A),
  get_byte(Input,C2),
  M2 is M + 1,
  free1(M2,Input,Output,C2).



#  [1] 授業単元:C言語演習 
#  [2] 問題文(含コード&リンク): 
#  1.fgets関数を用いてpgmファイルの始めの2行(添付ファイルの場合, P2, 304, 
#  322)をそれぞれ、変数header, width, heightに格納するプログラム 
#  2.上記で記憶したheader, width, heightを別ファイルに書き出すプログラム 
#  1.と2.をそれぞれ作成せよ。

pgmファイルヘッダの読み取り(_pgmファイル,_マジックナンバー,_画像の幅方向サイズ,_画像の高さサイズ,画像の最大階調レベル) :- 
      open(_pgmファイル,read,Input,[type(binary)]), 
      pgmヘッダ(Input,_マジックナンバー,_画像の幅方向サイズ,_画像の高さサイズ,画像の最大階調レベル), 
      close(Input),!. 

pgmファイルヘッダ(Input,_マジックナンバー,_画像の幅方向サイズ,_画像の高さサイズ,画像の最大階調レベル) :- 
      マジックナンバー(Input,_マジックナンバー), 
      画像の幅方向サイズ(Input,_画像の幅方向サイズ), 
      画像の幅方向サイズ(Input,_画像の幅方向サイズ), 
      画像の高さサイズ(Input,_画像の高さサイズ),!. 

マジックナンバー(Input,_マジックナンバー) :- 
      findall(Y,(repeat,get_byte(Input,X),('Whitespace'(X),!,fail;char_code(Y,X))),L), 
      concat_atom(L,_マジックナンバー),!. 

画像の幅方向サイズ(Input,_画像の幅方向サイズ) :- 
      findall(X,(repeat,get_byte(Input,X),('Whitespace'(X),!,fail;true)),L), 
      number_codes(_画像の幅方向サイズ,L),!. 

画像の高さサイズ(Input,_画像の高さサイズ) :- 
      findall(X,(repeat,get_byte(Input,X),('Whitespace'(X),!,fail;true)),L), 
      number_codes(_画像の高さサイズ,L),!. 

画像の最大階調レベル(Input,_画像の最大階調レベル) :- 
      findall(X,(repeat,get_byte(Input,X),('Whitespace'(X),!,fail;true)),L), 
      number_codes(_画像の最大階調レベル,L),!. 

'Whitespace'(X) :- X < 48. 
'Whitespace'(X) :- X > 57. 

マジックナンバー(Input,_マジックナンバー) :-
      findall(Y,(repeat,get_byte(Input,X),('Whitespace'(X),!,fail;char_code(Y,X))),L),
      concat_atom(L,_マジックナンバー),!.

画像の幅方向サイズ(Input,_画像の幅方向サイズ) :-
      repeat,
      get_byte(C),
      \+('Whitespace'(C)),
      findall(X,(repeat,get_byte(Input,X),('Whitespace'(X),!,fail;true)),L),
      number_codes(_画像の幅方向サイズ,[C|L]),!.