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>
|
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"
|
05c2f4 | 2018-02-19 | Martin Nilsson | | #include "module_support.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))
|
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) | | |
13670c | 2015-05-25 | Martin Nilsson | | **!
|
e3cb4b | 1997-04-03 | Mirar (Pontus Hagland) | | **! Method for scaling is rather complex;
**! the image is transformed via a cosine transform,
**! and then resampled back.
**!
**! This gives a quality-conserving upscale,
**! but the algorithm used is n*n+n*m, where n
**! and m is pixels in the original and new image.
**!
**! Recommended wrapping algorithm is to scale
**! overlapping parts of the image-to-be-scaled.
**!
**! This functionality is actually added as an
**! true experiment, but works...
|
ba09c2 | 1997-04-30 | Mirar (Pontus Hagland) | | **!
**! note
|
13670c | 2015-05-25 | Martin Nilsson | | **! Do NOT use this function if you don't know what
|
ba09c2 | 1997-04-30 | Mirar (Pontus Hagland) | | **! you're dealing with! Read some signal theory first...
|
204bdf | 1999-04-22 | Mirar (Pontus Hagland) | | **!
|
c5bd93 | 2004-05-03 | Martin Nilsson | | **! 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;
|
7d60af | 2004-05-19 | Martin Nilsson | |
|
48b151 | 2018-02-22 | Martin Nilsson | | CHECK_INIT();
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
05c2f4 | 2018-02-19 | Martin Nilsson | | get_all_args("dct", args, "%d%d", &x, &y);
x = MAXIMUM(1, x);
y = MAXIMUM(1, y);
|
1c3883 | 2003-08-21 | Martin Nilsson | | #ifdef DCT_DEBUG
|
b82986 | 1997-03-10 | Henrik Grubbström (Grubba) | | fprintf(stderr,"%lu bytes, %lu bytes\n",
|
cc7cf4 | 2015-10-14 | Martin Nilsson | | (unsigned long)(sizeof(rgbd_group)*THIS->xsize*THIS->ysize),
(unsigned long)(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1));
|
1c3883 | 2003-08-21 | Martin Nilsson | | #endif
|
1a597d | 2005-08-15 | Henrik Grubbström (Grubba) | | area=xalloc(sizeof(rgbd_group)*THIS->xsize*THIS->ysize+1);
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
1a597d | 2005-08-15 | Henrik Grubbström (Grubba) | | if (!(costbl=malloc(sizeof(double)*THIS->xsize+1)))
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
free(area);
|
d118f2 | 2018-02-19 | Martin Nilsson | | out_of_memory_error(NULL, -1, 0);
|
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;
|
05c2f4 | 2018-02-19 | Martin Nilsson | | img->xsize = x;
img->ysize = y;
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
dc8d02 | 2014-04-27 | Martin Nilsson | | if (!(img->img=malloc(sizeof(rgb_group)*
img->xsize*img->ysize+RGB_VEC_PAD)))
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
free(area);
free(costbl);
free_object(o);
|
d118f2 | 2018-02-19 | Martin Nilsson | | out_of_memory_error(NULL, -1, 0);
|
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;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
ab6aec | 1997-02-11 | Fredrik Hübinette (Hubbe) | | 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;
|
13670c | 2015-05-25 | Martin Nilsson | | z = (u?1:c0) * costbl[u] * z0;
|
cc7cf4 | 2015-10-14 | Martin Nilsson | | sum.r += (float)(val->r*z);
sum.g += (float)(val->g*z);
sum.b += (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;
|
f6b3b5 | 2016-02-12 | Martin Nilsson | | pix->r=testrange((int)(sum.r+0.5));
pix->g=testrange((int)(sum.g+0.5));
pix->b=testrange((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);
}
|