pike.git
/
src
/
modules
/
Image
/
dct.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/modules/Image/dct.c:1:
+
/* $Id: dct.c,v 1.1 1997/02/11 08:35:42 hubbe Exp $ */
-
+
#include "global.h"
+
+
#include <math.h>
+
#include <ctype.h>
+
+
#include "stralloc.h"
+
#include "global.h"
+
#include "types.h"
+
#include "macros.h"
+
#include "object.h"
+
#include "constants.h"
+
#include "interpret.h"
+
#include "svalue.h"
+
#include "array.h"
+
#include "error.h"
+
+
#include "image.h"
+
+
extern struct program *image_program;
+
#define THIS ((struct image *)(fp->current_storage))
+
#define THISOBJ (fp->current_object)
+
+
#define min(a,b) ((a)<(b)?(a):(b))
+
#define max(a,b) ((a)<(b)?(b):(a))
+
#define testrange(x) max(min((x),255),0)
+
+
static const double c0=0.70710678118654752440;
+
static const double pi=3.14159265358979323846;
+
+
void image_dct(INT32 args)
+
{
+
rgbd_group *area,*val;
+
struct object *o;
+
struct image *img;
+
INT32 x,y,u,v;
+
double xsz2,ysz2,enh,xp,yp,dx,dy;
+
double *costbl;
+
rgb_group *pix;
+
+
if (!THIS->img) error("no image\n");
+
+
fprintf(stderr,"%d bytes, %d bytes\n",
+
sizeof(rgbd_group)*THIS->xsize*THIS->ysize,
+
sizeof(rgb_group)*THIS->xsize*THIS->ysize+1);
+
+
if (!(area=malloc(sizeof(rgbd_group)*THIS->xsize*THIS->ysize+1)))
+
error("Out of memory\n");
+
+
if (!(costbl=malloc(sizeof(double)*THIS->xsize+1)))
+
{
+
free(area);
+
error("Out of memory\n");
+
}
+
+
o=clone(image_program,0);
+
img=(struct image*)(o->storage);
+
*img=*THIS;
+
+
if (args>=2
+
&& sp[-args].type==T_INT
+
&& sp[1-args].type==T_INT)
+
{
+
img->xsize=max(1,sp[-args].u.integer);
+
img->ysize=max(1,sp[1-args].u.integer);
+
}
+
else error("Illegal arguments to image->dct()\n");
+
+
if (!(img->img=malloc(sizeof(rgb_group)*img->xsize*img->ysize+1)))
+
{
+
free(area);
+
free(costbl);
+
free_object(o);
+
error("Out of memory\n");
+
}
+
+
xsz2=THIS->xsize*2.0;
+
ysz2=THIS->ysize*2.0;
+
+
enh=(8.0/THIS->xsize)*(8.0/THIS->ysize);
+
+
for (u=0; u<THIS->xsize; u++)
+
{
+
double d,z0;
+
rgbd_group sum;
+
+
for (v=0; v<THIS->ysize; v++)
+
{
+
d=(u?1:c0)*(v?1:c0)/4.0;
+
sum.r=sum.g=sum.b=0;
+
pix=THIS->img;
+
+
for (x=0; x<THIS->xsize; x++)
+
costbl[x]=cos( (2*x+1)*u*pi/xsz2 );
+
+
for (y=0; y<THIS->ysize; y++)
+
{
+
z0=cos( (2*y+1)*v*pi/ysz2 );
+
for (x=0; x<THIS->xsize; x++)
+
{
+
double z;
+
z = costbl[x] * z0;
+
sum.r+=pix->r*z;
+
sum.g+=pix->g*z;
+
sum.b+=pix->b*z;
+
pix++;
+
}
+
}
+
sum.r*=d;
+
sum.g*=d;
+
sum.b*=d;
+
area[u+v*THIS->xsize]=sum;
+
}
+
fprintf(stderr,"."); fflush(stderr);
+
}
+
fprintf(stderr,"\n");
+
+
dx=((double)(THIS->xsize-1))/(img->xsize);
+
dy=((double)(THIS->ysize-1))/(img->ysize);
+
+
pix=img->img;
+
for (y=0,yp=0; y<img->ysize; y++,yp+=dy)
+
{
+
double z0;
+
rgbd_group sum;
+
+
for (x=0,xp=0; x<img->xsize; x++,xp+=dx)
+
{
+
sum.r=sum.g=sum.b=0;
+
val=area;
+
+
for (u=0; u<THIS->xsize; u++)
+
costbl[u]=cos( (2*xp+1)*u*pi/xsz2 );
+
+
for (v=0; v<THIS->ysize; v++)
+
{
+
z0=cos( (2*yp+1)*v*pi/ysz2 )*(v?1:c0)/4.0;
+
for (u=0; u<THIS->xsize; u++)
+
{
+
double z;
+
z = (u?1:c0) * costbl[u] * z0;
+
sum.r+=val->r*z;
+
sum.g+=val->g*z;
+
sum.b+=val->b*z;
+
val++;
+
}
+
}
+
sum.r*=enh;
+
sum.g*=enh;
+
sum.b*=enh;
+
pix->r=testrange(((int)(sum.r+0.5)));
+
pix->g=testrange(((int)(sum.g+0.5)));
+
pix->b=testrange(((int)(sum.b+0.5)));
+
pix++;
+
}
+
fprintf(stderr,"."); fflush(stderr);
+
}
+
+
free(area);
+
free(costbl);
+
+
pop_n_elems(args);
+
push_object(o);
+
}
Newline at end of file added.