e576bb | 2002-10-11 | Martin Nilsson | | |
2ba920 | 2004-03-06 | Martin Nilsson | | || $Id: dct.c,v 1.25 2004/03/05 23:04:02 nilsson Exp $
|
e576bb | 2002-10-11 | Martin Nilsson | | */
|
e3cb4b | 1997-04-03 | Mirar (Pontus Hagland) | |
|
448c20 | 1999-04-13 | Mirar (Pontus Hagland) | | **! class Image
|
e3cb4b | 1997-04-03 | Mirar (Pontus Hagland) | | */
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
#include "global.h"
#include <math.h>
#include <ctype.h>
#include "global.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #include "object.h"
#include "interpret.h"
#include "svalue.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_error.h"
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
#include "image.h"
|
6dc277 | 2000-07-28 | Fredrik Hübinette (Hubbe) | |
|
d56918 | 2002-05-11 | Martin Nilsson | | #define sp Pike_sp
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | extern struct program *image_program;
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | #ifdef THIS
#undef THIS /* Needed for NT */
#endif
|
d56918 | 2002-05-11 | Martin Nilsson | | #define THIS ((struct image *)(Pike_fp->current_storage))
#define THISOBJ (Pike_fp->current_object)
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
721019 | 1997-12-22 | Fredrik Hübinette (Hubbe) | | #define testrange(x) MAXIMUM(MINIMUM((x),255),0)
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
static const double c0=0.70710678118654752440;
static const double pi=3.14159265358979323846;
|
e3cb4b | 1997-04-03 | Mirar (Pontus Hagland) | | |
ba09c2 | 1997-04-30 | Mirar (Pontus Hagland) | | **!
**! note
**! Do NOT use this function if you don't know what
**! you're dealing with! Read some signal theory first...
|
204bdf | 1999-04-22 | Mirar (Pontus Hagland) | | **!
**! It write's dots on stderr, to indicate some sort
**! of progress. It doesn't use any fct (compare: fft)
**! algorithms.
|
e3cb4b | 1997-04-03 | Mirar (Pontus Hagland) | | **! returns the new image object
**! arg int newx
**! arg int newy
**! new image size in pixels
**!
*/
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | 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;
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if (!THIS->img) Pike_error("Called Image.Image object is not initialized\n");;
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
1c3883 | 2003-08-21 | Martin Nilsson | | #ifdef DCT_DEBUG
|
b82986 | 1997-03-10 | Henrik Grubbström (Grubba) | | fprintf(stderr,"%lu bytes, %lu bytes\n",
|
8778a7 | 2000-08-10 | Henrik Grubbström (Grubba) | | DO_NOT_WARN((unsigned long)(sizeof(rgbd_group)*THIS->xsize*THIS->ysize)),
DO_NOT_WARN((unsigned long)(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1)));
|
1c3883 | 2003-08-21 | Martin Nilsson | | #endif
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | if (!(area=malloc(sizeof(rgbd_group)*THIS->xsize*THIS->ysize+1)))
|
80f30b | 1999-06-18 | Mirar (Pontus Hagland) | | resource_error(NULL,0,0,"memory",0,"Out of memory.\n");
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if (!(costbl=malloc(sizeof(double)*THIS->xsize+1)))
{
free(area);
|
80f30b | 1999-06-18 | Mirar (Pontus Hagland) | | resource_error(NULL,0,0,"memory",0,"Out of memory.\n");
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
e70975 | 1997-03-12 | Fredrik Hübinette (Hubbe) | | o=clone_object(image_program,0);
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | img=(struct image*)(o->storage);
*img=*THIS;
if (args>=2
&& sp[-args].type==T_INT
&& sp[1-args].type==T_INT)
{
|
721019 | 1997-12-22 | Fredrik Hübinette (Hubbe) | | img->xsize=MAXIMUM(1,sp[-args].u.integer);
img->ysize=MAXIMUM(1,sp[1-args].u.integer);
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
80f30b | 1999-06-18 | Mirar (Pontus Hagland) | | else bad_arg_error("image->dct",sp-args,args,0,"",sp-args,
"Bad arguments to image->dct()\n");
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
e3cb4b | 1997-04-03 | Mirar (Pontus Hagland) | | if (!(img->img=(rgb_group*)malloc(sizeof(rgb_group)*
img->xsize*img->ysize+1)))
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
free(area);
free(costbl);
free_object(o);
|
80f30b | 1999-06-18 | Mirar (Pontus Hagland) | | resource_error(NULL,0,0,"memory",0,"Out of memory.\n");
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
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;
|
3d94d1 | 2001-07-12 | Henrik Grubbström (Grubba) | | sum.r += (float)(pix->r*z);
sum.g += (float)(pix->g*z);
sum.b += (float)(pix->b*z);
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | pix++;
}
}
|
3d94d1 | 2001-07-12 | Henrik Grubbström (Grubba) | | sum.r *= (float)d;
sum.g *= (float)d;
sum.b *= (float)d;
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | area[u+v*THIS->xsize]=sum;
}
|
1c3883 | 2003-08-21 | Martin Nilsson | | #ifdef DCT_DEBUG
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"."); fflush(stderr);
|
1c3883 | 2003-08-21 | Martin Nilsson | | #endif
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
1c3883 | 2003-08-21 | Martin Nilsson | | #ifdef DCT_DEBUG
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"\n");
|
1c3883 | 2003-08-21 | Martin Nilsson | | #endif
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
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;
|
9e3e5a | 2001-09-24 | Henrik Grubbström (Grubba) | | sum.r += DO_NOT_WARN((float)(val->r*z));
sum.g += DO_NOT_WARN((float)(val->g*z));
sum.b += DO_NOT_WARN((float)(val->b*z));
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | val++;
}
}
|
3d94d1 | 2001-07-12 | Henrik Grubbström (Grubba) | | sum.r *= (float)enh;
sum.g *= (float)enh;
sum.b *= (float)enh;
|
8778a7 | 2000-08-10 | Henrik Grubbström (Grubba) | | pix->r=testrange((DOUBLE_TO_INT(sum.r+0.5)));
pix->g=testrange((DOUBLE_TO_INT(sum.g+0.5)));
pix->b=testrange((DOUBLE_TO_INT(sum.b+0.5)));
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | pix++;
}
|
1c3883 | 2003-08-21 | Martin Nilsson | | #ifdef DCT_DEBUG
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"."); fflush(stderr);
|
1c3883 | 2003-08-21 | Martin Nilsson | | #endif
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
free(area);
free(costbl);
pop_n_elems(args);
push_object(o);
}
|