r2958 - maintenance->trunk sync of changeset:2920
[racktables] / render_image.php
1 <?php
2
3
4 ob_start();
5 try {
6 require 'inc/init.php';
7
8 assertStringArg ('img', __FILE__);
9 switch ($_REQUEST['img'])
10 {
11 case 'minirack': // rack security context
12 assertUIntArg ('rack_id', __FILE__);
13 $pageno = 'rack';
14 $tabno = 'default';
15 fixContext();
16 if (!permitted())
17 renderAccessDeniedImage();
18 else
19 renderRackThumb ($_REQUEST['rack_id']);
20 break;
21 case 'progressbar': // no security context
22 assertUIntArg ('done', __FILE__, TRUE);
23 renderProgressBarImage ($_REQUEST['done']);
24 break;
25 case 'view': // file security context
26 case 'preview':
27 assertUIntArg ('file_id', __FILE__);
28 $pageno = 'file';
29 $tabno = 'default';
30 fixContext();
31 if (!permitted())
32 renderAccessDeniedImage();
33 else
34 renderFilePreview ($_REQUEST['file_id'], $_REQUEST['img']);
35 break;
36 default:
37 renderError();
38 }
39
40 ob_end_flush();
41 }
42 catch (Exception $e)
43 {
44 ob_end_clean();
45 printException($e);
46 }
47
48
49
50 //------------------------------------------------------------------------
51 function renderError ()
52 {
53 // A hardcoded value is worth of saving lots of code here.
54 $img = imagecreatefrompng ('pix/error.png');
55 header("Content-type: image/png");
56 imagepng ($img);
57 imagedestroy ($img);
58 }
59
60 // Having a local caching array speeds things up. A little.
61 function colorFromHex ($image, $hex)
62 {
63 static $colorcache = array ();
64 if (isset ($colorcache[$hex]))
65 return $colorcache[$hex];
66 $r = hexdec ('0x' . substr ($hex, 0, 2));
67 $g = hexdec ('0x' . substr ($hex, 2, 2));
68 $b = hexdec ('0x' . substr ($hex, 4, 2));
69 $c = imagecolorallocate ($image, $r, $g, $b);
70 $colorcache[$hex] = $c;
71 return $c;
72 }
73
74 function renderRackThumb ($rack_id = 0)
75 {
76 // Don't call DB extra times, hence we are most probably not the
77 // only script wishing to acces the same data now.
78 if (NULL !== ($thumbcache = loadThumbCache ($rack_id)))
79 {
80 header("Content-type: image/png");
81 echo $thumbcache;
82 return;
83 }
84 ob_start();
85 if (FALSE !== generateMiniRack ($rack_id))
86 {
87 $capture = ob_get_clean();
88 header("Content-type: image/png");
89 echo $capture;
90 saveThumbCache ($rack_id, $capture);
91 return;
92 }
93 // error text in the buffer
94 ob_end_flush();
95 }
96
97 // Output a binary string containing the PNG minirack. Indicate error with return code.
98 function generateMiniRack ($rack_id)
99 {
100 if (NULL === ($rackData = spotEntity ('rack', $rack_id)))
101 return FALSE;
102 amplifyCell ($rackData);
103 markupObjectProblems ($rackData);
104 global $rtwidth;
105 $rtdepth = 9;
106 $offset[0] = 3;
107 $offset[1] = 3 + $rtwidth[0];
108 $offset[2] = 3 + $rtwidth[0] + $rtwidth[1];
109 $totalheight = 3 + 3 + $rackData['height'] * 2;
110 $totalwidth = $offset[2] + $rtwidth[2] + 3;
111 $img = @imagecreatetruecolor ($totalwidth, $totalheight)
112 or die("Cannot Initialize new GD image stream");
113 // cache our palette as well
114 $color = array();
115 foreach (array ('F', 'A', 'U', 'T', 'Th', 'Tw', 'Thw') as $statecode)
116 $color[$statecode] = colorFromHex ($img, getConfigVar ('color_' . $statecode));
117 $color['black'] = colorFromHex ($img, '000000');
118 $color['gray'] = colorFromHex ($img, 'c0c0c0');
119 imagerectangle ($img, 0, 0, $totalwidth - 1, $totalheight - 1, $color['black']);
120 imagerectangle ($img, 1, 1, $totalwidth - 2, $totalheight - 2, $color['gray']);
121 imagerectangle ($img, 2, 2, $totalwidth - 3, $totalheight - 3, $color['black']);
122 for ($unit_no = 1; $unit_no <= $rackData['height']; $unit_no++)
123 {
124 for ($locidx = 0; $locidx < 3; $locidx++)
125 {
126 $colorcode = $rackData[$unit_no][$locidx]['state'];
127 if (isset ($rackData[$unit_no][$locidx]['hl']))
128 $colorcode = $colorcode . $rackData[$unit_no][$locidx]['hl'];
129 imagerectangle
130 (
131 $img,
132 $offset[$locidx],
133 3 + ($rackData['height'] - $unit_no) * 2,
134 $offset[$locidx] + $rtwidth[$locidx] - 1,
135 3 + ($rackData['height'] - $unit_no) * 2 + 1,
136 $color[$colorcode]
137 );
138 }
139 }
140 imagepng ($img);
141 imagedestroy ($img);
142 return TRUE;
143 }
144
145 function renderProgressBarImage ($done)
146 {
147 $img = @imagecreatetruecolor (100, 10);
148 switch (isset ($_REQUEST['theme']) ? $_REQUEST['theme'] : 'rackspace')
149 {
150 case 'sparenetwork':
151 $color['T'] = colorFromHex ($img, '808080');
152 $color['F'] = colorFromHex ($img, 'c0c0c0');
153 break;
154 case 'rackspace': // teal
155 default:
156 $color['T'] = colorFromHex ($img, getConfigVar ('color_T'));
157 $color['F'] = colorFromHex ($img, getConfigVar ('color_F'));
158 }
159 imagefilledrectangle ($img, 0, 0, $done, 10, $color['T']);
160 imagefilledrectangle ($img, $done, 0, 100, 10, $color['F']);
161 header("Content-type: image/png");
162 imagepng ($img);
163 imagedestroy ($img);
164 }
165
166 function renderAccessDeniedImage ()
167 {
168 $img = @imagecreatetruecolor (1, 1);
169 imagefilledrectangle ($img, 0, 0, 1, 1, colorFromHex ($img, '000000'));
170 header("Content-type: image/png");
171 imagepng ($img);
172 imagedestroy ($img);
173 }
174
175 function renderFilePreview ($file_id = 0, $mode = 'view')
176 {
177 switch ($mode)
178 {
179 case 'view':
180 // GFX files can become really big, if we uncompress them in memory just to
181 // provide a PNG version of a file. To keep things working, just send the
182 // contents as is for known MIME types.
183 $file = getFile ($file_id);
184 if (!in_array ($file['type'], array ('image/jpeg', 'image/png', 'image/gif')))
185 {
186 showError ('Invalid MIME type on file', __FUNCTION__);
187 break;
188 }
189 header("Content-type: ${file['type']}");
190 echo $file['contents'];
191 break;
192 case 'preview':
193 $file = getFile ($file_id);
194 $image = imagecreatefromstring ($file['contents']);
195 unset ($file);
196 $width = imagesx ($image);
197 $height = imagesy ($image);
198 if ($width > getConfigVar ('PREVIEW_IMAGE_MAXPXS') or $height > getConfigVar ('PREVIEW_IMAGE_MAXPXS'))
199 {
200 // TODO: cache thumbs for faster page generation
201 $ratio = getConfigVar ('PREVIEW_IMAGE_MAXPXS') / max ($width, $height);
202 $newwidth = $width * $ratio;
203 $newheight = $height * $ratio;
204 $resampled = imagecreatetruecolor ($newwidth, $newheight);
205 imagecopyresampled ($resampled, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
206 imagedestroy ($image);
207 $image = $resampled;
208 unset ($resampled);
209 }
210 header("Content-type: image/png"); // don't announce content-length, it may have changed after resampling
211 imagepng ($image);
212 imagedestroy ($image);
213 break;
214 default:
215 showError ('Invalid argument', __FUNCTION__);
216 break;
217 }
218 }
219 ?>