diff --git a/.gitattributes b/.gitattributes
index 5037a003e704fce871d74e016a11791c454dd9ec..0f45768685fee925442dcb83a89eea76fd4629cb 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -35,6 +35,7 @@ testfont binary
 /src/modules/gdbmmod/gdbmmod.c foreign_ident
 /src/modules/gmpmod/mpz_glue.c foreign_ident
 /src/modules/image/blit.c foreign_ident
+/src/modules/image/dct.c foreign_ident
 /src/modules/image/font.c foreign_ident
 /src/modules/image/image.c foreign_ident
 /src/modules/image/image.h foreign_ident
diff --git a/src/modules/image/dct.c b/src/modules/image/dct.c
new file mode 100644
index 0000000000000000000000000000000000000000..0e63a9a9109411406ceb9b3733602e863dc27794
--- /dev/null
+++ b/src/modules/image/dct.c
@@ -0,0 +1,165 @@
+/* $Id: dct.c,v 1.1 1996/12/03 21:58:35 law 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"
+
+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)/img->xsize;
+   dy=((double)THIS->ysize)/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);
+}
diff --git a/src/modules/image/image.c b/src/modules/image/image.c
index 4a51b6d09ada4eb1e228244d1f06f374f055353e..352d17f1246722a722cf6bd159a96c0077e040f5 100644
--- a/src/modules/image/image.c
+++ b/src/modules/image/image.c
@@ -1,4 +1,4 @@
-/* $Id: image.c,v 1.30 1996/12/02 07:04:15 hubbe Exp $ */
+/* $Id: image.c,v 1.31 1996/12/03 21:58:37 law Exp $ */
 
 #include "global.h"
 
@@ -7,7 +7,7 @@
 
 #include "stralloc.h"
 #include "global.h"
-RCSID("$Id: image.c,v 1.30 1996/12/02 07:04:15 hubbe Exp $");
+RCSID("$Id: image.c,v 1.31 1996/12/03 21:58:37 law Exp $");
 #include "types.h"
 #include "macros.h"
 #include "object.h"
@@ -1630,13 +1630,8 @@ void init_image_programs()
    add_function("turbulence",image_turbulence,
                 "function(array(float|int|array(int)),int|void,float|void,float|void,float|void,float|void:object)",0);
 
-#if 0
-   /* If you check this in, maybe you should chekin dct.c too? 
-    * /Hubbe
-    */
    add_function("dct",image_dct,
 		"function(:object)",0);
-#endif
 		
    set_init_callback(init_image_struct);
    set_exit_callback(exit_image_struct);
diff --git a/src/modules/image/image.h b/src/modules/image/image.h
index 013cc34dcf4358d8df0d954c30e8935887b20c31..3fde4326e9d5c27766a43c4521b92b6d8255441c 100644
--- a/src/modules/image/image.h
+++ b/src/modules/image/image.h
@@ -1,16 +1,16 @@
-/* $Id: image.h,v 1.13 1996/12/01 04:08:18 law Exp $ */
+/* $Id: image.h,v 1.14 1996/12/03 21:58:39 law Exp $ */
 
 #define MAX_NUMCOL 32768
 
-#define QUANT_MAP_BITSR 3
+#define QUANT_MAP_BITSR 4
 #define QUANT_MAP_SKIP_BITSR (8-(QUANT_MAP_BITSR))
 #define QUANT_MAP_THISR(X) ((X)>>QUANT_MAP_SKIP_BITSR)
 #define QUANT_MAP_REALR (1L<<QUANT_MAP_BITSR)
-#define QUANT_MAP_BITSG 8
+#define QUANT_MAP_BITSG 4
 #define QUANT_MAP_SKIP_BITSG (8-(QUANT_MAP_BITSG))
 #define QUANT_MAP_THISG(X) ((X)>>QUANT_MAP_SKIP_BITSG)
 #define QUANT_MAP_REALG (1L<<QUANT_MAP_BITSG)
-#define QUANT_MAP_BITSB 2
+#define QUANT_MAP_BITSB 4
 #define QUANT_MAP_SKIP_BITSB (8-(QUANT_MAP_BITSB))
 #define QUANT_MAP_THISB(X) ((X)>>QUANT_MAP_SKIP_BITSB)
 #define QUANT_MAP_REALB (1L<<QUANT_MAP_BITSB)