プロが教えるわが家の防犯対策術!

唐突ですみません。

サイズが640*480の画像を180枚読み込むプログラムをポインタを使って作成しようと考えています。

以下で示すプログラムは画像を読み込むための作成したものですが、エラーが出てしまい実行することができません。
間違えている箇所があればご指摘お願いします。
また、そのほかに効率の良いやり方などがありましたらご教授願います。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define xsize 640
#define ysize 480
#define round 180

#include "Input.h"

void Input_task(unsigned char ***In);

void main()
{
  static unsigned char ***In;
  int i,j;
  In=(unsigned char***)malloc(sizeof(unsigned char)*round);
  for(i=0;i<round;i++)
  {
    In[i]=(unsigned char**)malloc(sizeof(unsigned char)*ysize);
    for(j=0;j<ysize;j++)
    {
      In[i][j]=(unsigned char*)malloc(sizeof(unsigned char)*xsize);
    }
  }
  Input_task(In);
}



Input.hの中身
void Input_task(unsigned char ***In)
{
  char filename[30];
  int i,j,k;
  FILE *fp;

  for(i=0;i<round;i++)
  {
    sprintf(filename,"b20_%04d.raw",i);
    fp=fopen(filename,"rb");

   for(j=0;j<ysize;j++)
    {
      for(k=0;k<xsize;k++)
      {
        *(*(*(In+i)+j)+k)=(unsigned char)getc(fp);
      }
    }

   fclose(fp);
  }

}

A 回答 (2件)

★3次元配列のポインタ宣言が間違っています。


・3次元配列のポインタは『static unsigned char (*In)[ysize][xsize];』と宣言しますよ。
・ちなみに、3次元配列は『static unsigned char ln[round][ysize][xsize];』と同じになります。
・分かりますか?→多次元配列のポインタはなれないと難しいですよ。考え方が。宣言方法がね。
・『Input.h』内の『Input_task』の引数宣言も『unsigned char (*In)[ysize][xsize]』とします。

★その他
・640×480の画像を180枚ということは 55,296,000 バイト(約53Mバイト)ですよ。メモリ容量は大丈夫?
・『効率』良くというのならば、『getc』ではなく『fread』で一度に『640×480=307,200』バイトを
 読み込みます。→メモリを確保しているので出来ますよ。あとは、180枚分をループして読み込みます。
・サンプルを載せておきます。解説しませんので読み取って下さい。

/* main関数のサンプル */
void main()
{
 static unsigned char (*In)[ysize][xsize];
 
 if ( (In = (unsigned char (*)[ysize][xsize])malloc(round * ysize * xsize)) == NULL ){
  printf( "メモリが足りません。\n" );
  exit( 255 );
 }
 Input_task( In );
 free( In ); ←忘れずに!
}

/* Input.hの中身 */
void Input_task( unsigned char (*In)[ysize][xsize] )
{
 char filename[30];
 int i;
 FILE *fp;
 
 for ( i = 0 ; i < round ; i++ ){
  sprintf( filename, "b20_%04d.raw", i );
  
  if ( (fp = fopen(filename,"rb")) != NULL ){
   fread( In[i], xsize, ysize, fp );
   fclose( fp );
  }
 }
}

最後に:
・回答者 No.1 さんと同じくヘッダにはソースは記述してはいけません。→トラブルの原因になるから。
・また、単純に1次元配列を確保して自分で掛け算してアクセスするのも方法の1つですよ。
・以上。

この回答への補足

回答ありがとうございました。
実際まだポインタに慣れていないので、自分の理想とするものを作ることガで木津にいたのですが、この返答は理想に近いもので驚きました。

本当にありがとうございました。

補足日時:2006/12/22 21:41
    • good
    • 0

>In=(unsigned char***)malloc(sizeof(unsigned char)*round);


In=(unsigned char***)malloc(sizeof(unsigned char **)*round);

>In[i]=(unsigned char**)malloc(sizeof(unsigned char)*ysize);
In[i]=(unsigned char**)malloc(sizeof(unsigned char *)*ysize);

InとIn[i]はポインタの配列ですよ。


私なら・・・
単純に一次元配列で確保して
unsigned char *In;
In = (unsigned char*)malloc(sizeof(unsigned char)*round*ysize*xsize);

Input_taskの代入部分
*In++ = (unsigned char)getc(fp);

後から参照する時は
In[i*ysize*xsize + j*xsize + k]

あと、ヘッダファイルにはプログラムは書かないですね。
    • good
    • 0
この回答へのお礼

的確な回答ありがとうございました。
確かに、一次元配列で確保したほうがいいですね。
まだ慣れていないせいもあり、苦労しているところですTT

お礼日時:2006/12/22 21:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!