diff --git a/.travis.yml b/.travis.yml index dec358df..0ef156f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,19 +2,21 @@ language: c env: - - XCC=clang HOST= WINE= - - XCC=gcc HOST= WINE= - - XCC=i686-w64-mingw32-gcc HOST="--host=i686-w64-mingw32" WINE=wine - - XCC=i586-mingw32msvc-gcc HOST="--host=i586-mingw32msvc" WINE=wine - - XCC=x86_64-w64-mingw32-gcc HOST="--host=x86_64-w64-mingw32" WINE=wine64 - - XCC=clang HOST= WINE= GDKPIXBUF="--with-gdk-pixbuf2" - - XCC=clang HOST= WINE= LIBCURL="--with-libcurl" - - XCC=clang HOST= WINE= GD="--with-gd" - - XCC=clang HOST= WINE= GDKPIXBUF="--with-gdk-pixbuf2" LIBCURL="--with-libcurl" - - XCC=clang HOST= WINE= GD="--with-gd" LIBCURL="--with-libcurl" - - XCC=clang HOST= WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" - - XCC=clang HOST= WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" LIBCURL="--with-libcurl" - - XCC=clang HOST= WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" LIBCURL="--with-libcurl" GCOV="--enable-gcov" STATIC="--disable-shared" + - XCC=clang HOST= PREFIX=/usr WINE= LIBCURL=--without-libcurl JPEG=--without-jpeg PNG=--without-png + - XCC=gcc HOST= PREFIX=/usr WINE= LIBCURL=--without-libcurl JPEG=--without-jpeg PNG=--without-png + - XCC=i686-w64-mingw32-gcc CROSS_COMPILE="yes" HOST="--host=i686-w64-mingw32" PREFIX="/usr/i686-w64-mingw32" WINE=wine + - XCC=i586-mingw32msvc-gcc CROSS_COMPILE="yes" HOST="--host=i586-mingw32msvc" PREFIX="/usr/i586-mingw32msvc" WINE=wine + - XCC=x86_64-w64-mingw32-gcc CROSS_COMPILE="yes" HOST="--host=x86_64-w64-mingw32" PREFIX="/usr/x86_64-w64-mingw32" WINE=wine64 + - XCC=clang HOST= PREFIX=/usr WINE= JPEG="--with-jpeg" + - XCC=clang HOST= PREFIX=/usr WINE= PNG="--with-png" + - XCC=clang HOST= PREFIX=/usr WINE= GDKPIXBUF="--with-gdk-pixbuf2" JPEG=--without-jpeg PNG=--without-png + - XCC=clang HOST= PREFIX=/usr WINE= LIBCURL="--with-libcurl" JPEG=--without-jpeg PNG=--without-png + - XCC=clang HOST= PREFIX=/usr WINE= GD="--with-gd" JPEG=--without-jpeg PNG=--without-png + - XCC=clang HOST= PREFIX=/usr WINE= GDKPIXBUF="--with-gdk-pixbuf2" LIBCURL="--with-libcurl" JPEG=--without-jpeg PNG=--without-png + - XCC=clang HOST= PREFIX=/usr WINE= GD="--with-gd" LIBCURL="--with-libcurl" JPEG=--without-jpeg PNG=--without-png + - XCC=clang HOST= PREFIX=/usr WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" JPEG=--without-jpeg PNG=--without-png + - XCC=clang HOST= PREFIX=/usr WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" LIBCURL="--with-libcurl" JPEG=--without-jpeg PNG=--without-png + - XCC=clang HOST= PREFIX=/usr WINE= JPEG="--with-jpeg" PNG="--with-png" GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" LIBCURL="--with-libcurl" GCOV="--enable-gcov" STATIC="--disable-shared" before_install: - "sudo apt-get -qq update --force-yes > /dev/null" @@ -32,8 +34,7 @@ before_install: - "if [ x$GCOV != x ]; then sudo pip install cpp-coveralls pyyaml; fi" before_script: - - "echo ./configure --prefix=/usr ${HOST} ${GDKPIXBUF} ${GD} ${LIBCURL} ${GCOV} ${STATIC}" - - "CC=$XCC ./configure --prefix=/usr ${HOST} ${GDKPIXBUF} ${GD} ${LIBCURL} ${GCOV} ${STATIC}" + - "CC=$XCC cross_compile=${CROSS_COMPILE} ./configure --prefix=${PREFIX} ${HOST} ${GDKPIXBUF} ${GD} ${LIBCURL} ${GCOV} ${STATIC}" script: - "make" @@ -52,3 +53,4 @@ script: after_success: - "if [ x$WINE = x ]; then make valgrind && exit 0 || cat valgrind.log && exit 1; fi" + - "make coveralls" diff --git a/ChangeLog b/ChangeLog index e5fde705..f0902ce1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,166 @@ +2014-10-25 Hayaki Saito + + * configure, configure.ac: Don't terminate configure process if + --with-libcurl=auto + + * configure, configure.ac: Don't check pkg-config availability if + $cross_compile == yes + + * Makefile.in, configure, configure.ac, converters/Makefile.in, + include/Makefile.in, src/Makefile.in: Use $PKG_CONFIG environment variable + instead of $have_pkg_config + + * configure, configure.ac: Don't use system pkg-config if $cross_compile == + "yes" + + * configure, configure.ac: Checks zlib availability with libpng, workaround + for MinGW build + + * README.md, configure, configure.ac: Links libcurl automatically + + * Makefile.in, NEWS, configure, configure.ac, converters/Makefile.am, + converters/Makefile.in, include/Makefile.in, src/Makefile.in: Build with + libjpeg/libpng automatically + + * converters/loader.c: Strip alpha in png loader + +2014-10-22 Hayaki Saito + + * Makefile.am, Makefile.in, converters/Makefile.am, converters/Makefile.in, + images/snake.png: Add test for loading png with libpng + + * configure, configure.ac, converters/Makefile.am, converters/Makefile.in, + images/snake-progressive.jpg: Add a test for loading progressive jpeg + +2014-10-20 Hayaki Saito + + * configure, configure.ac, include/sixel.h.in, src/dither.c, src/dither.h, + src/tosixel.c: Add new API, sixel_dither_set_body_only + + * converters/img2sixel.c: Update usage + + * configure: Minor fix + + * configure, configure.ac: Minor fix + + * configure.ac: Fix build error + + * converters/loader.c: Fix build error + + * converters/loader.c: Use libpng reader + + * Makefile.in, config.h.in, configure, configure.ac, converters/Makefile.am, + converters/Makefile.in, include/Makefile.in, src/Makefile.in: Add --with-png + configure option + + * LICENSE.xterm, README.md, src/fromsixel.c: Fix wrong HLS-to-RGB conversion + routine + +2014-10-18 Hayaki Saito + + * converters/img2sixel.c: Introduce --verbose option + + * src/fromsixel.c: Rename some functions as snake case + + * src/fromsixel.c: Rename some functions as snake case + +2014-10-17 Hayaki Saito + + * src/tosixel.c: Omit DCS parameters by default + + * src/tosixel.c: Strip an extra DECGNL character at the end of output data + + * src/tosixel.c: Strip an extra LF character from output data + + * converters/loader.c: Suppress gdk-pixbuf assersion on processing some GIF + images, reported by @ttdoda + +2014-10-14 Hayaki Saito + + * LICENSE.sdump, Makefile.in, README.md, config.h.in, configure, + configure.ac, converters/Makefile.am, converters/Makefile.in, + converters/loader.c, include/Makefile.in, src/Makefile.in: Add libjpeg + support with --with-jpeg configure option + +2014-10-12 Hayaki Saito + + * package.json.in.in: clib integration: add --with-libcurl option by default + + * NEWS: Add missing items to NEWS + + * converters/loader.c: Include errno.h in loader.c + + * converters/Makefile.am, converters/Makefile.in, src/Makefile.am, + src/Makefile.in: Add -Werror to CFLAGS when --enable-debug configure option + is specified + + * config.h.in, configure, configure.ac: Introduce --enable-debug configure + option + + * converters/img2sixel.c: Fix a double free error + +2014-10-11 Hayaki Saito + + * NEWS, README.md: Document updates + + * converters/loader.c, src/quant.c: Suppress some compiler wanings + + * src/quant.c: Fix a bug caused by an uninitialized variable + + * converters/Makefile.am, converters/Makefile.in, src/Makefile.am, + src/Makefile.in: Add missing -Wall option to cflags to privent stupid bugs + like #9 + + * converters/loader.c: Quick fix for Issue #9 + +2014-10-11 Bruce Mitchener + + * converters/loader.c, converters/shell-completion/bash/img2sixel, + converters/sixel2png.1, include/sixel.h.in, src/output.c: Remove whitespace + at EOL. + + * ChangeLog, README.md, converters/img2sixel.1, converters/img2sixel.c, + converters/quant.h, converters/shell-completion/bash/img2sixel, + converters/shell-completion/zsh/_img2sixel, include/sixel.h.in, src/dither.h, + src/quant.c: Fix typos. + + * converters/img2sixel.c: Fix uninitialized variable. + + * converters/img2sixel.c, converters/scale.c: Remove unused functions. + + * converters/img2sixel.c, converters/loader.c, converters/sixel2png.c, + src/quant.c, src/tosixel.c: Remove unused variables. + + * include/sixel.h.in, src/output.c, src/quant.c: Remove invalid const + specifier on return type. + +2014-10-11 Hayaki Saito + + * Makefile.in, NEWS: Add NEWS + +2014-10-09 Hayaki Saito + + * converters/shell-completion/bash/img2sixel: Update bash completion file + + * converters/shell-completion/zsh/_img2sixel: Update zsh completion file + + * converters/img2sixel.1: Add missing descriptions to img2sixel manpage + + * README.md, converters/img2sixel.1, converters/img2sixel.c: Update documents + + * data/example_opengl.gif, data/ffmpeg.png, data/gnuplot.png, data/gs.png, + data/libsixel-1.png, data/q_libsixel.png, data/q_ppmtosixel.png, + data/q_ppmtosixel2.png, data/q_sixel.png, data/q_sixelconv.png, + data/qemu.png, data/sixel.gif, data/w3m-sixel.png, data/wesnoth.png, + data/xsdl.png, data/xsixel.png, data/zx81.png: Remove data directory + +2014-10-08 Hayaki Saito + + * README.md, converters/img2sixel.1, converters/img2sixel.c: Update documents + + * converters/img2sixel.c, converters/loader.c, converters/loader.h: Introduce + --static option + 2014-10-07 Hayaki Saito * converters/img2sixel.c: Fix for animation GIF quality degradation @@ -12,6 +175,8 @@ 2014-10-01 Hayaki Saito + * configure, configure.ac: Update libtool minor version + * configure, configure.ac: Update libtool micro version * LICENSE.stb: Declare patches/applied/stb_image.h.diff is in public domain @@ -27,6 +192,9 @@ 2014-09-29 Hayaki Saito + * src/tosixel.c: Merge arakiken's amend patch: + http://mlterm.sourceforge.net/libsixel-penetrate2.patch + * converters/img2sixel.c: Print short usage explanation if invalid option is given. @@ -35,9 +203,31 @@ 2014-09-28 Hayaki Saito + * converters/img2sixel.c, include/sixel.h.in, src/dither.c, src/dither.h, + src/quant.c, src/quant.h: Introduce -C(complexion score) option and implement + complexion correction + + * include/sixel.h.in, src/tosixel.c: Fix build broken by fb1cd8a + + * converters/img2sixel.c, src/output.c, src/output.h, src/tosixel.c: Apply + arakiken's patch for GNU Screen integration: + http://mlterm.sourceforge.net/libsixel-penetrate.patch + + * converters/img2sixel.c, include/sixel.h.in, src/output.c, src/output.h, + src/tosixel.c: Introduce new APIs: sixel_output_{get,set}_skip_dcs_envelope + * src/Makefile.am, src/Makefile.in, src/dither.c, src/dither.h, src/image.c, src/image.h, src/tosixel.c: Drop sixel_image_t object and related functions +2014-09-27 Hayaki Saito + + * src/dither.c, src/output.c: Add NULL checks + + * src/dither.c, src/output.c: Add NULL checks + + * src/dither.c, src/image.c: Add input parameter validation for some + functions + 2014-09-26 Hayaki Saito * converters/img2sixel.c: Fix a compile error @@ -1468,10 +1658,10 @@ * src/quant.c: Minor fix for creating palette - * src/quant.c: Minor fix around creating histogram + * src/quant.c: Minor fix around creating histgram * src/quant.c: Add new parameter for selecting method for detecting largest - splitting dimension + splitting dimention * src/quant.c: Import largestByLuminosity function from pnmcolormap.c @@ -1481,7 +1671,7 @@ * src/quant.c: Fix a memory leak problem - * src/tosixel.c: Comment out unused code which makes histogram + * src/tosixel.c: Comment out unused code which makes histgram * src/quant.c: Minor fix @@ -1523,9 +1713,9 @@ 2014-03-28 Hayaki Saito - * quant.c: Reduce sample pixels for creating histogram + * quant.c: Reduce sample pixels for creating histgram - * quant.c: Improve the allocation method for creating histogram + * quant.c: Improve the allocation method for creating histgram * quant.c: Minor fix diff --git a/LICENSE.sdump b/LICENSE.sdump new file mode 100644 index 00000000..ce40e806 --- /dev/null +++ b/LICENSE.sdump @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2014 haru + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSE.xterm b/LICENSE.xterm new file mode 100644 index 00000000..627f4c9f --- /dev/null +++ b/LICENSE.xterm @@ -0,0 +1,34 @@ +The helper function hls2rgb in src/fromsixel.c is imported from +graphics.c in Xterm pl#310 originally written by Ross Combs. + +http://invisible-island.net/xterm/ + + +Copyright 2013,2014 by Ross Combs + + All Rights Reserved + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name(s) of the above copyright +holders shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Software without prior written +authorization. + diff --git a/Makefile.am b/Makefile.am index 37ff23d3..c9400e5f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,7 +13,7 @@ all-am: cp package.json.in package.json test: all - $(MAKE) test -C converters > test.log + $(MAKE) test -C converters 2>&1 |tee test.log winetest: all $(MAKE) winetest -C converters diff --git a/Makefile.in b/Makefile.in index ba400877..7bfdb554 100644 --- a/Makefile.in +++ b/Makefile.in @@ -264,6 +264,8 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBJPEG_CFLAGS = @LIBJPEG_CFLAGS@ +LIBJPEG_LIBS = @LIBJPEG_LIBS@ LIBOBJS = @LIBOBJS@ LIBPNG_CFLAGS = @LIBPNG_CFLAGS@ LIBPNG_LIBS = @LIBPNG_LIBS@ @@ -327,7 +329,6 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_pkg_config = @have_pkg_config@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -880,7 +881,7 @@ all-am: cp package.json.in package.json test: all - $(MAKE) test -C converters > test.log + $(MAKE) test -C converters 2>&1 |tee test.log winetest: all $(MAKE) winetest -C converters diff --git a/NEWS b/NEWS index a7e57cee..28ff8787 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,28 @@ - -------------------------------- - What's new in libsixel-1.2.0 ? - -------------------------------- + ------------------------------ + What's new in libsixel-1.3 ? + ------------------------------ + +* Now libcurl is automatically linked. + If you don't want to build with libcurl, you should configure with + --without-libcurl option. + +* Add libjpeg integration(linked automatically). + +* Add libpng integration(linked automatically). + +* Introduce -t(--palette-type) option. + img2sixel can output HLS paletted sixel with "-t hls". + Add new API sixel_output_set_palette_type. + +* Introduce -v(--verbose) option. + +* Add new API sixel_dither_set_body_only. + +* Some bug fixes and minor improvements. + + ------------------------------ + What's new in libsixel-1.2 ? + ------------------------------ * Introduce GNU Screen penetration (-P) feature written by @arakiken. This works with arakiken's GNU screen sixel branch @@ -8,12 +30,20 @@ * Introduce crop operation (-c) feature written by @arakiken. This works with arakiken's w3m remoteimg branch - (w3m with "-sixel" option, https://bitbucket.org/arakiken/w3m/branch/remoteimg). + https://bitbucket.org/arakiken/w3m/branch/remoteimg + (w3m with "-sixel" option) + +* Introduce -C (complexion score) option and implement complexion correction + feature. (discussion with @tsutsui) -* Introduce -C (complexion score) option and implement complexion correction feature. (discussion with @tsutsui) +* Introduce static image extraction from Gif animation (-S). + (discussion with @isaki68k) -* Introduce static image extraction from Gif animation (-S). (discussion with @isaki68k) +* Introduce --enable-debug configure option. -* Add APIs for skipping DCS envelope (sixel_output_{get,set}_skip_dcs_envelope). (disscussion with @uobikiemukot) +* Add APIs for skipping DCS envelope + sixel_output_{get,set}_skip_dcs_envelope. (disscussion with @uobikiemukot) -* Some bug fixes and minor improvements (Thanks to @elfring, @isaki68k, @knok, @mattn, @tsutsui and @waywardmonkeys). +* Some bug fixes and minor improvements. + Thanks to @elfring, @isaki68k, @knok, @mattn, @tsutsui, @waywardmonkeys + and @ttdoda. diff --git a/README.md b/README.md index 296c0316..6278a14f 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,58 @@ Some NetBSD/OpenBSD users are doing amazing challenge. ![sayaka-chan](https://raw.githubusercontent.com/saitoha/libsixel/data/data/sayaka-netbsd-x68k.jpg) +## Highlighted features + +### Improved compression + +Former sixel encoders(such as [ppmtosixel](http://netpbm.sourceforge.net/doc/ppmtosixel.html)) are mainly designed for dot-matrix printers. +They minimize the amount of printer-head movement distance. +But nowadays this method did not represent the best performance for displaying sixel data on terminal emulators. +SIXEL data for terminals were found in 80's Usenet, but the technology of how to create them seems to be lost. +[kmiya's sixel](http://nanno.dip.jp/softlib/man/rlogin/sixel.tar.gz) introduces the encoding method which is re-designed +for terminal emulators to optimize the overhead of transporting SIXEL with keeping compatibility with former SIXEL terminal. +Now libsixel and ImageMagick's sixel coder follow it. + + +### High quality quantization + +img2sixel(1) supports color image quantization. It works well even if few number of colors are allowed. + +- ppmtosixel (netpbm) + + $ jpegtopnm images/snake.jpg | pnmquant 16 | ppmtosixel + + ![ppmtosixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_ppmtosixel.png) + + +- ppmtosixel with Floyd–Steinberg dithering (netpbm) + + $ jpegtopnm images/snake.jpg | pnmquant 16 -floyd | ppmtosixel + + ![ppmtosixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_ppmtosixel2.png) + + +- kmiya's sixel + + $ sixel -p16 images/snake.jpg + + ![kmiya's sixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_sixel.png) + + +- PySixel (sixelconv command) + + $ sixelconv -n16 images/snake.jpg + + ![PySixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_sixelconv.png) + + +- libsixel (img2sixel command) + + $ img2sixel -p16 images/snake.jpg + + ![PySixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_libsixel.png) + + ## Terminal requirements If you want to view a SIXEL image, you have to get a terminal which support sixel graphics. @@ -170,44 +222,6 @@ Now SIXEL feature is supported by the following terminals. - [yacp](https://github.com/fd00/yacp/tree/master/libsixel) - [Debian](https://ftp-master.debian.org/new/libsixel_1.1.2-1.html) -## Quantization quality - -img2sixel(1) supports high quality color image quantization. - -- ppmtosixel (netpbm) - - $ jpegtopnm images/snake.jpg | pnmquant 16 | ppmtosixel - - ![ppmtosixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_ppmtosixel.png) - - -- ppmtosixel with Floyd–Steinberg dithering (netpbm) - - $ jpegtopnm images/snake.jpg | pnmquant 16 -floyd | ppmtosixel - - ![ppmtosixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_ppmtosixel2.png) - - -- kmiya's sixel - - $ sixel -p16 images/snake.jpg - - ![kmiya's sixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_sixel.png) - - -- PySixel (sixelconv command) - - $ sixelconv -n16 images/snake.jpg - - ![PySixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_sixelconv.png) - - -- libsixel (img2sixel command) - - $ img2sixel -p16 images/snake.jpg - - ![PySixel](https://raw.githubusercontent.com/saitoha/libsixel/data/data/q_libsixel.png) - ## Build and install @@ -222,10 +236,11 @@ $ make ### Build with optional packages ``` +--with-libcurl build with libcurl (default: auto) +--with-gd build with libgd (default: no) --with-gdk-pixbuf2 build with gdk-pixbuf2 (default: no) ---with-libcurl build with libcurl (default: no) ---with-gd build with gd (default: no) ---with-png build with libpng (default: no) +--with-jpeg build with libjpeg (default: auto) +--with-png build with libpng (default: auto) --with-pkgconfigdir specify pkgconfig dir (default is libdir/pkgconfig) --with-bashcompletiondir specify bashcompletion.d --with-zshcompletiondir specify zshcompletion.d @@ -260,6 +275,10 @@ Options: DECDMAC and make terminal memorize SIXEL image. No image is shown if this option is specified +-C COMPLEXIONSCORE, --complexion-score=COMPLEXIONSCORE + specify an number argument for the + score of complexion correction. + COMPLEXIONSCORE must be 1 or more. -g, --ignore-delay render GIF animation without delay -S, --static render animated GIF as a static image -d DIFFUSIONTYPE, --diffusion=DIFFUSIONTYPE @@ -295,16 +314,16 @@ Options: when -p option (color reduction) is specified SELECTTYPE is one of them: - auto -> choose selecting - method automatically - (default) - center -> choose the center of - the box - average -> calculate the color - average into the box + auto -> choose selecting + method automatically + (default) + center -> choose the center of + the box + average -> calculate the color + average into the box histogram -> similar with average - but considers color - histogram + but considers color + histogram -c REGION, --crop=REGION crop source image to fit the specified geometry. REGION should be formatted as '%dx%d+%d+%d' @@ -649,6 +668,22 @@ http://netpbm.sourceforge.net/ > implied warranty. +### loader.h (@uobikiemukot's sdump) + +Some parts of converters/loader.c are imported from @uobikiemukot's +[sdump](https://github.com/uobikiemukot/sdump) project + +> The MIT License (MIT) +> +> Copyright (c) 2014 haru +> +> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + ### ax_gcc_var_attribute / ax_gcc_func_attribute These are useful m4 macros for detecting some GCC attributes. @@ -664,6 +699,41 @@ http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html > warranty. +### graphics.c (from Xterm pl#310) + +The helper function *hls2rgb* in *src/fromsixel.c* is imported from +*graphics.c* in [Xterm pl#310](http://invisible-island.net/xterm/), +originally written by Ross Combs. + +> Copyright 2013,2014 by Ross Combs +> +> All Rights Reserved +> +> Permission is hereby granted, free of charge, to any person obtaining a +> copy of this software and associated documentation files (the +> "Software"), to deal in the Software without restriction, including +> without limitation the rights to use, copy, modify, merge, publish, +> distribute, sublicense, and/or sell copies of the Software, and to +> permit persons to whom the Software is furnished to do so, subject to +> the following conditions: +> +> The above copyright notice and this permission notice shall be included +> in all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +> OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +> IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY +> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +> +> Except as contained in this notice, the name(s) of the above copyright +> holders shall not be used in advertising or otherwise to promote the +> sale, use or other dealings in this Software without prior written +> authorization. + + ### test images #### http://public-domain-photos.com/ @@ -703,7 +773,7 @@ img2sixel in reference to the line-up of filters of MagickCore's resize.c. ## Similar software -- [ppmtosixel (netpbm)](http://netpbm.sourceforge.net/) +- [netpbm](http://netpbm.sourceforge.net/) You can get SIXEL graphics using [ppmtosixel](http://netpbm.sourceforge.net/doc/ppmtosixel.html) or [pbmtoln03](http://netpbm.sourceforge.net/doc/ppmtosixel.html). @@ -719,6 +789,11 @@ img2sixel in reference to the line-up of filters of MagickCore's resize.c. Python implementation of SIXEL converter +- [ImageMagick](http://www.imagemagick.org/) + + Now SIXEL coder is available in svn trunk and V6 branch. + + - [monosixel in arakiken's tw](https://bitbucket.org/arakiken/tw/branch/sixel) A monochrome SIXEL converter diff --git a/config.h.in b/config.h.in index 8e8b746a..8fecfe9d 100644 --- a/config.h.in +++ b/config.h.in @@ -6,6 +6,9 @@ /* Define to 1 if you have the `clock' function. */ #undef HAVE_CLOCK +/* enable debugging support */ +#undef HAVE_DEBUG + /* Define to 1 if you have the declaration of `gdImageCreateFromBmpPtr', and to 0 if you don't. */ #undef HAVE_DECL_GDIMAGECREATEFROMBMPPTR @@ -88,6 +91,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* whether jpeg codec library is available */ +#undef HAVE_JPEG + /* whether libcurl is available */ #undef HAVE_LIBCURL diff --git a/configure b/configure index 09fd9c1e..4a125883 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sixel 1.2.0. +# Generated by GNU Autoconf 2.69 for sixel 1.2.2. # # Report bugs to . # @@ -589,8 +589,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sixel' PACKAGE_TARNAME='sixel' -PACKAGE_VERSION='1.2.0' -PACKAGE_STRING='sixel 1.2.0' +PACKAGE_VERSION='1.2.2' +PACKAGE_STRING='sixel 1.2.2' PACKAGE_BUGREPORT='user@zuse.jp' PACKAGE_URL='' @@ -634,8 +634,14 @@ ac_unique_file="src/fromsixel.c" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS +HAVE_PNG_FALSE +HAVE_PNG_TRUE +HAVE_JPEG_FALSE +HAVE_JPEG_TRUE LIBPNG_LIBS LIBPNG_CFLAGS +LIBJPEG_LIBS +LIBJPEG_CFLAGS LIBCURL_LIBS LIBCURL_CFLAGS GD_LIBS @@ -643,12 +649,13 @@ GD_CFLAGS GDK_PIXBUF_LIBS GDK_PIXBUF_CFLAGS LIBOBJS -have_pkg_config PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG COND_GCOV_FALSE COND_GCOV_TRUE +COND_DEBUG_FALSE +COND_DEBUG_TRUE zshcompletiondir bashcompletiondir pkgconfigdir @@ -789,10 +796,12 @@ enable_sixel2png with_gdk_pixbuf2 with_gd with_libcurl +with_jpeg with_png with_pkgconfigdir with_bashcompletiondir with_zshcompletiondir +enable_debug enable_gcov ' ac_precious_vars='build_alias @@ -1355,7 +1364,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sixel 1.2.0 to adapt to many kinds of systems. +\`configure' configures sixel 1.2.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1425,7 +1434,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sixel 1.2.0:";; + short | recursive ) echo "Configuration of sixel 1.2.2:";; esac cat <<\_ACEOF @@ -1446,6 +1455,7 @@ Optional Features: --disable-libtool-lock avoid locking (might break parallel builds) --disable-img2sixel whether to build img2sixel (default: yes) --disable-sixel2png whether to build sixel2png (default: yes) + --enable-debug Use debug macro and specific CFLAGS --enable-gcov Use gcov Optional Packages: @@ -1458,8 +1468,9 @@ Optional Packages: (or the compiler's sysroot if not specified). --with-gdk-pixbuf2 whether to build with gdk-pixbuf2 (default: no) --with-gd whether to build with gd (default: no) - --with-libcurl whether to build with libcurl (default: no) - --with-png whether to build with libpng (default: no) + --with-libcurl whether to build with libcurl (default: auto) + --with-jpeg whether to build with libjpeg (default: auto) + --with-png whether to build with libpng (default: auto) --with-pkgconfigdir Use the specified pkgconfig dir (default is libdir/pkgconfig) --with-bashcompletiondir @@ -1560,7 +1571,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sixel configure 1.2.0 +sixel configure 1.2.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1975,7 +1986,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sixel $as_me 1.2.0, which was +It was created by sixel $as_me 1.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2324,7 +2335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu LS_LT_CURRENT=1 -LS_LT_REVISION=1 +LS_LT_REVISION=2 LS_LT_AGE=0 LS_LTVERSION=$LS_LT_CURRENT:$LS_LT_REVISION:$LS_LT_AGE @@ -2918,7 +2929,7 @@ fi # Define the identity of the package. PACKAGE='sixel' - VERSION='1.2.0' + VERSION='1.2.2' cat >>confdefs.h <<_ACEOF @@ -11735,7 +11746,16 @@ fi if test "${with_libcurl+set}" = set; then : withval=$with_libcurl; else - with_libcurl=no + with_libcurl=auto +fi + + + +# Check whether --with-jpeg was given. +if test "${with_jpeg+set}" = set; then : + withval=$with_jpeg; +else + with_jpeg=auto fi @@ -11744,7 +11764,7 @@ fi if test "${with_png+set}" = set; then : withval=$with_png; else - with_png=no + with_png=auto fi @@ -11790,6 +11810,24 @@ fi $as_echo "$as_me: zsh-completion directory is ${zshcompletiondir}" >&6;} +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; +$as_echo "#define HAVE_DEBUG 1" >>confdefs.h + +else + enable_debug=no +fi + + if test x$enable_debug != xno; then + COND_DEBUG_TRUE= + COND_DEBUG_FALSE='#' +else + COND_DEBUG_TRUE='#' + COND_DEBUG_FALSE= +fi + + # Check whether --enable-gcov was given. if test "${enable_gcov+set}" = set; then : enableval=$enable_gcov; @@ -12534,6 +12572,7 @@ fi +if test x$cross_compile != xyes; then : @@ -12654,45 +12693,8 @@ $as_echo "no" >&6; } PKG_CONFIG="" fi fi -# Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_have_pkg_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$have_pkg_config"; then - ac_cv_prog_have_pkg_config="$have_pkg_config" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_have_pkg_config="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_have_pkg_config" && ac_cv_prog_have_pkg_config="no" -fi -fi -have_pkg_config=$ac_cv_prog_have_pkg_config -if test -n "$have_pkg_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pkg_config" >&5 -$as_echo "$have_pkg_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } fi - - # For wic integration #AC_PROG_CXX @@ -12975,6 +12977,7 @@ _ACEOF loaders="stb_image" have_curl="no" +have_jpeg="no" have_png="no" #have_wic="no" @@ -12991,7 +12994,7 @@ have_png="no" #fi if test x$with_gdk_pixbuf2 != xno; then - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GDK_PIXBUF" >&5 @@ -13135,7 +13138,7 @@ fi fi - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then if test x$have_gd != xyes; then pkg_failed=no @@ -13885,7 +13888,7 @@ fi if test x$have_curl != xyes; then - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBCURL" >&5 @@ -13964,7 +13967,11 @@ fi $as_echo "#define HAVE_LIBCURL 1" >>confdefs.h else - as_fn_error $? "unable to find libcurl" "$LINENO" 5 + if test x$with_libcurl != xauto; then + as_fn_error $? "unable to find libcurl" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: libcurl is not available" >&5 +$as_echo "$as_me: libcurl is not available" >&6;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: libcurl cflags is ${LIBCURL_CFLAGS}" >&5 $as_echo "$as_me: libcurl cflags is ${LIBCURL_CFLAGS}" >&6;} @@ -13974,6 +13981,74 @@ fi +if test x$with_jpeg != xno; then + ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" +if test "x$ac_cv_header_jpeglib_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_read_header in -ljpeg" >&5 +$as_echo_n "checking for jpeg_read_header in -ljpeg... " >&6; } +if ${ac_cv_lib_jpeg_jpeg_read_header+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ljpeg $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char jpeg_read_header (); +int +main () +{ +return jpeg_read_header (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_jpeg_jpeg_read_header=yes +else + ac_cv_lib_jpeg_jpeg_read_header=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_read_header" >&5 +$as_echo "$ac_cv_lib_jpeg_jpeg_read_header" >&6; } +if test "x$ac_cv_lib_jpeg_jpeg_read_header" = xyes; then : + have_jpeg=yes LIBJPEG_LIBS=-ljpeg +else + have_jpeg=no +fi + +fi + + + if test x$have_jpeg = xyes; then + +$as_echo "#define HAVE_JPEG 1" >>confdefs.h + + loaders="${loaders} jpeg" + { $as_echo "$as_me:${as_lineno-$LINENO}: jpeg cflags is ${LIBJPEG_CFLAGS}" >&5 +$as_echo "$as_me: jpeg cflags is ${LIBJPEG_CFLAGS}" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: jpeg libs is ${LIBJPEG_LIBS}" >&5 +$as_echo "$as_me: jpeg libs is ${LIBJPEG_LIBS}" >&6;} + else + if test x$with_jpeg != xauto; then + as_fn_error $? "unable to find jpeg codec library" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: libjpeg is not available" >&5 +$as_echo "$as_me: libjpeg is not available" >&6;} + fi +fi + + + if test x$with_png != xno; then ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default" if test "x$ac_cv_header_png_h" = xyes; then : @@ -14023,7 +14098,7 @@ fi if test x$have_png != xyes; then - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBPNG" >&5 @@ -14101,14 +14176,18 @@ fi $as_echo "#define HAVE_LIBPNG 1" >>confdefs.h - loaders="${loaders} libpng" - else - as_fn_error $? "unable to find libpng" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: libpng cflags is ${LIBPNG_CFLAGS}" >&5 + loaders="${loaders} png" + { $as_echo "$as_me:${as_lineno-$LINENO}: libpng cflags is ${LIBPNG_CFLAGS}" >&5 $as_echo "$as_me: libpng cflags is ${LIBPNG_CFLAGS}" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: libpng libs is ${LIBPNG_LIBS}" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: libpng libs is ${LIBPNG_LIBS}" >&5 $as_echo "$as_me: libpng libs is ${LIBPNG_LIBS}" >&6;} + else + if test x$with_png != xauto; then + as_fn_error $? "unable to find libpng" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: libpng is not available" >&5 +$as_echo "$as_me: libpng is not available" >&6;} + fi fi @@ -14118,6 +14197,23 @@ fi touch aclocal.m4 Makefile.in */Makefile.in configure config.h.in + if test x$have_jpeg == xyes; then + HAVE_JPEG_TRUE= + HAVE_JPEG_FALSE='#' +else + HAVE_JPEG_TRUE='#' + HAVE_JPEG_FALSE= +fi + + if test x$have_png == xyes; then + HAVE_PNG_TRUE= + HAVE_PNG_FALSE='#' +else + HAVE_PNG_TRUE='#' + HAVE_PNG_FALSE= +fi + + ac_config_files="$ac_config_files Makefile libsixel.pc package.json.in include/sixel.h src/Makefile include/Makefile converters/Makefile" @@ -14262,6 +14358,10 @@ if test -z "${WANT_SIXEL2PNG_TRUE}" && test -z "${WANT_SIXEL2PNG_FALSE}"; then as_fn_error $? "conditional \"WANT_SIXEL2PNG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${COND_DEBUG_TRUE}" && test -z "${COND_DEBUG_FALSE}"; then + as_fn_error $? "conditional \"COND_DEBUG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${COND_GCOV_TRUE}" && test -z "${COND_GCOV_FALSE}"; then as_fn_error $? "conditional \"COND_GCOV\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -14270,6 +14370,14 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_JPEG_TRUE}" && test -z "${HAVE_JPEG_FALSE}"; then + as_fn_error $? "conditional \"HAVE_JPEG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_PNG_TRUE}" && test -z "${HAVE_PNG_FALSE}"; then + as_fn_error $? "conditional \"HAVE_PNG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -14667,7 +14775,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sixel $as_me 1.2.0, which was +This file was extended by sixel $as_me 1.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14733,7 +14841,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sixel config.status 1.2.0 +sixel config.status 1.2.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -16517,5 +16625,6 @@ echo " Bash completion dir : $bashcompletiondir" echo " Zsh completion dir : $zshcompletiondir" #echo " WIC integration : $have_wic" echo " gcov integration : $enable_gcov" +echo " debugging : $enable_debug" echo "" echo "" diff --git a/configure.ac b/configure.ac index ff13a9f1..f983a429 100644 --- a/configure.ac +++ b/configure.ac @@ -3,9 +3,9 @@ AC_PREREQ([2.60]) LT_PREREQ([2.4]) -AC_INIT([sixel], [1.2.0], [user@zuse.jp]) +AC_INIT([sixel], [1.2.2], [user@zuse.jp]) LS_LT_CURRENT=1 -LS_LT_REVISION=1 +LS_LT_REVISION=2 LS_LT_AGE=0 AC_SUBST([LS_LTVERSION], [$LS_LT_CURRENT:$LS_LT_REVISION:$LS_LT_AGE]) AC_SUBST([PACKAGE_DESCRIPTION], @@ -60,15 +60,21 @@ AC_ARG_WITH([gd], AC_ARG_WITH([libcurl], [AS_HELP_STRING([--with-libcurl], - [whether to build with libcurl (default: no)])], + [whether to build with libcurl (default: auto)])], [], - [with_libcurl=no]) + [with_libcurl=auto]) + +AC_ARG_WITH([jpeg], + [AS_HELP_STRING([--with-jpeg], + [whether to build with libjpeg (default: auto)])], + [], + [with_jpeg=auto]) AC_ARG_WITH([png], [AS_HELP_STRING([--with-png], - [whether to build with libpng (default: no)])], + [whether to build with libpng (default: auto)])], [], - [with_png=no]) + [with_png=auto]) #AC_ARG_WITH([wic], # [AS_HELP_STRING([--with-wic], @@ -100,6 +106,13 @@ AC_ARG_WITH(zshcompletiondir, AC_MSG_NOTICE([zsh-completion directory is ${zshcompletiondir}]) AC_SUBST(zshcompletiondir) +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [Use debug macro and specific CFLAGS])], + [AC_DEFINE(HAVE_DEBUG, [1], [enable debugging support])], + [enable_debug=no]) +AM_CONDITIONAL([COND_DEBUG], [test x$enable_debug != xno]) + AC_ARG_ENABLE([gcov], [AS_HELP_STRING([--enable-gcov], [Use gcov])], @@ -110,8 +123,7 @@ AM_CONDITIONAL([COND_GCOV], [test x$enable_gcov != xno]) # Checks for programs. AC_PROG_CC AC_PROG_INSTALL -PKG_PROG_PKG_CONFIG -AC_CHECK_PROG(have_pkg_config, pkg-config, yes, no) +AS_IF([test x$cross_compile != xyes], [PKG_PROG_PKG_CONFIG], []) # For wic integration #AC_PROG_CXX @@ -168,6 +180,7 @@ AC_CHECK_DECLS([SIGINT, SIGTERM, SIGHUP],,, loaders="stb_image" have_curl="no" +have_jpeg="no" have_png="no" #have_wic="no" @@ -184,7 +197,7 @@ have_png="no" #fi if test x$with_gdk_pixbuf2 != xno; then - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0], [have_gdk_pixbuf2=yes], @@ -214,7 +227,7 @@ if test x$with_gd != xno; then [gdImageCreateFromGifPtr], [have_gd="yes" GD_LIBS=-lgd], [have_gd="no"])]) - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then if test x$have_gd != xyes; then PKG_CHECK_MODULES(GD, [gdlib], [have_gd=yes], [have_gd=no]) fi @@ -278,7 +291,7 @@ if test x$with_libcurl != xno; then [have_curl=yes LIBCURL_LIBS=-lcurl], [have_curl=no])]) if test x$have_curl != xyes; then - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then PKG_CHECK_MODULES(LIBCURL, [libcurl], [have_curl=yes], @@ -288,7 +301,10 @@ if test x$with_libcurl != xno; then if test x$have_curl = xyes; then AC_DEFINE(HAVE_LIBCURL, 1, [whether libcurl is available]) else - AC_MSG_ERROR([unable to find libcurl]) + if test x$with_libcurl != xauto; then + AC_MSG_ERROR([unable to find libcurl]) + fi + AC_MSG_NOTICE([libcurl is not available]) fi AC_MSG_NOTICE([libcurl cflags is ${LIBCURL_CFLAGS}]) AC_MSG_NOTICE([libcurl libs is ${LIBCURL_LIBS}]) @@ -296,6 +312,27 @@ fi AC_SUBST(LIBCURL_CFLAGS) AC_SUBST(LIBCURL_LIBS) +if test x$with_jpeg != xno; then + AC_CHECK_HEADER([jpeglib.h], + [AC_CHECK_LIB([jpeg], + [jpeg_read_header], + [have_jpeg=yes LIBJPEG_LIBS=-ljpeg], + [have_jpeg=no])]) + if test x$have_jpeg = xyes; then + AC_DEFINE(HAVE_JPEG, 1, [whether jpeg codec library is available]) + loaders="${loaders} jpeg" + AC_MSG_NOTICE([jpeg cflags is ${LIBJPEG_CFLAGS}]) + AC_MSG_NOTICE([jpeg libs is ${LIBJPEG_LIBS}]) + else + if test x$with_jpeg != xauto; then + AC_MSG_ERROR([unable to find jpeg codec library]) + fi + AC_MSG_NOTICE([libjpeg is not available]) + fi +fi +AC_SUBST(LIBJPEG_CFLAGS) +AC_SUBST(LIBJPEG_LIBS) + if test x$with_png != xno; then AC_CHECK_HEADER([png.h], [AC_CHECK_LIB([png], @@ -303,7 +340,7 @@ if test x$with_png != xno; then [have_png=yes LIBPNG_LIBS=-lpng], [have_png=no])]) if test x$have_png != xyes; then - if test x$have_pkg_config != xno; then + if test x${PKG_CONFIG} != x; then PKG_CHECK_MODULES(LIBPNG, [libpng], [have_png=yes], @@ -312,12 +349,15 @@ if test x$with_png != xno; then fi if test x$have_png = xyes; then AC_DEFINE(HAVE_LIBPNG, 1, [whether libpng is available]) - loaders="${loaders} libpng" + loaders="${loaders} png" + AC_MSG_NOTICE([libpng cflags is ${LIBPNG_CFLAGS}]) + AC_MSG_NOTICE([libpng libs is ${LIBPNG_LIBS}]) else - AC_MSG_ERROR([unable to find libpng]) + if test x$with_png != xauto; then + AC_MSG_ERROR([unable to find libpng]) + fi + AC_MSG_NOTICE([libpng is not available]) fi - AC_MSG_NOTICE([libpng cflags is ${LIBPNG_CFLAGS}]) - AC_MSG_NOTICE([libpng libs is ${LIBPNG_LIBS}]) fi AC_SUBST(LIBPNG_CFLAGS) AC_SUBST(LIBPNG_LIBS) @@ -327,6 +367,9 @@ AC_DEFUN([LS_UPDATE_TIMESTAMP], [ ]) LS_UPDATE_TIMESTAMP +AM_CONDITIONAL([HAVE_JPEG], [test x$have_jpeg == xyes]) +AM_CONDITIONAL([HAVE_PNG], [test x$have_png == xyes]) + AC_CONFIG_FILES([Makefile libsixel.pc package.json.in @@ -348,5 +391,6 @@ echo " Bash completion dir : $bashcompletiondir" echo " Zsh completion dir : $zshcompletiondir" #echo " WIC integration : $have_wic" echo " gcov integration : $enable_gcov" +echo " debugging : $enable_debug" echo "" echo "" diff --git a/converters/Makefile.am b/converters/Makefile.am index 2903106d..b498189b 100644 --- a/converters/Makefile.am +++ b/converters/Makefile.am @@ -19,8 +19,15 @@ if WANT_IMG2SIXEL bin_PROGRAMS += img2sixel img2sixel_SOURCES = img2sixel.c scale.c malloc_stub.c loader.c frompnm.c \ scale.h malloc_stub.h loader.h frompnm.h -img2sixel_CFLAGS = -Wall -I$(top_builddir)/include/ $(MAYBE_COVERAGE) $(GDK_PIXBUF_CFLAGS) $(LIBCURL_CFLAGS) $(GD_CFLAGS) $(LIBPNG_CFLAGS) -img2sixel_LDADD = $(top_builddir)/src/libsixel.la -lm $(GDK_PIXBUF_LIBS) $(LIBCURL_LIBS) $(GD_LIBS) $(LIBPNG_LIBS) +img2sixel_CFLAGS = -I$(top_builddir)/include/ \ + $(MAYBE_COVERAGE) $(GDK_PIXBUF_CFLAGS) $(LIBCURL_CFLAGS) \ + $(GD_CFLAGS) $(LIBJPEG_CFLAGS) $(LIBPNG_CFLAGS) +if COND_DEBUG +img2sixel_CFLAGS += -Werror +endif +img2sixel_LDADD = $(top_builddir)/src/libsixel.la -lm \ + $(GDK_PIXBUF_LIBS) $(LIBCURL_LIBS) $(GD_LIBS) \ + $(LIBJPEG_LIBS) $(LIBPNG_LIBS) dist_man_MANS += img2sixel.1 dist_bashcompletion_DATA += shell-completion/bash/img2sixel dist_zshcompletion_DATA += shell-completion/zsh/_img2sixel @@ -30,41 +37,37 @@ if WANT_SIXEL2PNG bin_PROGRAMS += sixel2png sixel2png_SOURCES = sixel2png.c stb_image_write.c malloc_stub.c \ stb_image_write.h malloc_stub.h -sixel2png_CFLAGS = -Wall -I$(top_builddir)/include/ $(MAYBE_COVERAGE) $(LIBPNG_CFLAGS) +sixel2png_CFLAGS = -Wall -I$(top_builddir)/include/ \ + $(MAYBE_COVERAGE) $(LIBPNG_CFLAGS) +if COND_DEBUG +sixel2png_CFLAGS += -Werror +endif sixel2png_LDADD = $(top_builddir)/src/libsixel.la $(LIBPNG_LIBS) dist_man_MANS += sixel2png.1 endif test: all if WANT_IMG2SIXEL - ./img2sixel ../images/snake.jpg | tee snake.sixel - ./img2sixel ../images/snake.jpg -w50% --height=100 | tee snake2.sixel + $(WINE) ./img2sixel ../images/snake.jpg | tee snake.sixel + $(WINE) ./img2sixel ../images/snake.jpg -w50% --height=100 | tee snake2.sixel +if HAVE_JPEG + $(WINE) ./img2sixel ../images/snake-progressive.jpg | tee snake.sixel endif -if WANT_SIXEL2PNG - ./sixel2png < snake.sixel > snake1.png - ./sixel2png -i snake.sixel -o snake2.png -endif -if WANT_IMG2SIXEL - ./img2sixel -m ../images/map8.png ../images/egret.jpg - ./img2sixel -m ../images/map16.png ../images/snake.pnm - ./img2sixel -p 8 ../images/snake.jpg - ./img2sixel -p 2 ../images/snake.jpg - ./img2sixel -e ../images/snake.jpg +if HAVE_PNG + $(WINE) ./img2sixel ../images/snake.png | tee snake.sixel endif - -winetest: all -if WANT_IMG2SIXEL - wine ./img2sixel.exe ../images/snake.jpg | tee snake.sixel - wine ./img2sixel ../images/snake.jpg -w50% --height=100 | tee snake2.sixel endif if WANT_SIXEL2PNG - wine ./sixel2png < snake.sixel > snake1.png - wine ./sixel2png -i snake.sixel -o snake2.png + $(WINE) ./sixel2png < snake.sixel > snake1.png + $(WINE) ./sixel2png -i snake.sixel -o snake2.png endif if WANT_IMG2SIXEL - wine ./img2sixel -m ../images/map8.png ../images/egret.jpg - wine ./img2sixel -m ../images/map16.png ../images/snake.pnm - wine ./img2sixel -p 8 ../images/snake.jpg - wine ./img2sixel -p 2 ../images/snake.jpg - wine ./img2sixel -e ../images/snake.jpg + $(WINE) ./img2sixel -m ../images/map8.png ../images/egret.jpg + $(WINE) ./img2sixel -m ../images/map16.png ../images/snake.pnm + $(WINE) ./img2sixel -p 8 ../images/snake.jpg + $(WINE) ./img2sixel -p 2 ../images/snake.jpg + $(WINE) ./img2sixel -e ../images/snake.jpg endif + +winetest: all + WINE=wine $(MAKE) test diff --git a/converters/Makefile.in b/converters/Makefile.in index 26c834a6..6fa416c2 100644 --- a/converters/Makefile.in +++ b/converters/Makefile.in @@ -81,11 +81,13 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) @WANT_IMG2SIXEL_TRUE@am__append_1 = img2sixel -@WANT_IMG2SIXEL_TRUE@am__append_2 = img2sixel.1 -@WANT_IMG2SIXEL_TRUE@am__append_3 = shell-completion/bash/img2sixel -@WANT_IMG2SIXEL_TRUE@am__append_4 = shell-completion/zsh/_img2sixel -@WANT_SIXEL2PNG_TRUE@am__append_5 = sixel2png -@WANT_SIXEL2PNG_TRUE@am__append_6 = sixel2png.1 +@COND_DEBUG_TRUE@@WANT_IMG2SIXEL_TRUE@am__append_2 = -Werror +@WANT_IMG2SIXEL_TRUE@am__append_3 = img2sixel.1 +@WANT_IMG2SIXEL_TRUE@am__append_4 = shell-completion/bash/img2sixel +@WANT_IMG2SIXEL_TRUE@am__append_5 = shell-completion/zsh/_img2sixel +@WANT_SIXEL2PNG_TRUE@am__append_6 = sixel2png +@COND_DEBUG_TRUE@@WANT_SIXEL2PNG_TRUE@am__append_7 = -Werror +@WANT_SIXEL2PNG_TRUE@am__append_8 = sixel2png.1 subdir = converters SUBDIRS = DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ @@ -125,6 +127,7 @@ am__DEPENDENCIES_1 = @WANT_IMG2SIXEL_TRUE@ $(am__DEPENDENCIES_1) \ @WANT_IMG2SIXEL_TRUE@ $(am__DEPENDENCIES_1) \ @WANT_IMG2SIXEL_TRUE@ $(am__DEPENDENCIES_1) \ +@WANT_IMG2SIXEL_TRUE@ $(am__DEPENDENCIES_1) \ @WANT_IMG2SIXEL_TRUE@ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -321,6 +324,8 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBJPEG_CFLAGS = @LIBJPEG_CFLAGS@ +LIBJPEG_LIBS = @LIBJPEG_LIBS@ LIBOBJS = @LIBOBJS@ LIBPNG_CFLAGS = @LIBPNG_CFLAGS@ LIBPNG_LIBS = @LIBPNG_LIBS@ @@ -384,7 +389,6 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_pkg_config = @have_pkg_config@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -416,20 +420,30 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ zshcompletiondir = @zshcompletiondir@ DIST_SUBDIRS = $(SUBDIRS) -dist_man_MANS = $(am__append_2) $(am__append_6) -dist_bashcompletion_DATA = $(am__append_3) -dist_zshcompletion_DATA = $(am__append_4) +dist_man_MANS = $(am__append_3) $(am__append_8) +dist_bashcompletion_DATA = $(am__append_4) +dist_zshcompletion_DATA = $(am__append_5) @COND_GCOV_TRUE@MAYBE_COVERAGE = --coverage CLEANFILES = *.gcno *.gcda *.gcov snake1.png snake2.png snake2.sixel @WANT_IMG2SIXEL_TRUE@img2sixel_SOURCES = img2sixel.c scale.c malloc_stub.c loader.c frompnm.c \ @WANT_IMG2SIXEL_TRUE@ scale.h malloc_stub.h loader.h frompnm.h -@WANT_IMG2SIXEL_TRUE@img2sixel_CFLAGS = -Wall -I$(top_builddir)/include/ $(MAYBE_COVERAGE) $(GDK_PIXBUF_CFLAGS) $(LIBCURL_CFLAGS) $(GD_CFLAGS) $(LIBPNG_CFLAGS) -@WANT_IMG2SIXEL_TRUE@img2sixel_LDADD = $(top_builddir)/src/libsixel.la -lm $(GDK_PIXBUF_LIBS) $(LIBCURL_LIBS) $(GD_LIBS) $(LIBPNG_LIBS) +@WANT_IMG2SIXEL_TRUE@img2sixel_CFLAGS = -I$(top_builddir)/include/ \ +@WANT_IMG2SIXEL_TRUE@ $(MAYBE_COVERAGE) $(GDK_PIXBUF_CFLAGS) \ +@WANT_IMG2SIXEL_TRUE@ $(LIBCURL_CFLAGS) $(GD_CFLAGS) \ +@WANT_IMG2SIXEL_TRUE@ $(LIBJPEG_CFLAGS) $(LIBPNG_CFLAGS) \ +@WANT_IMG2SIXEL_TRUE@ $(am__append_2) +@WANT_IMG2SIXEL_TRUE@img2sixel_LDADD = $(top_builddir)/src/libsixel.la -lm \ +@WANT_IMG2SIXEL_TRUE@ $(GDK_PIXBUF_LIBS) $(LIBCURL_LIBS) $(GD_LIBS) \ +@WANT_IMG2SIXEL_TRUE@ $(LIBJPEG_LIBS) $(LIBPNG_LIBS) + @WANT_SIXEL2PNG_TRUE@sixel2png_SOURCES = sixel2png.c stb_image_write.c malloc_stub.c \ @WANT_SIXEL2PNG_TRUE@ stb_image_write.h malloc_stub.h -@WANT_SIXEL2PNG_TRUE@sixel2png_CFLAGS = -Wall -I$(top_builddir)/include/ $(MAYBE_COVERAGE) $(LIBPNG_CFLAGS) +@WANT_SIXEL2PNG_TRUE@sixel2png_CFLAGS = -Wall \ +@WANT_SIXEL2PNG_TRUE@ -I$(top_builddir)/include/ \ +@WANT_SIXEL2PNG_TRUE@ $(MAYBE_COVERAGE) $(LIBPNG_CFLAGS) \ +@WANT_SIXEL2PNG_TRUE@ $(am__append_7) @WANT_SIXEL2PNG_TRUE@sixel2png_LDADD = $(top_builddir)/src/libsixel.la $(LIBPNG_LIBS) all: all-recursive @@ -1051,26 +1065,20 @@ uninstall-man: uninstall-man1 test: all -@WANT_IMG2SIXEL_TRUE@ ./img2sixel ../images/snake.jpg | tee snake.sixel -@WANT_IMG2SIXEL_TRUE@ ./img2sixel ../images/snake.jpg -w50% --height=100 | tee snake2.sixel -@WANT_SIXEL2PNG_TRUE@ ./sixel2png < snake.sixel > snake1.png -@WANT_SIXEL2PNG_TRUE@ ./sixel2png -i snake.sixel -o snake2.png -@WANT_IMG2SIXEL_TRUE@ ./img2sixel -m ../images/map8.png ../images/egret.jpg -@WANT_IMG2SIXEL_TRUE@ ./img2sixel -m ../images/map16.png ../images/snake.pnm -@WANT_IMG2SIXEL_TRUE@ ./img2sixel -p 8 ../images/snake.jpg -@WANT_IMG2SIXEL_TRUE@ ./img2sixel -p 2 ../images/snake.jpg -@WANT_IMG2SIXEL_TRUE@ ./img2sixel -e ../images/snake.jpg +@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel ../images/snake.jpg | tee snake.sixel +@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel ../images/snake.jpg -w50% --height=100 | tee snake2.sixel +@HAVE_JPEG_TRUE@@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel ../images/snake-progressive.jpg | tee snake.sixel +@HAVE_PNG_TRUE@@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel ../images/snake.png | tee snake.sixel +@WANT_SIXEL2PNG_TRUE@ $(WINE) ./sixel2png < snake.sixel > snake1.png +@WANT_SIXEL2PNG_TRUE@ $(WINE) ./sixel2png -i snake.sixel -o snake2.png +@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel -m ../images/map8.png ../images/egret.jpg +@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel -m ../images/map16.png ../images/snake.pnm +@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel -p 8 ../images/snake.jpg +@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel -p 2 ../images/snake.jpg +@WANT_IMG2SIXEL_TRUE@ $(WINE) ./img2sixel -e ../images/snake.jpg winetest: all -@WANT_IMG2SIXEL_TRUE@ wine ./img2sixel.exe ../images/snake.jpg | tee snake.sixel -@WANT_IMG2SIXEL_TRUE@ wine ./img2sixel ../images/snake.jpg -w50% --height=100 | tee snake2.sixel -@WANT_SIXEL2PNG_TRUE@ wine ./sixel2png < snake.sixel > snake1.png -@WANT_SIXEL2PNG_TRUE@ wine ./sixel2png -i snake.sixel -o snake2.png -@WANT_IMG2SIXEL_TRUE@ wine ./img2sixel -m ../images/map8.png ../images/egret.jpg -@WANT_IMG2SIXEL_TRUE@ wine ./img2sixel -m ../images/map16.png ../images/snake.pnm -@WANT_IMG2SIXEL_TRUE@ wine ./img2sixel -p 8 ../images/snake.jpg -@WANT_IMG2SIXEL_TRUE@ wine ./img2sixel -p 2 ../images/snake.jpg -@WANT_IMG2SIXEL_TRUE@ wine ./img2sixel -e ../images/snake.jpg + WINE=wine $(MAKE) test # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/converters/img2sixel.c b/converters/img2sixel.c index ac03c0dd..f84d8714 100644 --- a/converters/img2sixel.c +++ b/converters/img2sixel.c @@ -141,6 +141,7 @@ prepare_specified_palette(char const *mapfile, int reqcolors) if (dither == NULL) { return NULL; } + ret = sixel_dither_initialize(dither, mappixels, map_sx, map_sy, 3, LARGE_NORM, REP_CENTER_BOX, QUALITY_LOW); if (ret != 0) { @@ -190,6 +191,7 @@ typedef struct Settings { int clipfirst; int macro_number; int penetrate_multiplexer; + int verbose; int show_version; int show_help; } settings_t; @@ -208,7 +210,7 @@ prepare_palette(unsigned char *frame, int sx, int sy, settings_t *psettings) } } else if (psettings->mapfile) { dither = prepare_specified_palette(psettings->mapfile, - psettings->reqcolors); + psettings->reqcolors); if (!dither) { return NULL; } @@ -339,6 +341,22 @@ static int do_crop(unsigned char **frames, int frame_count, } +static void +print_palette(sixel_dither_t *dither) +{ + unsigned char *palette; + int i; + + fprintf(stderr, "palette:\n"); + palette = sixel_dither_get_palette(dither); + for (i = 0; i < sixel_dither_get_num_of_palette_colors(dither); ++i) { + fprintf(stderr, "%d: #%02x%02x%02x\n", i, + palette[i * 3 + 1], + palette[i * 3 + 2], + palette[i * 3 + 3]); + } +} + static int convert_to_sixel(char const *filename, settings_t *psettings) { @@ -417,6 +435,10 @@ convert_to_sixel(char const *filename, settings_t *psettings) goto end; } + if (psettings->verbose) { + print_palette(dither); + } + if (psettings->method_for_diffuse == DIFFUSE_AUTO) { psettings->method_for_diffuse = DIFFUSE_FS; } @@ -469,7 +491,6 @@ convert_to_sixel(char const *filename, settings_t *psettings) nret = sixel_encode(frames[n], sx, sy, 3, dither, context); if (nret != 0) { - free(p); goto end; } @@ -811,7 +832,7 @@ main(int argc, char *argv[]) int number; char unit[32]; int parsed; - char const *optstring = "78p:m:ed:f:s:c:w:h:r:q:il:ugSn:PC:VH"; + char const *optstring = "78p:m:ed:f:s:c:w:h:r:q:il:ugvSn:PC:VH"; settings_t settings = { -1, /* reqcolors */ @@ -863,6 +884,7 @@ main(int argc, char *argv[]) {"loop-control", required_argument, &long_opt, 'l'}, {"use-macro", no_argument, &long_opt, 'u'}, {"ignore-delay", no_argument, &long_opt, 'g'}, + {"verbose", no_argument, &long_opt, 'v'}, {"static", no_argument, &long_opt, 'S'}, {"macro-number", required_argument, &long_opt, 'n'}, {"penetrate", no_argument, &long_opt, 'P'}, @@ -1100,6 +1122,9 @@ main(int argc, char *argv[]) case 'g': settings.fignore_delay = 1; break; + case 'v': + settings.verbose = 1; + break; case 'S': settings.fstatic = 1; break; @@ -1178,7 +1203,7 @@ main(int argc, char *argv[]) argerr: exit_code = EXIT_FAILURE; - fprintf(stderr, "usage: img2sixel [-78eiugVH] [-p colors] [-m file] [-d diffusiontype]\n" + fprintf(stderr, "usage: img2sixel [-78eiugvVH] [-p colors] [-m file] [-d diffusiontype]\n" " [-f findtype] [-s selecttype] [-c geometory] [-w width]\n" " [-h height] [-r resamplingtype] [-q quality] [-l loopmode]\n" " [-n macronumber] [filename ...]\n" diff --git a/converters/loader.c b/converters/loader.c index bc07912a..35f8a5a2 100644 --- a/converters/loader.c +++ b/converters/loader.c @@ -25,6 +25,11 @@ #include #include +#if HAVE_JPEG +# include +# include +#endif /* HAVE_JPEG */ + #if HAVE_SYS_TYPES_H # include #endif @@ -66,6 +71,10 @@ # include #endif +#ifdef HAVE_ERRNO_H +# include +#endif + #ifdef HAVE_LIBPNG # include #endif /* HAVE_LIBPNG */ @@ -139,7 +148,7 @@ open_binary_file(char const *filename) } f = fopen(filename, "rb"); if (!f) { -#if _ERRNO_H +#if HAVE_ERRNO_H fprintf(stderr, "fopen('%s') failed.\n" "reason: %s.\n", filename, strerror(errno)); #endif /* HAVE_ERRNO_H */ @@ -162,7 +171,7 @@ get_chunk_from_file(char const *filename, chunk_t *pchunk) chunk_init(pchunk, 64 * 1024); if (pchunk->buffer == NULL) { -#if _ERRNO_H +#if HAVE_ERRNO_H fprintf(stderr, "get_chunk_from_file('%s'): malloc failed.\n" "reason: %s.\n", filename, strerror(errno)); #endif /* HAVE_ERRNO_H */ @@ -173,7 +182,7 @@ get_chunk_from_file(char const *filename, chunk_t *pchunk) if ((pchunk->max_size - pchunk->size) < 4096) { pchunk->max_size *= 2; if ((pchunk->buffer = (unsigned char *)realloc(pchunk->buffer, pchunk->max_size)) == NULL) { -#if _ERRNO_H +#if HAVE_ERRNO_H fprintf(stderr, "get_chunk_from_file('%s'): relloc failed.\n" "reason: %s.\n", filename, strerror(errno)); #endif /* HAVE_ERRNO_H */ @@ -221,6 +230,56 @@ get_chunk_from_url(char const *url, chunk_t *pchunk) return 0; } # endif /* HAVE_LIBCURL */ + + +# if HAVE_JPEG +/* import from @uobikiemukot's sdump loader.h */ +static unsigned char * +load_jpeg(unsigned char *data, int datasize, + int *pwidth, int *pheight, int *pdepth) +{ + int row_stride, size; + unsigned char *result; + JSAMPARRAY buffer; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr pub; + + cinfo.err = jpeg_std_error(&pub); + + jpeg_create_decompress(&cinfo); + jpeg_mem_src(&cinfo, data, datasize); + jpeg_read_header(&cinfo, TRUE); + + /* disable colormap (indexed color), grayscale -> rgb */ + cinfo.quantize_colors = FALSE; + cinfo.out_color_space = JCS_RGB; + jpeg_start_decompress(&cinfo); + + *pwidth = cinfo.output_width; + *pheight = cinfo.output_height; + *pdepth = cinfo.output_components; + + size = *pwidth * *pheight * *pdepth; + if ((result = (uint8_t *)calloc(1, size)) == NULL) { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return NULL; + } + + row_stride = cinfo.output_width * cinfo.output_components; + buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + while (cinfo.output_scanline < cinfo.output_height) { + jpeg_read_scanlines(&cinfo, buffer, 1); + memcpy(result + (cinfo.output_scanline - 1) * row_stride, buffer[0], row_stride); + } + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + return result; +} +# endif /* HAVE_JPEG */ static int @@ -326,6 +385,21 @@ chunk_is_gif(chunk_t const *chunk) } +#if HAVE_JPEG +static int +chunk_is_jpeg(chunk_t const *chunk) +{ + if (chunk->size < 2) { + return 0; + } + if (memcmp("\xFF\xD8", chunk->buffer, 2) == 0) { + return 1; + } + return 0; +} +#endif /* HAVE_JPEG */ + + #if HAVE_LIBPNG static void read_png(png_structp png_ptr, png_bytep data, png_size_t length) @@ -376,7 +450,7 @@ load_with_builtin(chunk_t const *pchunk, int *psx, int *psy, pixels = load_pnm(pchunk->buffer, pchunk->size, psx, psy, pcomp, pstride); if (!pixels) { -#if _ERRNO_H +#if HAVE_ERRNO_H fprintf(stderr, "load_pnm failed.\n" "reason: %s.\n", strerror(errno)); #endif /* HAVE_ERRNO_H */ @@ -385,6 +459,14 @@ load_with_builtin(chunk_t const *pchunk, int *psx, int *psy, *pframe_count = 1; *ploop_count = 1; } +#if HAVE_JPEG + else if (chunk_is_jpeg(pchunk)) { + pixels = load_jpeg(pchunk->buffer, pchunk->size, + psx, psy, pcomp); + *pframe_count = 1; + *ploop_count = 1; + } +#endif /* HAVE_JPEG */ #if HAVE_LIBPNG else if (chunk_is_png(pchunk)) { png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); @@ -408,13 +490,17 @@ load_with_builtin(chunk_t const *pchunk, int *psx, int *psy, switch (png_get_color_type(png_ptr, info_ptr)) { case PNG_COLOR_TYPE_PALETTE: png_set_palette_to_rgb(png_ptr); - *pcomp = 3; + *pcomp = 4; break; case PNG_COLOR_TYPE_GRAY: if (bitdepth < 8) { png_set_expand_gray_1_2_4_to_8(png_ptr); } break; + case PNG_COLOR_MASK_ALPHA: + png_set_strip_alpha(png_ptr); + *pcomp = 3; + break; default: break; } @@ -520,7 +606,7 @@ load_with_gdkpixbuf(chunk_t const *pchunk, int *psx, int *psy, loader = gdk_pixbuf_loader_new(); gdk_pixbuf_loader_write(loader, pchunk->buffer, pchunk->size, NULL); animation = gdk_pixbuf_loader_get_animation(loader); - if (fstatic || gdk_pixbuf_animation_is_static_image(animation)) { + if (!animation || fstatic || gdk_pixbuf_animation_is_static_image(animation)) { pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); if (pixbuf == NULL) { return NULL; @@ -726,7 +812,7 @@ load_with_gd(chunk_t const *pchunk, int *psx, int *psy, int *pcomp, int *pstride *pstride = *psx * *pcomp; p = pixels = malloc(*pstride * *psy); if (p == NULL) { -#if _ERRNO_H +#if HAVE_ERRNO_H fprintf(stderr, "load_with_gd failed.\n" "reason: %s.\n", strerror(errno)); #endif /* HAVE_ERRNO_H */ diff --git a/images/snake-progressive.jpg b/images/snake-progressive.jpg new file mode 100644 index 00000000..addaefc0 Binary files /dev/null and b/images/snake-progressive.jpg differ diff --git a/images/snake.png b/images/snake.png new file mode 100644 index 00000000..3ffc0768 Binary files /dev/null and b/images/snake.png differ diff --git a/include/Makefile.in b/include/Makefile.in index ff1c9586..d89e6d23 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -200,6 +200,8 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBJPEG_CFLAGS = @LIBJPEG_CFLAGS@ +LIBJPEG_LIBS = @LIBJPEG_LIBS@ LIBOBJS = @LIBOBJS@ LIBPNG_CFLAGS = @LIBPNG_CFLAGS@ LIBPNG_LIBS = @LIBPNG_LIBS@ @@ -263,7 +265,6 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_pkg_config = @have_pkg_config@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ diff --git a/include/sixel.h.in b/include/sixel.h.in index 014adf5d..6f21fb29 100644 --- a/include/sixel.h.in +++ b/include/sixel.h.in @@ -194,6 +194,12 @@ sixel_dither_get_palette(sixel_dither_t /* in */ *dither); /* dither context ob void sixel_dither_set_complexion_score(sixel_dither_t /* in */ *dither, /* dither context object */ int /* in */ score); /* complexion score (>= 1) */ + +void +sixel_dither_set_body_only(sixel_dither_t /* in */ *dither, /* dither context object */ + int /* in */ bodyonly); /* 0: output palette section + 1: do not output palette section */ + #ifdef __cplusplus } #endif diff --git a/package.json b/package.json index af40a839..2cdb8f77 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "libsixel", - "version": "1.2.0", + "version": "1.2.2", "repo": "saitoha/libsixel", "description": "A lightweight, fast implementation of DEC SIXEL graphics codec", "keywords": ["terminal", "graphics", "image", "sixel"], "license": "MIT", - "install": "./configure && make install" + "install": "./configure --with-libcurl && make install" } diff --git a/package.json.in.in b/package.json.in.in index 6d6d57be..35c1781f 100644 --- a/package.json.in.in +++ b/package.json.in.in @@ -5,5 +5,5 @@ "description": "@PACKAGE_DESCRIPTION@", "keywords": ["terminal", "graphics", "image", "sixel"], "license": "MIT", - "install": "./configure && make install" + "install": "./configure --with-libcurl && make install" } diff --git a/src/Makefile.am b/src/Makefile.am index 07598665..87c4e021 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,5 +8,8 @@ CLEANFILES = *.gcno *.gcda *.gcov lib_LTLIBRARIES = libsixel.la libsixel_la_SOURCES = output.c fromsixel.c tosixel.c quant.c dither.c libsixel_la_CFLAGS = -Wall -I$(top_builddir)/include/ $(MAYBE_COVERAGE) +if COND_DEBUG +libsixel_la_CFLAGS += -Werror +endif libsixel_la_LDFLAGS = -version-info $(LS_LTVERSION) dist_man_MANS = sixel.5 diff --git a/src/Makefile.in b/src/Makefile.in index e4fcedb9..8b2b43ff 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -78,6 +78,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@COND_DEBUG_TRUE@am__append_1 = -Werror subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp $(dist_man_MANS) @@ -237,6 +238,8 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ +LIBJPEG_CFLAGS = @LIBJPEG_CFLAGS@ +LIBJPEG_LIBS = @LIBJPEG_LIBS@ LIBOBJS = @LIBOBJS@ LIBPNG_CFLAGS = @LIBPNG_CFLAGS@ LIBPNG_LIBS = @LIBPNG_LIBS@ @@ -300,7 +303,6 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_pkg_config = @have_pkg_config@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -335,7 +337,8 @@ zshcompletiondir = @zshcompletiondir@ CLEANFILES = *.gcno *.gcda *.gcov lib_LTLIBRARIES = libsixel.la libsixel_la_SOURCES = output.c fromsixel.c tosixel.c quant.c dither.c -libsixel_la_CFLAGS = -Wall -I$(top_builddir)/include/ $(MAYBE_COVERAGE) +libsixel_la_CFLAGS = -Wall -I$(top_builddir)/include/ \ + $(MAYBE_COVERAGE) $(am__append_1) libsixel_la_LDFLAGS = -version-info $(LS_LTVERSION) dist_man_MANS = sixel.5 all: all-am diff --git a/src/dither.c b/src/dither.c index a1f75e8b..ace99710 100644 --- a/src/dither.c +++ b/src/dither.c @@ -142,6 +142,7 @@ sixel_dither_create(int ncolors) dither->keycolor = (-1); dither->optimized = 0; dither->complexion = 1; + dither->bodyonly = 0; dither->method_for_largest = LARGE_NORM; dither->method_for_rep = REP_CENTER_BOX; dither->method_for_diffuse = DIFFUSE_FS; @@ -294,6 +295,14 @@ sixel_dither_set_complexion_score(sixel_dither_t /* in */ *dither, /* dither co dither->complexion = score; } +void +sixel_dither_set_body_only(sixel_dither_t /* in */ *dither, /* dither context object */ + int /* in */ bodyonly) /* 0: output palette section + 1: do not output palette section */ +{ + dither->bodyonly = bodyonly; +} + unsigned char * sixel_apply_palette(unsigned char *pixels, int width, int height, sixel_dither_t *dither) { diff --git a/src/dither.h b/src/dither.h index 1a2d3513..a5b793c2 100644 --- a/src/dither.h +++ b/src/dither.h @@ -32,6 +32,7 @@ typedef struct sixel_dither { int origcolors; /* original colors */ int optimized; /* pixel is 15bpp compressable */ int complexion; /* for complexion correction */ + int bodyonly; /* do not output palette section if true */ int method_for_largest; /* method for finding the largest dimention for splitting */ int method_for_rep; /* method for choosing a color from the box */ diff --git a/src/fromsixel.c b/src/fromsixel.c index 594b15be..3c554ad0 100644 --- a/src/fromsixel.c +++ b/src/fromsixel.c @@ -13,6 +13,39 @@ * Hayaki Saito modified this and re-licensed * it under the MIT license. * + * The helper function hls2rgb is imported from Xterm pl#310. + * This is originally written by Ross Combs. + * Hayaki Saito slightly modified this. + * + * ------------------------------------------------------------------------- + * Copyright 2013,2014 by Ross Combs + * + * All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization. + * ------------------------------------------------------------------------- */ #include "config.h" #include /* NULL */ @@ -28,8 +61,6 @@ #define RGB(r, g, b) (((r) << 16) + ((g) << 8) + (b)) -#define RGBA(r, g, b, a) (((a) << 24) + ((r) << 16) + ((g) << 8) + (b)) - #define PALVAL(n,a,m) (((n) * (a) + ((m) / 2)) / (m)) #define XRGB(r,g,b) RGB(PALVAL(r, 255, 100), PALVAL(g, 255, 100), PALVAL(b, 255, 100)) @@ -54,60 +85,92 @@ static int const ColTab[] = { }; +/* + * Primary color hues: + * blue: 0 degrees + * red: 120 degrees + * green: 240 degrees + */ static int -HueToRGB(int n1, int n2, int hue) +hls2rgb(int hue, int lum, int sat) { - const int HLSMAX = 100; + double hs = (hue + 240) % 360; + double hv = hs / 360.0; + double lv = lum / 100.0; + double sv = sat / 100.0; + double c, x, m, c2; + double r1, g1, b1; + int r, g, b; + int hpi; - if (hue < 0) { - hue += HLSMAX; + if (sat == 0) { + r = g = b = lum * 255 / 100; + return RGB(r, g, b); } - if (hue > HLSMAX) { - hue -= HLSMAX; + if ((c2 = ((2.0 * lv) - 1.0)) < 0.0) + c2 = -c2; + c = (1.0 - c2) * sv; + hpi = (int) (hv * 6.0); + x = (hpi & 1) ? c : 0.0; + m = lv - 0.5 * c; + + switch (hpi) { + case 0: + r1 = c; + g1 = x; + b1 = 0.0; + break; + case 1: + r1 = x; + g1 = c; + b1 = 0.0; + break; + case 2: + r1 = 0.0; + g1 = c; + b1 = x; + break; + case 3: + r1 = 0.0; + g1 = x; + b1 = c; + break; + case 4: + r1 = x; + g1 = 0.0; + b1 = c; + break; + case 5: + r1 = c; + g1 = 0.0; + b1 = x; + break; + default: + return RGB(255, 255, 255); } - if (hue < (HLSMAX / 6)) { - return (n1 + (((n2 - n1) * hue + (HLSMAX / 12)) / (HLSMAX / 6))); - } - if (hue < (HLSMAX / 2)) { - return (n2); - } - if (hue < ((HLSMAX * 2) / 3)) { - return (n1 + (((n2 - n1) * (((HLSMAX * 2) / 3) - hue) + (HLSMAX / 12))/(HLSMAX / 6))); - } - return (n1); + r = (short) ((r1 + m) * 100.0 + 0.5); + g = (short) ((g1 + m) * 100.0 + 0.5); + b = (short) ((b1 + m) * 100.0 + 0.5); + + if (r < 0) + r = 0; + else if (r > 100) + r = 100; + if (g < 0) + g = 0; + else if (g > 100) + g = 100; + if (b < 0) + b = 0; + else if (b > 100) + b = 100; + return RGB(r * 255 / 100, g * 255 / 100, b * 255 / 100); } - -static int -HLStoRGB(int hue, int lum, int sat) -{ - int R, G, B; - int Magic1, Magic2; - const int RGBMAX = 255; - const int HLSMAX = 100; - - if (sat == 0) { - R = G = B = (lum * RGBMAX) / HLSMAX; - } else { - if (lum <= (HLSMAX / 2)) { - Magic2 = (lum * (HLSMAX + sat) + (HLSMAX / 2)) / HLSMAX; - } else { - Magic2 = lum + sat - ((lum * sat) + (HLSMAX / 2)) / HLSMAX; - } - Magic1 = 2 * lum - Magic2; - - R = (HueToRGB(Magic1, Magic2, hue + (HLSMAX / 3)) * RGBMAX + (HLSMAX / 2)) / HLSMAX; - G = (HueToRGB(Magic1, Magic2, hue) * RGBMAX + (HLSMAX / 2)) / HLSMAX; - B = (HueToRGB(Magic1, Magic2, hue - (HLSMAX / 3)) * RGBMAX + (HLSMAX/2)) / HLSMAX; - } - return RGB(R, G, B); -} - - static unsigned char * -GetParam(unsigned char *p, int *param, int *len) +sixel_getparams(unsigned char *p, int *param, int *len) { int n; @@ -217,7 +280,7 @@ sixel_decode(unsigned char /* in */ *p, /* sixel bytes */ } s = ++p; - p = GetParam(p, param, &n); + p = sixel_getparams(p, param, &n); if (s < p) { for (i = 0; i < 255 && s < p;) { pam[i++] = *(s++); @@ -277,7 +340,7 @@ sixel_decode(unsigned char /* in */ *p, /* sixel bytes */ } else if (*p == '"') { /* DECGRA Set Raster Attributes " Pan; Pad; Ph; Pv */ s = p++; - p = GetParam(p, param, &n); + p = sixel_getparams(p, param, &n); if (s < p) { for (i = 0; i < 255 && s < p;) { gra[i++] = *(s++); @@ -312,7 +375,7 @@ sixel_decode(unsigned char /* in */ *p, /* sixel bytes */ } else if (*p == '!') { /* DECGRI Graphics Repeat Introducer ! Pn Ch */ - p = GetParam(++p, param, &n); + p = sixel_getparams(++p, param, &n); if (n > 0) { repeat_count = param[0]; @@ -320,7 +383,7 @@ sixel_decode(unsigned char /* in */ *p, /* sixel bytes */ } else if (*p == '#') { /* DECGCI Graphics Color Introducer # Pc; Pu; Px; Py; Pz */ - p = GetParam(++p, param, &n); + p = sixel_getparams(++p, param, &n); if (n > 0) { if ((color_index = param[0]) < 0) { @@ -335,7 +398,7 @@ sixel_decode(unsigned char /* in */ *p, /* sixel bytes */ if (param[2] > 360) param[2] = 360; if (param[3] > 100) param[3] = 100; if (param[4] > 100) param[4] = 100; - sixel_palet[color_index] = HLStoRGB(param[2] * 100 / 360, param[3], param[4]); + sixel_palet[color_index] = hls2rgb(param[2], param[3], param[4]); } else if (param[1] == 2) { /* RGB */ if (param[2] > 100) param[2] = 100; if (param[3] > 100) param[3] = 100; diff --git a/src/tosixel.c b/src/tosixel.c index 9484720e..0b0bdd6f 100644 --- a/src/tosixel.c +++ b/src/tosixel.c @@ -176,7 +176,7 @@ sixel_put_node(sixel_output_t *const context, int x, static int sixel_encode_impl(unsigned char *pixels, int width, int height, unsigned char *palette, int ncolors, int keycolor, - sixel_output_t *context) + int bodyonly, sixel_output_t *context) { int x, y, i, n, c; int sx, mx; @@ -185,6 +185,9 @@ sixel_encode_impl(unsigned char *pixels, int width, int height, sixel_node_t *np, *tp, top; unsigned char list[SIXEL_PALETTE_MAX]; int nwrite; + int p[3] = {0, 0, 0}; + int pcount = 3; + int use_raster_attributes = 1; context->pos = 0; @@ -220,19 +223,53 @@ sixel_encode_impl(unsigned char *pixels, int width, int height, sixel_advance(context, nwrite); } - nwrite = sprintf((char *)context->buffer + context->pos, "0;0;0" "q"); - if (nwrite <= 0) { - return (-1); + if (p[2] == 0) { + pcount--; + if (p[1] == 0) { + pcount--; + if (p[0] == 0) { + pcount--; + } + } + } + + if (pcount > 0) { + nwrite = sprintf((char *)context->buffer + context->pos, "%d", p[0]); + if (nwrite <= 0) { + return (-1); + } + sixel_advance(context, nwrite); + if (pcount > 1) { + nwrite = sprintf((char *)context->buffer + context->pos, ";%d", p[1]); + if (nwrite <= 0) { + return (-1); + } + sixel_advance(context, nwrite); + if (pcount > 2) { + nwrite = sprintf((char *)context->buffer + context->pos, ";%d", p[2]); + if (nwrite <= 0) { + return (-1); + } + sixel_advance(context, nwrite); + } + } } - sixel_advance(context, nwrite); - nwrite = sprintf((char *)context->buffer + context->pos, "\"1;1;%d;%d", width, height); + nwrite = sprintf((char *)context->buffer + context->pos, "q"); if (nwrite <= 0) { return (-1); } sixel_advance(context, nwrite); - if (ncolors != 2 || keycolor == -1) { + if (use_raster_attributes) { + nwrite = sprintf((char *)context->buffer + context->pos, "\"1;1;%d;%d", width, height); + if (nwrite <= 0) { + return (-1); + } + sixel_advance(context, nwrite); + } + + if (!bodyonly && (ncolors != 2 || keycolor == -1)) { for (n = 0; n < ncolors; n++) { /* DECGCI Graphics Color Introducer # Pc ; Pu; Px; Py; Pz */ nwrite = sprintf((char *)context->buffer + context->pos, "#%d;2;%d;%d;%d", @@ -248,8 +285,6 @@ sixel_encode_impl(unsigned char *pixels, int width, int height, return (-1); } } - context->buffer[context->pos] = '\n'; - sixel_advance(context, 1); } for (y = i = 0; y < height; y++) { @@ -319,6 +354,15 @@ sixel_encode_impl(unsigned char *pixels, int width, int height, } + if (y != 5) { + /* DECGNL Graphics Next Line */ + context->buffer[context->pos] = '-'; + sixel_advance(context, 1); + if (nwrite <= 0) { + return (-1); + } + } + for (x = 0; (np = context->node_top) != NULL;) { if (x > np->sx) { /* DECGCR Graphics Carriage Return */ @@ -343,13 +387,6 @@ sixel_encode_impl(unsigned char *pixels, int width, int height, } } - /* DECGNL Graphics Next Line */ - context->buffer[context->pos] = '-'; - sixel_advance(context, 1); - if (nwrite <= 0) { - return (-1); - } - i = 0; memset(map, 0, len); } @@ -408,7 +445,7 @@ int sixel_encode(unsigned char /* in */ *pixels, /* pixel bytes */ sixel_encode_impl(paletted_pixels, width, height, dither->palette, dither->ncolors, - dither->keycolor, context); + dither->keycolor, dither->bodyonly, context); sixel_dither_unref(dither); free(paletted_pixels);