From f8382861ee7bff6d129bd149579d26bf9b81ada0 Mon Sep 17 00:00:00 2001 From: hackbard Date: Wed, 6 Oct 2004 18:33:30 +0000 Subject: [PATCH] added 2d dft + bmp api (TESTING - may break!) --- bmp/bmp.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++ bmp/bmp.h | 73 ++++++++++++++++++++++++ fourier/fourier.c | 105 +++++++++++++++++++++++++++++++++- fourier/fourier.h | 6 ++ 4 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 bmp/bmp.c create mode 100644 bmp/bmp.h diff --git a/bmp/bmp.c b/bmp/bmp.c new file mode 100644 index 0000000..2476140 --- /dev/null +++ b/bmp/bmp.c @@ -0,0 +1,141 @@ +/* bmp.c -- bmp write/read api + * + * author: hackbard@hackdaworld.dyndns.org + * + */ + +#include "bmp.h" + +int bmp_init(t_bmp *bmp,int outfd) { + + dprintf(outfd,"[bmp] initializing bmp api ...\n"); + + memset(bmp,0,sizeof(t_bmp)); + bmp->outfd=outfd; + + return B_SUCCESS; +} + +int bmp_shutdown(t_bmp *bmp) { + + if(bmp->map!=NULL) { + dprintf(bmp->outfd,"[bmp] free pixmap memory\n"); + free(bmp->map); + } + + dprintf(bmp->outfd,"[bmp] shutdown\n"); + + return B_SUCCESS; +} + +int bmp_check_header_and_info(t_bmp *bmp) { + + if(bmp->info.compression!=0) { + dprintf(bmp->outfd,"[bmp] compression not supported\n"); + return B_NO_SUPPORT; + } + + if(bmp->info.bpp!=24) { + dprintf(bmp->outfd,"[bmp] only true color (24bpp) supported\n"); + return B_NO_SUPPORT; + } + + if(bmp->hdr.offset!=B_H_SIZE+B_I_SIZE) { + dprintf(bmp->outfd,"[bmp] files with %d bytes offset not supported\n", + bmp->hdr-offset); + return B_NO_SUPPORT; + } + + if(bmp->info.size!=BMP_I_SIZE) { + dprintf(bmp->outfd,"[bmp] files with %d bytes info size not supported\n", + bmp->info.size); + return B_NO_SUPPORT; + } + + return B_SUCCESS; +} + +int bmp_write_file(t_bmp *bmp) { + + int fill,xsize,size; + + xsize=bmp->width*3; + fill=(4-(xsize%4))%4; + size=(xsize+fill)*bmp->height; + + /* construct it */ + bmp->hdr.identifier='B'|('M'<<8); + bmp->hdr.size=size+BMP_H_SIZE+BMP_I_SIZE; + bmp->hdr.offset=BMP_H_SIZE+BMP_I_SIZE; + bmp->info.size=BMP_I_SIZE; + bmp->info.width=bmp->width; + bmp->info.height=bmp->height; + bmp->info.planes=1; + bmp->info.bpp=24; + bmp->info.imagesize=size; + if(bmp->info.xres==0) bmp->info.xres=2048; + if(bmp->info.yres==0) bmp->info.yres=2048; + bmp->info.noc=0; + bmp->info.ic=0; + + /* write it */ + ... + + + return B_SUCCESS; +} + +int bmp_read_file(t_bmp *bmp) { + + unsigned char buf[BMP_HI_SIZE]; + int y,xsize; + int crop; + unsigned char *data; + + if(!(bmp->mode&READ)) { + dprintf(bmp->outfd,"[bmp] read mode not specified"); + return B_NO_READ_MODE; + } + + if((bmp->fd=open(bmp->file,O_RDONLY))<0) { + dprintf(bmp->outfd,"[bmp] unable to open file %s\n",bmp->file); + return B_NO_FILE; + } + + if(read(bmp->fd,buf,BMP_H_SIZE+BMP_I_SIZE)outfd,"[bmp] error reading bmp header & info\n"); + return B_NO_HI; + } + + memcpy(&(bmp->hdr),buf,BMP_H_SIZE); + memcpy(&(bmp->info),buf+BMP_H_SIZE,BMP_I_SIZE); + + if(bmp_check_header_and_info(bmp)!=B_SUCCESS) { + dprintf(bmp->outfd,"[bmp] header/info check failed\n"); + return B_HI_FAIL; + } + + bmp->map=(t_pixel *)malloc(bmp->info.width*bmp->info.height*sizeof(t_pixel)); + if(bmp->map==NULL) { + dprintf(bmp->outfd,"[bmp] malloc of map memory failed\n"); + return B_E_MEM; + } + + crop=(bmp->info.imagesize/bmp->info.height)%4; + xsize=(bmp->info.bpp/8)*bmp->info.width; + + for(y=0;yinfo.height;y++) { + if(read(bmp->fd,bmp->map+y*bmp->info.width,xsize)outfd,"[bmp] reading image data of line %d failed\n",y); + return B_E_READ_DATA; + } + if(read(bmp->fd,buf,crop)outfd,"[bmp] failed reading rest of line\n"); + return B_E_READ_DATA; + } + } + + close(bmp->fd); + + return B_SUCCESS; +} diff --git a/bmp/bmp.h b/bmp/bmp.h new file mode 100644 index 0000000..58bee0a --- /dev/null +++ b/bmp/bmp.h @@ -0,0 +1,73 @@ +/* bmp.h -- bmp headers */ + +#ifndef BMP_H +#define BMP_H + +/* includes */ +#define _GNU_SOURCE +#include +#include +#include + +/* defines */ +#define B_SUCCESS 1 +#define B_ERROR -1 +#define B_NO_READ_MODE -2 +#define B_NO_FILE -3 +#define B_NO_HI -4 +#define B_NO_SUPPORT -5 +#define B_HI_FAIL -6 +#define B_E_MEM -7 +#define B_E_READ_DATA -8; +#define MAX_CHARS_FILE 32 +#define BMP_H_SIZE 14 +#define BMP_I_SIZE 40 + +/* bmp specific variables */ +typedef struct s_bmp_hdr { + unsigned short int identifier; + unsigned int size; + unsigned short int reserved1; + unsigned short int reserved2; + unsigned int offset; /* <- 14 + 40 bytes = 0x36 */ +} t_bmp_hdr; /* 14 bytes */ + +typedef struct s_bmp_info { + unsigned int size; /* 40 bytes = 0x28 */ + int width; + int height; + unsigned short int planes; + unsigned short int bpp; + unsigned int compression; + unsigned int imagesize; + unsigned int xres; + unsigned int yres; + unsigned int noc; + unsigned int ic; +} t_bmp_info; /* 40 bytes */ + +typedef struct s_pixel { + unsigned char r; + unsigned char g; + unsigned char b; +} t_pixel; + +typedef struct s_bmp { + int outfd; + int width; + int height; + unsigned char mode; +#define READ (1<<0) +#define WRITE (1<<1) + char file[MAX_CHARS_FILE]; + int fd; + t_bmp_hdr hdr; + t_bmp_info info; + t_pixel *map; +} t_bmp; + +/* function prototypes */ +int bmp_init(t_bmp *bmp); +int bmp_shutdown(t_bmp *bmp); + +#endif diff --git a/fourier/fourier.c b/fourier/fourier.c index 045bf65..d322bc0 100644 --- a/fourier/fourier.c +++ b/fourier/fourier.c @@ -24,6 +24,9 @@ int fourier_alloc_data(t_fourier *fourier) { size=1; for(i=0;idim;i++) size*=fourier->data_len[i]; + dprintf(fourier->outfd,"[fourier] allocating %d bytes for data ...\n", + 2*size*sizeof(t_complex)); + fourier->data=(t_complex *)malloc(2*size*sizeof(t_complex)); fourier->ftdata=&(fourier->data[size]); @@ -46,11 +49,77 @@ int fourier_shutdown(t_fourier *fourier) { return F_SUCCESS; } +/* fft functions */ + +int fourier_fft_1d_init(t_fourier *fourier) { + + unsigned int i,j,m,r; + int mask[32]; + + /* calculate m = log 2 (N) + check N = 2^m */ + m=0; + while(m<32) { + if(1<data_len[0]) break; + else m++; + } + if(m==32) { + dprintf(fourier->outfd, + "[fourier] fft impossible (N > 2^32 or not a power of 2\n"); + return F_FFT_IMPOSSIBLE; + } + dprintf(fourier->outfd,"[fourier] log2(%d) = %d\n",fourier->data_len[0],m); + fourier->log2len[0]=m; + + /* pointer array which will point to reversed t_complex data */ + fourier->revdata=(t_complex **)malloc(fourier->data_len[0]*sizeof(t_complex *)); + if(fourier->revdata==NULL) { + dprintf(fourier->outfd, + "[fourier] malloc for reversed data pointers failed\n"); + return F_ALLOC_FAIL; + } + + dprintf(fourier->outfd,"[fourier] fft: allocated data pointers\n"); + + /* swap data (bit reversal) */ + for(i=0;idata_len[0];i++) { + r=0; + for(j=0;j>j)<<(m-j-1)); + fourier->revdata[i]=fourier->ftdata+r; + } + + return F_SUCCESS; +} + +int fourier_fft_1d_shutdown(t_fourier *fourier) { + + dprintf(fourier->outfd,"[fourier] fft shutdown\n"); + + free(fourier->revdata); + + return F_SUCCESS; +} + + int fourier_fft_1d(t_fourier *fourier) { - int i,j,k; + int i,j; + + /* copy src to destination, destination is modified in place */ + memcpy(fourier->ftdata,fourier->data,fourier->data_len[0]*sizeof(t_complex)); + /* from now on access bit reversed data by revdata[i]->... */ + + // for(i=0;ilog2len[0];i++) { - + + // } + + + for(i=0;idata_len[0];i++) + dprintf(fourier->outfd,"%f %f\n", + fourier->ftdata[i]->r,fourier->revdata[i]->i); + + return F_NOT_SUPPORTED; return F_SUCCESS; } @@ -90,7 +159,37 @@ int fourier_dft_1d(t_fourier *fourier) { } int fourier_dft_2d(t_fourier *fourier) { - return F_NOT_SUPPORTED; + + int off_f,off_r; + int u,v,x,y; + int X,Y; + double arg; + + X=fourier->data_len[0]; + Y=fourier->data_len[1]; + + if(fourier->type&BWD) return F_NOT_SUPPORTED; + + /* stupid way - actually you would do: ft_on_index_1(ft_on_index_2(f(x,y))) */ + for(v=0;vftdata[off+u].r=0; + fourier->ftdata[off+u].i=0; + for(y=0;yftdata[off+u].r+=(cos(arg)*fourier->data[off_r+x].r-sin(arg)*fourier->data[off_r+x].i); + fourier->ftdata[off+u].i+=(sin(arg)*fourier->data[off_r+x].r+cos(arg)*fourier->data[off_r+x].i); + } + } + fourier->ftdata[off_f+u].r/=(X*Y); + fourier->ftdata[off_f+u].i/=(X*Y); + } + } + + return F_SUCCESS; } int fourier_dft_3d(t_fourier *fourier) { diff --git a/fourier/fourier.h b/fourier/fourier.h index fcaa3e9..57ef187 100644 --- a/fourier/fourier.h +++ b/fourier/fourier.h @@ -16,6 +16,7 @@ #define F_NOT_SUPPORTED -2 #define F_DIM_FAILURE -3 #define F_ALLOC_FAIL -4 +#define F_FFT_IMPOSSIBLE -5 /* fourier specific variables */ typedef struct s_complex { @@ -34,7 +35,9 @@ typedef struct s_fourier { int dim; t_complex *data; t_complex *ftdata; + t_complex **revdata; int data_len[MAX_DIM]; + int log2len[MAX_DIM]; } t_fourier; /* function prototypes */ @@ -43,5 +46,8 @@ int fourier_alloc_data(t_fourier *fourier); int fourier_dft_1d(t_fourier *fourier); int fourier_dft_2d(t_fourier *fourier); int fourier_dft_3d(t_fourier *fourier); +int fourier_fft_1d_init(t_fourier *fourier); +int fourier_fft_1d(t_fourier *fourier); +int fourier_shutdown(t_fourier *fourier); #endif -- 2.20.1