今、北海道の工業系の大学に通っているものです。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
ppm
Re:ppm
マンデルブロのコードは、
/* 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{
typedef struct _thread_arg{
typedef struct _job{
job_t mandel_jobs[JOB_NUM];
pthread_mutex_t job_mutex;
int job_index;
void init_jobs(){
}
job_t *get_next_job(){
void plot_point(rgb_t* buf,unsigned int color){
unsigned int calc_point(complex_t c){
void plot_mandelbrot(image_t *img,int sx, int sy, int w, int h){
void thread_func(void *arg){
}
int main(){
}
です。
/* 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;
}
です。