From: Matthew Mondor Date: Wed, 9 Sep 2015 23:58:12 +0000 (+0000) Subject: Import old forgotten file X-Git-Url: http://git.pulsar-zone.net/?a=commitdiff_plain;h=da272efbe384e3e68f0a3b5041e32fa4864f2ddd;p=mmondor.git Import old forgotten file --- diff --git a/mmsoftware/js/js-sh/app/thumb/th.js b/mmsoftware/js/js-sh/app/thumb/th.js new file mode 100644 index 0000000..bd18116 --- /dev/null +++ b/mmsoftware/js/js-sh/app/thumb/th.js @@ -0,0 +1,257 @@ +/* $Id: th.js,v 1.1 2015/09/09 23:58:12 mmondor Exp $ */ + +/* + * Copyright (c) 2006, Matthew Mondor + * ALL RIGHTS RESERVED. + */ + +/* + * TODO: + * - Implement getopt-like class and allow to provide command line arguments + * - Generate multiple indexes with list of index links at top and bottom + * for large directories + * - Work on better presentation + */ + +function thumbnail_jpeg(fh) +{ + this.jpeg(fh, 50); +} + +function thumbnail(from, to, xmax, ymax) +{ + var ofh, tfd, nfd, oimg, ox, oy, timg, tfh; + var ret = false; + var type = undefined; + var i, to; + + /* XXX */ + stderr.write('Processing: ' + from + "\n"); + + /* + * Set load and save functions relative to image file type. + */ + if (from.match(/\.jpg$|\.jpeg$/)) { + GD.load = GD.createFromJpeg; + GDImage.prototype.save = thumbnail_jpeg; + } else if (from.match(/\.png$/)) { + GD.load = GD.createFromPng; + GDImage.prototype.save = GDImage.prototype.png; + } else if (from.match(/\.gif$/)) { + GD.load = GD.createFromGif; + GDImage.prototype.save = GDImage.prototype.gif; + } + + /* + * We use a single try block which breaks out of for before setting + * res to true. We use a dummy for loop since goto doesn't work. + */ + for (;;) { + try { + var otime, tstat; + + /* + * First open descriptors so that we may fstat(2) + * to determine if the thumbnail is more recent than + * the original image, in which case we don't avoid to + * create a thumb for nothing. We'll use File's + * fdopen(3) functionality afterwards if need be. + * We do this because image resizing is a rather CPU + * intensive operation. + */ + ofd = new FD(); + ofd.open(from, FD.O_RDONLY); + otime = (ofd.fstat()).st_mtime; + + tfd = new FD(); + tfd.open(to, FD.O_WRONLY | FD.O_CREAT); + tstat = tfd.fstat(); + + if (otime <= tstat.st_mtime && tstat.st_size != 0) { + ofd.close(); + tfd.close(); + return true; + } + + /* + * Load original image and determine thumb size. + */ + ofh = new File(ofd.fd, 'r'); + oimg = GD.load(ofh); + + ox = oimg.imageSX(); + oy = oimg.imageSY(); + if (ox <= xmax && oy <= ymax) { + tx = ox; + ty = oy; + } else if (ox < oy) { + tx = Math.round((xmax / oy) * ox); + ty = ymax; + } else { + tx = xmax; + ty = Math.round((ymax / ox) * oy); + } + + /* + * Create and save new thumbnail. It's important to + * first truncate the file to zero length which + * fopen(3) would have done for us but which fdopen(3) + * won't. + */ + tfd.ftruncate(0); + tfh = new File(tfd.fd, 'w'); + + timg = GD.createTrueColor(tx, ty); + //oimg.copyResampled(timg, 0, 0, 0, 0, tx, ty, ox, oy); + oimg.copyResized(timg, 0, 0, 0, 0, tx, ty, ox, oy); + + timg.save(tfh); + } catch (x) { + Syslog.log(Syslog.LOG_NOTICE, x + ' (' + from + ')'); + break; + } + + /* Success */ + ret = true; + break; + } + + /* + * We close/destroy the objects in the same order they appeared since + * if we get an exception the others won't execute. Although the + * language supports a GC and objects will eventually be destroyed, + * there's no point in leaving them dangling unnecessary resources for + * a while. File descriptors shouldn't be open for nothing, and + * images take up a lot of memory. + */ + ofh.close(); + oimg.destroy(); + tfh.close(); + timg.destroy(); + + delete GD.load; + delete GDImage.prototype.save; + + return ret; +} + +function thumbnail_dir(path, xmax, ymax) +{ + var dir, fh; + var ret = false; + var i, f, index = []; + + for (;;) { + try { + + dir = new Dir(path); + while ((e = dir.read()) != null) { + if ((e.type & Dir.DT_DIR) != 0 && + e.name.charAt(0) != '.') { + index.push({t: 'DIR', l: e.name}); + if (!thumbnail_dir(path + '/' + e.name, xmax, + ymax)) + break; + } else if ((e.type & Dir.DT_REG) != 0 && e.name.match( + /\.jpg$|\.jpeg$|\.png$|\.gif$/)) { + if (e.name.match(/_thumb/)) + continue; + i = e.name.lastIndexOf('.'); + newname = e.name.substring(0, i) + '_thumb' + + e.name.substring(i); + if (!thumbnail(path + '/' + e.name, path + + '/' + newname, xmax, ymax)) + break; + index.push({t: 'IMG', o: e.name, n: newname}); + } + } + if (index.length == 0) { + ret = true; + break; + } + /* XXX sort */ + fh = new File(path + '/index.html', 'w'); + fh.write("\n" + + '
../ (parent directory)' + + "

\n"); + for (i in index) { + f = index[i]; + if (f.t == 'DIR') { + var t; + + fh.write('' + + "
' + + ''); + if ((t = dir_findthumb(path + '/' + f.l)) + != null) + fh.write('' + t + ''); + fh.write('
' + f.l + '/
\n"); + } + } + for (i in index) { + f = index[i]; + if (f.t == 'IMG') + fh.write('' + f.n +
+				    '' + "\n"); + } + fh.write('
Thumb gallery generated by: ' + + '$Id: th.js,v 1.1 2015/09/09 23:58:12 mmondor Exp $' + + '
(source)
' + "\n"); + fh.write("\n"); + fh.close(); + + } catch (x) { + Syslog.log(Syslog.LOG_NOTICE, x.toString()); + break; + } + + ret = true; + break; + } + + try { + dir.close(); + fh.close(); + } catch (x) {} + + return ret; +} + +function dir_findthumb(path) +{ + var ret = null; + var dir, e, o, s = 0; + + for (;;) { + try { + dir = new Dir(path); + while ((e = dir.read()) != null) { + if (e.name.match(/_thumb/)) { + o = FS.stat(path + '/' + e.name); + if (o.st_size > s) + ret = e.name; + } + } + } catch (x) { + Syslog.log(Syslog.LOG_NOTICE, x.toString()); + break; + } + break; + } + + try { + dir.close(); + } catch (x) {} + + return ret; +} + +thumbnail_dir('/home/data/www/lesbolides.org/htdocs/commanditaires', 150, 150);