[obs submit-request 78514] openSUSE:Factory:Contrib/fbi: created by Lazy_Kent
home:Lazy_Kent:branches:openSUSE:Factory:Contrib/fbi -> openSUSE:Factory:Contrib/fbi https://build.opensuse.org/request/diff/78514 Description: Update to 2.08. changes files: -------------- --- fbi.changes +++ fbi.changes @@ -1,0 +2,14 @@ +Sun Aug 7 05:47:14 UTC 2011 - lazy.kent@opensuse.org + +- update to 2.08 +- removed libpng-1.4 and jpeg-8.0.2 patches (fixed upstream) +- fix build dependencies (requires libpcd-devel) +- fbi package requires ghostscript-library to run fbgs script +- added desktop_database_post/un macros for ida +- updated site URL +- corrected License tags +- use full URL for source +- man pages marked as doc +- minor spec formatting + +------------------------------------------------------------------- old: ---- fbi-jpeg-8.0.2.patch fbi-libpng-1.4.patch fbida-2.07.tar.bz2 ready new: ---- fbida-2.08.tar.gz spec files: ----------- --- fbi.spec +++ fbi.spec @@ -1,34 +1,40 @@ # -# spec file for package fbi (Version 2.07) +# spec file for package fbi (Version 2.08) # -# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. -# This file and all modifications and additions to the pristine -# package are under the same license as the package itself. +# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany. # +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + # Please submit bugfixes or comments via http://bugs.opensuse.org/ # -# norootforbuild - - Name: fbi -Url: http://linux.bytesex.org/fbida/ -License: GPL v2 or later -Group: Productivity/Graphics/Viewers -AutoReqProv: on -Version: 2.07 +Version: 2.08 Release: 1 +License: GPL-2.0+ Summary: Image Viewer for the Linux Framebuffer Console -Source0: fbida-%{version}.tar.bz2 +Url: http://www.kraxel.org/blog/linux/fbida/ +Group: Productivity/Graphics/Viewers +Source0: http://www.kraxel.org/releases/fbida/fbida-%{version}.tar.gz Source1: ida.png Patch0: ida-desktop.patch -Patch1: fbi-libpng-1.4.patch -%if 0%{?suse_version} == 1130 -Patch2: fbi-jpeg-8.0.2.patch -%endif -BuildRequires: pkgconfig update-desktop-files -BuildRequires: curl-devel freetype2-devel libexif-devel openmotif-devel -BuildRequires: giflib-devel libpcd2-devel libpng-devel libtiff-devel +BuildRequires: curl-devel +BuildRequires: freetype2-devel +BuildRequires: giflib-devel +BuildRequires: libpcd-devel +BuildRequires: libpng-devel +BuildRequires: libtiff-devel +BuildRequires: openmotif-devel +BuildRequires: pkgconfig(libexif) +BuildRequires: update-desktop-files +Requires: ghostscript-library BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -44,7 +50,7 @@ Gerd Knorr <kraxel@suse.de> %package -n exiftran -License: LGPL v2.1 or later +License: LGPL-2.1+ Summary: Transform Digital Camera JPEG Images Group: Productivity/Graphics/Other @@ -63,9 +69,9 @@ Gerd Knorr <kraxel@suse.de> %package -n ida -License: GPL v2 or later -Group: Productivity/Graphics/Viewers +License: GPL-2.0+ Summary: Image viewer & editor +Group: Productivity/Graphics/Viewers %description -n ida Small & fast image viewer for X11. Also has some editing functions and @@ -80,108 +86,48 @@ %prep %setup -q -n fbida-%{version} %patch0 -p0 -%patch1 -p1 -%if 0%{?suse_version} == 1130 -%patch2 -p1 -%endif + %build -export CFLAGS="$RPM_OPT_FLAGS" -make prefix=/usr +export CFLAGS="%{optflags}" +make %{?_smp_mflags} prefix=%{_prefix} %install -make prefix=/usr DESTDIR="%{buildroot}" INSTALL_BINARY='$(INSTALL)' install -install -d %{buildroot}/usr/share/pixmaps -install -m 644 %{S:1} %{buildroot}/usr/share/pixmaps/ida.png -gzip %{buildroot}/usr/share/man/man*/* +%make_install prefix=%{_prefix} +install -Dm 644 %{SOURCE1} %{buildroot}%{_datadir}/pixmaps/ida.png %suse_update_desktop_file -i ida Graphics Viewer +%if 0%{?suse_version} >= 1140 +%post -n ida +%desktop_database_post + +%postun -n ida +%desktop_database_postun +%endif + %clean -rm -rf "%{buildroot}" +rm -rf %{buildroot} %files %defattr(-,root,root) %doc COPYING -%{_bindir}/fbi %{_bindir}/fbgs -%{_mandir}/man1/fbi.1.gz -%{_mandir}/man1/fbgs.1.gz +%{_bindir}/fbi +%doc %{_mandir}/man1/fb*.* %files -n exiftran %defattr(-,root,root) %doc COPYING %{_bindir}/exiftran -%{_mandir}/man1/exiftran.1.gz +%doc %{_mandir}/man1/exiftran.* %files -n ida %defattr(-,root,root) -%doc COPYING +%doc Changes COPYING TODO %{_bindir}/ida -%{_mandir}/man1/ida.1.gz -/usr/share/applications/ida.desktop -/usr/share/pixmaps/ida.png +%{_datadir}/applications/ida.desktop +%{_datadir}/pixmaps/ida.png %{_datadir}/X11/app-defaults/Ida +%doc %{_mandir}/man1/ida.* %changelog -* Wed Jun 25 2008 puzel@suse.cz -- updated to 2.07 - * bugfix release - * removed fbida-2.06.diff (fixed in upstream) -* Sat Apr 26 2008 coolo@suse.de -- remove unused header -* Tue Jul 17 2007 pcerny@suse.cz -- fixed some rpmlint complaints -* Wed May 09 2007 pcerny@suse.cz -- updated to 2.06 -* Sat Mar 03 2007 aj@suse.de -- Fix buildrequires. -* Tue Nov 07 2006 cthiel@suse.de -- fix build (images in /usr/share/pixmaps/ don't need to be executable) -* Tue Aug 08 2006 cthiel@suse.de -- fix build with X.org 7.1 -* Tue Jul 25 2006 kraxel@suse.de -- update to version 2.05 - * bugfix release, #194659, DSA 1124-1 -* Thu Jun 15 2006 kraxel@suse.de -- update to version 2.04 - * bugfix release, closes #168728 -* Wed Jan 25 2006 mls@suse.de -- converted neededforbuild to BuildRequires -* Fri Jan 13 2006 schwab@suse.de -- Don't strip binaries. -* Tue Jan 25 2005 kraxel@suse.de -- update to version 2.03 -* Mon Jan 10 2005 adrian@suse.de -- fix last fix -* Tue Dec 14 2004 hvogel@suse.de -- fix desktop file -* Mon Nov 08 2004 kraxel@suse.de -- update to version 2.02 -* Fri Jul 30 2004 meissner@suse.de -- Ported to use new libexif. -* Tue Jun 08 2004 kraxel@suse.de -- update to version 2.00 -* Thu Mar 25 2004 kraxel@suse.de -- remove workaround for #34903 (fixed now). -* Tue Mar 09 2004 kraxel@suse.de -- workaround #34903. -* Sat Mar 06 2004 kraxel@suse.de -- add libexif to neededforbuild. -* Fri Feb 27 2004 kraxel@suse.de -- updated to version 1.31. -* Thu Jan 29 2004 kraxel@suse.de -- updated to version 1.30. -* Wed Jan 07 2004 kraxel@suse.de -- updated to version 1.29, added exiftran subpackage. -* Fri Oct 17 2003 kraxel@suse.de -- updated to version 1.28 -* Fri Feb 07 2003 kraxel@suse.de -- updated to version 1.26 -* Thu Jun 20 2002 kraxel@suse.de -- updated to version 1.25 -* Tue Apr 30 2002 kraxel@suse.de -- updated to version 1.24 -* Fri Feb 01 2002 ro@suse.de -- changed neededforbuild <libpng> to <libpng-devel-packages> -* Mon Jan 28 2002 kraxel@suse.de -- initial release. other changes: -------------- ++++++ fbida-2.07.tar.bz2 -> fbida-2.08.tar.gz --- COPYING +++ COPYING (renamed to fbida-2.08/COPYING) --- Changes +++ Changes (renamed to fbida-2.08/Changes) --- GNUmakefile +++ GNUmakefile @@ -1,218 +0,0 @@ -# config -srcdir = . -VPATH = $(srcdir) --include Make.config -include $(srcdir)/mk/Variables.mk - -resdir = $(DESTDIR)$(RESDIR) - -# fixup flags -CFLAGS += -DVERSION='"$(VERSION)"' -I$(srcdir) -CFLAGS += -Wno-pointer-sign - -# default target -all: build - -# what to build -TARGETS := exiftran thumbnail.cgi -ifeq ($(HAVE_LINUX_FB_H),yes) - TARGETS += fbi -endif -ifeq ($(HAVE_MOTIF),yes) - TARGETS += ida -endif - - -################################################################# -# poor man's autoconf ;-) - -include $(srcdir)/mk/Autoconf.mk - -define make-config -LIB := $(LIB) -RESDIR := $(call ac_resdir) -HAVE_ENDIAN_H := $(call ac_header,endian.h) -HAVE_LINUX_FB_H := $(call ac_header,linux/fb.h) -HAVE_NEW_EXIF := $(call ac_header,libexif/exif-log.h) -HAVE_GLIBC := $(call ac_func,fopencookie) -HAVE_STRCASESTR := $(call ac_func,strcasestr) -HAVE_LIBPCD := $(call ac_lib,pcd_open,pcd) -HAVE_LIBUNGIF := $(call ac_lib,DGifOpenFileName,ungif) -HAVE_LIBPNG := $(call ac_lib,png_read_info,png,-lz) -HAVE_LIBTIFF := $(call ac_lib,TIFFOpen,tiff) -#HAVE_LIBMAGICK := $(call ac_binary,Magick-config) -HAVE_LIBSANE := $(call ac_lib,sane_init,sane) -HAVE_LIBCURL := $(call ac_lib,curl_easy_init,curl) -HAVE_LIBLIRC := $(call ac_lib,lirc_init,lirc_client) -HAVE_MOTIF := $(call ac_lib,XmStringGenerate,Xm,-L/usr/X11R6/$(LIB) -lXpm -lXt -lXext -lX11) -endef - -# transparent http/ftp access using curl depends on fopencookie (glibc) -ifneq ($(HAVE_GLIBC),yes) - HAVE_LIBCURL := no -endif - -# catch fopen calls for transparent ftp/http access -ifeq ($(HAVE_LIBCURL),yes) - ida fbi : CFLAGS += -D_GNU_SOURCE - ida fbi : LDFLAGS += -Wl,--wrap=fopen -endif - - -######################################################################## -# conditional stuff - -includes = ENDIAN_H STRCASESTR NEW_EXIF -libraries = PCD UNGIF PNG TIFF CURL SANE LIRC -ida_libs = PCD UNGIF PNG TIFF CURL SANE -fbi_libs = PCD UNGIF PNG TIFF CURL LIRC - -#MAGICK_CFLAGS = $(shell Magick-config --cflags) -#MAGICK_LDFLAGS = $(shell Magick-config --ldflags) -#MAGICK_LDLIBS = $(shell Magick-config --libs) -#MAGICK_OBJS := rd/magick.o - -PNG_LDLIBS := -lpng -lz -TIFF_LDLIBS := -ltiff -PCD_LDLIBS := -lpcd -UNGIF_LDLIBS := -lungif -SANE_LDLIBS := -lsane -CURL_LDLIBS := -lcurl -LIRC_LDLIBS := -llirc_client - -PNG_OBJS := rd/read-png.o wr/write-png.o -TIFF_OBJS := rd/read-tiff.o wr/write-tiff.o -PCD_OBJS := rd/read-pcd.o -UNGIF_OBJS := rd/read-gif.o -SANE_OBJS := sane.o -CURL_OBJS := curl.o -LIRC_OBJS := lirc.o - -# common objs -OBJS_READER := readers.o rd/read-ppm.o rd/read-bmp.o rd/read-jpeg.o -OBJS_WRITER := writers.o wr/write-ppm.o wr/write-ps.o wr/write-jpeg.o - -# update various flags depending on HAVE_* -CFLAGS += $(call ac_inc_cflags,$(includes)) -CFLAGS += $(call ac_lib_cflags,$(libraries)) -CFLAGS += $(call ac_lib_mkvar,$(libraries),CFLAGS) -LDFLAGS += $(call ac_lib_mkvar,$(libraries),LDFLAGS) - -# link which conditional libs -ida : LDLIBS += $(call ac_lib_mkvar,$(ida_libs),LDLIBS) -fbi : LDLIBS += $(call ac_lib_mkvar,$(fbi_libs),LDLIBS) - - -######################################################################## -# rules for the small tools - -# jpeg/exif libs -exiftran : LDLIBS += -ljpeg -lexif -lm -thumbnail.cgi : LDLIBS += -lexif -lm - -exiftran: exiftran.o genthumbnail.o jpegtools.o jpeg/transupp.o \ - filter.o op.o readers.o rd/read-jpeg.o -thumbnail.cgi: thumbnail.cgi.o - - -######################################################################## -# rules for ida - -# object files -OBJS_IDA := \ - ida.o man.o hex.o x11.o viewer.o dither.o icons.o \ - parseconfig.o idaconfig.o fileops.o desktop.o \ - RegEdit.o selections.o xdnd.o jpeg/transupp.o \ - filebutton.o filelist.o browser.o jpegtools.o \ - op.o filter.o lut.o color.o \ - rd/read-xwd.o rd/read-xpm.o - -OBJS_IDA += $(call ac_lib_mkvar,$(ida_libs),OBJS) - -# for X11 + Motif -ida : CFLAGS += -I/usr/X11R6/include -ida : LDFLAGS += -L/usr/X11R6/$(LIB) -ida : LDLIBS += -lXm -lXpm -lXt -lXext -lX11 - -# jpeg/exif libs -ida : LDLIBS += -ljpeg -lexif -lm - -# RegEdit.c is good old K&R ... -RegEdit.o : CFLAGS += -Wno-missing-prototypes -Wno-strict-prototypes - -ida: $(OBJS_IDA) $(OBJS_READER) $(OBJS_WRITER) - -Ida.ad.h: Ida.ad $(srcdir)/fallback.pl - perl $(srcdir)/fallback.pl < $< > $@ - -logo.h: logo.jpg - hexdump -v -e '1/1 "0x%02x,"' < $< > $@ - echo >> $@ # make gcc 3.x happy - -ida.o: Ida.ad.h logo.h - - -######################################################################## -# rules for fbi - -# object files -OBJS_FBI := \ - fbi.o fbtools.o fb-gui.o desktop.o \ - parseconfig.o fbiconfig.o \ - jpegtools.o jpeg/transupp.o \ - dither.o filter.o op.o - -OBJS_FBI += $(filter-out wr/%,$(call ac_lib_mkvar,$(fbi_libs),OBJS)) - -# jpeg/exif libs -fbi : CFLAGS += $(shell pkg-config --cflags freetype2 fontconfig) -fbi : LDLIBS += $(shell pkg-config --libs freetype2 fontconfig) -fbi : LDLIBS += -ljpeg -lexif -lm - -fbi: $(OBJS_FBI) $(OBJS_READER) - - -######################################################################## -# general rules - -.PHONY: build install clean distclean realclean -build: $(TARGETS) - -install: build - $(INSTALL_DIR) $(bindir) - $(INSTALL_DIR) $(mandir)/man1 - $(INSTALL_BINARY) exiftran $(bindir) - $(INSTALL_DATA) $(srcdir)/exiftran.man $(mandir)/man1/exiftran.1 -ifeq ($(HAVE_LINUX_FB_H),yes) - $(INSTALL_BINARY) fbi $(bindir) - $(INSTALL_SCRIPT) fbgs $(bindir) - $(INSTALL_DATA) $(srcdir)/fbi.man $(mandir)/man1/fbi.1 - $(INSTALL_DATA) $(srcdir)/fbgs.man $(mandir)/man1/fbgs.1 -endif -ifeq ($(HAVE_MOTIF),yes) - $(INSTALL_BINARY) ida $(bindir) - $(INSTALL_DATA) $(srcdir)/ida.man $(mandir)/man1/ida.1 - $(INSTALL_DIR) $(resdir)/app-defaults - $(INSTALL_DATA) $(srcdir)/Ida.ad $(resdir)/app-defaults/Ida -endif - -clean: - -rm -f *.o jpeg/*.o rd/*.o wr/*.o $(depfiles) core core.* - -realclean distclean: clean - -rm -f Make.config - -rm -f $(TARGETS) *~ rd/*~ wr/*~ xpm/*~ Ida.ad.h logo.h - - -include $(srcdir)/mk/Compile.mk --include $(depfiles) - - -######################################################################## -# maintainer stuff - -include $(srcdir)/mk/Maintainer.mk - -sync:: - cp $(srcdir)/../xawtv/common/parseconfig.[ch] $(srcdir) - cp $(srcdir)/../xawtv/console/fbtools.[ch] $(srcdir) --- INSTALL +++ INSTALL (renamed to fbida-2.08/INSTALL) --- Ida.ad +++ Ida.ad (renamed to fbida-2.08/Ida.ad) --- README +++ README (renamed to fbida-2.08/README) --- RegEdit.c +++ RegEdit.c (renamed to fbida-2.08/RegEdit.c) --- RegEdit.h +++ RegEdit.h (renamed to fbida-2.08/RegEdit.h) --- RegEditI.h +++ RegEditI.h (renamed to fbida-2.08/RegEditI.h) --- TODO +++ TODO (renamed to fbida-2.08/TODO) --- VERSION +++ VERSION @@ -1 +0,0 @@ -2.07 --- backup +++ backup -(directory) --- backup/Ida-de +++ backup/Ida-de (renamed to fbida-2.08/backup/Ida-de) --- backup/Ida-default +++ backup/Ida-default (renamed to fbida-2.08/backup/Ida-default) --- backup/Ida-fixed +++ backup/Ida-fixed (renamed to fbida-2.08/backup/Ida-fixed) --- browser.c +++ browser.c (renamed to fbida-2.08/browser.c) --- browser.h +++ browser.h (renamed to fbida-2.08/browser.h) --- color.c +++ color.c (renamed to fbida-2.08/color.c) --- color.h +++ color.h (renamed to fbida-2.08/color.h) --- config.h +++ config.h --- curl.c +++ curl.c (renamed to fbida-2.08/curl.c) --- curl.h +++ curl.h (renamed to fbida-2.08/curl.h) --- desktop +++ desktop -(directory) --- desktop.c +++ desktop.c (renamed to fbida-2.08/desktop.c) --- desktop.h +++ desktop.h (renamed to fbida-2.08/desktop.h) --- desktop/ida.desktop +++ desktop/ida.desktop (renamed to fbida-2.08/desktop/ida.desktop) --- dither.c +++ dither.c (renamed to fbida-2.08/dither.c) --- dither.h +++ dither.h (renamed to fbida-2.08/dither.h) --- exiftran.c +++ exiftran.c @@ -1,269 +0,0 @@ -/* - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - -#include <libexif/exif-data.h> - -#include <jpeglib.h> -#include "jpeg/transupp.h" /* Support routines for jpegtran */ -#include "jpegtools.h" -#include "genthumbnail.h" - -/* ---------------------------------------------------------------------- */ - -static void dump_exif(FILE *out, ExifData *ed) -{ - const char *title, *value; -#ifdef HAVE_NEW_EXIF - char buffer[256]; -#endif - ExifEntry *ee; - int tag,i; - - for (i = 0; i < EXIF_IFD_COUNT; i++) { - fprintf(out," ifd %s\n", exif_ifd_get_name (i)); - for (tag = 0; tag < 0xffff; tag++) { - title = exif_tag_get_title(tag); - if (!title) - continue; - ee = exif_content_get_entry (ed->ifd[i], tag); - if (NULL == ee) - continue; -#ifdef HAVE_NEW_EXIF - value = exif_entry_get_value(ee, buffer, sizeof(buffer)); -#else - value = exif_entry_get_value(ee); -#endif - fprintf(out," 0x%04x %-30s %s\n", tag, title, value); - } - } - if (ed->data && ed->size) - fprintf(out," thumbnail\n %d bytes data\n", ed->size); -} - -static int dump_file(FILE *out, char *filename) -{ - ExifData *ed; - - ed = exif_data_new_from_file (filename); - if (NULL == ed) { - fprintf(stderr,"%s: no EXIF data\n",filename); - return -1; - } - - fprintf(out,"%s\n",filename); - dump_exif(out,ed); - fprintf(out,"--\n"); - - exif_data_unref (ed); - return 0; -} - -/* ---------------------------------------------------------------------- */ - -#define THUMB_MAX 65536 - -static void -usage(FILE *fp, char *name) -{ - char *h; - - if (NULL != (h = strrchr(name, '/'))) - name = h+1; - fprintf(fp, - "usage: %s [ options ] file\n" - "\n" - "transform options:\n" - " -a automatic (using exif orientation tag)\n" - " -9 rotate by 90 degrees\n" - " -1 rotate by 180 degrees\n" - " -2 rotate by 270 degrees\n" - " -f flip vertical\n" - " -F flip horizontal\n" - " -t transpose\n" - " -T transverse\n" - "\n" - " -nt don't rotate exif thumbnail\n" - " -ni don't rotate jpeg image\n" - " -no don't update the orientation tag\n" - "\n" - "other options:\n" - " -h print this text\n" - " -d dump exif data\n" - " -c <text> create/update comment\n" - " -g (re)generate thumbnail\n" - " -o <file> output file\n" - " -i change files inplace\n" - " -b create a backup file (with -i)\n" - " -p preserve timestamps (with -i)\n" - "\n" - "-- \n" - "Gerd Hoffmann <kraxel@bytesex.org> [SUSE Labs]\n", - name); -} - -int main(int argc, char *argv[]) -{ - JXFORM_CODE transform = JXFORM_NONE; - unsigned char *comment = NULL; - unsigned char *outfile = NULL; - unsigned char *thumbnail = NULL; - int tsize = 0; - int inplace = 0; - unsigned int flags = - JFLAG_TRANSFORM_IMAGE | - JFLAG_TRANSFORM_THUMBNAIL | - JFLAG_UPDATE_ORIENTATION; - int dump = 0; - int i, c, rc; - - for (;;) { - c = getopt(argc, argv, "hbpid912fFtTagc:o:n:"); - if (c == -1) - break; - switch (c) { - case '9': - transform = JXFORM_ROT_90; - break; - case '1': - transform = JXFORM_ROT_180; - break; - case '2': - transform = JXFORM_ROT_270; - break; - case 'f': - transform = JXFORM_FLIP_V; - break; - case 'F': - transform = JXFORM_FLIP_H; - break; - case 't': - transform = JXFORM_TRANSPOSE; - break; - case 'T': - transform = JXFORM_TRANSVERSE; - break; - case 'a': - transform = -1; /* automagic */ - break; - - case 'n': - /* don't ... */ - switch (optarg[0]) { - case 't': - flags &= ~JFLAG_TRANSFORM_THUMBNAIL; - break; - case 'i': - flags &= ~JFLAG_TRANSFORM_IMAGE; - break; - case 'o': - flags &= ~JFLAG_UPDATE_ORIENTATION; - break; - default: - fprintf(stderr,"unknown option -n%c\n",optarg[0]); - exit(1); - } - break; - - case 'c': - flags |= JFLAG_UPDATE_COMMENT; - comment = optarg; - break; - case 'g': - flags |= JFLAG_UPDATE_THUMBNAIL; - break; - case 'o': - outfile = optarg; - break; - case 'd': - dump = 1; - break; - - case 'b': - flags |= JFLAG_FILE_BACKUP; - break; - case 'p': - flags |= JFLAG_FILE_KEEP_TIME; - break; - case 'i': - inplace = 1; - break; - - case 'h': - usage(stdout,argv[0]); - exit(0); - default: - usage(stderr,argv[0]); - exit(1); - } - } - - /* sanity checks on the arguments */ - if (optind == argc) { - fprintf(stderr, - "no image file specified (try -h for more info)\n"); - exit(1); - } - - /* read-only stuff */ - if (dump) { - rc = 0; - for (i = optind; i < argc; i++) { - if (0 != dump_file(stdout,argv[i])) - rc = 1; - } - return rc; - } - - /* r/w sanity checks */ - if (NULL != outfile && optind+1 > argc) { - fprintf(stderr, - "when specifying a output file you can process\n" - "one file at a time only (try -h for more info).\n"); - exit(1); - } - if (NULL == outfile && 0 == inplace) { - fprintf(stderr, - "you have to either specify a output file (-o <file>)\n" - "or enable inplace editing (-i). Try -h for more info.\n"); - exit(1); - } - if (JXFORM_NONE == transform && - !(flags & JFLAG_UPDATE_COMMENT) && - !(flags & JFLAG_UPDATE_THUMBNAIL)) { - fprintf(stderr, - "What do you want to do today? Neither a new comment nor a\n" - "tranformation operation was specified (try -h for more info).\n"); - exit(1); - } - - /* do actual update work */ - if (outfile) { - if (flags & JFLAG_UPDATE_THUMBNAIL) { - thumbnail = malloc(THUMB_MAX); - tsize = create_thumbnail(argv[optind],thumbnail,THUMB_MAX); - } - return jpeg_transform_files(argv[optind], outfile, transform, - comment, thumbnail, tsize, flags); - } else { - rc = 0; - for (i = optind; i < argc; i++) { - fprintf(stderr,"processing %s\n",argv[i]); - if (flags & JFLAG_UPDATE_THUMBNAIL) { - thumbnail = malloc(THUMB_MAX); - tsize = create_thumbnail(argv[i],thumbnail,THUMB_MAX); - } - if (0 != jpeg_transform_inplace(argv[i], transform, comment, - thumbnail, tsize, flags)) - rc = 1; - } - return rc; - } -} --- exiftran.man +++ exiftran.man (renamed to fbida-2.08/exiftran.man) --- fallback.pl +++ fallback.pl (renamed to fbida-2.08/fallback.pl) --- fb-gui.c +++ fb-gui.c (renamed to fbida-2.08/fb-gui.c) --- fb-gui.h +++ fb-gui.h (renamed to fbida-2.08/fb-gui.h) --- fbgs +++ fbgs (renamed to fbida-2.08/fbgs) --- fbgs.man +++ fbgs.man @@ -1,21 +0,0 @@ -.TH fbps 1 "(c) 1999-2003 Gerd Knorr" -.SH NAME -fbgs - poor man's PostScript/pdf viewer for the linux -framebuffer console -.SH SYNOPSIS -.B fbgs [ options ] file -.SH DESCRIPTION -.B fbgs -is a simple wrapper script which takes a PostScript or pdf -file as input, renders the pages using ghostscript into a -temporary directory and finally calls fbi to display them. -.SH OPTIONS -fbps understands all fbi options (they are passed through). -Additionally you can specify -l, -xl or -xxl to get the pages -rendered with 100, 120 or 150 dpi (default is 75). You can -use option -p <password> if your PDF file requires password. -With -c you can ask fbgs to render the pages in color. -.SH SEE ALSO -fbi(1), gs(1) -.SH AUTHOR -Gerd Knorr <kraxel@bytesex.org> --- fbi.c +++ fbi.c @@ -1,1616 +0,0 @@ -/* - * image viewer, for framebuffer devices - * - * (c) 1998-2004 Gerd Hoffmann <kraxel@bytesex.org> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <time.h> -#include <fcntl.h> -#include <errno.h> -#include <termios.h> -#include <getopt.h> -#include <math.h> -#include <setjmp.h> -#include <signal.h> -#include <ctype.h> -#include <locale.h> -#include <wchar.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <linux/fb.h> - -#include <jpeglib.h> - -#include <libexif/exif-data.h> - -#ifdef HAVE_LIBLIRC -# include "lirc/lirc_client.h" -# include "lirc.h" -#endif - -#include "readers.h" -#include "dither.h" -#include "fbtools.h" -#include "fb-gui.h" -#include "filter.h" -#include "desktop.h" -#include "list.h" -#include "fbiconfig.h" - -#include "jpeg/transupp.h" /* Support routines for jpegtran */ -#include "jpegtools.h" - -#define TRUE 1 -#define FALSE 0 -#undef MAX -#define MAX(x,y) ((x)>(y)?(x):(y)) -#undef MIN -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -#define KEY_EOF -1 /* ^D */ -#define KEY_ESC -2 -#define KEY_SPACE -3 -#define KEY_Q -4 -#define KEY_PGUP -5 -#define KEY_PGDN -6 -#define KEY_TIMEOUT -7 -#define KEY_TAGFILE -8 -#define KEY_PLUS -9 -#define KEY_MINUS -10 -#define KEY_VERBOSE -11 -#define KEY_ASCALE -12 -#define KEY_DESC -13 - -/* with arg */ -#define KEY_GOTO -100 -#define KEY_SCALE -101 -#define KEY_DELAY -102 - -/* edit */ -#define KEY_DELETE -200 -#define KEY_ROT_CW -201 -#define KEY_ROT_CCW -202 - -#define DEFAULT_DEVICE "/dev/fb0" - -/* ---------------------------------------------------------------------- */ - -/* lirc fd */ -int lirc = -1; - -/* variables for read_image */ -int32_t lut_red[256], lut_green[256], lut_blue[256]; -int dither = FALSE, pcd_res = 3; -int v_steps = 50; -int h_steps = 50; -int textreading = 0, redraw = 0, statusline = 1; -int fitwidth; - -/* file list */ -struct flist { - /* file list */ - int nr; - int tag; - char *name; - struct list_head list; - - /* image cache */ - int seen; - int top; - int left; - int text_steps; - float scale; - struct ida_image *fimg; - struct ida_image *simg; - struct list_head lru; -}; -static LIST_HEAD(flist); -static LIST_HEAD(flru); -static int fcount; -static struct flist *fcurrent; -static struct ida_image *img; - -/* accounting */ -static int img_cnt, min_cnt = 2, max_cnt = 16; -static int img_mem, max_mem_mb; - -/* framebuffer */ -char *fbdev = NULL; -char *fbmode = NULL; -int fd, switch_last, debug; - -unsigned short red[256], green[256], blue[256]; -struct fb_cmap cmap = { 0, 256, red, green, blue }; - -static float fbgamma = 1; - -/* Command line options. */ -int autodown; -int autoup; -int comments; -int transparency = 40; -int timeout; -int backup; -int preserve; -int read_ahead; -int editable; -int blend_msecs; -int perfmon = 0; - -/* font handling */ -static char *fontname = NULL; -static FT_Face face; - -/* ---------------------------------------------------------------------- */ -/* fwd declarations */ - -static struct ida_image *flist_img_get(struct flist *f); -static void *flist_malloc(size_t size); -static void flist_img_load(struct flist *f, int prefetch); - -/* ---------------------------------------------------------------------- */ - -static void -version(void) -{ - fprintf(stderr, - "fbi version " VERSION ", compiled on %s\n" - "(c) 1999-2006 Gerd Hoffmann <kraxel@bytesex.org> [SUSE Labs]\n", - __DATE__ ); -} - -static void -usage(char *name) -{ - char *h; - - if (NULL != (h = strrchr(name, '/'))) - name = h+1; - fprintf(stderr, - "\n" - "This program displays images using the Linux framebuffer device.\n" - "Supported formats: PhotoCD, jpeg, ppm, gif, tiff, xwd, bmp, png.\n" - "It tries to use ImageMagick's convert for unknown file formats.\n" - "\n" - "usage: %s [ options ] file1 file2 ... fileN\n" - "\n", - name); - - cfg_help_cmdline(stderr,fbi_cmd,4,20,0); - cfg_help_cmdline(stderr,fbi_cfg,4,20,40); - - fprintf(stderr, - "\n" - "Large images can be scrolled using the cursor keys. Zoom in/out\n" - "works with '+' and '-'. Use ESC or 'q' to quit. Space and PgDn\n" - "show the next, PgUp shows the previous image. Jumping to a image\n" - "works with <number>g. Return acts like Space but additionally\n" - "prints the filename of the currently displayed image to stdout.\n" - "\n"); -} - -/* ---------------------------------------------------------------------- */ - -static int flist_add(char *filename) -{ - struct flist *f; - - f = malloc(sizeof(*f)); - memset(f,0,sizeof(*f)); - f->name = strdup(filename); - list_add_tail(&f->list,&flist); - INIT_LIST_HEAD(&f->lru); - return 0; -} - -static int flist_add_list(char *listfile) -{ - char filename[256]; - FILE *list; - - list = fopen(listfile,"r"); - if (NULL == list) { - fprintf(stderr,"open %s: %s\n",listfile,strerror(errno)); - return -1; - } - while (NULL != fgets(filename,sizeof(filename)-1,list)) { - size_t off = strcspn(filename,"\r\n"); - if (off) - filename[off] = 0; - flist_add(filename); - } - fclose(list); - return 0; -} - -static int flist_del(struct flist *f) -{ - list_del(&f->list); - free(f->name); - free(f); - return 0; -} - -static void flist_renumber(void) -{ - struct list_head *item; - struct flist *f; - int i = 0; - - list_for_each(item,&flist) { - f = list_entry(item, struct flist, list); - f->nr = ++i; - } - fcount = i; -} - -static int flist_islast(struct flist *f) -{ - return (&flist == f->list.next) ? 1 : 0; -} - -static int flist_isfirst(struct flist *f) -{ - return (&flist == f->list.prev) ? 1 : 0; -} - -static struct flist* flist_first(void) -{ - return list_entry(flist.next, struct flist, list); -} - -static struct flist* flist_last(void) -{ - return list_entry(flist.prev, struct flist, list); -} - -static struct flist* flist_next(struct flist *f, int eof, int loop) -{ - if (flist_islast(f)) { - if (eof) - return NULL; - if (loop) - return flist_first(); - return f; - } - return list_entry(f->list.next, struct flist, list); -} - -static struct flist* flist_prev(struct flist *f, int loop) -{ - if (flist_isfirst(f)) { - if (loop) - return flist_last(); - return f; - } - return list_entry(f->list.prev, struct flist, list); -} - -static struct flist* flist_goto(int dest) -{ - struct list_head *item; - struct flist *f; - - list_for_each(item,&flist) { - f = list_entry(item, struct flist, list); - if (f->nr == dest) - return f; - } - return NULL; -} - -static void flist_randomize(void) -{ - struct flist *f; - int count; - - srand((unsigned)time(NULL)); - flist_renumber(); - for (count = fcount; count > 0; count--) { - f = flist_goto((rand() % count)+1); - list_del(&f->list); - list_add_tail(&f->list,&flist); - flist_renumber(); - } -} - -static void flist_print_tagged(FILE *fp) -{ - struct list_head *item; - struct flist *f; - - list_for_each(item,&flist) { - f = list_entry(item, struct flist, list); - if (f->tag) - fprintf(fp,"%s\n",f->name); - } -} - -/* ---------------------------------------------------------------------- */ - -static void -shadow_draw_image(struct ida_image *img, int xoff, int yoff, - unsigned int first, unsigned int last, int weight) -{ - unsigned int dwidth = MIN(img->i.width, fb_var.xres); - unsigned int dheight = MIN(img->i.height, fb_var.yres); - unsigned int data, offset, y, xs, ys; - - if (100 == weight) - shadow_clear_lines(first, last); - else - shadow_darkify(0, fb_var.xres-1, first, last, 100 - weight); - - /* offset for image data (image > screen, select visible area) */ - offset = (yoff * img->i.width + xoff) * 3; - - /* offset for video memory (image < screen, center image) */ - xs = 0, ys = 0; - if (img->i.width < fb_var.xres) - xs += (fb_var.xres - img->i.width) / 2; - if (img->i.height < fb_var.yres) - ys += (fb_var.yres - img->i.height) / 2; - - /* go ! */ - for (data = 0, y = 0; - data < img->i.width * img->i.height * 3 - && data / img->i.width / 3 < dheight; - data += img->i.width * 3, y++) { - if (ys+y < first) - continue; - if (ys+y > last) - continue; - if (100 == weight) - shadow_draw_rgbdata(xs, ys+y, dwidth, - img->data + data + offset); - else - shadow_merge_rgbdata(xs, ys+y, dwidth, weight, - img->data + data + offset); - } -} - -static void status_prepare(void) -{ - struct ida_image *img = flist_img_get(fcurrent); - int y1 = fb_var.yres - (face->size->metrics.height >> 6); - int y2 = fb_var.yres - 1; - - if (img) { - shadow_draw_image(img, fcurrent->left, fcurrent->top, y1, y2, 100); - shadow_darkify(0, fb_var.xres-1, y1, y2, transparency); - } else { - shadow_clear_lines(y1, y2); - } - shadow_draw_line(0, fb_var.xres-1, y1-1, y1-1); -} - -static void status_update(unsigned char *desc, char *info) -{ - int yt = fb_var.yres + (face->size->metrics.descender >> 6); - wchar_t str[128]; - - if (!statusline) - return; - status_prepare(); - - swprintf(str,ARRAY_SIZE(str),L"%s",desc); - shadow_draw_string(face, 0, yt, str, -1); - if (info) { - swprintf(str,ARRAY_SIZE(str), L"[ %s ] H - Help", info); - } else { - swprintf(str,ARRAY_SIZE(str), L"| H - Help"); - } - shadow_draw_string(face, fb_var.xres, yt, str, 1); - - shadow_render(); -} - -static void status_error(unsigned char *msg) -{ - int yt = fb_var.yres + (face->size->metrics.descender >> 6); - wchar_t str[128]; - - status_prepare(); - - swprintf(str,ARRAY_SIZE(str), L"%s", msg); - shadow_draw_string(face, 0, yt, str, -1); - - shadow_render(); - sleep(2); -} - -static void status_edit(unsigned char *msg, int pos) -{ - int yt = fb_var.yres + (face->size->metrics.descender >> 6); - wchar_t str[128]; - - status_prepare(); - - swprintf(str,ARRAY_SIZE(str), L"%s", msg); - shadow_draw_string_cursor(face, 0, yt, str, pos); - - shadow_render(); -} - -static void show_exif(struct flist *f) -{ - static unsigned int tags[] = { - 0x010f, // Manufacturer - 0x0110, // Model - - 0x0112, // Orientation - 0x0132, // Date and Time - - 0x01e3, // White Point - 0x829a, // Exposure Time - 0x829d, // FNumber - 0x9206, // Subject Distance - 0xa40c, // Subject Distance Range - 0xa405, // Focal Length In 35mm Film - 0x9209, // Flash - }; - ExifData *ed; - ExifEntry *ee; - unsigned int tag,l1,l2,len,count,i; - const char *title[ARRAY_SIZE(tags)]; - char *value[ARRAY_SIZE(tags)]; - wchar_t *linebuffer[ARRAY_SIZE(tags)]; - - if (!visible) - return; - - ed = exif_data_new_from_file(f->name); - if (NULL == ed) { - status_error("image has no EXIF data"); - return; - } - - /* pass one -- get data + calc size */ - l1 = 0; - l2 = 0; - for (tag = 0; tag < ARRAY_SIZE(tags); tag++) { - ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], tags[tag]); - if (NULL == ee) - ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], tags[tag]); - if (NULL == ee) { - title[tag] = NULL; - value[tag] = NULL; - continue; - } - title[tag] = exif_tag_get_title(tags[tag]); -#ifdef HAVE_NEW_EXIF - value[tag] = malloc(128); - exif_entry_get_value(ee, value[tag], 128); -#else - value[tag] = strdup(exif_entry_get_value(ee)); -#endif - len = strlen(title[tag]); - if (l1 < len) - l1 = len; - len = strlen(value[tag]); - if (l2 < len) - l2 = len; - } - - /* pass two -- print stuff */ - count = 0; - for (tag = 0; tag < ARRAY_SIZE(tags); tag++) { - if (NULL == title[tag]) - continue; - linebuffer[count] = malloc(sizeof(wchar_t)*(l1+l2+8)); - swprintf(linebuffer[count], l1+l2+8, - L"%-*.*s : %-*.*s", - l1, l1, title[tag], - l2, l2, value[tag]); - count++; - } - shadow_draw_text_box(face, 24, 16, transparency, - linebuffer, count); - shadow_render(); - - /* pass three -- free data */ - for (tag = 0; tag < ARRAY_SIZE(tags); tag++) - if (NULL != value[tag]) - free(value[tag]); - exif_data_unref (ed); - for (i = 0; i < count; i++) - free(linebuffer[i]); -} - -static void show_help(void) -{ - static wchar_t *help[] = { - L"keyboard commands", - L"~~~~~~~~~~~~~~~~~", - L" ESC, Q - quit", - L" pgdn, space - next image", - L" pgup - previous image", - L" +/- - zoom in/out", - L" A - autozoom image", - L" cursor keys - scroll image", - L"", - L" H - show this help text", - L" I - show EXIF info", - L" P - pause slideshow", - L" V - toggle statusline", - L"", - L"available if started with --edit switch,", - L"rotation works for jpeg images only:", - L" shift+D - delete image", - L" R - rotate clockwise", - L" L - rotate counter-clockwise", - }; - - shadow_draw_text_box(face, 24, 16, transparency, - help, ARRAY_SIZE(help)); - shadow_render(); -} - -/* ---------------------------------------------------------------------- */ - -struct termios saved_attributes; -int saved_fl; - -static void -tty_raw(void) -{ - struct termios tattr; - - fcntl(0,F_GETFL,&saved_fl); - tcgetattr (0, &saved_attributes); - - fcntl(0,F_SETFL,O_NONBLOCK); - memcpy(&tattr,&saved_attributes,sizeof(struct termios)); - tattr.c_lflag &= ~(ICANON|ECHO); - tattr.c_cc[VMIN] = 1; - tattr.c_cc[VTIME] = 0; - tcsetattr (0, TCSAFLUSH, &tattr); -} - -static void -tty_restore(void) -{ - fcntl(0,F_SETFL,saved_fl); - tcsetattr (0, TCSANOW, &saved_attributes); -} - -/* testing: find key codes */ -static void debug_key(char *key) -{ - char linebuffer[128]; - int i,len; - - len = sprintf(linebuffer,"key: "); - for (i = 0; key[i] != '\0'; i++) - len += snprintf(linebuffer+len, sizeof(linebuffer)-len, - "%s%c", - key[i] < 0x20 ? "^" : "", - key[i] < 0x20 ? key[i] + 0x40 : key[i]); - status_update(linebuffer, NULL); -} - -static void -console_switch(void) -{ - switch (fb_switch_state) { - case FB_REL_REQ: - fb_switch_release(); - case FB_INACTIVE: - visible = 0; - break; - case FB_ACQ_REQ: - fb_switch_acquire(); - case FB_ACTIVE: - visible = 1; - ioctl(fd,FBIOPAN_DISPLAY,&fb_var); - shadow_set_palette(fd); - shadow_set_dirty(); - shadow_render(); - break; - default: - break; - } - switch_last = fb_switch_state; - return; -} - -/* ---------------------------------------------------------------------- */ - -static void free_image(struct ida_image *img) -{ - if (img) { - if (img->data) { - img_mem -= img->i.width * img->i.height * 3; - free(img->data); - } - free(img); - } -} - -static struct ida_image* -read_image(char *filename) -{ - struct ida_loader *loader = NULL; - struct ida_image *img; - struct list_head *item; - char blk[512]; - FILE *fp; - unsigned int y; - void *data; - - /* open file */ - if (NULL == (fp = fopen(filename, "r"))) { - fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); - return NULL; - } - memset(blk,0,sizeof(blk)); - fread(blk,1,sizeof(blk),fp); - rewind(fp); - - /* pick loader */ - list_for_each(item,&loaders) { - loader = list_entry(item, struct ida_loader, list); - if (NULL == loader->magic) - break; - if (0 == memcmp(blk+loader->moff,loader->magic,loader->mlen)) - break; - loader = NULL; - } - if (NULL == loader) { - /* no loader found, try to use ImageMagick's convert */ - int p[2]; - - if (0 != pipe(p)) - return NULL; - switch (fork()) { - case -1: /* error */ - perror("fork"); - close(p[0]); - close(p[1]); - return NULL; - case 0: /* child */ - dup2(p[1], 1 /* stdout */); - close(p[0]); - close(p[1]); - execlp("convert", "convert", "-depth", "8", filename, "ppm:-", NULL); - exit(1); - default: /* parent */ - close(p[1]); - fp = fdopen(p[0], "r"); - if (NULL == fp) - return NULL; - loader = &ppm_loader; - } - } - - /* load image */ - img = malloc(sizeof(*img)); - memset(img,0,sizeof(*img)); - data = loader->init(fp,filename,0,&img->i,0); - if (NULL == data) { - fprintf(stderr,"loading %s [%s] FAILED\n",filename,loader->name); - free_image(img); - return NULL; - } - img->data = flist_malloc(img->i.width * img->i.height * 3); - img_mem += img->i.width * img->i.height * 3; - for (y = 0; y < img->i.height; y++) { - if (switch_last != fb_switch_state) - console_switch(); - loader->read(img->data + img->i.width * 3 * y, y, data); - } - loader->done(data); - return img; -} - -static struct ida_image* -scale_image(struct ida_image *src, float scale) -{ - struct op_resize_parm p; - struct ida_rect rect; - struct ida_image *dest; - void *data; - unsigned int y; - - dest = malloc(sizeof(*dest)); - memset(dest,0,sizeof(*dest)); - memset(&rect,0,sizeof(rect)); - memset(&p,0,sizeof(p)); - - p.width = src->i.width * scale; - p.height = src->i.height * scale; - p.dpi = src->i.dpi; - if (0 == p.width) - p.width = 1; - if (0 == p.height) - p.height = 1; - - data = desc_resize.init(src,&rect,&dest->i,&p); - dest->data = flist_malloc(dest->i.width * dest->i.height * 3); - img_mem += dest->i.width * dest->i.height * 3; - for (y = 0; y < dest->i.height; y++) { - if (switch_last != fb_switch_state) - console_switch(); - desc_resize.work(src,&rect, - dest->data + 3 * dest->i.width * y, - y, data); - } - desc_resize.done(data); - return dest; -} - -static float auto_scale(struct ida_image *img) -{ - float xs,ys,scale; - - xs = (float)fb_var.xres / img->i.width; - if (fitwidth) - return xs; - ys = (float)fb_var.yres / img->i.height; - scale = (xs < ys) ? xs : ys; - return scale; -} - -/* ---------------------------------------------------------------------- */ - -static void effect_blend(struct flist *f, struct flist *t) -{ - struct timeval start, now; - int msecs, weight = 0; - char linebuffer[80]; - int pos = 0; - int count = 0; - - gettimeofday(&start, NULL); - do { - gettimeofday(&now, NULL); - msecs = (now.tv_sec - start.tv_sec) * 1000; - msecs += (now.tv_usec - start.tv_usec) / 1000; - weight = msecs * 100 / blend_msecs; - if (weight > 100) - weight = 100; - shadow_draw_image(flist_img_get(f), f->left, f->top, - 0, fb_var.yres-1, 100); - shadow_draw_image(flist_img_get(t), t->left, t->top, - 0, fb_var.yres-1, weight); - - if (perfmon) { - pos += snprintf(linebuffer+pos, sizeof(linebuffer)-pos, - " %d%%", weight); - status_update(linebuffer, NULL); - count++; - } - - shadow_render(); - } while (weight < 100); - - if (perfmon) { - gettimeofday(&now, NULL); - msecs = (now.tv_sec - start.tv_sec) * 1000; - msecs += (now.tv_usec - start.tv_usec) / 1000; - pos += snprintf(linebuffer+pos, sizeof(linebuffer)-pos, - " | %d/%d -> %d msec", - msecs, count, msecs/count); - status_update(linebuffer, NULL); - shadow_render(); - sleep(2); - } -} - -static int -svga_show(struct flist *f, struct flist *prev, - int timeout, char *desc, char *info, int *nr) -{ - static int paused = 0, skip = KEY_SPACE; - - struct ida_image *img = flist_img_get(f); - int exif = 0, help = 0; - int rc; - char key[11]; - fd_set set; - struct timeval limit; - char linebuffer[80]; - int fdmax; - - *nr = 0; - if (NULL == img) - return skip; - - redraw = 1; - for (;;) { - if (redraw) { - redraw = 0; - if (img->i.height <= fb_var.yres) { - f->top = 0; - } else { - if (f->top < 0) - f->top = 0; - if (f->top + fb_var.yres > img->i.height) - f->top = img->i.height - fb_var.yres; - } - if (img->i.width <= fb_var.xres) { - f->left = 0; - } else { - if (f->left < 0) - f->left = 0; - if (f->left + fb_var.xres > img->i.width) - f->left = img->i.width - fb_var.xres; - } - if (blend_msecs && prev && prev != f && - flist_img_get(prev) && flist_img_get(f)) { - effect_blend(prev, f); - prev = NULL; - } else { - shadow_draw_image(img, f->left, f->top, 0, fb_var.yres-1, 100); - } - status_update(desc, info); - shadow_render(); - - if (read_ahead) { - struct flist *f = flist_next(fcurrent,1,0); - if (f && !f->fimg) - flist_img_load(f,1); - status_update(desc, info); - shadow_render(); - } - } - if (switch_last != fb_switch_state) { - console_switch(); - continue; - } - FD_ZERO(&set); - FD_SET(0, &set); - fdmax = 1; -#ifdef HAVE_LIBLIRC - if (-1 != lirc) { - FD_SET(lirc,&set); - fdmax = lirc+1; - } -#endif - limit.tv_sec = timeout; - limit.tv_usec = 0; - rc = select(fdmax, &set, NULL, NULL, - (0 != timeout && !paused) ? &limit : NULL); - if (switch_last != fb_switch_state) { - console_switch(); - continue; - } - if (0 == rc) - return KEY_TIMEOUT; - - if (FD_ISSET(0,&set)) { - /* stdin, i.e. keyboard */ - rc = read(0, key, sizeof(key)-1); - if (rc < 1) { - /* EOF */ - return KEY_EOF; - } - key[rc] = 0; - } -#ifdef HAVE_LIBLIRC - if (lirc != -1 && FD_ISSET(lirc,&set)) { - /* lirc input */ - if (-1 == lirc_fbi_havedata(&rc,key)) { - fprintf(stderr,"lirc: connection lost\n"); - close(lirc); - lirc = -1; - } - key[rc] = 0; - } -#endif - - if (rc == 1 && (*key == 'q' || *key == 'Q' || - *key == 'e' || *key == 'E' || - *key == '\x1b' || *key == '\n')) { - if (*key == '\n') - return KEY_TAGFILE; - if (*key == '\x1b') - return KEY_ESC; - return KEY_Q; - - } else if (0 == strcmp(key, " ")) { - if (textreading && f->top < (int)(img->i.height - fb_var.yres)) { - redraw = 1; - f->top += f->text_steps; - } else { - skip = KEY_SPACE; - return KEY_SPACE; - } - - } else if (0 == strcmp(key, "\x1b[A") && img->i.height > fb_var.yres) { - redraw = 1; - f->top -= v_steps; - } else if (0 == strcmp(key, "\x1b[B") && img->i.height > fb_var.yres) { - redraw = 1; - f->top += v_steps; - } else if (0 == strcmp(key, "\x1b[1~") && img->i.height > fb_var.yres) { - redraw = 1; - f->top = 0; - } else if (0 == strcmp(key, "\x1b[4~")) { - redraw = 1; - f->top = img->i.height - fb_var.yres; - } else if (0 == strcmp(key, "\x1b[D") && img->i.width > fb_var.xres) { - redraw = 1; - f->left -= h_steps; - } else if (0 == strcmp(key, "\x1b[C") && img->i.width > fb_var.xres) { - redraw = 1; - f->left += h_steps; - - } else if (0 == strcmp(key, "\x1b[5~") || - 0 == strcmp(key, "j") || - 0 == strcmp(key, "J")) { - if (textreading && f->top > 0) { - redraw = 1; - f->top -= f->text_steps; - } else { - skip = KEY_PGUP; - return KEY_PGUP; - } - - } else if (0 == strcmp(key, "\x1b[6~") || - 0 == strcmp(key, "k") || - 0 == strcmp(key, "K") || - 0 == strcmp(key, "n") || - 0 == strcmp(key, "N")) { - if (textreading && f->top < (int)(img->i.height - fb_var.yres)) { - redraw = 1; - f->top += f->text_steps; - } else { - skip = KEY_PGDN; - return KEY_PGDN; - } - - } else if (0 == strcmp(key, "+")) { - return KEY_PLUS; - } else if (0 == strcmp(key, "-")) { - return KEY_MINUS; - } else if (0 == strcmp(key, "a") || - 0 == strcmp(key, "A")) { - return KEY_ASCALE; - - } else if (0 == strcmp(key, "p") || - 0 == strcmp(key, "P")) { - if (0 != timeout) { - paused = !paused; - status_update(paused ? "pause on " : "pause off", NULL); - } - - } else if (0 == strcmp(key, "D")) { - return KEY_DELETE; - } else if (0 == strcmp(key, "r") || - 0 == strcmp(key, "R")) { - return KEY_ROT_CW; - } else if (0 == strcmp(key, "l") || - 0 == strcmp(key, "L")) { - return KEY_ROT_CCW; - - } else if (0 == strcmp(key, "h") || - 0 == strcmp(key, "H")) { - if (!help) { - show_help(); - help = 1; - } else { - redraw = 1; - help = 0; - } - exif = 0; - - } else if (0 == strcmp(key, "i") || - 0 == strcmp(key, "I")) { - if (!exif) { - show_exif(fcurrent); - exif = 1; - } else { - redraw = 1; - exif = 0; - } - help = 0; - - } else if (0 == strcmp(key, "v") || - 0 == strcmp(key, "V")) { - return KEY_VERBOSE; - - } else if (0 == strcmp(key, "t") || - 0 == strcmp(key, "T")) { - return KEY_DESC; - - } else if (rc == 1 && (*key == 'g' || *key == 'G')) { - return KEY_GOTO; - } else if (rc == 1 && (*key == 's' || *key == 'S')) { - return KEY_SCALE; - } else if (rc == 1 && (*key == 'x' || *key == 'X')) { - return KEY_DELAY; - } else if (rc == 1 && *key >= '0' && *key <= '9') { - *nr = *nr * 10 + (*key - '0'); - snprintf(linebuffer, sizeof(linebuffer), "> %d",*nr); - status_update(linebuffer, NULL); - } else { - *nr = 0; -#if 0 - debug_key(key); -#endif - } - } -} - -static void scale_fix_top_left(struct flist *f, float old, float new) -{ - struct ida_image *img = flist_img_get(f); - unsigned int width, height; - float cx,cy; - - cx = (float)(f->left + fb_var.xres/2) / (img->i.width * old); - cy = (float)(f->top + fb_var.yres/2) / (img->i.height * old); - - width = img->i.width * new; - height = img->i.height * new; - f->left = cx * width - fb_var.xres/2; - f->top = cy * height - fb_var.yres/2; -} - -/* ---------------------------------------------------------------------- */ - -static char *my_basename(char *filename) -{ - char *h; - - h = strrchr(filename,'/'); - if (h) - return h+1; - return filename; -} - -static char *file_desktop(char *filename) -{ - static char desc[128]; - char *h; - - strncpy(desc,filename,sizeof(desc)-1); - if (NULL != (h = strrchr(filename,'/'))) { - snprintf(desc,sizeof(desc),"%.*s/%s", - (int)(h - filename), filename, - ".directory"); - } else { - strcpy(desc,".directory"); - } - return desc; -} - -static char *make_desc(struct ida_image_info *img, char *filename) -{ - static char linebuffer[128]; - struct ida_extra *extra; - char *desc; - int len; - - memset(linebuffer,0,sizeof(linebuffer)); - strncpy(linebuffer,filename,sizeof(linebuffer)-1); - - if (comments) { - extra = load_find_extra(img, EXTRA_COMMENT); - if (extra) - snprintf(linebuffer,sizeof(linebuffer),"%.*s", - extra->size,extra->data); - } else { - desc = file_desktop(filename); - len = desktop_read_entry(desc, "Comment=", linebuffer, sizeof(linebuffer)); - if (0 != len) - snprintf(linebuffer+len,sizeof(linebuffer)-len, - " (%s)", my_basename(filename)); - } - return linebuffer; -} - -static char *make_info(struct ida_image *img, float scale) -{ - static char linebuffer[128]; - - snprintf(linebuffer, sizeof(linebuffer), - "%s%.0f%% %dx%d %d/%d", - fcurrent->tag ? "* " : "", - scale*100, - img->i.width, img->i.height, - fcurrent->nr, fcount); - return linebuffer; -} - -static char edit_line(struct ida_image *img, char *line, int max) -{ - int len = strlen(line); - int pos = len; - int rc; - char key[11]; - fd_set set; - - do { - status_edit(line,pos); - - FD_SET(0, &set); - rc = select(1, &set, NULL, NULL, NULL); - if (switch_last != fb_switch_state) { - console_switch(); - continue; - } - rc = read(0, key, sizeof(key)-1); - if (rc < 1) { - /* EOF */ - return KEY_EOF; - } - key[rc] = 0; - - if (0 == strcmp(key,"\x0a")) { - /* Enter */ - return 0; - - } else if (0 == strcmp(key,"\x1b")) { - /* ESC */ - return KEY_ESC; - - } else if (0 == strcmp(key,"\x1b[C")) { - /* cursor right */ - if (pos < len) - pos++; - - } else if (0 == strcmp(key,"\x1b[D")) { - /* cursor left */ - if (pos > 0) - pos--; - - } else if (0 == strcmp(key,"\x1b[1~")) { - /* home */ - pos = 0; - - } else if (0 == strcmp(key,"\x1b[4~")) { - /* end */ - pos = len; - - } else if (0 == strcmp(key,"\x7f")) { - /* backspace */ - if (pos > 0) { - memmove(line+pos-1,line+pos,len-pos+1); - pos--; - len--; - } - - } else if (0 == strcmp(key,"\x1b[3~")) { - /* delete */ - if (pos < len) { - memmove(line+pos,line+pos+1,len-pos); - len--; - } - - } else if (1 == rc && isprint(key[0]) && len < max) { - /* new key */ - if (pos < len) - memmove(line+pos+1,line+pos,len-pos+1); - line[pos] = key[0]; - pos++; - len++; - line[len] = 0; - - } else if (0 /* debug */) { - debug_key(key); - sleep(1); - } - } while (1); -} - -static void edit_desc(struct ida_image *img, char *filename) -{ - static char linebuffer[128]; - char *desc; - int len, rc; - - desc = file_desktop(filename); - len = desktop_read_entry(desc, "Comment=", linebuffer, sizeof(linebuffer)); - if (0 == len) { - linebuffer[0] = 0; - len = 0; - } - rc = edit_line(img, linebuffer, sizeof(linebuffer)-1); - if (0 != rc) - return; - desktop_write_entry(desc, "Directory", "Comment=", linebuffer); -} - -/* ---------------------------------------------------------------------- */ - -static struct ida_image *flist_img_get(struct flist *f) -{ - if (1 != f->scale) - return f->simg; - else - return f->fimg; -} - -static void flist_img_free(struct flist *f) -{ - if (!f->fimg) - return; - - free_image(f->fimg); - if (f->simg) - free_image(f->simg); - f->fimg = NULL; - f->simg = NULL; - list_del(&f->lru); - img_cnt--; -} - -static int flist_img_free_lru(void) -{ - struct flist *f; - - if (img_cnt <= min_cnt) - return -1; - f = list_entry(flru.next, struct flist, lru); - flist_img_free(f); - return 0; -} - -static void flist_img_release_memory(void) -{ - int try_release; - - for (;;) { - try_release = 0; - if (img_cnt > max_cnt) - try_release = 1; - if (img_mem > max_mem_mb * 1024 * 1024) - try_release = 1; - if (!try_release) - break; - if (0 != flist_img_free_lru()) - break; - } - return; -} - -static void *flist_malloc(size_t size) -{ - void *ptr; - - for (;;) { - ptr = malloc(size); - if (ptr) - return ptr; - if (0 != flist_img_free_lru()) { - status_error("Oops: out of memory, exiting"); - exit(1); - } - } -} - -static void flist_img_scale(struct flist *f, float scale, int prefetch) -{ - char linebuffer[128]; - - if (!f->fimg) - return; - if (f->simg && f->scale == scale) - return; - - if (f->simg) { - free_image(f->simg); - f->simg = NULL; - } - if (scale != 1) { - if (!prefetch) { - snprintf(linebuffer, sizeof(linebuffer), - "scaling (%.0f%%) %s ...", - scale*100, f->name); - status_update(linebuffer, NULL); - } - f->simg = scale_image(f->fimg,scale); - if (!f->simg) { - snprintf(linebuffer,sizeof(linebuffer), - "%s: scaling FAILED",f->name); - status_error(linebuffer); - } - } - f->scale = scale; -} - -static void flist_img_load(struct flist *f, int prefetch) -{ - char linebuffer[128]; - float scale = 1; - - if (f->fimg) { - /* touch */ - list_del(&f->lru); - list_add_tail(&f->lru, &flru); - return; - } - - snprintf(linebuffer,sizeof(linebuffer),"%s %s ...", - prefetch ? "prefetch" : "loading", f->name); - status_update(linebuffer, NULL); - f->fimg = read_image(f->name); - if (!f->fimg) { - snprintf(linebuffer,sizeof(linebuffer), - "%s: loading FAILED",f->name); - status_error(linebuffer); - return; - } - - if (!f->seen) { - scale = 1; - if (autoup || autodown) { - scale = auto_scale(f->fimg); - if (scale < 1 && !autodown) - scale = 1; - if (scale > 1 && !autoup) - scale = 1; - } - } else { - scale = f->scale; - } - flist_img_scale(f, scale, prefetch); - - if (!f->seen) { - struct ida_image *img = flist_img_get(f); - if (img->i.width > fb_var.xres) - f->left = (img->i.width - fb_var.xres) / 2; - if (img->i.height > fb_var.yres) { - f->top = (img->i.height - fb_var.yres) / 2; - if (textreading) { - int pages = ceil((float)img->i.height / fb_var.yres); - f->text_steps = ceil((float)img->i.height / pages); - f->top = 0; - } - } - } - - list_add_tail(&f->lru, &flru); - f->seen = 1; - img_cnt++; -} - -/* ---------------------------------------------------------------------- */ - -static void cleanup_and_exit(int code) -{ - shadow_fini(); - fb_clear_screen(); - tty_restore(); - fb_cleanup(); - flist_print_tagged(stdout); - exit(code); -} - -int -main(int argc, char *argv[]) -{ - int once; - int i, arg, key; - char *info, *desc, *filelist; - char linebuffer[128]; - struct flist *fprev = NULL; - -#if 0 - /* debug aid, to attach gdb ... */ - fprintf(stderr,"pid %d\n",getpid()); - sleep(10); -#endif - - setlocale(LC_ALL,""); -#ifdef HAVE_LIBLIRC - lirc = lirc_fbi_init(); -#endif - fbi_read_config(); - cfg_parse_cmdline(&argc,argv,fbi_cmd); - cfg_parse_cmdline(&argc,argv,fbi_cfg); - - if (GET_AUTO_ZOOM()) { - cfg_set_bool(O_AUTO_UP, 1); - cfg_set_bool(O_AUTO_DOWN, 1); - } - - if (GET_HELP()) { - usage(argv[0]); - exit(0); - } - if (GET_VERSION()) { - version(); - exit(0); - } - if (GET_WRITECONF()) - fbi_write_config(); - - once = GET_ONCE(); - autoup = GET_AUTO_UP(); - autodown = GET_AUTO_DOWN(); - fitwidth = GET_FIT_WIDTH(); - statusline = GET_VERBOSE(); - textreading = GET_TEXT_MODE(); - editable = GET_EDIT(); - backup = GET_BACKUP(); - preserve = GET_PRESERVE(); - read_ahead = GET_READ_AHEAD(); - - max_mem_mb = GET_CACHE_MEM(); - blend_msecs = GET_BLEND_MSECS(); - v_steps = GET_SCROLL(); - h_steps = GET_SCROLL(); - timeout = GET_TIMEOUT(); - pcd_res = GET_PCD_RES(); - - fbgamma = GET_GAMMA(); - - fontname = cfg_get_str(O_FONT); - filelist = cfg_get_str(O_FILE_LIST); - - if (filelist) - flist_add_list(filelist); - for (i = optind; i < argc; i++) - flist_add(argv[i]); - flist_renumber(); - - if (0 == fcount) { - usage(argv[0]); - exit(1); - } - - if (GET_RANDOM()) - flist_randomize(); - fcurrent = flist_first(); - - font_init(); - if (NULL == fontname) - fontname = "monospace:size=16"; - face = font_open(fontname); - if (NULL == face) { - fprintf(stderr,"can't open font: %s\n",fontname); - exit(1); - } - fd = fb_init(cfg_get_str(O_DEVICE), - cfg_get_str(O_VIDEO_MODE), - GET_VT()); - fb_catch_exit_signals(); - fb_switch_init(); - shadow_init(); - shadow_set_palette(fd); - signal(SIGTSTP,SIG_IGN); - - /* svga main loop */ - tty_raw(); - desc = NULL; - info = NULL; - for (;;) { - flist_img_load(fcurrent, 0); - flist_img_release_memory(); - img = flist_img_get(fcurrent); - if (img) { - desc = make_desc(&fcurrent->fimg->i, fcurrent->name); - info = make_info(fcurrent->fimg, fcurrent->scale); - } - - key = svga_show(fcurrent, fprev, timeout, desc, info, &arg); - fprev = fcurrent; - switch (key) { - case KEY_DELETE: - if (editable) { - struct flist *fdel = fcurrent; - if (flist_islast(fcurrent)) - fcurrent = flist_prev(fcurrent,0); - else - fcurrent = flist_next(fcurrent,0,0); - unlink(fdel->name); - flist_img_free(fdel); - flist_del(fdel); - flist_renumber(); - if (list_empty(&flist)) { - /* deleted last one */ - cleanup_and_exit(0); - } - } else { - status_error("readonly mode, sorry [start with --edit?]"); - } - break; - case KEY_ROT_CW: - case KEY_ROT_CCW: - { - if (editable) { - snprintf(linebuffer,sizeof(linebuffer), - "rotating %s ...",fcurrent->name); - status_update(linebuffer, NULL); - jpeg_transform_inplace - (fcurrent->name, - (key == KEY_ROT_CW) ? JXFORM_ROT_90 : JXFORM_ROT_270, - NULL, - NULL,0, - (backup ? JFLAG_FILE_BACKUP : 0) | - (preserve ? JFLAG_FILE_KEEP_TIME : 0) | - JFLAG_TRANSFORM_IMAGE | - JFLAG_TRANSFORM_THUMBNAIL | - JFLAG_UPDATE_ORIENTATION); - flist_img_free(fcurrent); - } else { - status_error("readonly mode, sorry [start with --edit?]"); - } - break; - } - case KEY_TAGFILE: - fcurrent->tag = !fcurrent->tag; - /* fall throuth */ - case KEY_SPACE: - fcurrent = flist_next(fcurrent,1,0); - if (NULL != fcurrent) - break; - /* else fall */ - case KEY_ESC: - case KEY_Q: - case KEY_EOF: - cleanup_and_exit(0); - break; - case KEY_PGDN: - fcurrent = flist_next(fcurrent,0,1); - break; - case KEY_PGUP: - fcurrent = flist_prev(fcurrent,1); - break; - case KEY_TIMEOUT: - fcurrent = flist_next(fcurrent,once,1); - if (NULL == fcurrent) { - cleanup_and_exit(0); - } - /* FIXME: wrap around */ - break; - case KEY_PLUS: - case KEY_MINUS: - case KEY_ASCALE: - case KEY_SCALE: - { - float newscale, oldscale = fcurrent->scale; - - if (key == KEY_PLUS) { - newscale = fcurrent->scale * 1.6; - } else if (key == KEY_MINUS) { - newscale = fcurrent->scale / 1.6; - } else if (key == KEY_ASCALE) { - newscale = auto_scale(fcurrent->fimg); - } else { - newscale = arg / 100.0; - } - if (newscale < 0.1) - newscale = 0.1; - if (newscale > 10) - newscale = 10; - flist_img_scale(fcurrent, newscale, 0); - scale_fix_top_left(fcurrent, oldscale, newscale); - break; - } - case KEY_GOTO: - if (arg > 0 && arg <= fcount) - fcurrent = flist_goto(arg); - break; - case KEY_DELAY: - timeout = arg; - break; - case KEY_VERBOSE: -#if 0 /* fbdev testing/debugging hack */ - { - ioctl(fd,FBIOBLANK,1); - sleep(1); - ioctl(fd,FBIOBLANK,0); - } -#endif - statusline = !statusline; - break; - case KEY_DESC: - if (!comments) { - edit_desc(img, fcurrent->name); - desc = make_desc(&fcurrent->fimg->i,fcurrent->name); - } - break; - } - } -} --- fbi.man +++ fbi.man @@ -1,159 +0,0 @@ -.TH fbi 1 "(c) 1999-2004 Gerd Knorr" -.SH NAME -fbi - linux \fBf\fPrame\fBb\fPuffer \fBi\fPmageviewer -.SH SYNOPSIS -.B fbi [ options ] file ... -.SH DESCRIPTION -.B fbi -displays the specified file(s) on the linux console using the -framebuffer device. PhotoCD, jpeg, ppm, gif, tiff, xwd, bmp and png -are supported directly. For other formats fbi tries to use -ImageMagick's convert. -.SH OPTIONS -.TP -.B -h -print usage info -.TP -.B -d device -framebuffer device to use. Default is the one your vc is -mapped to. -.TP -.B -m mode -name of the video mode to use (video mode must be listed in -/etc/fb.modes). Default is not to change the video mode. -.TP -.B -v -be verbose: enable status line on the bottom of the screen. -.TP -.B -P -Enable textreading mode. This has the effect that fbi will display -large images without vertical offset (default is to center the -images). Space will first try to scroll down and go to the next image -only if it is already on the bottom of the page. Useful if the images -you are watching text pages, all you have to do to get the next piece -of text is to press space... -.TP -.B -t sec -timeout: load next image after >sec< seconds without any -keypress (i.e. slideshow) -.TP -.B -g gamma -gamma correction. Can also be put into the FBGAMMA environment -variable. Default is 1.0. Requires Pseudocolor or Directcolor -visual, doesn't work for Truecolor. -.TP -.B -r n -select resolution. PhotoCD only, n = 1..5. -.TP -.B -s n -set scroll steps in pixels (default is 50). -.TP -.B -f font -Set font. This can be anything fontconfig accepts. Try fc-list for a -list of known fonts on your system. The fontconfig config file is -evaluated as well, so any generic stuff defined there (such as mono, -sans) will work as well. It is recommended to use monospaced fonts, -the textboxes (help text, exif info) look better then. -.TP -.B -a -Enable autozoom. fbi will automagically pick a reasonable zoom factor -when loading a new image. -.TP -.B --autoup -Like autozoom, but scale up only. -.TP -.B --autodown -Like autozoom, but scale down only. -.TP -.B -u -Randomize the order of the filenames. -.TP -.B -e -Enable editing commands. -.TP -.B -b -create backup files (when editing images). -.TP -.B -p -preserve timestamps (when editing images). -.TP -.B --comments -Display comment tags (if present) instead of the filename. Probably -only useful if you added reasonable comments yourself (using wrjpgcom -for example), otherwise you likely just find texts pointing to the -software which created the image. -.SH KEYS -.nf -cursor keys scroll large images -+, - zoom in/out -ESQ, Q quit -PgUp previous image -PgDn, Space next image -Return next image, write the filename of the current - image to stdout. -P pause the slideshow (if started with -t, toggle) -V enable/disable status line -H display textbox with brief help -I display textbox with some EXIF info -<number>g jump to image #<number> -<number>s set zoom to <number>% -.fi -.P -The Return vs. Space key thing can be used to create a file list while -reviewing the images and use the list for batch processing later on. -.SH EDIT IMAGE -fbi also provides some very basic image editing facilities. You have -to start fbi with the -e switch to use them. -.P -.nf -Shift+D delete image -R rotate 90° clockwise -L rotate 90° counter-clock wise -.fi -.P -The delete function actually wants a capital letter 'D', thus you have -to type Shift+D. This is done to avoid deleting images by mistake -because there are no safety bells: If you ask fbi to delete the image, -it will be deleted without questions asked. -.P -The rotate function actually works for JPEG images only. It does -a lossless transformation of the image. -.SH COMMON PROBLEMS -.B fbi -needs rw access to the framebuffer devices (/dev/fbN), i.e you (our -your admin) have to make sure fbi can open the devices in rw mode. -The IMHO most elegant way is to use pam_console (see -/etc/security/console.perms) to chown the devices to the user logged -in on the console. Another way is to create some group, chown the -special files to that group and put the users which are allowed to use -the framebuffer device into the group. You can also make the special -files world writable, but be aware of the security implications this -has. On a private box it might be fine to handle it this way -though. -.P -.B fbi -also needs access to the linux console (i.e. /dev/ttyN) for sane -console switch handling. That is obviously no problem for console -logins, but any kind of a pseudo tty (xterm, ssh, screen, ...) will -.B not -work. -.SH SEE ALSO -fbset(1), convert(1) -.SH AUTHOR -Gerd Knorr <kraxel@bytesex.org> -.SH COPYRIGHT -Copyright (C) 1999-2004 Gerd Knorr <kraxel@bytesex.org> -.P -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. -.P -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -.P -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. --- fbiconfig.c +++ fbiconfig.c (renamed to fbida-2.08/fbiconfig.c) --- fbiconfig.h +++ fbiconfig.h (renamed to fbida-2.08/fbiconfig.h) --- fbida-2.08 +++ fbida-2.08 +(directory) --- fbida-2.08/.gitignore +++ fbida-2.08/.gitignore @@ -0,0 +1,8 @@ +Ida.ad.h +Make.config +exiftran +fbi +ida +logo.h +thumbnail.cgi +*.o --- fbida-2.08/COPYING +++ fbida-2.08/COPYING (renamed from COPYING) --- fbida-2.08/Changes +++ fbida-2.08/Changes (renamed from Changes) --- fbida-2.08/GNUmakefile +++ fbida-2.08/GNUmakefile @@ -0,0 +1,236 @@ +# config +srcdir = . +VPATH = $(srcdir) +-include Make.config +include $(srcdir)/mk/Variables.mk + +resdir = $(DESTDIR)$(RESDIR) + +# fixup flags +CFLAGS += -DVERSION='"$(VERSION)"' -I$(srcdir) +CFLAGS += -Wno-pointer-sign + +# default target +all: build + +# what to build +TARGETS := exiftran thumbnail.cgi +ifeq ($(HAVE_LINUX_FB_H),yes) + TARGETS += fbi +endif +ifeq ($(HAVE_MOTIF),yes) + TARGETS += ida +endif + + +################################################################# +# poor man's autoconf ;-) + +include $(srcdir)/mk/Autoconf.mk + +ac_jpeg_ver = $(shell \ + $(call ac_init,for libjpeg version);\ + $(call ac_s_cmd,echo -e '\#include <jpeglib.h>\nJPEG_LIB_VERSION' \ + | cpp | tail -n 1);\ + $(call ac_fini)) + +define make-config +LIB := $(LIB) +RESDIR := $(call ac_resdir) +HAVE_ENDIAN_H := $(call ac_header,endian.h) +HAVE_LINUX_FB_H := $(call ac_header,linux/fb.h) +HAVE_NEW_EXIF := $(call ac_header,libexif/exif-log.h) +HAVE_GLIBC := $(call ac_func,fopencookie) +HAVE_STRCASESTR := $(call ac_func,strcasestr) +HAVE_LIBPCD := $(call ac_lib,pcd_open,pcd) +HAVE_LIBUNGIF := $(call ac_lib,DGifOpenFileName,ungif) +HAVE_LIBPNG := $(call ac_lib,png_read_info,png,-lz) +HAVE_LIBTIFF := $(call ac_lib,TIFFOpen,tiff) +HAVE_LIBWEBP := $(call ac_lib,WebPDecodeRGBA,webp) +#HAVE_LIBMAGICK := $(call ac_binary,Magick-config) +HAVE_LIBSANE := $(call ac_lib,sane_init,sane) +HAVE_LIBCURL := $(call ac_lib,curl_easy_init,curl) +HAVE_LIBLIRC := $(call ac_lib,lirc_init,lirc_client) +HAVE_MOTIF := $(call ac_lib,XmStringGenerate,Xm,-L/usr/X11R6/$(LIB) -lXpm -lXt -lXext -lX11) +JPEG_VER := $(call ac_jpeg_ver) +endef + +# transposing +CFLAGS += -Ijpeg/$(JPEG_VER) + +# transparent http/ftp access using curl depends on fopencookie (glibc) +ifneq ($(HAVE_GLIBC),yes) + HAVE_LIBCURL := no +endif + +# catch fopen calls for transparent ftp/http access +ifeq ($(HAVE_LIBCURL),yes) + ida fbi : CFLAGS += -D_GNU_SOURCE + ida fbi : LDFLAGS += -Wl,--wrap=fopen +endif + + +######################################################################## +# conditional stuff + +includes = ENDIAN_H STRCASESTR NEW_EXIF +libraries = PCD UNGIF PNG TIFF WEBP CURL SANE LIRC +ida_libs = PCD UNGIF PNG TIFF WEBP CURL SANE +fbi_libs = PCD UNGIF PNG TIFF WEBP CURL LIRC + +#MAGICK_CFLAGS = $(shell Magick-config --cflags) +#MAGICK_LDFLAGS = $(shell Magick-config --ldflags) +#MAGICK_LDLIBS = $(shell Magick-config --libs) +#MAGICK_OBJS := rd/magick.o + +PNG_LDLIBS := -lpng -lz +TIFF_LDLIBS := -ltiff +WEBP_LDLIBS := -lwebp +PCD_LDLIBS := -lpcd +UNGIF_LDLIBS := -lungif +SANE_LDLIBS := -lsane +CURL_LDLIBS := -lcurl +LIRC_LDLIBS := -llirc_client + +PNG_OBJS := rd/read-png.o wr/write-png.o +TIFF_OBJS := rd/read-tiff.o wr/write-tiff.o +WEBP_OBJS := rd/read-webp.o +PCD_OBJS := rd/read-pcd.o +UNGIF_OBJS := rd/read-gif.o +SANE_OBJS := sane.o +CURL_OBJS := curl.o +LIRC_OBJS := lirc.o + +# common objs +OBJS_READER := readers.o rd/read-ppm.o rd/read-bmp.o rd/read-jpeg.o +OBJS_WRITER := writers.o wr/write-ppm.o wr/write-ps.o wr/write-jpeg.o + +# update various flags depending on HAVE_* +CFLAGS += $(call ac_inc_cflags,$(includes)) +CFLAGS += $(call ac_lib_cflags,$(libraries)) +CFLAGS += $(call ac_lib_mkvar,$(libraries),CFLAGS) +LDFLAGS += $(call ac_lib_mkvar,$(libraries),LDFLAGS) + +# link which conditional libs +ida : LDLIBS += $(call ac_lib_mkvar,$(ida_libs),LDLIBS) +fbi : LDLIBS += $(call ac_lib_mkvar,$(fbi_libs),LDLIBS) + + +######################################################################## +# rules for the small tools + +# jpeg/exif libs +exiftran : LDLIBS += -ljpeg -lexif -lm +thumbnail.cgi : LDLIBS += -lexif -lm + +exiftran: exiftran.o genthumbnail.o jpegtools.o \ + jpeg/$(JPEG_VER)/transupp.o \ + filter.o op.o readers.o rd/read-jpeg.o +thumbnail.cgi: thumbnail.cgi.o + + +######################################################################## +# rules for ida + +# object files +OBJS_IDA := \ + ida.o man.o hex.o x11.o viewer.o dither.o icons.o \ + parseconfig.o idaconfig.o fileops.o desktop.o \ + RegEdit.o selections.o xdnd.o jpeg/$(JPEG_VER)/transupp.o \ + filebutton.o filelist.o browser.o jpegtools.o \ + op.o filter.o lut.o color.o \ + rd/read-xwd.o rd/read-xpm.o + +OBJS_IDA += $(call ac_lib_mkvar,$(ida_libs),OBJS) + +# for X11 + Motif +ida : CFLAGS += -I/usr/X11R6/include +ida : LDFLAGS += -L/usr/X11R6/$(LIB) +ida : LDLIBS += -lXm -lXpm -lXt -lXext -lX11 + +# jpeg/exif libs +ida : LDLIBS += -ljpeg -lexif -lm + +# RegEdit.c is good old K&R ... +RegEdit.o : CFLAGS += -Wno-missing-prototypes -Wno-strict-prototypes + +ida: $(OBJS_IDA) $(OBJS_READER) $(OBJS_WRITER) + +Ida.ad.h: Ida.ad $(srcdir)/fallback.pl + perl $(srcdir)/fallback.pl < $< > $@ + +logo.h: logo.jpg + hexdump -v -e '1/1 "0x%02x,"' < $< > $@ + echo >> $@ # make gcc 3.x happy + +ida.o: Ida.ad.h logo.h + + +######################################################################## +# rules for fbi + +# object files +OBJS_FBI := \ + fbi.o fbtools.o fb-gui.o desktop.o \ + parseconfig.o fbiconfig.o \ + jpegtools.o jpeg/$(JPEG_VER)/transupp.o \ + dither.o filter.o op.o + +OBJS_FBI += $(filter-out wr/%,$(call ac_lib_mkvar,$(fbi_libs),OBJS)) + +# jpeg/exif libs +fbi : CFLAGS += $(shell pkg-config --cflags freetype2 fontconfig) +fbi : LDLIBS += $(shell pkg-config --libs freetype2 fontconfig) +fbi : LDLIBS += -ljpeg -lexif -lm + +fbi: $(OBJS_FBI) $(OBJS_READER) + + +######################################################################## +# general rules + +.PHONY: check-libjpeg build install clean distclean realclean +build: check-libjpeg $(TARGETS) + +check-libjpeg: + @test -d jpeg/$(JPEG_VER) || \ + ( echo "Need files from libjpeg $(JPEG_VER) in jpeg/"; false) + +install: build + $(INSTALL_DIR) $(bindir) + $(INSTALL_DIR) $(mandir)/man1 + $(INSTALL_BINARY) exiftran $(bindir) + $(INSTALL_DATA) $(srcdir)/exiftran.man $(mandir)/man1/exiftran.1 +ifeq ($(HAVE_LINUX_FB_H),yes) + $(INSTALL_BINARY) fbi $(bindir) + $(INSTALL_SCRIPT) fbgs $(bindir) + $(INSTALL_DATA) $(srcdir)/fbi.man $(mandir)/man1/fbi.1 + $(INSTALL_DATA) $(srcdir)/fbgs.man $(mandir)/man1/fbgs.1 +endif +ifeq ($(HAVE_MOTIF),yes) + $(INSTALL_BINARY) ida $(bindir) + $(INSTALL_DATA) $(srcdir)/ida.man $(mandir)/man1/ida.1 + $(INSTALL_DIR) $(resdir)/app-defaults + $(INSTALL_DATA) $(srcdir)/Ida.ad $(resdir)/app-defaults/Ida +endif + +clean: + -rm -f *.o jpeg/$(JPEG_VER)/*.o rd/*.o wr/*.o $(depfiles) core core.* + +realclean distclean: clean + -rm -f Make.config + -rm -f $(TARGETS) *~ rd/*~ wr/*~ xpm/*~ Ida.ad.h logo.h + + +include $(srcdir)/mk/Compile.mk +-include $(depfiles) + + +######################################################################## +# maintainer stuff + +include $(srcdir)/mk/Maintainer.mk + +sync:: + cp $(srcdir)/../xawtv/common/parseconfig.[ch] $(srcdir) + cp $(srcdir)/../xawtv/console/fbtools.[ch] $(srcdir) --- fbida-2.08/INSTALL +++ fbida-2.08/INSTALL (renamed from INSTALL) --- fbida-2.08/Ida.ad +++ fbida-2.08/Ida.ad (renamed from Ida.ad) --- fbida-2.08/README +++ fbida-2.08/README (renamed from README) --- fbida-2.08/RegEdit.c +++ fbida-2.08/RegEdit.c (renamed from RegEdit.c) --- fbida-2.08/RegEdit.h +++ fbida-2.08/RegEdit.h (renamed from RegEdit.h) --- fbida-2.08/RegEditI.h +++ fbida-2.08/RegEditI.h (renamed from RegEditI.h) --- fbida-2.08/TODO +++ fbida-2.08/TODO (renamed from TODO) --- fbida-2.08/VERSION +++ fbida-2.08/VERSION @@ -0,0 +1 @@ +2.08 --- fbida-2.08/backup +++ fbida-2.08/backup +(directory) --- fbida-2.08/backup/Ida-de +++ fbida-2.08/backup/Ida-de (renamed from backup/Ida-de) --- fbida-2.08/backup/Ida-default +++ fbida-2.08/backup/Ida-default (renamed from backup/Ida-default) --- fbida-2.08/backup/Ida-fixed +++ fbida-2.08/backup/Ida-fixed (renamed from backup/Ida-fixed) --- fbida-2.08/browser.c +++ fbida-2.08/browser.c (renamed from browser.c) --- fbida-2.08/browser.h +++ fbida-2.08/browser.h (renamed from browser.h) --- fbida-2.08/color.c +++ fbida-2.08/color.c (renamed from color.c) --- fbida-2.08/color.h +++ fbida-2.08/color.h (renamed from color.h) --- fbida-2.08/config.h +++ fbida-2.08/config.h --- fbida-2.08/curl.c +++ fbida-2.08/curl.c (renamed from curl.c) --- fbida-2.08/curl.h +++ fbida-2.08/curl.h (renamed from curl.h) --- fbida-2.08/desktop +++ fbida-2.08/desktop +(directory) --- fbida-2.08/desktop.c +++ fbida-2.08/desktop.c (renamed from desktop.c) --- fbida-2.08/desktop.h +++ fbida-2.08/desktop.h (renamed from desktop.h) --- fbida-2.08/desktop/ida.desktop +++ fbida-2.08/desktop/ida.desktop (renamed from desktop/ida.desktop) --- fbida-2.08/dither.c +++ fbida-2.08/dither.c (renamed from dither.c) --- fbida-2.08/dither.h +++ fbida-2.08/dither.h (renamed from dither.h) --- fbida-2.08/exiftran.c +++ fbida-2.08/exiftran.c @@ -0,0 +1,269 @@ +/* + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +#include <libexif/exif-data.h> + +#include <jpeglib.h> +#include "transupp.h" /* Support routines for jpegtran */ +#include "jpegtools.h" +#include "genthumbnail.h" + +/* ---------------------------------------------------------------------- */ + +static void dump_exif(FILE *out, ExifData *ed) +{ + const char *title, *value; +#ifdef HAVE_NEW_EXIF + char buffer[256]; +#endif + ExifEntry *ee; + int tag,i; + + for (i = 0; i < EXIF_IFD_COUNT; i++) { + fprintf(out," ifd %s\n", exif_ifd_get_name (i)); + for (tag = 0; tag < 0xffff; tag++) { + title = exif_tag_get_title(tag); + if (!title) + continue; + ee = exif_content_get_entry (ed->ifd[i], tag); + if (NULL == ee) + continue; +#ifdef HAVE_NEW_EXIF + value = exif_entry_get_value(ee, buffer, sizeof(buffer)); +#else + value = exif_entry_get_value(ee); +#endif + fprintf(out," 0x%04x %-30s %s\n", tag, title, value); + } + } + if (ed->data && ed->size) + fprintf(out," thumbnail\n %d bytes data\n", ed->size); +} + +static int dump_file(FILE *out, char *filename) +{ + ExifData *ed; + + ed = exif_data_new_from_file (filename); + if (NULL == ed) { + fprintf(stderr,"%s: no EXIF data\n",filename); + return -1; + } + + fprintf(out,"%s\n",filename); + dump_exif(out,ed); + fprintf(out,"--\n"); + + exif_data_unref (ed); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +#define THUMB_MAX 65536 + +static void +usage(FILE *fp, char *name) +{ + char *h; + + if (NULL != (h = strrchr(name, '/'))) + name = h+1; + fprintf(fp, + "usage: %s [ options ] file\n" + "\n" + "transform options:\n" + " -a automatic (using exif orientation tag)\n" + " -9 rotate by 90 degrees\n" + " -1 rotate by 180 degrees\n" + " -2 rotate by 270 degrees\n" + " -f flip vertical\n" + " -F flip horizontal\n" + " -t transpose\n" + " -T transverse\n" + "\n" + " -nt don't rotate exif thumbnail\n" + " -ni don't rotate jpeg image\n" + " -no don't update the orientation tag\n" + "\n" + "other options:\n" + " -h print this text\n" + " -d dump exif data\n" + " -c <text> create/update comment\n" + " -g (re)generate thumbnail\n" + " -o <file> output file\n" + " -i change files inplace\n" + " -b create a backup file (with -i)\n" + " -p preserve timestamps (with -i)\n" + "\n" + "-- \n" + "Gerd Hoffmann <kraxel@bytesex.org> [SUSE Labs]\n", + name); +} + +int main(int argc, char *argv[]) +{ + JXFORM_CODE transform = JXFORM_NONE; + unsigned char *comment = NULL; + unsigned char *outfile = NULL; + unsigned char *thumbnail = NULL; + int tsize = 0; + int inplace = 0; + unsigned int flags = + JFLAG_TRANSFORM_IMAGE | + JFLAG_TRANSFORM_THUMBNAIL | + JFLAG_UPDATE_ORIENTATION; + int dump = 0; + int i, c, rc; + + for (;;) { + c = getopt(argc, argv, "hbpid912fFtTagc:o:n:"); + if (c == -1) + break; + switch (c) { + case '9': + transform = JXFORM_ROT_90; + break; + case '1': + transform = JXFORM_ROT_180; + break; + case '2': + transform = JXFORM_ROT_270; + break; + case 'f': + transform = JXFORM_FLIP_V; + break; + case 'F': + transform = JXFORM_FLIP_H; + break; + case 't': + transform = JXFORM_TRANSPOSE; + break; + case 'T': + transform = JXFORM_TRANSVERSE; + break; + case 'a': + transform = -1; /* automagic */ + break; + + case 'n': + /* don't ... */ + switch (optarg[0]) { + case 't': + flags &= ~JFLAG_TRANSFORM_THUMBNAIL; + break; + case 'i': + flags &= ~JFLAG_TRANSFORM_IMAGE; + break; + case 'o': + flags &= ~JFLAG_UPDATE_ORIENTATION; + break; + default: + fprintf(stderr,"unknown option -n%c\n",optarg[0]); + exit(1); + } + break; + + case 'c': + flags |= JFLAG_UPDATE_COMMENT; + comment = optarg; + break; + case 'g': + flags |= JFLAG_UPDATE_THUMBNAIL; + break; + case 'o': + outfile = optarg; + break; + case 'd': + dump = 1; + break; + + case 'b': + flags |= JFLAG_FILE_BACKUP; + break; + case 'p': + flags |= JFLAG_FILE_KEEP_TIME; + break; + case 'i': + inplace = 1; + break; + + case 'h': + usage(stdout,argv[0]); + exit(0); + default: + usage(stderr,argv[0]); + exit(1); + } + } + + /* sanity checks on the arguments */ + if (optind == argc) { + fprintf(stderr, + "no image file specified (try -h for more info)\n"); + exit(1); + } + + /* read-only stuff */ + if (dump) { + rc = 0; + for (i = optind; i < argc; i++) { + if (0 != dump_file(stdout,argv[i])) + rc = 1; + } + return rc; + } + + /* r/w sanity checks */ + if (NULL != outfile && optind+1 > argc) { + fprintf(stderr, + "when specifying a output file you can process\n" + "one file at a time only (try -h for more info).\n"); + exit(1); + } + if (NULL == outfile && 0 == inplace) { + fprintf(stderr, + "you have to either specify a output file (-o <file>)\n" + "or enable inplace editing (-i). Try -h for more info.\n"); + exit(1); + } + if (JXFORM_NONE == transform && + !(flags & JFLAG_UPDATE_COMMENT) && + !(flags & JFLAG_UPDATE_THUMBNAIL)) { + fprintf(stderr, + "What do you want to do today? Neither a new comment nor a\n" + "tranformation operation was specified (try -h for more info).\n"); + exit(1); + } + + /* do actual update work */ + if (outfile) { + if (flags & JFLAG_UPDATE_THUMBNAIL) { + thumbnail = malloc(THUMB_MAX); + tsize = create_thumbnail(argv[optind],thumbnail,THUMB_MAX); + } + return jpeg_transform_files(argv[optind], outfile, transform, + comment, thumbnail, tsize, flags); + } else { + rc = 0; + for (i = optind; i < argc; i++) { + fprintf(stderr,"processing %s\n",argv[i]); + if (flags & JFLAG_UPDATE_THUMBNAIL) { + thumbnail = malloc(THUMB_MAX); + tsize = create_thumbnail(argv[i],thumbnail,THUMB_MAX); + } + if (0 != jpeg_transform_inplace(argv[i], transform, comment, + thumbnail, tsize, flags)) + rc = 1; + } + return rc; + } +} --- fbida-2.08/exiftran.man +++ fbida-2.08/exiftran.man (renamed from exiftran.man) --- fbida-2.08/fallback.pl +++ fbida-2.08/fallback.pl (renamed from fallback.pl) --- fbida-2.08/fb-gui.c +++ fbida-2.08/fb-gui.c (renamed from fb-gui.c) --- fbida-2.08/fb-gui.h +++ fbida-2.08/fb-gui.h (renamed from fb-gui.h) --- fbida-2.08/fbgs +++ fbida-2.08/fbgs (renamed from fbgs) --- fbida-2.08/fbgs.man +++ fbida-2.08/fbgs.man @@ -0,0 +1,51 @@ +.TH FBGS 1 "(c) 1999\-2003 Gerd Knorr" "FBGS 2.07" "PostScript/pdf viewer for the linux framebuffer console" +\# +\# +.SH NAME +fbgs \- Poor man's PostScript/pdf viewer for the linux framebuffer console. +\# +\# +.SH SYNOPSIS +\fBfbgs\fP\ [\fB\-l\fP|\fB\-xl\fP|\fB\-xxl\fP]\ [\fB\-c\fP]\ [\fB\-p\fP\ \fIpassword\fP]\ [\fIfbi\ options\fP]\ \fIfile\fP +\# +\# +.SH DESCRIPTION +.BR Fbgs +is a simple wrapper script which takes a \fIPostScript\fP (PS) or +\fIPortable Document Format\fP (PDF) file as input, renders the pages +using +.BR gs (1) +\- GhostScript \- into a temporary directory and finally calls +.BR fbi (1) +to display them. +.SH OPTIONS +.BR Fbgs +understands all +.BR fbi (1) +options (they are passed through). +Additionally you can specify: +.TP +\fB\-l\fP +To get the pages rendered with 100 dpi (default is 75). +.TP +\fB\-xl\fP +To get the pages rendered with 120 dpi. +.TP +\fB\-xxl\fP +To get the pages rendered with 150 dpi. +.TP +\fB\-c\fP +To render the pages in color (default is N&B). +.TP +\fB\-p\fP \fIpassword\fP +You can use on if your PDF file requires password. +\# +\# +.SH AUTHOR +Gerd Knorr +.BR <kraxel@bytesex.org> +\# +\# +.SH SEE ALSO +.BR fbi (1), +.BR gs (1) --- fbida-2.08/fbi.c +++ fbida-2.08/fbi.c @@ -0,0 +1,1616 @@ +/* + * image viewer, for framebuffer devices + * + * (c) 1998-2004 Gerd Hoffmann <kraxel@bytesex.org> + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <fcntl.h> +#include <errno.h> +#include <termios.h> +#include <getopt.h> +#include <math.h> +#include <setjmp.h> +#include <signal.h> +#include <ctype.h> +#include <locale.h> +#include <wchar.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <linux/fb.h> + +#include <jpeglib.h> + +#include <libexif/exif-data.h> + +#ifdef HAVE_LIBLIRC +# include "lirc/lirc_client.h" +# include "lirc.h" +#endif + +#include "readers.h" +#include "dither.h" +#include "fbtools.h" +#include "fb-gui.h" +#include "filter.h" +#include "desktop.h" +#include "list.h" +#include "fbiconfig.h" + +#include "transupp.h" /* Support routines for jpegtran */ +#include "jpegtools.h" + +#define TRUE 1 +#define FALSE 0 +#undef MAX +#define MAX(x,y) ((x)>(y)?(x):(y)) +#undef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +#define KEY_EOF -1 /* ^D */ +#define KEY_ESC -2 +#define KEY_SPACE -3 +#define KEY_Q -4 +#define KEY_PGUP -5 +#define KEY_PGDN -6 +#define KEY_TIMEOUT -7 +#define KEY_TAGFILE -8 +#define KEY_PLUS -9 +#define KEY_MINUS -10 +#define KEY_VERBOSE -11 +#define KEY_ASCALE -12 +#define KEY_DESC -13 + +/* with arg */ +#define KEY_GOTO -100 +#define KEY_SCALE -101 +#define KEY_DELAY -102 + +/* edit */ +#define KEY_DELETE -200 +#define KEY_ROT_CW -201 +#define KEY_ROT_CCW -202 + +#define DEFAULT_DEVICE "/dev/fb0" + +/* ---------------------------------------------------------------------- */ + +/* lirc fd */ +int lirc = -1; + +/* variables for read_image */ +int32_t lut_red[256], lut_green[256], lut_blue[256]; +int dither = FALSE, pcd_res = 3; +int v_steps = 50; +int h_steps = 50; +int textreading = 0, redraw = 0, statusline = 1; +int fitwidth; + +/* file list */ +struct flist { + /* file list */ + int nr; + int tag; + char *name; + struct list_head list; + + /* image cache */ + int seen; + int top; + int left; + int text_steps; + float scale; + struct ida_image *fimg; + struct ida_image *simg; + struct list_head lru; +}; +static LIST_HEAD(flist); +static LIST_HEAD(flru); +static int fcount; +static struct flist *fcurrent; +static struct ida_image *img; + +/* accounting */ +static int img_cnt, min_cnt = 2, max_cnt = 16; +static int img_mem, max_mem_mb; + +/* framebuffer */ +char *fbdev = NULL; +char *fbmode = NULL; +int fd, switch_last, debug; + +unsigned short red[256], green[256], blue[256]; +struct fb_cmap cmap = { 0, 256, red, green, blue }; + +static float fbgamma = 1; + +/* Command line options. */ +int autodown; +int autoup; +int comments; +int transparency = 40; +int timeout; +int backup; +int preserve; +int read_ahead; +int editable; +int blend_msecs; +int perfmon = 0; + +/* font handling */ +static char *fontname = NULL; +static FT_Face face; + +/* ---------------------------------------------------------------------- */ +/* fwd declarations */ + +static struct ida_image *flist_img_get(struct flist *f); +static void *flist_malloc(size_t size); +static void flist_img_load(struct flist *f, int prefetch); + +/* ---------------------------------------------------------------------- */ + +static void +version(void) +{ + fprintf(stderr, + "fbi version " VERSION ", compiled on %s\n" + "(c) 1999-2006 Gerd Hoffmann <kraxel@bytesex.org> [SUSE Labs]\n", + __DATE__ ); +} + +static void +usage(char *name) +{ + char *h; + + if (NULL != (h = strrchr(name, '/'))) + name = h+1; + fprintf(stderr, + "\n" + "This program displays images using the Linux framebuffer device.\n" + "Supported formats: PhotoCD, jpeg, ppm, gif, tiff, xwd, bmp, png.\n" + "It tries to use ImageMagick's convert for unknown file formats.\n" + "\n" + "usage: %s [ options ] file1 file2 ... fileN\n" + "\n", + name); + + cfg_help_cmdline(stderr,fbi_cmd,4,20,0); + cfg_help_cmdline(stderr,fbi_cfg,4,20,40); + + fprintf(stderr, + "\n" + "Large images can be scrolled using the cursor keys. Zoom in/out\n" + "works with '+' and '-'. Use ESC or 'q' to quit. Space and PgDn\n" + "show the next, PgUp shows the previous image. Jumping to a image\n" + "works with <number>g. Return acts like Space but additionally\n" + "prints the filename of the currently displayed image to stdout.\n" + "\n"); +} + +/* ---------------------------------------------------------------------- */ + +static int flist_add(char *filename) +{ + struct flist *f; + + f = malloc(sizeof(*f)); + memset(f,0,sizeof(*f)); + f->name = strdup(filename); + list_add_tail(&f->list,&flist); + INIT_LIST_HEAD(&f->lru); + return 0; +} + +static int flist_add_list(char *listfile) +{ + char filename[256]; + FILE *list; + + list = fopen(listfile,"r"); + if (NULL == list) { + fprintf(stderr,"open %s: %s\n",listfile,strerror(errno)); + return -1; + } + while (NULL != fgets(filename,sizeof(filename)-1,list)) { + size_t off = strcspn(filename,"\r\n"); + if (off) + filename[off] = 0; + flist_add(filename); + } + fclose(list); + return 0; +} + +static int flist_del(struct flist *f) +{ + list_del(&f->list); + free(f->name); + free(f); + return 0; +} + +static void flist_renumber(void) +{ + struct list_head *item; + struct flist *f; + int i = 0; + + list_for_each(item,&flist) { + f = list_entry(item, struct flist, list); + f->nr = ++i; + } + fcount = i; +} + +static int flist_islast(struct flist *f) +{ + return (&flist == f->list.next) ? 1 : 0; +} + +static int flist_isfirst(struct flist *f) +{ + return (&flist == f->list.prev) ? 1 : 0; +} + +static struct flist* flist_first(void) +{ + return list_entry(flist.next, struct flist, list); +} + +static struct flist* flist_last(void) +{ + return list_entry(flist.prev, struct flist, list); +} + +static struct flist* flist_next(struct flist *f, int eof, int loop) +{ + if (flist_islast(f)) { + if (eof) + return NULL; + if (loop) + return flist_first(); + return f; + } + return list_entry(f->list.next, struct flist, list); +} + +static struct flist* flist_prev(struct flist *f, int loop) +{ + if (flist_isfirst(f)) { + if (loop) + return flist_last(); + return f; + } + return list_entry(f->list.prev, struct flist, list); +} + +static struct flist* flist_goto(int dest) +{ + struct list_head *item; + struct flist *f; + + list_for_each(item,&flist) { + f = list_entry(item, struct flist, list); + if (f->nr == dest) + return f; + } + return NULL; +} + +static void flist_randomize(void) +{ + struct flist *f; + int count; + + srand((unsigned)time(NULL)); + flist_renumber(); + for (count = fcount; count > 0; count--) { + f = flist_goto((rand() % count)+1); + list_del(&f->list); + list_add_tail(&f->list,&flist); + flist_renumber(); + } +} + +static void flist_print_tagged(FILE *fp) +{ + struct list_head *item; + struct flist *f; + + list_for_each(item,&flist) { + f = list_entry(item, struct flist, list); + if (f->tag) + fprintf(fp,"%s\n",f->name); + } +} + +/* ---------------------------------------------------------------------- */ + +static void +shadow_draw_image(struct ida_image *img, int xoff, int yoff, + unsigned int first, unsigned int last, int weight) +{ + unsigned int dwidth = MIN(img->i.width, fb_var.xres); + unsigned int dheight = MIN(img->i.height, fb_var.yres); + unsigned int data, offset, y, xs, ys; + + if (100 == weight) + shadow_clear_lines(first, last); + else + shadow_darkify(0, fb_var.xres-1, first, last, 100 - weight); + + /* offset for image data (image > screen, select visible area) */ + offset = (yoff * img->i.width + xoff) * 3; + + /* offset for video memory (image < screen, center image) */ + xs = 0, ys = 0; + if (img->i.width < fb_var.xres) + xs += (fb_var.xres - img->i.width) / 2; + if (img->i.height < fb_var.yres) + ys += (fb_var.yres - img->i.height) / 2; + + /* go ! */ + for (data = 0, y = 0; + data < img->i.width * img->i.height * 3 + && data / img->i.width / 3 < dheight; + data += img->i.width * 3, y++) { + if (ys+y < first) + continue; + if (ys+y > last) + continue; + if (100 == weight) + shadow_draw_rgbdata(xs, ys+y, dwidth, + img->data + data + offset); + else + shadow_merge_rgbdata(xs, ys+y, dwidth, weight, + img->data + data + offset); + } +} + +static void status_prepare(void) +{ + struct ida_image *img = flist_img_get(fcurrent); + int y1 = fb_var.yres - (face->size->metrics.height >> 6); + int y2 = fb_var.yres - 1; + + if (img) { + shadow_draw_image(img, fcurrent->left, fcurrent->top, y1, y2, 100); + shadow_darkify(0, fb_var.xres-1, y1, y2, transparency); + } else { + shadow_clear_lines(y1, y2); + } + shadow_draw_line(0, fb_var.xres-1, y1-1, y1-1); +} + +static void status_update(unsigned char *desc, char *info) +{ + int yt = fb_var.yres + (face->size->metrics.descender >> 6); + wchar_t str[128]; + + if (!statusline) + return; + status_prepare(); + + swprintf(str,ARRAY_SIZE(str),L"%s",desc); + shadow_draw_string(face, 0, yt, str, -1); + if (info) { + swprintf(str,ARRAY_SIZE(str), L"[ %s ] H - Help", info); + } else { + swprintf(str,ARRAY_SIZE(str), L"| H - Help"); + } + shadow_draw_string(face, fb_var.xres, yt, str, 1); + + shadow_render(); +} + +static void status_error(unsigned char *msg) +{ + int yt = fb_var.yres + (face->size->metrics.descender >> 6); + wchar_t str[128]; + + status_prepare(); + + swprintf(str,ARRAY_SIZE(str), L"%s", msg); + shadow_draw_string(face, 0, yt, str, -1); + + shadow_render(); + sleep(2); +} + +static void status_edit(unsigned char *msg, int pos) +{ + int yt = fb_var.yres + (face->size->metrics.descender >> 6); + wchar_t str[128]; + + status_prepare(); + + swprintf(str,ARRAY_SIZE(str), L"%s", msg); + shadow_draw_string_cursor(face, 0, yt, str, pos); + + shadow_render(); +} + +static void show_exif(struct flist *f) +{ + static unsigned int tags[] = { + 0x010f, // Manufacturer + 0x0110, // Model + + 0x0112, // Orientation + 0x0132, // Date and Time + + 0x01e3, // White Point + 0x829a, // Exposure Time + 0x829d, // FNumber + 0x9206, // Subject Distance + 0xa40c, // Subject Distance Range + 0xa405, // Focal Length In 35mm Film + 0x9209, // Flash + }; + ExifData *ed; + ExifEntry *ee; + unsigned int tag,l1,l2,len,count,i; + const char *title[ARRAY_SIZE(tags)]; + char *value[ARRAY_SIZE(tags)]; + wchar_t *linebuffer[ARRAY_SIZE(tags)]; + + if (!visible) + return; + + ed = exif_data_new_from_file(f->name); + if (NULL == ed) { + status_error("image has no EXIF data"); + return; + } + + /* pass one -- get data + calc size */ + l1 = 0; + l2 = 0; + for (tag = 0; tag < ARRAY_SIZE(tags); tag++) { + ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], tags[tag]); + if (NULL == ee) + ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], tags[tag]); + if (NULL == ee) { + title[tag] = NULL; + value[tag] = NULL; + continue; + } + title[tag] = exif_tag_get_title(tags[tag]); +#ifdef HAVE_NEW_EXIF + value[tag] = malloc(128); + exif_entry_get_value(ee, value[tag], 128); +#else + value[tag] = strdup(exif_entry_get_value(ee)); +#endif + len = strlen(title[tag]); + if (l1 < len) + l1 = len; + len = strlen(value[tag]); + if (l2 < len) + l2 = len; + } + + /* pass two -- print stuff */ + count = 0; + for (tag = 0; tag < ARRAY_SIZE(tags); tag++) { + if (NULL == title[tag]) + continue; + linebuffer[count] = malloc(sizeof(wchar_t)*(l1+l2+8)); + swprintf(linebuffer[count], l1+l2+8, + L"%-*.*s : %-*.*s", + l1, l1, title[tag], + l2, l2, value[tag]); + count++; + } + shadow_draw_text_box(face, 24, 16, transparency, + linebuffer, count); + shadow_render(); + + /* pass three -- free data */ + for (tag = 0; tag < ARRAY_SIZE(tags); tag++) + if (NULL != value[tag]) + free(value[tag]); + exif_data_unref (ed); + for (i = 0; i < count; i++) + free(linebuffer[i]); +} + +static void show_help(void) +{ + static wchar_t *help[] = { + L"keyboard commands", + L"~~~~~~~~~~~~~~~~~", + L" ESC, Q - quit", + L" pgdn, space - next image", + L" pgup - previous image", + L" +/- - zoom in/out", + L" A - autozoom image", + L" cursor keys - scroll image", + L"", + L" H - show this help text", + L" I - show EXIF info", + L" P - pause slideshow", + L" V - toggle statusline", + L"", + L"available if started with --edit switch,", + L"rotation works for jpeg images only:", + L" shift+D - delete image", + L" R - rotate clockwise", + L" L - rotate counter-clockwise", + }; + + shadow_draw_text_box(face, 24, 16, transparency, + help, ARRAY_SIZE(help)); + shadow_render(); +} + +/* ---------------------------------------------------------------------- */ + +struct termios saved_attributes; +int saved_fl; + +static void +tty_raw(void) +{ + struct termios tattr; + + fcntl(0,F_GETFL,&saved_fl); + tcgetattr (0, &saved_attributes); + + fcntl(0,F_SETFL,O_NONBLOCK); + memcpy(&tattr,&saved_attributes,sizeof(struct termios)); + tattr.c_lflag &= ~(ICANON|ECHO); + tattr.c_cc[VMIN] = 1; + tattr.c_cc[VTIME] = 0; + tcsetattr (0, TCSAFLUSH, &tattr); +} + +static void +tty_restore(void) +{ + fcntl(0,F_SETFL,saved_fl); + tcsetattr (0, TCSANOW, &saved_attributes); +} + +/* testing: find key codes */ +static void debug_key(char *key) +{ + char linebuffer[128]; + int i,len; + + len = sprintf(linebuffer,"key: "); + for (i = 0; key[i] != '\0'; i++) + len += snprintf(linebuffer+len, sizeof(linebuffer)-len, + "%s%c", + key[i] < 0x20 ? "^" : "", + key[i] < 0x20 ? key[i] + 0x40 : key[i]); + status_update(linebuffer, NULL); +} + +static void +console_switch(void) +{ + switch (fb_switch_state) { + case FB_REL_REQ: + fb_switch_release(); + case FB_INACTIVE: + visible = 0; + break; + case FB_ACQ_REQ: + fb_switch_acquire(); + case FB_ACTIVE: + visible = 1; + ioctl(fd,FBIOPAN_DISPLAY,&fb_var); + shadow_set_palette(fd); + shadow_set_dirty(); + shadow_render(); + break; + default: + break; + } + switch_last = fb_switch_state; + return; +} + +/* ---------------------------------------------------------------------- */ + +static void free_image(struct ida_image *img) +{ + if (img) { + if (img->data) { + img_mem -= img->i.width * img->i.height * 3; + free(img->data); + } + free(img); + } +} + +static struct ida_image* +read_image(char *filename) +{ + struct ida_loader *loader = NULL; + struct ida_image *img; + struct list_head *item; + char blk[512]; + FILE *fp; + unsigned int y; + void *data; + + /* open file */ + if (NULL == (fp = fopen(filename, "r"))) { + fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); + return NULL; + } + memset(blk,0,sizeof(blk)); + fread(blk,1,sizeof(blk),fp); + rewind(fp); + + /* pick loader */ + list_for_each(item,&loaders) { + loader = list_entry(item, struct ida_loader, list); + if (NULL == loader->magic) + break; + if (0 == memcmp(blk+loader->moff,loader->magic,loader->mlen)) + break; + loader = NULL; + } + if (NULL == loader) { + /* no loader found, try to use ImageMagick's convert */ + int p[2]; + + if (0 != pipe(p)) + return NULL; + switch (fork()) { + case -1: /* error */ + perror("fork"); + close(p[0]); + close(p[1]); + return NULL; + case 0: /* child */ + dup2(p[1], 1 /* stdout */); + close(p[0]); + close(p[1]); + execlp("convert", "convert", "-depth", "8", filename, "ppm:-", NULL); + exit(1); + default: /* parent */ + close(p[1]); + fp = fdopen(p[0], "r"); + if (NULL == fp) + return NULL; + loader = &ppm_loader; + } + } + + /* load image */ + img = malloc(sizeof(*img)); + memset(img,0,sizeof(*img)); + data = loader->init(fp,filename,0,&img->i,0); + if (NULL == data) { + fprintf(stderr,"loading %s [%s] FAILED\n",filename,loader->name); + free_image(img); + return NULL; + } + img->data = flist_malloc(img->i.width * img->i.height * 3); + img_mem += img->i.width * img->i.height * 3; + for (y = 0; y < img->i.height; y++) { + if (switch_last != fb_switch_state) + console_switch(); + loader->read(img->data + img->i.width * 3 * y, y, data); + } + loader->done(data); + return img; +} + +static struct ida_image* +scale_image(struct ida_image *src, float scale) +{ + struct op_resize_parm p; + struct ida_rect rect; + struct ida_image *dest; + void *data; + unsigned int y; + + dest = malloc(sizeof(*dest)); + memset(dest,0,sizeof(*dest)); + memset(&rect,0,sizeof(rect)); + memset(&p,0,sizeof(p)); + + p.width = src->i.width * scale; + p.height = src->i.height * scale; + p.dpi = src->i.dpi; + if (0 == p.width) + p.width = 1; + if (0 == p.height) + p.height = 1; + + data = desc_resize.init(src,&rect,&dest->i,&p); + dest->data = flist_malloc(dest->i.width * dest->i.height * 3); + img_mem += dest->i.width * dest->i.height * 3; + for (y = 0; y < dest->i.height; y++) { + if (switch_last != fb_switch_state) + console_switch(); + desc_resize.work(src,&rect, + dest->data + 3 * dest->i.width * y, + y, data); + } + desc_resize.done(data); + return dest; +} + +static float auto_scale ... This diff was cut by Hermes due to size limitations. Check on the server. To REVIEW against the previous version: osc request show --diff 78514 To ACCEPT the request: osc request accept 78514 --message="reviewed ok." To DECLINE the request: osc request decline 78514 --message="declined for reason xyz (see ... for background / policy / ...)." To REVOKE the request: osc request revoke 78514 --message="retracted because ..., sorry / thx / see better version ..." -- Hermes messaging (http://hermes.opensuse.org) openSUSE Build Service (https://build.opensuse.org/) Collaboration: http://en.opensuse.org/Build_Service/Collaboration -- To unsubscribe, e-mail: opensuse-contrib+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-contrib+help@opensuse.org
participants (1)
-
lazy.kent@opensuse.org