グレースケール画像をファイルから読み込む関数と書き込む関数を
int load_pgm(const char *filename, int *w, int *h, unsigned char *buf);
int save_pgm(const char *filename, int w, int h, unsigned char *buf);
を次のプロトタイプ宣言を用いて作る。
(返り値は読み込み/書き込みに成功すれば 1 、失敗したら 0 とする。filename は入力となるファイル名、w, h は画像の横幅と縦幅、buf は画像データが入った配列とする。)
という課題に挑戦していますが方針が立ちません。
一応下記のとおりに作りました。
#include <stdio.h>
#define MAX_IMAGE_SIZE 512
int load_pgm(const char *filename, int *w, int *h, unsigned char *buf);
int save_pgm(const char *filename, int w, int h, unsigned char *buf);
int main(int argc,char *argv[])
{
int wide,height;
unsigned char data;
char name[MAX_IMAGE_SIZE];
load_pgm(argv[1], &wide, &height, name);
save_pgm(argv[2], wide, height, name);
}
int load_pgm(const char *filename, int *w, int *h, unsigned char *buf)
{
int i,j;
char P[6][3]={"P1", "P2", "P3", "P4", "P5", "P6"};
char hedda[3];
char aka;
int a, p;
FILE *fp1;
fp1=fopen(filename, "rb");
if (fp1 == NULL){
printf("ファイルをオープンできませんでした。\n");
return 0;
}
fscanf(fp1, "%s", hedda);
fscanf(fp1, "%d %d", w, h);
fscanf(fp1, "%d", &aka);
for(i=0; i<6; i++){
if(strcmp(P[i], hedda)==0)
p=i;
}
if(p==1){
for(i=0; i<*w; i++){
for(j=0; j<*h; j++){
a = i + *w * *h;
fscanf(fp1, "%d", buf[a]);
}
}
return 1;
}
else if(p==4){
fseek(fp1, 1, SEEK_CUR);
for(i=0; i<*w; i++){
for(j=0; j<*h; j++){
a = i + *w * *h;
fread(&buf[a], sizeof(unsigned char), 1, fp1);
}
}
fclose(fp1);
return 1;
}
else{
fclose(fp1);
return 0;
}
}
int save_pgm(const char *filename, int w, int h, unsigned char *buf)
{
int a,i,j;
FILE *fp2;
fp2=fopen(filename, "wb");
if (fp2 == NULL){
printf("ファイルをオープンできませんでした。\n");
return 0;
}
fprintf(fp2, "%s ", hedda);
fprintf(fp2, "%d %d ", w, h);
fprintf(fp2, "%d " ,aka);
for(i=0; i<w; i++){
for(j=0; j<h; j++){
a = i + w * h;
fprintf(fp2,"%d ", buf[a]);
}
}
fclose(fp2);
return 1;
}
とりあえずまず聞きたいことは、pgmファイルのヘッダ記号 P2やP4 などは書き込みの関数の渡し方と、バイナリファイルへのデータの書き込み方(fprintf)の使い方です。