Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放.

Similar presentations


Presentation on theme: "1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放."— Presentation transcript:

1 1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放

2 2 画像ファイル内での画素データのフォーマット データ構造 ~ 1 画素をどう表現するか~ typedef struct { unsigned char r; unsigned char g; unsigned char b; } PIXEL, *PPIXEL; 88 (136) B1 (177) E7 (231) 8A (138) B2 (178) E7 (231) … 1 画素あたり RGB 各 8 ビット 合計 3 バイト 88 B1 E7 PIXEL 構造体 r g b

3 3 画像ファイル内での画素データのフォーマット データ構造 ~ 1 画素をどう表現するか~ typedef struct { unsigned char r; unsigned char g; unsigned char b; } PIXEL, *PPIXEL; 88 (136) B1 (177) E7 (231) 8A (138) B2 (178) E7 (231) … 1 画素あたり RGB 各 8 ビット 合計 3 バイト 88 B1 E7 PIXEL 構造体 r g b PIXEL 構造体へのポインタ型. 名前は PPIXEL にするよ この構造体の型名は PIXEL にするよ

4 4 データ構造 ~画像データをどう表現するか~ typedef struct { int xsize; int ysize; int level; PPIXEL *pBuffer; } IMAGE; 画像ファイルのフォーマット ヘッダー ( 画像サイズ,最大輝度 ) 画像データ 256 192 255 IMAGE 構造体 xsize ysize level pBuffer 画像データのサイズは,ヘッダ読み込み後 でないと分からない → 画像用のメモリは [ ] 88 (136) B1 (177) E7 (231)

5 5 データ構造 ~画像データをどう表現するか~ typedef struct { int xsize; int ysize; int level; PPIXEL *pBuffer; } IMAGE; 画像ファイルのフォーマット ヘッダー ( 画像サイズ,最大輝度 ) 画像データ 画像データのサイズは,ヘッダ読み込み後 でないと分からない → 画像用のメモリは 動的 に確保 256 192 255 IMAGE 構造体 xsize ysize level pBuffer PPIXEL へのポインタ = ( PIXEL へのポインタ)へのポイン タ 88 (136) B1 (177) E7 (231)

6 6 ポインタの配列 ~課題 2 の文字列のソートの復習~ strawberry\0 lines[0] lines[1] lines[2] watermelon\0 banana\0 lines[MAXLINES-1] char *lines[MAXLINES]; 文字列にあわせた長さ 定数 MAXLINES 個 ( 20000 )

7 7 ポインタの配列 ~画像バッファの確 保~ void iioMallocImageBuffer(IMAGE *pImage) 256 192 255 xsize ysize level pBuffer ysize 個の [ ] の配列を確保 malloc(ysize * sizeof(PPIXEL)); xsize 個の [ ] の配列を確保 malloc(xsize * sizeof(PIXEL)); pImage

8 8 ポインタの配列 ~画像バッファの確 保~ void iioMallocImageBuffer(IMAGE *pImage) 256 192 255 xsize ysize level pBuffer xsize 個の PIXEL の配列を確保 malloc(xsize * sizeof(PIXEL)); pImage ysize 個の PPIXEL の配列を確保 malloc(ysize * sizeof(PPIXEL));

9 9 モジュール設計 どういう機能を用意するか モジュールごとの独立性をどう高めるか メイン main.c 画像処理 img_proc.c img_proc.h 画像のファイル入出力 画像データ用メモリ確保と解放 img_io.c img_io.h

10 10 復習:コンパイラの動作 (1) コンパイラはソースファイルを [ ] // 呼び出される関数 double func(double d) { return 0.0; } // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・ 関数呼出部分をコンパイルす るときに、コンパイラは呼び 出される関数の引数の数・型、 戻り値の型を知っておく必要 がある

11 11 復習:コンパイラの動作 (1) コンパイラはソースファイルを上から下へ解釈し ていく // 呼び出される関数 double func(double d) { return 0.0; } // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・ 関数呼出部分をコンパイルす るときに、コンパイラは呼び 出される関数の引数の数・型、 戻り値の型を知っておく必要 がある

12 12 コンパイラの動作 (2) 関数記述位置の上下を逆にすると・・・ // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } 正常にコンパイルできない ( C 処理系では warning が、 C++ 処理系ではエラーが発 生する)

13 13 コンパイラの動作 (2) 関数記述位置の上下を逆にすると・・・ // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } func 関数の引数の型も 引数の個数も知らないぞ・・・ 正常にコンパイルできない ( C 処理系では warning が、 C++ 処理系ではエラーが発 生する)

14 14 関数プロトタイプ宣言 double func(double d); // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } 関数呼出部分より前に [ ] を行うことにより、正常にコン パイルが可能となる func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・

15 15 関数プロトタイプ宣言 double func(double d); // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } // 呼び出される関数 double func(double d) { return 0.0; } 関数呼出部分より前に プロトタイプ宣 言 を行うことにより、正常にコン パイルが可能となる func という関数は、 double を受 け取って double を返すんだ な・・ double を渡して double を返し てもらうようなコードを生成し よう・・ 4 は 4.0 に変換してから渡そ う・・・ 最後はセミコロ ン

16 16 分割コンパイル ソースファイルを複数に分割し、それぞれをコンパイルしてできたオブジェ クトファイルをリンカで結合 更新されたソースファイルのみコンパイルすればよいため、プログラムの規 模が大きくなった場合でも、微細な変更時のビルド時間を大幅に短縮可能 gin.clime.c gin.objlime.objlibc.lib ginlime.exe ソースファイル オブジェクトファイル 実行ファイル ライブラリファイル ( コンパイル済 ) [ ]

17 17 分割コンパイル ソースファイルを複数に分割し、それぞれをコンパイルしてできたオブジェ クトファイルをリンカで結合 更新されたソースファイルのみコンパイルすればよいため、プログラムの規 模が大きくなった場合でも、微細な変更時のビルド時間を大幅に短縮可能 gin.clime.c gin.objlime.objlibc.lib ginlime.exe ソースファイル オブジェクトファイル 実行ファイル リンク コンパイル ライブラリファイル ( コンパイル済 )

18 18 単純にファイルを分割すると … // 呼び出される関数 double func(double d) { return 0.0; } module.c // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } caller.c コンパイルは [ ] ため、 caller.c は正常にコンパイルできない。 func って何 ?

19 19 単純にファイルを分割すると … // 呼び出される関数 double func(double d) { return 0.0; } module.c // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出し } caller.c コンパイルは ファイル単位で別々に実行さ れる ため、 caller.c は正常にコンパイルできない。 func って何 ?

20 20 ヘッダファイルの利用 #include “module.h” // 呼び出される関数 double func(double d) { return 0.0; } module.c #include “module.h” // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出 し } caller.c // プロトタイプ宣言 double func(double d); module.h コンパイラは #include 擬似命令 の部分で、 module.h ファイルを 読み込む 呼び出される関数のプロトタイプ宣言は に記述 呼び出し側のソースファイルで #include 擬似命令により、ヘッダ ファイル内の宣言を読み込む ヘッダファイル ” ” で囲んでいる ことに注意!

21 21 ヘッダファイルの利用 #include “module.h” // 呼び出される関数 double func(double d) { return 0.0; } module.c #include “module.h” // 呼び出し側関数 int caller(void) { f = func(4); // 関数呼び出 し } caller.c // プロトタイプ宣言 double func(double d); module.h 呼び出される関数のプロトタイプ宣言はヘッダファイルに記述 呼び出し側のソースファイルで #include 擬似命令により、ヘッダ ファイル内の宣言を読み込む ヘッダファイル コンパイラは #include 擬似命令 の部分で、 module.h ファイルを 読み込む ” ” で囲んでいる ことに注意!

22 22 と " " #include のように で囲まれて いると,プリプロセッサはシステムで定められた 場所にあるファイルを取り込む #include “module.h” のように ” ” で囲まれて いると,まずプログラムファイルと同じ場所を探 し,存在しない場合はシステムで定められた場所 を探す

23 23 モジュール化の基本 #include #include “module.h” int internal_func(int a); #define INT_MACRO(a) (…) static int internal_func(int a) { // モジュール内で // 使用する関数 } #define MAX 1024 typedef unsigned char BYTE; void exported_func(int i); module.c module.h void exported_func(int i) { // 外部に公開する関数 } ヘッダファイルには [ ] 関数のプロトタイプ宣 言 typedef 型宣言 #define マクロ定義 など プロトタイプ宣言が関数本体と一 致するように注意 モジュール内のみで使用する関数 のプロトタイプ宣言やマクロ定義 などは [ ] で 行う

24 24 モジュール化の基本 #include #include “module.h” int internal_func(int a); #define INT_MACRO(a) (…) static int internal_func(int a) { // モジュール内で // 使用する関数 } module.c module.h void exported_func(int i) { // 外部に公開する関数 } ヘッダファイルには 外部に公開する情報のみを記述 関数のプロトタイプ宣 言 typedef 型宣言 #define マクロ定義 など プロトタイプ宣言が関数本体と一 致するように注意 モジュール内のみで使用する関数 のプロトタイプ宣言やマクロ定義 などはモジュール内で行う モジュールで,何を公開し, 何を隠すかがポイント #define MAX 1024 typedef unsigned char BYTE; void exported_func(int i);

25 25 ファイルを分割したときの関数のス コープ × ○ #include #include “module.h” int internal_func(int a); #define INT_MACRO(a) (…) static int internal_func(int a) { // モジュール内で // 使用する関数 } module.c module.h void exported_func(int i) { // 外部に公開する関数 } #define MAX 1024 typedef unsigned char BYTE; void exported_func(int i); 別のモジュール #include “module.h” exported_func(15); internal_func(30); foo.c ヘッダファイルにプロトタイプ宣言がない 関数は外部から参照できない static な関数は外部から参照できない 見え る ?

26 26 img_io.c 画像ファイルのロード ファイルオープン 画像バッファ確保 データコピー ファイルクローズ 画像ファイルのセーブ 画像バッファ確保 画像バッファ解放 サンプルプログラム 2 の関数呼び出し 関係 main.c 画像ファイルをロードする関数を呼び出す 画像処理関数を呼び出す 画像ファイルをセーブする関数を呼び出す 画像バッファを解放 img_proc.c 画像を 90 度回転 作業用バッファを確保 データを移し変え 不要なバッファを解放 ( あとで処理を追加したい ) etc

27 27 img_io.c 画像ファイルのロード ファイルオープン 画像バッファ確保 データコピー ファイルクローズ 画像ファイルのセーブ 画像バッファ確保 画像バッファ解放 サンプルプログラム 2 の関数呼び出し 関係 main.c 画像ファイルをロードする関数を呼び出す 画像処理関数を呼び出す 画像ファイルをセーブする関数を呼び出す 画像バッファを解放 img_proc.c 画像を 90 度回転 作業用バッファを確保 データを移し変え 不要なバッファを解放 ( あとで処理を追加したい ) etc

28 28 関数の設計 ファイル入出力&メモリ確保 / 解放 関連 int iioLoadFile(IMAGE *pImage, const char *fname); int iioSaveFile(IMAGE *pImage, const char *fname); void iioMallocImageBuffer(IMAGE *pImage); void iioFreeImageBuffer(IMAGE *pImage); 画像処理関連 void ipRotateImage(IMAGE *pImage);

29 29 関数の設計 ファイル入出力&メモリ確保 / 解放 関連 int iioLoadFile(IMAGE *pImage, const char *fname); int iioSaveFile(IMAGE *pImage, const char *fname); void iioMallocImageBuffer(IMAGE *pImage); void iioFreeImageBuffer(IMAGE *pImage); 画像処理関連 void ipRotateImage(IMAGE *pImage); IMAGE 構造体 へのポインタ ファイル名を表す 文字列へのポイン タ

30 30 サンプルプログラム2の説明 実装済みの関数( main 関数, iioLoadFile , iioMallocImageBuffer )の説明をするので 配布資料のサンプルプログラムを見ること

31 31 画像ファイルのセーブ 出力用ファイルを バイナリモードでオープン ヘッダ情報を出力 画像データを出力 ファイルクローズ 開始 終了 int iioSaveFile(IMAGE *pImage, const char *fname) 256 192 255 xsize ysize level pBuffer pImage pBuffer[0] pBuffer[1] pBuffer[2] 一行ずつ出力 ヒント: fwrite ヒント 1: fprintf ヒント 2: xsize の後ろに空白 1 つ ysize の後ろに改行 level の後ろに改行 を忘れない

32 32 画像バッファの解放 void iioFreeImageBuffer(IMAGE *pImage) pBuffer を解放 ② 開始 終了 j < ysize? 256 192 255 xsize ysize level pBuffer pImage pBuffer[0] pBuffer[1] pBuffer[2] ① 一行ずつ解放 ②最後に各行へのポイ ンタの配列を解放 pBuffer[ j ] を解放 ① j++; j =0; Y N


Download ppt "1 全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える 処理後のデータを出力ファイルに書き出す 画像データ用に確保したメモリを解放."

Similar presentations


Ads by Google