added 2d dft + bmp api (TESTING - may break!)
authorhackbard <hackbard>
Wed, 6 Oct 2004 18:33:30 +0000 (18:33 +0000)
committerhackbard <hackbard>
Wed, 6 Oct 2004 18:33:30 +0000 (18:33 +0000)
bmp/bmp.c [new file with mode: 0644]
bmp/bmp.h [new file with mode: 0644]
fourier/fourier.c
fourier/fourier.h

diff --git a/bmp/bmp.c b/bmp/bmp.c
new file mode 100644 (file)
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)<BMP_H_SIZE+BMP_I_SIZE) {
+    dprintf(bmp->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;y<bmp->info.height;y++) {
+    if(read(bmp->fd,bmp->map+y*bmp->info.width,xsize)<xsize) {
+      dprintf(bmp->outfd,"[bmp] reading image data of line %d failed\n",y);
+      return B_E_READ_DATA;
+    }
+    if(read(bmp->fd,buf,crop)<crop) {
+      dprintf(bmp->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 (file)
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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* 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
index 045bf65..d322bc0 100644 (file)
@@ -24,6 +24,9 @@ int fourier_alloc_data(t_fourier *fourier) {
   size=1;
   for(i=0;i<fourier->dim;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<<m==fourier->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;i<m;i++) mask[i]=1<<i;
+  for(i=0;i<fourier->data_len[0];i++) {
+    r=0;
+    for(j=0;j<m;j++) r+=(((i&mask[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;i<fourier->log2len[0];i++) {
 
-  
+
+  // }
+
+
+  for(i=0;i<fourier->data_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;v<Y;v++) {
+    off=v*X;
+    for(u=0;u<X;u++) {
+      fourier->ftdata[off+u].r=0;
+      fourier->ftdata[off+u].i=0;
+      for(y=0;y<Y;y++) {
+        off_r=y*X;
+        for(x=0;x<X;x++) {
+          arg=-2.0*M_PI*((1.0*u*x)/X+(1.0*v*y)/Y);
+          fourier->ftdata[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) {
index fcaa3e9..57ef187 100644 (file)
@@ -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