diff --git a/lib/modules/_Image_PS.pmod b/lib/modules/_Image_PS.pmod
new file mode 100644
index 0000000000000000000000000000000000000000..64d50c18797ee7a4c680c9d6fd517f2d1241ec5f
--- /dev/null
+++ b/lib/modules/_Image_PS.pmod
@@ -0,0 +1,67 @@
+string find_in_path( string file )
+{
+  string path=getenv("PATH");
+  foreach(path ? path/":" : ({}) , path)
+    if(file_stat(path=combine_path(path,file)))
+      return path;
+}
+
+object decode( string data, mapping|void options )
+{
+  if(!options) options = ([]);
+  object fd, fd2;
+  object fd3, fd4;
+  string bbox;
+  int llx, lly;
+  int urx, ury;
+  fd = Stdio.File();
+  fd2 = fd->pipe();
+
+  fd3 = Stdio.File();
+  fd4 = fd3->pipe();
+
+  if(data[0..3] != "%!PS")
+    error("This is not a postscrip file!\n");
+
+  if(sscanf(data, "%*s\n%%%%BoundingBox: %s\n", bbox) == 2)
+  {
+    int x0,x1,y0,y1;
+    sscanf(bbox, "%d %d %d %d", x0,y0,x1,y1 );
+    llx = (int)((x0/72.0) * (options->dpy||100)+0.01);
+    lly = (int)((y0/72.0) * (options->dpy||100)+0.01);
+    urx = (int)((x1/72.0) * (options->dpy||100)+0.01);
+    ury = (int)((y1/72.0) * (options->dpy||100)+0.01);
+  }
+
+  array command = ({
+    find_in_path("gs")||("/bin/sh -c gs "),
+    "-quiet",
+    "-sDEVICE="+(options->device||"ppmraw"),
+    "-r"+(options->dpy||100),
+    "-dNOPAUSE",
+    "-sOutputFile=-",
+    "-",
+    "-c quit 2>/dev/null" 
+  });
+
+//   werror("running "+(command*" ")+"\n");
+  Process.create_process( command, ([
+    "stdin":fd,
+    "stdout":fd3,
+    "stderr":fd3,
+  ]));
+  destruct(fd);
+  destruct(fd3);
+  fd2->write( data );
+  destruct(fd2);
+  object i= Image.PNM.decode( fd4->read() );
+  
+  if(urx && ury)
+    i = i->mirrory()->copy(llx,lly,urx,ury)->mirrory();
+  return i;
+}
+
+mapping _decode( string data, mapping|void options )
+{
+  return ([ "image":decode( data,options ) ]);
+}