1<?php
2/**
3 * Tests for the Horde_Image package. Designed to return image data in response
4 * to an <img> tag on another page. Set the test parameter to one of the
5 * cases below.
6 *  <img src="imtest.php?driver=im&test=polaroid" />
7 *
8 * @package Image
9 */
10require_once __DIR__ . '/conf.php';
11
12require_once $horde . '/lib/Application.php';
13Horde_Registry::appInit(
14    'horde',
15    array('authentication' => 'none', 'session_control' => 'none')
16);
17
18// Putting these here so they don't interfere with timing/memory data when
19// profiling.
20$driver = Horde_Util::getFormData('driver', 'Im');
21$test = Horde_Util::getFormData('test');
22$handler = new Horde_Log_Handler_Stream(fopen('/tmp/imagetest.log','a+'));
23$logger = new Horde_Log_Logger($handler);
24
25try {
26    switch ($test) {
27    case 'smart':
28        $time = xdebug_time_index();
29        $image = getImageObject(array('filename' => 'img4.jpg'));
30        $image->addEffect('SmartCrop', array('width' => 100, 'height' => 100));
31        $image->display();
32        $time = xdebug_time_index() - $time;
33        $memory = xdebug_peak_memory_usage();
34        logThis($test, $time, $memory);
35        exit;
36
37    case 'crop':
38        $time = xdebug_time_index();
39        $image = getImageObject(array('filename' => 'img4.jpg'));
40        $image->crop(1, 1, 50, 50);
41        $image->display();
42        $time = xdebug_time_index() - $time;
43        $memory = xdebug_peak_memory_usage();
44        logThis($test, $time, $memory);
45        exit;
46
47    case 'liquid':
48        $time = xdebug_time_index();
49        $image = getImageObject(array('filename' => 'img4.jpg'));
50        $image->addEffect(
51            'LiquidResize',
52             array(
53                'ratio' => true,
54                'width' => 612,
55                'height' => 340,
56                'delta_x' => 3,
57                'rigidity' => 0
58            )
59        );
60        $image->display();
61        $time = xdebug_time_index() - $time;
62        $memory = xdebug_peak_memory_usage();
63        logThis($test, $time, $memory);
64        exit;
65
66    case 'multipage':
67        $time = xdebug_time_index();
68        $image = getImageObject(array('filename' => 'two_page.tif.tiff'));
69
70        $first = true;
71        foreach ($image as $index => $imObject) {
72            if (!$first) {
73                $image->display();
74            } else {
75                $first = false;
76            }
77        }
78        $time = xdebug_time_index() - $time;
79        $memory = xdebug_peak_memory_usage();
80        logThis($test, $time, $memory);
81
82    case 'testInitialState':
83        // Solid blue background color - basically tests initial state of the
84        // Horde_Image object.
85        $time = xdebug_time_index();
86        $image = getImageObject(array(
87            'height' => '200',
88            'width' => '200',
89            'background' => 'blue')
90        );
91        $image->display();
92        $time = xdebug_time_index() - $time;
93        $memory = xdebug_peak_memory_usage();
94        logThis($test, $time, $memory);
95        exit;
96        break;
97
98    case 'testInitialStateAfterLoad':
99        // Test loading an image from file directly.
100        $image = getImageObject(array('filename' => 'img1.jpg'));
101        $image->display();
102        break;
103
104    case 'testDefaultImageFormatDuringLoad':
105        // Tests image format during load
106        $image = getImageObject(array('filename' => 'img1.jpg'));
107        $image->display();
108        break;
109
110    case 'testForceImageFormatDuringLoad':
111        // Tests forcing image format during load
112        $image = getImageObject(array(
113            'filename' => 'img1.jpg',
114            'type' => 'jpeg')
115        );
116        $image->display();
117        break;
118
119    case 'testChangeImageFormatAfterLoad':
120        // Tests changing image format after load
121        $image = getImageObject(array('filename' => 'img1.jpg')); // Loads PNG
122        $image->setType('jpeg');
123        $image->display();
124        break;
125
126    case 'testResize':
127        $time = xdebug_time_index();
128        $image = getImageObject(array('filename' => 'img2.jpg'));
129        $image->resize(150, 150);
130        $image->display();
131
132        $time = xdebug_time_index() - $time;
133        $memory = xdebug_peak_memory_usage();
134        logThis($test, $time, $memory);
135        break;
136
137    case 'testPrimitivesTransparentBG':
138        $time = xdebug_time_index();
139
140        // Transparent PNG image with various primitives.
141        $image = getImageObject(array(
142            'height' => '200',
143            'width' => '200',
144            'background' => 'none')
145        );
146        $image->rectangle(30, 30, 100, 60, 'black', 'yellow');
147        $image->roundedRectangle(30, 30, 100, 60, 15, 'black', 'red');
148        $image->circle(30, 30, 30, 'black', 'blue');
149        $image->display();
150        $time = xdebug_time_index() - $time;
151        $memory = xdebug_peak_memory_usage();
152        logThis($test, $time, $memory);
153        break;
154
155    case 'testTransparentPrimitivesReversed':
156        // Transparent PNG image with various primitives.
157        // Circle should appear *under* the rectangles...
158        $image = getImageObject(array(
159            'height' => '200',
160            'width' => '200',
161            'background' => 'none')
162        );
163        $image->circle(30, 30, 30, 'black', 'blue');
164        $image->rectangle(30, 30, 100, 60, 'black', 'yellow');
165        $image->roundedRectangle(30, 30, 100, 60, 15, 'black', 'red');
166        $image->display();
167        break;
168
169    case 'testTransparentBGWithBorder':
170        $time = xdebug_time_index();
171        // Same as above, but with border.
172        $image = getImageObject(array(
173            'height' => '200',
174            'width' => '200',
175            'background' => 'none')
176        );
177        $image->rectangle(30, 30, 100, 60, 'black', 'yellow');
178        $image->roundedRectangle(30, 30, 100, 60, 15, 'black', 'red');
179        $image->circle(30, 30, 30, 'black', 'blue');
180        $image->addEffect('Border',
181            array('bordercolor' => 'blue',
182                  'borderwidth' => 1)
183        );
184        $image->display();
185        $time = xdebug_time_index() - $time;
186        $memory = xdebug_peak_memory_usage();
187        logThis($test, $time, $memory);
188        break;
189
190
191    case 'testAnnotateImage':
192            $image = getImageObject(array('filename' => 'img1.jpg'));
193            $image->resize(300,300);
194            $image->text("Hello World", 1, 150, '', 'blue', 0, 'large');
195            $image->display();
196            break;
197
198    case 'testPolylineCircleLineText':
199        // Various other primitives. Using different colors and strokewidths
200        // to make sure that they get reset after each call - so we don't
201        // inadvetantly apply a color/stroke/etc setting to a primitive
202        // further down the line...
203        $image = getImageObject(array(
204            'height' => '200',
205            'width' => '200',
206            'background' => 'none')
207        );
208
209        // Pie slice. Black outline, green fill
210        $image->polygon(
211            array(
212                array('x' => 30, 'y' => 50),
213                array('x' => 40, 'y' => 60),
214                array('x' => 50, 'y' => 40)
215            ),
216            'black',
217            'green'
218        );
219
220        // Yellow 'pizza slice' with blue outline
221        $image->arc(50, 50, 100, 0, 70, 'blue', 'yellow');
222
223        // Small red circle dot.
224        $image->brush(80, 150, 'red', 'circle');
225
226        // Thicker verticle green line
227        $image->line(5, 30, 5, 200, 'green', 5);
228
229        // Thinner verticle blue line
230        $image->line(20, 60, 20, 200, 'blue', 2);
231
232        // Yellow checkmark
233        $image->polyline(
234            array(
235                array('x' => 130, 'y' => 150),
236                array('x' => 140, 'y' => 160),
237                array('x' => 150, 'y' => 140)
238            ),
239            'yellow',
240            4
241        );
242
243        $image->text('Hello World', 60, 10, '', 'black', 0, 'large');
244        $image->display();
245        break;
246
247    case 'testRoundCorners':
248        $time = xdebug_time_index();
249        // Tests resizing, and rounding corners with background maintained.
250        $image = getImageObject(array('filename' => 'img1.jpg'));
251        $image->resize(150,150);
252        $image->addEffect(
253            'RoundCorners',
254            array(
255                'border' => 2,
256                'bordercolor' => '#333',
257                'background' => 'none'
258            )
259        );
260        $image->applyEffects();
261
262        $time = xdebug_time_index() - $time;
263        $memory = xdebug_peak_memory_usage();
264        logThis($test, $time, $memory);
265
266        $image->display();
267        break;
268
269    case 'testRoundCornersRedBG':
270        $time = xdebug_time_index();
271        // Tests resizing, and rounding corners with background maintained.
272        $image = getImageObject(array('filename' => 'img1.jpg'));
273        $image->resize(150,150);
274        $image->addEffect(
275            'RoundCorners',
276            array(
277                'border' => 2,
278                'bordercolor' => '#333',
279                'background' => 'red'
280            )
281        );
282        $image->applyEffects();
283        $image->display();
284        $time = xdebug_time_index() - $time;
285        $memory = xdebug_peak_memory_usage();
286        logThis($test, $time, $memory);
287        break;
288
289    case 'testRoundCornersDropShadowTransparentBG':
290        $time = xdebug_time_index();
291        $image = getImageObject(array('filename' => 'img1.jpg'));
292        $image->resize(150,150);
293        $image->addEffect(
294            'RoundCorners',
295            array(
296                'border' => 2,
297                'bordercolor' => '#333'
298            )
299        );
300        $image->addEffect(
301            'DropShadow',
302            array(
303                'background' => 'none',
304                'padding' => 5,
305                'distance' => 5,
306                'fade' => 3
307            )
308        );
309        $time = xdebug_time_index() - $time;
310        $mem = xdebug_peak_memory_usage();
311        logThis($test, $time, $mem);
312        $image->display();
313        break;
314
315    case 'testRoundCornersDropShadowYellowBG':
316        $time = xdebug_time_index();
317        $image = getImageObject(array('filename' => 'img1.jpg'));
318        $image->resize(150,150);
319        $image->addEffect(
320            'RoundCorners',
321            array(
322                'border' => 2,
323                'bordercolor' => '#333'
324            )
325        );
326        $image->addEffect(
327            'DropShadow',
328            array(
329                'background' => 'yellow',
330                'padding' => 5,
331                'distance' => 5,
332                'fade' => 3
333            )
334        );
335        $image->display();
336        $time = xdebug_time_index() - $time;
337        $memory = xdebug_peak_memory_usage();
338        logThis($test, $time, $memory);
339        break;
340
341    case 'testBorderedDropShadowTransparentBG':
342        $time = xdebug_time_index();
343
344        $image = getImageObject(array('filename' => 'img1.jpg'));
345        $image->resize(150, 150, true);
346        $image->addEffect(
347            'Border',
348            array(
349                'bordercolor' => '#333',
350                'borderwidth' => 1
351            )
352        );
353        $image->addEffect(
354            'DropShadow',
355            array(
356                'background' => 'none',
357                'padding' => 5,
358                'distance' => 8,
359                'fade' => 2
360            )
361        );
362        $image->display();
363        $time = xdebug_time_index() - $time;
364        $memory = xdebug_peak_memory_usage();
365        logThis($test, $time, $memory);
366        break;
367
368    case 'testBorderedDropShadowTransparentLoadString':
369        $image = getImageObject();
370        $data = file_get_contents('img1.jpg');
371        $image->loadString($data);
372        $image->resize(150,150, true);
373        $image->addEffect(
374            'Border',
375            array(
376                'bordercolor' => '#333',
377                'borderwidth' => 1
378            )
379        );
380        $image->addEffect(
381            'DropShadow',
382            array(
383                'background' => 'none',
384                'padding' => 5,
385                'distance' => 8,
386                'fade' => 2
387            )
388        );
389        $image->display();
390        break;
391
392    case 'testBorderedDropShadowBlueBG':
393        $time = xdebug_time_index();
394        $image = getImageObject(array('filename' => 'img1.jpg',
395                                      'background' => 'none'));
396        $image->resize(150,150);
397        $image->addEffect(
398            'Border',
399            array(
400                'bordercolor' => '#333',
401                'borderwidth' => 1
402            )
403        );
404        $image->addEffect(
405            'DropShadow',
406            array(
407                'background' => 'blue',
408                'padding' => 10,
409                'distance' => '10',
410                'fade' => 5
411            )
412        );
413        $image->display();
414        $time = xdebug_time_index() - $time;
415        $mem = xdebug_peak_memory_usage();
416        logThis($test, $time, $mem);
417        break;
418
419    case 'testPolaroidTransparentBG':
420        $time = xdebug_time_index();
421        $image = getImageObject(array('filename' => 'img1.jpg'));
422        $image->resize(150, 150);
423        $image->addEffect(
424            'PolaroidImage',
425            array(
426                'background' => 'none',
427                'padding' => 5
428            )
429        );
430        $image->display();
431        $time = xdebug_time_index() - $time;
432        $memory = xdebug_peak_memory_usage();
433        logThis($test, $time, $memory);
434        break;
435
436    case 'testPolaroidBlueBG':
437        $time = xdebug_time_index();
438        $image = getImageObject(array('filename' => 'img1.jpg'));
439        $image->resize(150, 150);
440        $image->addEffect(
441            'PolaroidImage',
442            array(
443                'background' => 'blue',
444                'padding' => 5
445            )
446        );
447        $image->display();
448        $time = xdebug_time_index() - $time;
449        $memory = xdebug_peak_memory_usage();
450        logThis($test, $time, $memory);
451        break;
452
453    case 'testPlainstackTransparentBG':
454        $time = xdebug_time_index();
455        $imgs = array(
456            getImageObject(array('filename' => 'img1.jpg')),
457            getImageObject(array('filename' => 'img2.jpg')),
458            getImageObject(array('filename' => 'img3.jpg'))
459        );
460        $baseImg = getImageObject(array(
461            'width' => 1,
462            'height' => 1,
463            'background' => 'none')
464        );
465
466        $baseImg->addEffect(
467            'PhotoStack',
468            array(
469                'images' => $imgs,
470                'resize_height' => 150,
471                'padding' => 0,
472                'background' => 'none',
473                 'type' => 'plain'
474            )
475        );
476        $baseImg->applyEffects();
477        $baseImg->display();
478        $time = xdebug_time_index() - $time;
479        $memory = xdebug_peak_memory_usage();
480        logThis($test, $time, $memory);
481        break;
482
483    case 'testPlainstackBlueBG':
484        $time = xdebug_time_index();
485
486        $imgs = array(
487            getImageObject(array('filename' => 'img1.jpg')),
488            getImageObject(array('filename' => 'img2.jpg')),
489            getImageObject(array('filename' => 'img3.jpg'))
490        );
491        $baseImg = getImageObject(
492            array(
493                'width' => 1,
494                'height' => 1,
495                'background' => 'blue'
496            )
497        );
498
499        $baseImg->addEffect(
500            'PhotoStack',
501            array(
502                'images' => $imgs,
503                'resize_height' => 150,
504                'padding' => 5,
505                'background' => 'blue',
506                'type' => 'plain'
507            )
508        );
509        $baseImg->applyEffects();
510        $baseImg->display();
511        $time = xdebug_time_index() - $time;
512        $memory = xdebug_peak_memory_usage();
513        logThis($test, $time, $memory);
514        break;
515
516    case 'testRoundstackTransparentBG':
517        $time = xdebug_time_index();
518        $imgs = array(
519            getImageObject(array('filename' => 'img1.jpg')),
520            getImageObject(array('filename' => 'img2.jpg')),
521            getImageObject(array('filename' => 'img3.jpg'))
522        );
523        $baseImg = getImageObject(array(
524            'width' => 1,
525            'height' => 1,
526            'background' => 'none')
527        );
528
529        $baseImg->addEffect(
530            'PhotoStack',
531            array(
532                'images' => $imgs,
533                'resize_height' => 150,
534                'padding' => 0,
535                'background' => 'none',
536                'type' => 'rounded'
537            )
538        );
539        $baseImg->applyEffects();
540        $baseImg->display();
541        $time = xdebug_time_index() - $time;
542        $memory = xdebug_peak_memory_usage();
543        logThis($test, $time, $memory);
544        break;
545
546    case 'testRoundstackBlueBG':
547        $time = xdebug_time_index();
548        $imgs = array(
549            getImageObject(array('filename' => 'img1.jpg')),
550            getImageObject(array('filename' => 'img2.jpg')),
551            getImageObject(array('filename' => 'img3.jpg'))
552        );
553        $baseImg = getImageObject(array(
554            'width' => 1,
555            'height' => 1,
556            'background' => 'blue')
557        );
558
559        $baseImg->addEffect(
560            'PhotoStack',
561            array(
562                'images' => $imgs,
563                'resize_height' => 150,
564                'padding' => 0,
565                'background' => 'blue',
566                'type' => 'rounded'
567            )
568        );
569        $baseImg->applyEffects();
570        $baseImg->display();
571        $time = xdebug_time_index() - $time;
572        $memory = xdebug_peak_memory_usage();
573        logThis($test, $time, $memory);
574        break;
575
576    case 'testPolaroidstackTransparentBG':
577        $time = xdebug_time_index();
578        $imgs = array(
579            getImageObject(array('filename' => 'img1.jpg')),
580            getImageObject(array('filename' => 'img2.jpg')),
581            getImageObject(array('filename' => 'img3.jpg'))
582        );
583        $baseImg = getImageObject(array(
584            'width' => 1,
585            'height' => 1,
586            'background' => 'none')
587        );
588
589        $baseImg->addEffect(
590            'PhotoStack',
591            array(
592                'images' => $imgs,
593                'resize_height' => 150,
594                'padding' => 0,
595                'background' => 'none',
596                'type' => 'polaroid'
597            )
598        );
599        $baseImg->applyEffects();
600        $baseImg->display();
601        $time = xdebug_time_index() - $time;
602        $memory = xdebug_peak_memory_usage();
603        logThis($test, $time, $memory);
604        break;
605
606    case 'testPolaroidstackBlueBG':
607        $imgs = array(
608            getImageObject(array('filename' => 'img1.jpg')),
609            getImageObject(array('filename' => 'img2.jpg')),
610            getImageObject(array('filename' => 'img3.jpg'))
611        );
612        $baseImg = getImageObject(array(
613            'width' => 1,
614            'height' => 1,
615            'background' => 'blue')
616        );
617
618        $baseImg->addEffect(
619            'PhotoStack',
620            array(
621                'images' => $imgs,
622                'resize_height' => 150,
623                'padding' => 5,
624                'background' => 'blue',
625                'type' => 'polaroid'
626            )
627        );
628        $baseImg->applyEffects();
629        $baseImg->display();
630        break;
631    }
632} catch (Exception $e) {
633    $logger->err($e);
634    header('Content-Type: image/png');
635    readfile('error.png');
636    exit;
637}
638
639/**
640 * Obtain a Horde_Image object
641 *
642 * @param array $params  Any additional parameters
643 *
644 * @return Horde_Image_Base The image object.
645 */
646function getImageObject($params = array())
647{
648    global $convert, $driver, $identify;
649
650    $context = array(
651        'tmpdir' => Horde::getTempdir(),
652    );
653
654    if ($driver == 'Im') {
655        $context['convert'] = $convert;
656        $context['identify'] = $identify;
657    }
658    // Use the default
659    $class = 'Horde_Image_' . $driver;
660    if (class_exists($class)) {
661        return new $class($params, $context);
662    }
663
664    throw new Horde_Exception(sprintf(
665        'Invalid Image driver specified: %s not found.',
666        $class)
667    );
668}
669
670function logThis($effect, $time, $memory)
671{
672    global $driver, $logger;
673
674    $logger->debug("$driver, $effect, $time, $memory");
675
676//    $db = $GLOBALS['injector']->getInstance('Horde_Db_Base');
677//    $sql = "INSERT INTO image_tests (test, driver, peak_memory, execution_time) VALUES (?, ?, ?, ?);";
678//    $db->insert($sql, array('test' => $effect,
679//                                     'driver' => $driver,
680//                                     'peak_memory' => $memory,
681//                                     'execution_time' => $time));
682}
683