ppm

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

ppm

#1

投稿記事 by mayuta » 15年前

今、北海道の工業系の大学に通っているものです。Cのプログラミングをして1年の初心者です。
現在、C++でマンデルブロを描画するためにPPMを使って描画しようとしているのですが、PPM画像用のヘッダにエラーが出ます。

ppb_ppm.h(35) : error C2514: 'real_ppm::stat' : クラスにコンストラクタが定義されていません。
ppb_ppm.h(30) : 'real_ppm::stat' の宣言を確認してください。
ppb_ppm.h(36) : error C2228: '.st_size' の左側はクラス、構造体、共用体でなければなりません。
型は 'real_ppm::stat *' です。
代わりに '->' を使用しますか?

どこを直したらエラーがなくなるでしょうか。皆さんのお力を貸してください。
実行環境は、microsoft windows xp sp3、microsoft visual C++ 2008 express editionです。

以下にPPMのヘッダを書きます。




/* ppm.h */
#ifndef _PPB_PPM_H
#define _PPB_PPM_H

#define PPM_MAGIC "P6"



typedef struct _rgb_t{
unsigned char r;
unsigned char g;
unsigned char b;
} rgb_t;

typedef struct _image_t{
int width;
int height;
rgb_t *buf;
} image_t;



int real_ppm(image_t* img,char* fname){
char *token, *pc;
char *buf;
char *del=" \t\n";

int filesize;
int i,w,h,luma,pixs;

struct stat *st;

rgb_t *dot;
FILE *fp;

stat(fname,&st);
filesize=(int)st.st_size;

buf=(char *)malloc(filesize*sizeof(char));

if((fp=fopen(fname, "r"))==NULL){
printf("Failed to open file\n");
return -1;
}

fseek(fp,0,SEEK_SET);
fread(buf,filesize * sizeof(char),1,fp);

fclose(fp);

token=(char *)strtok(buf,del);
if(strncmp(token,PPM_MAGIC,2) !=0){
return -1;
}

token=(char *)strtok(NULL,del);

if(token[0]=='#'){
token=(char *)strtok(NULL,"\n");
token=(char *)strtok(NULL,del);
}

w=strtoul(token,&pc,10);
token=(char *)strtok(NULL,del);
h=strtoul(token,&pc,10);
token=(char *)strtok(NULL,del);
luma=strtoul(token,&pc,10);

token=pc+1;

pixs=w*h;


img->buf=(rgb_t *)malloc(pixs * sizeof(rgb_t));


dot=img->buf;
for(i=0;i<pixs;i++,dot++){
dot->r=*token++;
dot->g=*token++;
dot->b=*token++;
}

img->width=w;
img->height=h;
return 0;
}


int write_ppm(image_t* img, char* fname){
int i,j;
int w=img->width;
int h=img->height;

FILE *fp;
if((fp=fopen(fname,"wb+"))==NULL){
fprintf(stderr,"failed to open file %s\n",fname);
return -1;
}


fprintf(fp,"%s\n%d %d\n255\n",PPM_MAGIC,w,h);


for(i=0;i<w;i++){
for(j=0;j<h;j++){
putc((int)img->buf[i*w+j].r,fp);
putc((int)img->buf[i*w+j].g,fp);
putc((int)img->buf[i*w+j].b,fp);
}
}
fclose(fp);
return 0;
}


void new_image(image_t* img,int w, int h){
img->width=w;
img->height=h;
img->buf=(rgb_t*)malloc(w*h*sizeof(rgb_t));
}


void delete_image(image_t *img){
free(img->buf);
}

#endif

mayuta

Re:ppm

#2

投稿記事 by mayuta » 15年前

すみません。タグを使わないで投稿してしまいました、見づらくて申し訳ございません。。。。

Poco

Re:ppm

#3

投稿記事 by Poco » 15年前

上記コードでは手元でコンパイルできないので、確認はしていません。

struct stat *st; → struct stat st;
stat(fname,&st); → ::stat(fname,&st);

でどうですか?

mayuta

Re:ppm

#4

投稿記事 by mayuta » 15年前

実行してみたのですが、

ppb_ppm.h(30) : error C2079: 'st' が 未定義の struct 'real_ppm::stat' で使用しています。
ppb_ppm.h(35) : error C2039: 'stat' : '`global namespace'' のメンバではありません。

という、エラーが増えてしまいました。。

mayuta

Re:ppm

#5

投稿記事 by mayuta » 15年前

マンデルブロのコードは、


/* mandel */

#include<stdio.h>
#include<stdlib.h>
#include "stdbool.h"
#include<limits.h>
#include "pthread.h"
#include <string.h>
#include "ppb_ppm.h"

#define THREAD_NUM 2
#define STEP_HEIGHT 10
#define JOB_NUM (IMG_HEIGHT/STEP_HEIGHT)

#define OUTPUT "out.ppm"
#define IMG_WIDTH 400
#define IMG_HEIGHT 400

#define COUNT_MAX 0xfff
#define REAL_MIN -1.5
#define REAL_MAX 1.5
#define IMAG_MIN -1.5
#define IMAG_MAX 1.5
#define SCALE_REAL ((REAL_MAX - REAL_MIN) / IMG_WIDTH)
#define SCALE_IMAG ((IMAG_MAX - IMAG_MIN) / IMG_HEIGHT)


typedef struct _complex{
float real;
float imag;
} complex_t;


typedef struct _thread_arg{
int id;
image_t *img;
} thread_arg_t;


typedef struct _job{
int x, y, w, h;
} job_t;

job_t mandel_jobs[JOB_NUM];
pthread_mutex_t job_mutex;
int job_index;



void init_jobs(){
int i;
for(i=0;i<JOB_NUM;i++){
[pre]mandel_jobs.x=0;
[/pre]
[pre]mandel_jobs.y=(IMG_HEIGHT/JOB_NUM)*i;
[/pre]
[pre]mandel_jobs.w=IMG_WIDTH;
[/pre]
[pre]mandel_jobs.h=STEP_HEIGHT;
[/pre]
}
pthread_mutex_init(&job_mutex,NULL);
job_index=0;

}


job_t *get_next_job(){
int index;
pthread_mutex_lock(&job_mutex);
if(job_index+1==JOB_NUM){
[pre]pthread_mutex_unlock(&job_mutex);
[/pre]
[pre]return NULL;
[/pre]
}
index=job_index++;
pthread_mutex_unlock(&job_mutex);
return &mandel_jobs[index];
}


void plot_point(rgb_t* buf,unsigned int color){
buf->r=(color&(0xf)<<8)>>4;
buf->g=(color&(0xf)<<4);
buf->b=(color&0xf)<<4;
}


unsigned int calc_point(complex_t c){
unsigned int count=0;
float temp, length_sq;
complex_t z;
z.real=z.imag=0.0f;
do{
[pre]temp=z.real*z.real-z.imag*z.imag+c.real;
[/pre]
[pre]z.imag=2*z.real*z.imag+c.imag;
[/pre]
[pre]z.real=temp;
[/pre]
[pre]length_sq=z.real*z.real+z.imag*z.imag;
[/pre]
[pre]count++;
[/pre]
} while ((length_sq<4.0)&&(count<COUNT_MAX));
return count;
}



void plot_mandelbrot(image_t *img,int sx, int sy, int w, int h){
complex_t c;
int x,y;
for(x=sx;x<sx+w;x++){
[pre]for(y=sy;y<sy+h;y++){
[/pre]
[pre][pre]c.real = REAL_MIN + ((float)x * SCALE_REAL);
[/pre][/pre]
[pre][pre]c.imag = IMAG_MIN + ((float)y * SCALE_IMAG);
[/pre][/pre]
[pre][pre]plot_point(&img->buf[y * IMG_WIDTH + x], calc_point(c));
[/pre][/pre]
[pre]}
[/pre]
}
}


void thread_func(void *arg){
thread_arg_t *targ=(thread_arg_t *)arg;
job_t *job;
while ((job=get_next_job()) !=NULL)
[pre]plot_mandelbrot(targ->img,job->x,job->y,job->w,job->h);
[/pre]
}


int main(){
int i;
image_t img;
pthread_t handle[THREAD_NUM];
thread_arg_t targ[THREAD_NUM];
new_image(&img,IMG_WIDTH,IMG_HEIGHT);
init_jobs();
for(i=0;i<THREAD_NUM;i++){
[pre]targ.id=i;
[/pre]
[pre]targ.img=&img;
[/pre]
[pre]pthread_create(&handle,NULL,(void *(__cdecl *)(void *))thread_func,(void *)&targ);
[/pre]
}

for(i=0;i<THREAD_NUM;i++)
[pre]pthread_join(handle,NULL);
[/pre]

write_ppm(&img,OUTPUT);
delete_image(&img);
return 0;

}

です。

Poco

Re:ppm

#6

投稿記事 by Poco » 15年前

> 実行してみたのですが、
>
> ppb_ppm.h(30) : error C2079: 'st' が 未定義の struct 'real_ppm::stat' で使用しています。
> ppb_ppm.h(35) : error C2039: 'stat' : '`global namespace'' のメンバではありません。
>
> という、エラーが増えてしまいました。。

構造体struct statが定義されているヘッダファイルをインクルードしてください。
同様に、関数statが定義されているヘッダファイルをインクルードしてください。

閉鎖

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