アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fuyo

アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

#1

投稿記事 by fuyo » 12年前

アスキー形式とバイナリー形式の二つのグレースケール画像を識別して読み込み、そのファイルの内容を出力するプログラムを作っているのですが、なかなかうまくいきません。どこがいけないでしょうか。お願いします。

コード:

#include<stdio.h>
#define MAX_IMAGE_SIZE 512
#define NUM 300

int main(int argc, char *argv[])
{
  FILE *fp;
  unsigned char idat[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
  char d[2];
  int i,j;
  int a = 0;
  if(argc!=2){
    printf("Usage: %s [input]\n", argv[0]);
    return 1;
  }

 if((fp=fopen(argv[1], "r"))==NULL){
    printf("input file open error\n");
    return 1;
  }

for(i=0;i<2;i++){
  fscanf(fp,"%d", &d[i]);
    }
 printf("image size: %s\n",d[1]);
   fclose(fp);


 if(d[0]==P2){
   fp=fopen(argv[1], "r");
   fseek(fp,4,SEEK_SET);
   for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
     fscanf(fp,"%d",&idat[i]);
    }
  fclose(fp);
 }else if(d[0]==P5){
   fp=fopen(argv[1], "rb");
   fseek(fp,4,SEEK_SET);
   for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
    fread(&idat[i], sizeof(unsigned char),1,fp);
    }
   fclose(fp);
 }else{
   return 1;
 }

 for(i=0;i<5;i++){
   for(j=0;j<5;j++){
     printf("(%d,%d) gray = %d\n", j,i,idat[a]);
     a++;
   }
 }
  return 0;
}

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

#2

投稿記事 by bitter_fox » 12年前

fuyo さんが書きました:アスキー形式とバイナリー形式の二つのグレースケール画像を識別して読み込み、そのファイルの内容を出力するプログラムを作っているのですが、なかなかうまくいきません。どこがいけないでしょうか。
具体的にどこがどううまくいかないのですか?

それからインデントは正しくしっかりつけましょう。

コード:


#include<stdio.h>
#define MAX_IMAGE_SIZE 512
#define NUM 300

int main(int argc, char *argv[])
{
	FILE *fp;
	unsigned char idat[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
	char d[2];
	int i,j;
	int a = 0;
	if(argc!=2){
		printf("Usage: %s [input]\n", argv[0]);
		return 1;
	}

	if((fp=fopen(argv[1], "r"))==NULL){
		printf("input file open error\n");
		return 1;
	}

	for(i=0;i<2;i++){
		fscanf(fp,"%d", &d[i]);
	}
	printf("image size: %s\n",d[1]);
	fclose(fp);


	if(d[0]==P2){
		fp=fopen(argv[1], "r");
		fseek(fp,4,SEEK_SET);
		for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
			fscanf(fp,"%d",&idat[i]);
		}
		fclose(fp);
	}else if(d[0]==P5){
		fp=fopen(argv[1], "rb");
		fseek(fp,4,SEEK_SET);
		for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
			fread(&idat[i], sizeof(unsigned char),1,fp);
		}
		fclose(fp);
	}else{
		return 1;
	}

	for(i=0;i<5;i++){
		for(j=0;j<5;j++){
			printf("(%d,%d) gray = %d\n", j,i,idat[a]);
			a++;
		}
	}
	return 0;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

#3

投稿記事 by softya(ソフト屋) » 12年前

なぞの事が多いので読み込むファイルの仕様(テキストとバイナリ)と起動パラメータの仕様を明らかにして下さい。
あと「なかなかうまくいきません」だそうですが、同ダメなのか説明してみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

fuyo

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

#4

投稿記事 by fuyo » 12年前

失礼しました。strはchar型にしたのですが、printf("image size: %s x %s\n",d[4], d[6]);のところと if(d[1]==2) else if(d[1]==5)のところがうまく読み取れていないのだと思います。
printf("image size: %s x %s\n",d[4], d[6]);では"4x4"を表示させたくて、if(d[1]==2) else if(d[1]==5)のところではP2かP5かを判別したいです。
さっきとコードを少しかえました。

コード:

#include<stdio.h>
#define MAX_IMAGE_SIZE 512
#define NUM 300

int main(int argc, char *argue[])
{
   FILE *fp;
   unsigned char idat[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
   char d[3];
   int i, j;
   int a = 0;
   if(argc!=2){
      printf("Usage: %s [input]\n", argv[0]);
          return 1;
     }

     if((fp=fopen(argv[1], "r"))==NULL){
          printf("input file open error\n");
          return 1;
     }

     for(i=0;i<3;i++){
          fscans(fp,"%s", &d[i]);
     }
     printf("image size: %s x %s\n",d[1], d[2]);
     fclose(fp);

     if(d[1]==2){
           fp=fopen(argv[1], "r");
           fseek(fp,4,SEEK_SET);
           for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
                fscanf(fp,"%s",&idat[i]);
     }
     fclose(fp);
     }else if(d[1]==5){
   	   fp=fopen(argv[1], "rb");
   	   fseek(fp,4,SEEK_SET);
          for(i=0;i<MAX_IMAGE_SIZE*MAX_IMAGE_SIZE;i++){
    	        fread(&idat[i], sizeof(unsigned char),1,fp);
     }
    fclose(fp);
    }else{
          return 1;
    }

    for(i=0;i<5;i++){
   	for(j=0;j<5;j++){
     		printf("(%d, %d) gray = %s\n", j, i, idat[a]);
    	 	a++;
        }
    }
    return 0;
}


アスキー型
P2
4 4
255
0 0 255 255 0 0 255 255 255 255 0 0 255 255 0 0

バイナリ型
P5
4 4
255
0 0 255 255 0 0 255 255 255 255 0 0 255 255 0 0

お願いします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

#5

投稿記事 by softya(ソフト屋) » 12年前

調べて見ましたが、これPGMのファイルフォーマットですね?
GIMP2で作って見ましたが、書かれているフォーマットと違うようです。
これが正解なのか、ご自身の書いたた物が正解なのか判断をお願いします。ただ、P2とP5が同じ形式なのは変だと思います。
気になるのは2行目のコメントの有無とP5の実際のフォーマットです。

[追記] それと指摘されていますがインデントが出鱈目です。インデントが何か分からないら聞いて下さい。

[P2] アスキー形式

コード:

P2
# CREATOR: GIMP PNM Filter Version 1.1
4 4
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
[P5] バイナリ形式 16進数ダンプ

コード:

 ADDRESS   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   0123456789ABCDEF 
------------------------------------------------------------------------------
 00000000  50 35 0A 23 20 43 52 45 41 54 4F 52 3A 20 47 49   P5.# CREATOR: GI 
 00000010  4D 50 20 50 4E 4D 20 46 69 6C 74 65 72 20 56 65   MP PNM Filter Ve 
 00000020  72 73 69 6F 6E 20 31 2E 31 0A 34 20 34 0A 32 35   rsion 1.1.4 4.25 
 00000030  35 0A FF FF FF FF FF FF FF FF FF FF FF FF FF FF   5............... 
 00000040  FF FF  
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

fuyo

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

#6

投稿記事 by fuyo » 12年前

ファイルの形式はPPM形式でした。
実際アスキー型のファイルをcat コマンドで表示すると

$ cat checker4x4_ascii.pgm
P2
4 4
255
0 0 255 255 0 0 255 255 255 255 0 0 255 255 0 0

となり実行すると

$ ./6-1a checker4x4_ascii.pgm
image size: 4x4
(0,0) gray = 0
(1,0) gray = 0
(2,0) gray = 255
(3,0) gray = 255
(0,1) gray = 0
(1,1) gray = 0
(2,1) gray = 255
(3,1) gray = 255
(0,2) gray = 255
(1,2) gray = 255
(2,2) gray = 0
(3,2) gray = 0
(0,3) gray = 255
(1,3) gray = 255
(2,3) gray = 0
(3,3) gray = 0

となればいいのですが、4x4となるはずのところが80x52と分け分からない数字がでてきて、その後が表示されません。

バイナリ型だと
$ ./6-1a checker4x4_binary.pgm
image size: 4x4
(0,0) gray = 0
(1,0) gray = 0
(2,0) gray = 255
(3,0) gray = 255
(0,1) gray = 0
(1,1) gray = 0
(2,1) gray = 255
(3,1) gray = 255
(0,2) gray = 255
(1,2) gray = 255
(2,2) gray = 0
(3,2) gray = 0
(0,3) gray = 255
(1,3) gray = 255
(2,3) gray = 0
(3,3) gray = 0

となるのが正しいです。

分かりにくくてすみません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: アスキー形式とバイナリー形式の二つのグレースケール画像を識別し読み込み、ファイルの内容を出力する。

#7

投稿記事 by softya(ソフト屋) » 12年前

PPMと言うのはP3とP6形式しか無くフルカラー用みたいです。グレイスケールですよね?情報は正確にお願いします。
cat checker4x4_ascii.pgm と名前はpgmですよね?

catで表示されている形式を信用すると、コメントは意識しなくて良いということでよいでしょうか?
規格的にはコメントを考慮する必要があるみたいですが。

まず、プログラムの問題ですが今のプログラムはコンパイルが通りませんので、コンパイルが通るようにしてインデントを直したプログラムを投稿してもらえませんか?
あとコメントもしてみてください。理解度が分かります。

それと文字コードと数値データを混同しているフシが見受けられます。
if( d[1] == 2 )
とかは数字では無く文字のチエックですので
if( d[1] == '2' )
が正しいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る