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

Last change on this file since 4333 was 4333, checked in by Sam Hocevar, 10 years ago

Large source code cleanup, getting rid of spaces, tabs, and svn keywords.

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