読者です 読者をやめる 読者になる 読者になる

end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転します

tiff.js (libtiff compiled by emscripten , html5 canvas , javascript)でtiff画像をブラウザ表示

https://github.com/seikichi/tiff.js
のんびりしている間に↑ここでlibtiffをemscriptenでcompileした方が現れたので、手慣らし的に写経。

sample src

https://github.com/seikichi/tiff.js に記載されている通りですが...
試しにA3(240dpi)サイズのtiffを使用したところ、2-3秒で表示されました。

<!doctype html>
<html>
<head>
</head>
<body>
  <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
  <script src="./tiff.min.js"></script>
  <script type="text/javascript">
   $(function () {
     var imageFiles = [
       'SAMPLE_A3_240dpi.TIF',
     ];

     //大サイズのTIFFを表示すると
     //Cannot enlarge memory arrays in asm.js と怒られるので、大メモリを確保
     Tiff.initialize({TOTAL_MEMORY: 16777216 * 10});
     
     var loadImage = function (filename) {
       var xhr = new XMLHttpRequest();
       xhr.open('GET', filename);
       xhr.responseType = 'arraybuffer';
       xhr.onload = function (e) {
	 var buffer = xhr.response;
	 var tiff = new Tiff({buffer: buffer});
	 var canvas = tiff.toCanvas(); //TIFFをcanvasに変換
	 var width =  tiff.width();
	 var height = tiff.height();
	 if (canvas) {
           var $elem = $('<div><div><a href="' + filename + '">' +
			 filename +
			 ' (width: ' + width + ', height:' + height + ')' +
			 '</a></div></div>');
           $elem.append(canvas);
           $('body').append($elem);
	 }
       };
       xhr.send();
     };
     
     for (var i = 0, len = imageFiles.length; i < len; ++i) {
       loadImage(imageFiles[i]);
     }
   });
  </script>
</body>
</html>

emscriptenによるcompile方法 ( build.sh )

http://d.hatena.ne.jp/end0tknr/20120714/1342233561
以前、試しにemscriptenでlibtiff付属のtiff2pdfをcompileしましたが、動作しなかったので、tiff.jsのbuild.shを拝見。(一部、コメント追加してます)
https://github.com/seikichi/tiff.js/blob/master/build.sh

#!/bin/bash

export EMCC_CFLAGS="-O2"
ZLIB_PKGVER=1.2.8
LIBTIFF_PKGVER=4.0.3

# build zlib
wget http://zlib.net/current/zlib-${ZLIB_PKGVER}.tar.gz
tar xf zlib-${ZLIB_PKGVER}.tar.gz
cd zlib-${ZLIB_PKGVER}
emconfigure ./configure
emmake make
cd ..

# build libtiff
wget http://download.osgeo.org/libtiff/tiff-${LIBTIFF_PKGVER}.tar.gz
tar xzvf tiff-${LIBTIFF_PKGVER}.tar.gz
cd tiff-${LIBTIFF_PKGVER}
# see: https://github.com/kripken/emscripten/issues/662 へぇ
patch -p0 < ../tif_open.c.patch
patch -p0 < ../tiff.h.patch
emconfigure ./configure --enable-shared
emmake make
cd ..

emcc -o tiff.raw.js \
    --pre-js pre.js \
    --post-js post.js \
    -s EXPORTED_FUNCTIONS="["\
"'_TIFFOpen',"\
"'_TIFFClose',"\
"'_TIFFGetField',"\
"'_TIFFReadRGBAImage',"\
"'_TIFFReadRGBAImageOriented',"\
"'_TIFFSetDirectory',"\
"'_TIFFCurrentDirectory',"\
"'_TIFFReadDirectory',"\
"'__TIFFmalloc',"\
"'__TIFFfree',"\
"'_GetField',"\
"'FS']" \
    export.c \
    tiff-${LIBTIFF_PKGVER}/libtiff/.libs/libtiff.a \
    zlib-${ZLIB_PKGVER}/libz.a

echo 'var TiffTag = {' > tiff_tag.ts
grep '^#define[[:space:]]\+TIFFTAG_[A-Za-z_]\+[[:space:]]\+' \
    tiff-4.0.3/libtiff/tiff.h \
    | sed -e "s@^\#define[[:space:]]*TIFFTAG_\([A-Za-z_]*\)[[:space:]]*\([A-Za-z0-9]*\).*@  \1 : \2,@g" \
    >> tiff_tag.ts
echo '};' >> tiff_tag.ts

# tscって、TypeScriptが必要なの?
tsc emscripten.d.ts tiff_tag.ts tiff_api.ts -d
cat LICENSE tiff.raw.js > tiff.js
echo '' >> tiff.js
cat tiff_tag.js tiff_api.js >> tiff.js
mv tiff_api.d.ts tiff.d.ts
rm -f tiff_tag.d.ts tiff_tag.js tiff_api.js

#試す程度なら、closure-compilerでminizeしなくてもいいですよね?
closure-compiler \
    --js=tiff.js \
    --js_output_file=tiff.min.js \
    --language_in ECMASCRIPT5 \
    --output_wrapper="(function() {%output%})();"