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

Last change on this file since 3315 was 3315, checked in by bsittler, 12 years ago

add more copyright info

  • 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 3315 2008-11-07 08:37:59Z 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        "        Copyright 2008 Benjamin C. Wiley Sittler\n" .
259        "Internet: <sam@zoy.org> <jylam@lnxscene.org> <bsittler@gmail.com> Version: %s\n" .
260        "\n" .
261        "img2txt, along with its documentation, may be freely copied and distributed.\n" .
262        "\n" .
263        "The latest version of img2txt is available from the web site,\n" .
264        "        http://caca.zoy.org/wiki/libcaca in the libcaca package.\n" .
265        "\n",
266        caca_get_version());
267}
268function main()
269{
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        global $file, $filename;
353
354        if((! $file) && ($argc == 2) && ($argv[1] == 'logo-caca.png'))
355        {
356                $file = 'logo-caca.png';
357                $argc = 1;
358        }
359
360        if($argc > 1)
361        {
362                $stderr .= sprintf("%s: too many arguments\n", $argv[0]);
363                usage($argc, $argv);
364                return 1;
365        }
366
367        if(! $file)
368        {
369                $stderr .= sprintf("%s: no image was provided\n", $argv[0]);
370                usage($argc, $argv);
371                return 1;
372        }
373
374        $cv = caca_create_canvas(0, 0);
375        if(!$cv)
376        {
377                $stderr .= sprintf("%s: unable to initialise libcaca\n", $argv[0]);
378                return 1;
379        }
380
381        $i_str = $file ? file_get_contents($file) : NULL;
382        $i = $i_str ? imagecreatefromstring($i_str) : NULL;
383        if(!$i)
384        {
385                $stderr .= sprintf("%s: unable to load %s\n", $argv[0], $filename);
386                return 1;
387        }
388
389        /* Assume a 6×10 font */
390        if(!$cols && !$lines)
391        {
392                $cols = 60;
393                $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
394        }
395        else if($cols && !$lines)
396        {
397                $lines = $cols * imagesy($i) * $font_width / imagesx($i) / $font_height;
398        }
399        else if(!$cols && $lines)
400        {
401                $cols = $lines * imagesx($i) * $font_height / imagesy($i) / $font_width;
402        }
403
404
405        caca_set_canvas_size($cv, $cols, $lines);
406        caca_set_color_ansi($cv, CACA_DEFAULT, CACA_TRANSPARENT);
407        caca_clear_canvas($cv);
408        $i_dither = caca_create_dither($i);
409        if(! caca_set_dither_algorithm($i_dither, $dither?$dither:"fstein"))
410        {
411                $stderr .= sprintf("%s: Can't dither image with algorithm '%s'\n", $argv[0], $dither?$dither:"fstein");
412                return -1;
413        }
414
415        if($brightness!=-1) caca_set_dither_brightness ($i_dither, $brightness);
416        if($contrast!=-1) caca_set_dither_contrast ($i_dither, $contrast);
417        if($gamma!=-1) caca_set_dither_gamma ($i_dither, $gamma);
418
419        caca_dither_bitmap($cv, 0, 0, $cols, $lines, $i_dither, $i);
420
421        $format = $format ? $format : 'html';
422
423        $export = caca_export_string($cv, $format);
424        if(!$export)
425        {
426                $stderr .= sprintf("%s: Can't export to format '%s'\n", $argv[0], $format);
427                return -1;
428        }
429        else
430        {
431                $content_type_map = array(
432                        'ansi' => 'text/plain; charset=CP437',
433                        'utf8' => 'text/plain; charset=UTF-8',
434                        'utf8cr' => 'text/plain; charset=UTF-8',
435                        'html' => 'text/html; charset=UTF-8',
436                        'html3' => 'text/html; charset=UTF-8',
437                        'bbfr' => 'text/plain; charset=UTF-8',
438                        'irc' => 'text/plain; charset=UTF-8',
439                        'ps' => 'application/postscript',
440                        'svg' => 'image/svg+xml',
441                        'tga' => 'image/x-targa'
442                        );
443
444                $download_extension_map = array(
445                        'caca' => 'caca',
446                        'ansi' => 'txt',
447                        'utf8' => 'txt',
448                        'utf8cr' => 'txt',
449                        'irc' => 'txt',
450                        'tga' => 'tga'
451                        );
452
453                $inline_extension_map = array(
454                        'bbfr' => 'txt',
455                        'ps' => 'ps',
456                        'svg' => 'svg'
457                        );
458
459                if (! array_key_exists($format, $content_type_map))
460                        $content_type = 'application/octet-stream';
461                else
462                        $content_type = $content_type_map[$format];
463
464                header('Content-Type: ' . $content_type);
465                if (array_key_exists($format, $download_extension_map))
466                        header('Content-Disposition: attachment; filename=export.' . $download_extension_map[$format]);
467                else if (array_key_exists($format, $inline_extension_map))
468                        header('Content-Disposition: inline; filename=export.' . $inline_extension_map[$format]);
469
470                echo $export;
471        }
472
473        return 0;
474}
475$ret = 1;
476if(isset($_REQUEST['args']) || $file)
477{
478        $ret = main();
479}
480if($ret || strlen($stdout) || strlen($stderr))
481{
482        header('Content-Type: text/html; charset=UTF-8');
483        ?>
484<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
485    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
486
487<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
488<head>
489<title>image to text converter</title>
490<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
491</head>
492<body>
493<form id="img2txtform" name="img2txtform" action="#" enctype="multipart/form-data" method="post">
494<label for="file">Image:</label>
495<input id="file" name="file" type="file" />
496<br />
497<label for="args">Options:</label>
498<input id="args" name="args" type="text" value="<?= isset($_REQUEST['args']) ? htmlspecialchars($_REQUEST['args']) : '' ?>" size="80" />
499<br />
500<input type="submit" />
501</form>
502<?php
503                ;
504        if(strlen($stderr))
505        {
506                ?><pre xml:space="preserve"><em><?= preg_replace('!(logo-caca[.]png)!', '<a href="$1">$1</a>', htmlspecialchars($stderr)) ?></em></pre><?php
507                        ;
508        }
509        if(strlen($stdout))
510        {
511                ?><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
512                        ;
513        }
514        ?>
515</body>
516</html>
517<?php
518                ;
519}
520?>
Note: See TracBrowser for help on using the repository browser.