guetzliをOrangePi One (Armbian環境)に導入する

 クオリティを維持したままJPEGファイルサイズを小さくできるという触れ込みのGoogleJPEGエンコーダGuetzliが話題になりました。
github.com

 実際どんな感じなのか試してみるべくGitHubリポジトリを見てみると、READMEの上の方にビルド手順が書いてあります。自前でビルドする必要があるのかと思い*1、GuetzliのためだけにWindowsでビルド環境を構築するのが面倒だと思ったため、シングルボードコンピュータのOrange Pi Oneで試してみることにしました。
 

導入手順

 READMEには以下の3ステップが示されていますが、Orange Pi Oneではこれだけではだめでした。

1. Get a copy of the source code, either by cloning this repository, or by downloading an archive and unpacking it.
2. Install libpng. If using your operating system package manager, install development versions of the packages if the distinction exists.

  • On Ubuntu, do apt-get install libpng-dev.
  • On Fedora, do dnf install libpng-devel.
  • On Arch Linux, do pacman -S libpng.

3. Run make and expect the binary to be created in bin/Release/guetzli.

 

Orange Pi OneへのGuetzli導入手順

前提
OS
ARMBIAN 5.25 (Ubuntu 16.04.2 LTS 3.4.113-sun8i)

 

試行手順

 以下の手順は結果的には不要だった試みも含まれます。手っ取り早く導入したい方は、次節まで読み飛ばしてください。

Cloning into 'guetzli'...
remote: Counting objects: 321, done.
remote: Total 321 (delta 0), reused 0 (delta 0), pack-reused 321
Receiving objects: 100% (321/321), 180.69 KiB | 0 bytes/s, done.
Resolving deltas: 100% (171/171), done.
Checking connectivity... done.

 

  • sudo apt-get install libpng-dev を実行してlibpngの開発バージョンを取得
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'libpng12-dev' instead of 'libpng-dev'
libpng12-dev is already the newest version (1.2.54-1ubuntu1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

libpng-devの代わりにlibpng12-devが入ってるし最新だから何もしないと言われたようです。
 

  • cd guetzli/ を実行
  • make を実行
==== Building guetzli (release) ====
Creating bin/Release
Creating obj/Release
butteraugli_comparator.cc
/bin/sh: 1: pkg-config: not found
dct_double.cc
/bin/sh: 1: pkg-config: not found
debug_print.cc
/bin/sh: 1: pkg-config: not found
entropy_encode.cc
/bin/sh: 1: pkg-config: not found
fdct.cc
/bin/sh: 1: pkg-config: not found
gamma_correct.cc
/bin/sh: 1: pkg-config: not found
guetzli.cc
/bin/sh: 1: pkg-config: not found
idct.cc
/bin/sh: 1: pkg-config: not found
jpeg_data.cc
/bin/sh: 1: pkg-config: not found
jpeg_data_decoder.cc
/bin/sh: 1: pkg-config: not found
jpeg_data_encoder.cc
/bin/sh: 1: pkg-config: not found
jpeg_data_reader.cc
/bin/sh: 1: pkg-config: not found
jpeg_data_writer.cc
/bin/sh: 1: pkg-config: not found
jpeg_huffman_decode.cc
/bin/sh: 1: pkg-config: not found
output_image.cc
/bin/sh: 1: pkg-config: not found
preprocess_downsample.cc
/bin/sh: 1: pkg-config: not found
processor.cc
/bin/sh: 1: pkg-config: not found
quality.cc
/bin/sh: 1: pkg-config: not found
quantize.cc
/bin/sh: 1: pkg-config: not found
score.cc
/bin/sh: 1: pkg-config: not found
butteraugli.cc
/bin/sh: 1: pkg-config: not found
third_party/butteraugli/butteraugli/butteraugli.cc: In function ‘void butteraugli::CheckImage(const ImageF&, const char*)’:
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘size_t {aka unsigned int}[-Wformat=]
                image.ysize());
                             ^
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘size_t {aka unsigned int}[-Wformat=]
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘size_t {aka unsigned int}[-Wformat=]
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘size_t {aka unsigned int}[-Wformat=]
Linking guetzli
/bin/sh: 1: pkg-config: not found
obj/Release/guetzli.o: In function `(anonymous namespace)::ReadPNG(_IO_FILE*, int*, int*, std::vector<unsigned char, std::allocator<unsigned char> >*) [clone .constprop.47]':
/home/opiuser/guetzli/guetzli/guetzli.cc:37: undefined reference to `png_create_read_struct'
/home/opiuser/guetzli/guetzli/guetzli.cc:42: undefined reference to `png_create_info_struct'
/home/opiuser/guetzli/guetzli/guetzli.cc:55: undefined reference to `png_init_io'
/home/opiuser/guetzli/guetzli/guetzli.cc:65: undefined reference to `png_read_png'
/home/opiuser/guetzli/guetzli/guetzli.cc:67: undefined reference to `png_get_rows'
/home/opiuser/guetzli/guetzli/guetzli.cc:69: undefined reference to `png_get_image_width'
/home/opiuser/guetzli/guetzli/guetzli.cc:70: undefined reference to `png_get_image_height'
/home/opiuser/guetzli/guetzli/guetzli.cc:73: undefined reference to `png_get_channels'
/home/opiuser/guetzli/guetzli/guetzli.cc:44: undefined reference to `png_destroy_read_struct'
/home/opiuser/guetzli/guetzli/guetzli.cc:127: undefined reference to `png_destroy_read_struct'
/home/opiuser/guetzli/guetzli/guetzli.cc:130: undefined reference to `png_destroy_read_struct'
collect2: error: ld returned 1 exit status
guetzli.make:103: recipe for target 'bin/Release/guetzli' failed
make[1]: *** [bin/Release/guetzli] Error 1
Makefile:26: recipe for target 'guetzli' failed
make: *** [guetzli] Error 2

 コンソール出力によればビルド失敗したようです。実際にbin/Releaseに実行体は生成されていません。

 "/bin/sh: 1: pkg-config: not found"が頭の方で大量に出力されています。makefileを読むと、当該箇所ではlibpng-dev関連のビルドをしているようです。
 先行ステップでlibpng-devインストール試行時にlibpng12-devが入っているから何もしないと言われたのがまずいのかと思い、以下のようにlibpngの強制再インストールなど試行錯誤しました(結果的に無関係だったようです)。

opiuser@orangepione:~$ apt-cache policy libpng12-dev
libpng12-dev:
  Installed: 1.2.54-1ubuntu1
  Candidate: 1.2.54-1ubuntu1
  Version table:
 *** 1.2.54-1ubuntu1 500
        500 http://ports.ubuntu.com xenial/main armhf Packages
        100 /var/lib/dpkg/status

opiuser@orangepione:~$ apt-cache policy libpng-dev
libpng-dev:
  Installed: (none)
  Candidate: (none)
  Version table:

opiuser@orangepione:~$ apt-cache policy libpng12-0
libpng12-0:
  Installed: 1.2.54-1ubuntu1
  Candidate: 1.2.54-1ubuntu1
  Version table:
 *** 1.2.54-1ubuntu1 500
        500 http://ports.ubuntu.com xenial/main armhf Packages
        100 /var/lib/dpkg/status

opiuser@orangepione:~$ sudo apt-get install --reinstall libpng12-0=1.2.54-1ubuntu1
Reading package lists... Done
Building dependency tree
Reading state information... Done
0 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 0 not upgraded.
Need to get 106 kB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 http://ports.ubuntu.com xenial/main armhf libpng12-0 armhf 1.2.54-1ubuntu1 [106 kB]
Fetched 106 kB in 1s (87.0 kB/s)
(Reading database ... 55533 files and directories currently installed.)
Preparing to unpack .../libpng12-0_1.2.54-1ubuntu1_armhf.deb ...
Unpacking libpng12-0:armhf (1.2.54-1ubuntu1) over (1.2.54-1ubuntu1) ...
Processing triggers for libc-bin (2.23-0ubuntu6) ...
Setting up libpng12-0:armhf (1.2.54-1ubuntu1) ...
Processing triggers for libc-bin (2.23-0ubuntu6) ...

opiuser@orangepione:~$ sudo apt-get install libpng-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'libpng12-dev' instead of 'libpng-dev'
libpng12-dev is already the newest version (1.2.54-1ubuntu1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

 上記試行後、make clean後にmakeを行って見ても症状は変わりませんでした。
 再度makefileを読んでみると、当該箇所はpkg-configを叩いているので、とりあえず手で当該行を実行してみたところエラー。というか、pkg-configが無いことが発覚しました。

opiuser@orangepione:~$ pkg-config
-bash: pkg-config: command not found

 pkg-configを導入します。

opiuser@orangepione:~$ sudo apt-get install pkg-config
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  pkg-config
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 42.2 kB of archives.
After this operation, 151 kB of additional disk space will be used.
Get:1 http://ports.ubuntu.com xenial/main armhf pkg-config armhf 0.29.1-0ubuntu1 [42.2 kB]
Fetched 42.2 kB in 0s (42.9 kB/s)
Selecting previously unselected package pkg-config.
(Reading database ... 55533 files and directories currently installed.)
Preparing to unpack .../pkg-config_0.29.1-0ubuntu1_armhf.deb ...
Unpacking pkg-config (0.29.1-0ubuntu1) ...
Processing triggers for man-db (2.7.5-1) ...
Setting up pkg-config (0.29.1-0ubuntu1) ...
  • make clean後、再度makeを試行
opiuser@orangepione:~/guetzli$ make clean
Cleaning guetzli
opiuser@orangepione:~/guetzli$ make
==== Building guetzli (release) ====
Creating obj/Release
butteraugli_comparator.cc
dct_double.cc
debug_print.cc
entropy_encode.cc
fdct.cc
gamma_correct.cc
guetzli.cc
idct.cc
jpeg_data.cc
jpeg_data_decoder.cc
jpeg_data_encoder.cc
jpeg_data_reader.cc
jpeg_data_writer.cc
jpeg_huffman_decode.cc
output_image.cc
preprocess_downsample.cc
processor.cc
quality.cc
quantize.cc
score.cc
butteraugli.cc
third_party/butteraugli/butteraugli/butteraugli.cc: In function ‘void butteraugli::CheckImage(const ImageF&, const char*)’:
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘size_t {aka unsigned int}[-Wformat=]
                image.ysize());
                             ^
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘size_t {aka unsigned int}[-Wformat=]
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘size_t {aka unsigned int}[-Wformat=]
third_party/butteraugli/butteraugli/butteraugli.cc:98:29: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘size_t {aka unsigned int}[-Wformat=]
Linking guetzli

 今度はビルドに成功したようです。libpngの強制再インストールも行いましたがそれはおそらく無関係で、Armbianの場合はmake前にpkg-configの導入手順が必要なようです。

 実行体が正常に生成されていることも確認できます。

opiuser@orangepione:~/guetzli$ ls -ltr ./bin/Release/
total 3176
-rwxrwxr-x 1 opiuser opiuser 3249744 Mar 21 19:42 guetzli

opiuser@orangepione:~/guetzli$ ./bin/Release/guetzli
Guetzli JPEG compressor. Usage:
guetzli [flags] input_filename output_filename

Flags:
  --verbose   - Print a verbose trace of all attempts to standard output.
  --quality Q - Visual quality to aim for, expressed as a JPEG quality value.

 

Armbian環境向け導入手順まとめ

 前述のトラブルシューティングを踏まえると、以下のコマンドで正常にビルド可能なはずです。

git clone https://github.com/google/guetzli
sudo apt-get install libpng-dev
sudo apt-get install pkg-config
cd guetzli
make

 

備考

 画質とファイルサイズとエンコード時間がどのような関係かは別途記載します。遅くメモリを大量消費するという情報は事前に目にしていましたが、驚異的に遅く、湯水の如くメモリを消費するようです。
 無邪気にミラーレスのRAWを現像したTIFから作ったPNGを処理させた*2ところ、十数分待たされた後、メモリが枯渇したようでOSにKILLされました。ということで、検証には時間がかかりそうです。
 



以上。

*1:READMEの下まで読めばバイナリも提供されていることが解ります。

*2:Guetzliの入力として与える非圧縮画像にはTIFやPSDは使えず、PNGしか使えない。