source: libcaca/trunk/caca-php/examples/www/img2txt.php @ 3313

Last change on this file since 3313 was 3313, checked in by bsittler, 11 years ago

obscure email addresses somewhat

  • Property svn:keywords set to Id
File size: 12.7 KB
Line 
1<?php
2/*
3 *  img2txt       image to text converter
4 *  Copyright (c) 2008 Benjamin C. Wiley Sittler <bsittler@gmail.com>
5 *
6 *  This file is a Php port of "src/img2txt.c"
7 *  which is:
8 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
9 *                2007 Jean-Yves Lamoureux <jylam@lnxscene.org>
10 *                All Rights Reserved
11 *
12 *  $Id: img2txt.php 3313 2008-11-07 08:35:29Z bsittler $
13 *
14 *  This program is free software. It comes without any warranty, to
15 *  the extent permitted by applicable law. You can redistribute it
16 *  and/or modify it under the terms of the Do What The Fuck You Want
17 *  To Public License, Version 2, as published by Sam Hocevar. See
18 *  http://sam.zoy.org/wtfpl/COPYING for more details.
19 */
20
21$img2txt_php = isset($_SERVER['SCRIPT_NAME'])
22                ?
23                $_SERVER['SCRIPT_NAME']
24                :
25                'img2txt.php';
26
27$argv = array(basename($img2txt_php));
28$file = isset($_FILES['file']) ? $_FILES['file']['tmp_name'] : NULL;
29$filename = isset($_FILES['file']) ? $_FILES['file']['name'] : NULL;
30$args = NULL;
31if(isset($_REQUEST['args']))
32{
33        $args = $_REQUEST['args'];
34        if(strlen($args))
35        {
36                foreach(explode(' ', $args) as $arg)
37                {
38                        $argv[] = $arg;
39                }
40        }
41}
42$argc = count($argv);
43$stderr = '';
44$stdout = '';
45
46class MygetoptException extends Exception
47{
48}
49
50$myoptind = 0;
51
52function mygetopt($shortopts, $longopts)
53{
54        global $argc, $argv, $myoptind;
55        if($myoptind < 0)
56        {
57                $myoptind = 0;
58        }
59        if(($myoptind + 1) >= $argc)
60        {
61                return NULL;
62        }
63        $myoptind ++;
64        $nextarg = $argv[$myoptind];
65        $ret = NULL;
66        if((substr($nextarg, 0, 1) != '-')
67        ||
68        ($nextarg == '-'))
69        {
70                $myoptind = $argc - 1;
71        }
72        else
73        {
74                $skipopt = $myoptind;
75                $skipopts = 1;
76                if($nextarg == '--')
77                {
78                        $myoptind = $argc - 1;
79                }
80                else
81                {
82                        $opt = NULL;
83                        $arg = NULL;
84                        foreach($longopts as $longopt)
85                        {
86                                $optional = false;
87                                $hasarg = false;
88                                if(($longopt != '::') && substr($longopt, -2) == '::')
89                                {
90                                        $optional = true;
91                                        $hasarg = true;
92                                        $longopt = substr($longopt, 0, -2);
93                                }
94                                else if(($longopt != ':') && substr($longopt, -1) == ':')
95                                {
96                                        $optional = false;
97                                        $hasarg = true;
98                                        $longopt = substr($longopt, 0, -1);
99                                }
100                                if($nextarg == ('--' . $longopt))
101                                {
102                                        $opt = '--' . $longopt;
103                                        if($hasarg && ! $optional)
104                                        {
105                                                if(($myoptind + 1) < $argc)
106                                                {
107                                                        $myoptind ++;
108                                                        $skipopts ++;
109                                                        $arg = $argv[$myoptind];
110                                                }
111                                                else
112                                                {
113                                                        throw new MygetoptException("option \"$opt\" requires an argument");
114                                                }
115                                        }
116                                        break;
117                                }
118                                else if(substr($nextarg, 0, strlen('--' . $longopt . '='))
119                                                ==
120                                                ('--' . $longopt . '='))
121                                {
122                                        $opt = '--' . $longopt;
123                                        $arg = substr($nextarg, strlen($opt . '='));
124                                        if(! $hasarg)
125                                        {
126                                                throw new MygetoptException("option \"$opt\" does not allow an argument");
127                                        }
128                                        break;
129                                }
130                        }
131                        if($opt === NULL)
132                        {
133                                for($i = 0; $i < strlen($shortopts); $i ++)
134                                {
135                                        $optional = false;
136                                        $hasarg = false;
137                                        $shortopt = substr($shortopts, $i, 1);
138                                        if(substr($shortopts, $i + 1, 2) == '::')
139                                        {
140                                                $optional = true;
141                                                $hasarg = true;
142                                                $i += 2;
143                                        }
144                                        else if(substr($shortopts, $i + 1, 1) == ':')
145                                        {
146                                                $hasarg = true;
147                                        }
148                                        if($nextarg
149                                        ==
150                                        ('-' . $shortopt))
151                                        {
152                                                $opt = '-' . $shortopt;
153                                                if($hasarg && ! $optional)
154                                                {
155                                                        if(($myoptind + 1) < $argc)
156                                                        {
157                                                                $myoptind ++;
158                                                                $skipopts ++;
159                                                                $arg = $argv[$myoptind];
160                                                        }
161                                                        else
162                                                        {
163                                                                throw new MygetoptException("option \"$opt\" requires an argument");
164                                                        }
165                                                }
166                                                break;
167                                        }
168                                        else if(substr($nextarg, 0, strlen('-' . $shortopt))
169                                                        ==
170                                                        ('-' . $shortopt))
171                                        {
172                                                $opt = '-' . $shortopt;
173                                                if($hasarg)
174                                                {
175                                                        $arg = substr($nextarg, strlen($opt));
176                                                }
177                                                else
178                                                {
179                                                        $argv[$myoptind] = '-' . substr($nextarg, strlen($opt));
180                                                        $myoptind --;
181                                                        $skipopts = 0;
182                                                }
183                                        }
184                                }
185                        }
186                        if($opt === NULL)
187                        {
188                                if(substr($nextarg, 0, strlen('--')) == '--')
189                                {
190                                        $longopt = substr($nextarg, strlen('--'));
191                                        if(strpos($longopt, '=') !== false)
192                                        {
193                                                $longopt = substr($longopt, 0, strpos($longopt, '='));
194                                        }
195                                        throw new MygetoptException("option \"--$longopt\" is not recognized");
196                                }
197                                $shortopt = substr($nextarg, strlen('-'), 1);
198                                throw new MygetoptException("option \"-$shortopt\" is not recognized");
199                        }
200                        $ret = array($opt, $arg);
201                }
202                if ($skipopts > 0)
203                {
204                        for($i = 0; $i < $argc; $i ++)
205                        {
206                                if(($i < $skipopt) || ($i >= ($skipopt + $skipopts)))
207                                {
208                                        $new_argv[] = $argv[$i];
209                                }
210                        }
211                        if($myoptind >= $skipopt)
212                        {
213                                $myoptind -= $skipopts;
214                        }
215                        $argv = $new_argv;
216                        $argc = count($argv);
217                }
218        }
219        return $ret;
220}
221
222function usage($argc, $argv)
223{
224        global $stderr;
225        $stderr .= sprintf("Usage: %s [OPTIONS]... <IMAGE>\n", $argv[0]);
226        $stderr .= sprintf("Convert IMAGE to any text based available format.\n");
227        $stderr .= sprintf("Example : -W 80 -f html logo-caca.png\n\n", $argv[0]);
228        $stderr .= sprintf("Options:\n");
229        $stderr .= sprintf("  -h, --help\t\t\tThis help\n");
230        $stderr .= sprintf("  -v, --version\t\t\tVersion of the program\n");
231        $stderr .= sprintf("  -W, --width=WIDTH\t\tWidth of resulting image\n");
232        $stderr .= sprintf("  -H, --height=HEIGHT\t\tHeight of resulting image\n");
233        $stderr .= sprintf("  -x, --font-width=WIDTH\t\tWidth of output font\n");
234        $stderr .= sprintf("  -y, --font-height=HEIGHT\t\tHeight of output font\n");
235        $stderr .= sprintf("  -b, --brightness=BRIGHTNESS\tBrightness of resulting image\n");
236        $stderr .= sprintf("  -c, --contrast=CONTRAST\tContrast of resulting image\n");
237        $stderr .= sprintf("  -g, --gamma=GAMMA\t\tGamma of resulting image\n");
238        $stderr .= sprintf("  -d, --dither=DITHER\t\tDithering algorithm to use :\n");
239        $list = caca_get_dither_algorithm_list(caca_create_dither(imagecreate(1, 1)));
240        foreach($list as $type => $name)
241        {
242                $stderr .= sprintf("\t\t\t%s: %s\n", $type, $name);
243        }
244
245        $stderr .= sprintf("  -f, --format=FORMAT\t\tFormat of the resulting image :\n");
246        $list = caca_get_export_list();
247        foreach($list as $type => $name)
248        {
249                $stderr .= sprintf("\t\t\t%s: %s\n", $type, $name);
250        }
251}
252
253function version()
254{
255        global $stdout;
256        $stdout .= sprintf(
257        "img2txt Copyright 2006-2007 Sam Hocevar and Jean-Yves Lamoureux\n" .
258        "Internet: <sam@zoy.org> <jylam@lnxscene.org> Version: %s\n" .
259        "\n" .
260        "img2txt, along with its documentation, may be freely copied and distributed.\n" .
261        "\n" .
262        "The latest version of img2txt is available from the web site,\n" .
263        "        http://caca.zoy.org/wiki/libcaca in the libcaca package.\n" .
264        "\n",
265        caca_get_version());
266}
267function main()
268{
269        global $argc, $argv;
270        global $stderr;
271        $cols = 0;
272        $lines = 0;
273        $font_width = 6;
274        $font_height = 10;
275        $format = NULL;
276        $dither = NULL;
277        $gamma = $brightness = $contrast = -1.0;
278
279        $long_options = array(
280                "width:"        => 'W',
281                "height:"       => 'H',
282                "font-width:"   => 'x',
283                "font-height:"  => 'y',
284                "format:"       => 'f',
285                "dither:"       => 'd',
286                "gamma:"        => 'g',
287                "brightness:"   => 'b',
288                "contrast:"     => 'c',
289                "help"          => 'h',
290                "version"       => 'v'
291                );
292
293        try {
294                while($opt_and_arg = mygetopt("W:H:f:d:g:b:c:hvx:y:", array_keys($long_options)))
295                {
296                        $opt = $opt_and_arg[0];
297                        $arg = $opt_and_arg[1];
298                        if((substr($opt, 0, 2) == '--')
299                                &&
300                                array_key_exists(substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : ''), $long_options))
301                        {
302                                $opt = '-' . $long_options[substr($opt, strlen('--')) . (($arg !== NULL) ? ':' : '')];
303                        }
304                        switch($opt)
305                        {
306                        case '-W': /* --width */
307                                $cols = intval($arg);
308                                break;
309                        case '-H': /* --height */
310                                $lines = intval($arg);
311                                break;
312                        case '-x': /* --width */
313                                $font_width = intval($arg);
314                                break;
315                        case '-y': /* --height */
316                                $font_height = intval($arg);
317                                break;
318                        case '-f': /* --format */
319                                $format = $arg;
320                                break;
321                        case '-d': /* --dither */
322                                $dither = $arg;
323                                break;
324                        case '-g': /* --gamma */
325                                $gamma = floatval($arg);
326                                break;
327                        case '-b': /* --brightness */
328                                $brightness = floatval($arg);
329                                break;
330                        case '-c': /* --contrast */
331                                $contrast = floatval($arg);
332                                break;
333                        case '-h': /* --help */
334                                usage($argc, $argv);
335                                return 0;
336                        case '-v': /* --version */
337                                version();
338                                return 0;
339                        default:
340                                return 1;
341                        }
342                }
343        }
344        catch (MygetoptException $e)
345        {
346                $stderr .= $argv[0] . ": " . $e->getMessage() . "\n";
347                usage($argc, $argv);
348                return 2;
349        }
350
351        global $file, $filename;
352
353        if((! $file) && ($argc == 2) && ($argv[1] == 'logo-caca.png'))
354        {
355                $file = 'logo-caca.png';
356                $argc = 1;
357        }
358
359        if($argc > 1)
360        {
361                $stderr .= sprintf("%s: too many arguments\n", $argv[0]);
362                usage($argc, $argv);
363                return 1;
364        }
365
366        if(! $file)
367        {
368                $stderr .= sprintf("%s: no image was provided\n", $argv[0]);
369                usage($argc, $argv);
370                return 1;
371        }
372
373        $cv = caca_create_canvas(0, 0);
374        if(!$cv)
375        {
376                $stderr .= sprintf("%s: unable to initialise libcaca\n", $argv[0]);
377                return 1;
378        }
379
380        $i_str = $file ? file_get_contents($file) : NULL;
381        $i = $i_str ? imagecreatefromstring($i_str) : NULL;
382        if(!$i)
383        {
384                $stderr .= sprintf("%s: unable to load %s\n", $argv[0], $filename);
385                return 1;
386        }
387
388        /* Assume a 6×10 font */
389        if(!$cols && !$lines)
390        {
391                $cols = 60;
392                $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
393        }
394        else if($cols && !$lines)
395        {
396                $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
397        }
398        else if(!$cols && $lines)
399        {
400                $cols = $lines * imagesx($i) * $font_height / imagesy($i) / $font_width;
401        }
402
403
404        caca_set_canvas_size($cv, $cols, $lines);
405        caca_set_color_ansi($cv, CACA_DEFAULT, CACA_TRANSPARENT);
406        caca_clear_canvas($cv);
407        $i_dither = caca_create_dither($i);
408        if(! caca_set_dither_algorithm($i_dither, $dither?$dither:"fstein"))
409        {
410                $stderr .= sprintf("%s: Can't dither image with algorithm '%s'\n", $argv[0], $dither?$dither:"fstein");
411                return -1;
412        }
413
414        if($brightness!=-1) caca_set_dither_brightness ($i_dither, $brightness);
415        if($contrast!=-1) caca_set_dither_contrast ($i_dither, $contrast);
416        if($gamma!=-1) caca_set_dither_gamma ($i_dither, $gamma);
417
418        caca_dither_bitmap($cv, 0, 0, $cols, $lines, $i_dither, $i);
419
420        $format = $format ? $format : 'html';
421
422        $export = caca_export_string($cv, $format);
423        if(!$export)
424        {
425                $stderr .= sprintf("%s: Can't export to format '%s'\n", $argv[0], $format);
426                return -1;
427        }
428        else
429        {
430                $content_type_map = array(
431                        'ansi' => 'text/plain; charset=CP437',
432                        'utf8' => 'text/plain; charset=UTF-8',
433                        'utf8cr' => 'text/plain; charset=UTF-8',
434                        'html' => 'text/html; charset=UTF-8',
435                        'html3' => 'text/html; charset=UTF-8',
436                        'bbfr' => 'text/plain; charset=UTF-8',
437                        'irc' => 'text/plain; charset=UTF-8',
438                        'ps' => 'application/postscript',
439                        'svg' => 'image/svg+xml',
440                        'tga' => 'image/x-targa'
441                        );
442
443                $download_extension_map = array(
444                        'caca' => 'caca',
445                        'ansi' => 'txt',
446                        'utf8' => 'txt',
447                        'utf8cr' => 'txt',
448                        'irc' => 'txt',
449                        'tga' => 'tga'
450                        );
451
452                $inline_extension_map = array(
453                        'bbfr' => 'txt',
454                        'ps' => 'ps',
455                        'svg' => 'svg'
456                        );
457
458                if (! array_key_exists($format, $content_type_map))
459                        $content_type = 'application/octet-stream';
460                else
461                        $content_type = $content_type_map[$format];
462
463                header('Content-Type: ' . $content_type);
464                if (array_key_exists($format, $download_extension_map))
465                        header('Content-Disposition: attachment; filename=export.' . $download_extension_map[$format]);
466                else if (array_key_exists($format, $inline_extension_map))
467                        header('Content-Disposition: inline; filename=export.' . $inline_extension_map[$format]);
468
469                echo $export;
470        }
471
472        return 0;
473}
474$ret = 1;
475if(isset($_REQUEST['args']) || $file)
476{
477        $ret = main();
478}
479if($ret || strlen($stdout) || strlen($stderr))
480{
481        header('Content-Type: text/html; charset=UTF-8');
482        ?>
483<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
484    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
485
486<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
487<head>
488<title>image to text converter</title>
489<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
490</head>
491<body>
492<form id="img2txtform" name="img2txtform" action="#" enctype="multipart/form-data" method="post">
493<label for="file">Image:</label>
494<input id="file" name="file" type="file" />
495<br />
496<label for="args">Options:</label>
497<input id="args" name="args" type="text" value="<?= isset($_REQUEST['args']) ? htmlspecialchars($_REQUEST['args']) : '' ?>" size="80" />
498<br />
499<input type="submit" />
500</form>
501<?php
502                ;
503        if(strlen($stderr))
504        {
505                ?><pre xml:space="preserve"><em><?= preg_replace('!(logo-caca[.]png)!', '<a href="$1">$1</a>', htmlspecialchars($stderr)) ?></em></pre><?php
506                        ;
507        }
508        if(strlen($stdout))
509        {
510                ?><pre xml:space="preserve"><?= preg_replace('!([&]lt;)([.a-zA-Z0-9]+[@])([-.a-zA-Z0-9]+)([&]gt;)!', '$1<a href="mailto:$2$3">$2...</a>$4', preg_replace('!(\s|^)(http://[-.:_/0-9a-zA-Z%?=&;#]+)(\s|$)!', '$1<a href="$2">$2</a>$3', htmlspecialchars($stdout))) ?></pre><?php
511                        ;
512        }
513        ?>
514</body>
515</html>
516<?php
517                ;
518}
519?>
Note: See TracBrowser for help on using the repository browser.