1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
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 ) ]); 
}