]> git.webhop.me Git - logoview.git/commitdiff
* initial commit
authorMarkham <markham001@gmx.de>
Sat, 30 Sep 2017 19:18:28 +0000 (21:18 +0200)
committerMarkham <markham001@gmx.de>
Sat, 30 Sep 2017 19:18:28 +0000 (21:18 +0200)
README [new file with mode: 0644]
_Makefile [new file with mode: 0644]
_logoview.mk [new file with mode: 0644]
jpeg.cpp [new file with mode: 0644]
jpeg.h [new file with mode: 0644]
logoview.cpp [new file with mode: 0644]
logoview.h [new file with mode: 0644]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..c315f99
--- /dev/null
+++ b/README
@@ -0,0 +1,41 @@
+-------------------------------------------------------------------------
+       logoview - Tool zum Anzeigen von Bildern auf der Coolstream
+-------------------------------------------------------------------------
+
+Unterstützt werden zur Zeit nur JPG-Bilder.
+Das Bild sollte in HD Auflösung (1208x720) vorliegen, wird jedoch, wenn
+nötig, skaliert.
+logoview liest die Informationen über Bildschirmauflösung, OSD-Bereich aus
+der neutrino.conf, wenn diese nicht vorhanden ist (neues Image), wird
+keine Bild angezeigt.
+logoview benötigt keine libcoolstream, ist also unabhängig von eventuellen
+Änderungen in dieser Library.
+
+Lizenz:
+       GPL Version 2
+
+Sourcecode ansehen:
+       http://tuxcode.git.sourceforge.net/git/gitweb.cgi?p=tuxcode/cs-tools;a=log;h=refs/heads/master
+
+Sourcecode herunterladen:
+       git clone git://tuxcode.git.sourceforge.net/gitroot/tuxcode/cs-tools cs-tools
+
+
+Aufruf:
+-------
+
+   logoview [LogoName] &
+       LogoName   : Path to logofile (jpg only)
+                    default = /share/tuxbox/neutrino/icons/start.jpg
+
+   logoview <Options>
+       Options:
+       --------
+         -l | --logo         Path to logofile (jpg only)
+         -b | --background   Run in background
+         -t | --timeout      Timeout in sec. (default 0 = no timeout)
+         -c | --clearscreen  Clear screen when timeout (default = no)
+         -h | --help         This help
+
+   Example:
+     logoview --background -t 3 --logo=/var/share/icons/logo.jpg
diff --git a/_Makefile b/_Makefile
new file mode 100644 (file)
index 0000000..fe63480
--- /dev/null
+++ b/_Makefile
@@ -0,0 +1,60 @@
+###
+###  Makefile logoview - für Coolstream
+###
+
+## Diese beiden Pfade müssen u.U. angepasst werden!
+CROSS_CDK = /opt/newcross/arm-cx2450x-linux-gnueabi
+BUILDSYSTEM = $(HOME)/coolstream/cs-neutrino
+
+# includes
+includedir1 = -I$(BUILDSYSTEM)/root/include
+#includedir2 = -I$(CROSS_CDK)/arm-cx2450x-linux-gnueabi/include
+
+# libraries und cdk
+libdir1 = -L$(BUILDSYSTEM)/root/lib
+#libdir2 = -L$(CROSS_CDK)/arm-cx2450x-linux-gnueabi/lib
+
+# Pfad zum Cross-Compiler
+CCPATH        = $(CROSS_CDK)/bin
+HOST          = arm-cx2450x-linux-gnueabi
+CROSS_COMPILE = $(CCPATH)/$(HOST)
+
+CC            = $(CROSS_COMPILE)-gcc
+#CPP           = $(CROSS_COMPILE)-gcc -E
+#CXX           = $(CROSS_COMPILE)-g++
+#CXXCPP        = $(CROSS_COMPILE)-g++ -E
+#LD            = $(CROSS_COMPILE)-ld
+#LD            = $(CROSS_CDK)/$(HOST)/bin/ld
+#AR            = $(CROSS_COMPILE)-ar
+#NM            = $(CROSS_COMPILE)-nm
+#RANLIB        = $(CROSS_COMPILE)-ranlib
+#OBJDUMP       = $(CROSS_COMPILE)-objdump
+STRIP         = $(CROSS_COMPILE)-strip
+
+INCLUDES = $(includedir1) $(includedir2)
+LIBS = $(libdir1) $(libdir2)
+#LIBS += -L$(CROSS_CDK)/lib
+LIBS += -lstdc++ -ljpeg
+
+CFLAGS = $(INCLUDES) -Wall -W -Wshadow -Wl,-O1 -pipe -g -O2 -fno-strict-aliasing -DUSE_NEVIS_GXA
+CPPFLAGS = 
+CXXFLAGS = $(INCLUDES) -Wall -W -Wshadow -Wl,-O1 -g -O2 -fno-strict-aliasing -DUSE_NEVIS_GXA
+LDFLAGS = $(LIBS)
+
+.c.o:
+       $(CC) $(CFLAGS) $(LDFLAGS) -MT $@ -MD -MP -c -o $@ $<
+
+.cpp.o:
+       $(CC) $(CFLAGS) $(LDFLAGS) -MT $@ -MD -MP -c -o $@ $<
+
+all: clean logoview strip
+
+logoview: logoview.cpp logoview.h jpeg.cpp jpeg.h jpeg.o
+       $(CC) $(CFLAGS) $(LDFLAGS) logoview.cpp jpeg.cpp -o logoview
+
+clean:
+       rm -f *.o *.d
+       rm -f logoview
+
+strip:
+       $(STRIP) logoview
diff --git a/_logoview.mk b/_logoview.mk
new file mode 100644 (file)
index 0000000..a4bf922
--- /dev/null
@@ -0,0 +1,22 @@
+
+## Diese beiden Pfade müssen u.U. angepasst werden!
+BUILDSYSTEM = $(HOME)/coolstream/cs-neurino
+LW_SOURCE = $(BUILDSYSTEM)/source/custom/logoview
+
+INCLUDES = -I.
+INCLUDES += -I$(BUILDSYSTEM)/root/include
+LIBS = -L$(BUILDSYSTEM)/root/lib -lstdc++ -ljpeg
+
+STRIP = arm-cx2450x-linux-gnueabi-strip
+
+ML_CFLAGS  = -Wall -W -Wshadow -fno-strict-aliasing
+ML_CFLAGS += -DUSE_NEVIS_GXA
+
+.cpp.o:
+       $(TARGET)-gcc $(INCLUDES) $(LIBS) -MT $@ -MD -MP -c -o $@ $<
+
+logoview: $(LW_SOURCE)/logoview.cpp $(LW_SOURCE)/logoview.h $(LW_SOURCE)/jpeg.o $(LW_SOURCE)/jpeg.cpp $(LW_SOURCE)/jpeg.h
+       cd $(LW_SOURCE) && \
+               rm -f logoview *.o *.d && \
+               $(TARGET)-gcc -W -Wall $(INCLUDES) $(ML_CFLAGS) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) $(LIBS) logoview.cpp jpeg.cpp -o logoview && \
+               $(STRIP) logoview
diff --git a/jpeg.cpp b/jpeg.cpp
new file mode 100644 (file)
index 0000000..8ab5193
--- /dev/null
+++ b/jpeg.cpp
@@ -0,0 +1,179 @@
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+       
+#include <setjmp.h>
+#include "jpeg.h"
+
+#undef HAVE_STDLIB_H // -Werror complain
+extern "C" {
+#include <jpeglib.h>
+}
+
+#define MIN(a,b) ((a)>(b)?(b):(a))
+
+struct r_jpeg_error_mgr
+{
+       struct jpeg_error_mgr pub;
+       jmp_buf envbuffer;
+};
+
+
+int jpeg_id(const char *name)
+{
+//     dbout("jpeg_id {\n");
+       int fd;
+       unsigned char id[10];
+       fd=open(name,O_RDONLY); if(fd==-1) return(0);
+       read(fd,id,10);
+       close(fd);
+//      dbout("jpeg_id }\n");
+       if(id[6]=='J' && id[7]=='F' && id[8]=='I' && id[9]=='F')        return(1);
+       if(id[0]==0xff && id[1]==0xd8 && id[2]==0xff) return(1);
+       return(0);
+}
+
+
+void jpeg_cb_error_exit(j_common_ptr cinfo)
+{
+//     dbout("jpeg_cd_error_exit {\n");
+       struct r_jpeg_error_mgr *mptr;
+       mptr=(struct r_jpeg_error_mgr*) cinfo->err;
+       (*cinfo->err->output_message) (cinfo);
+       longjmp(mptr->envbuffer,1);
+//      dbout("jpeg_cd_error_exit }\n");
+}
+
+int jpeg_load(const char *filename, unsigned char **buffer, int* x, int* y)
+{
+       //dbout("jpeg_load_local (%s/%d/%d) {\n",basename(filename),*x,*y);
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_decompress_struct *ciptr;
+       struct r_jpeg_error_mgr emgr;
+       unsigned char *bp;
+       int px,py,c;
+       FILE *fh;
+       JSAMPLE *lb;
+
+       ciptr=&cinfo;
+       if(!(fh=fopen(filename,"rb"))) return(FH_ERROR_FILE);
+       ciptr->err=jpeg_std_error(&emgr.pub);
+       emgr.pub.error_exit=jpeg_cb_error_exit;
+       if(setjmp(emgr.envbuffer)==1)
+       {
+               // FATAL ERROR - Free the object and return...
+               jpeg_destroy_decompress(ciptr);
+               fclose(fh);
+//     dbout("jpeg_load } - FATAL ERROR\n");
+               return(FH_ERROR_FORMAT);
+       }
+
+       jpeg_create_decompress(ciptr);
+       jpeg_stdio_src(ciptr,fh);
+       jpeg_read_header(ciptr,TRUE);
+       ciptr->out_color_space=JCS_RGB;
+       ciptr->dct_method=JDCT_FASTEST;
+       if(*x==(int)ciptr->image_width)
+               ciptr->scale_denom=1;
+       else if(abs(*x*2 - ciptr->image_width) < 2)
+               ciptr->scale_denom=2;
+       else if(abs(*x*4 - ciptr->image_width) < 4)
+               ciptr->scale_denom=4;
+       else if(abs(*x*8 - ciptr->image_width) < 8)
+               ciptr->scale_denom=8;
+       else
+               ciptr->scale_denom=1;
+
+       jpeg_start_decompress(ciptr);
+
+       px=ciptr->output_width; py=ciptr->output_height;
+       c=ciptr->output_components;
+       if(px > *x || py > *y)
+       {
+               // pic act larger, e.g. because of not responding jpeg server
+               free(*buffer);
+               *buffer = (unsigned char*) malloc(px*py*3);
+               *x = px;
+               *y = py;
+       }
+
+       if(c==3)
+       {
+               lb=(JSAMPLE*)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr,JPOOL_PERMANENT,c*px);
+               bp=*buffer;
+               while(ciptr->output_scanline < ciptr->output_height)
+               {
+                       jpeg_read_scanlines(ciptr, &lb, 1);
+                       memmove(bp,lb,px*c);
+                       bp+=px*c;
+               }                 
+
+       }
+       jpeg_finish_decompress(ciptr);
+       jpeg_destroy_decompress(ciptr);
+       fclose(fh);
+       //dbout("jpeg_load_local }\n");
+       return(FH_ERROR_OK);
+}
+
+int jpeg_getsize(const char *filename,int *x,int *y, int wanted_width, int wanted_height)
+{
+//     dbout("jpeg_getsize {\n");
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_decompress_struct *ciptr;
+       struct r_jpeg_error_mgr emgr;
+
+       int px,py,c;
+       FILE *fh;
+       ciptr=&cinfo;
+       if(!(fh=fopen(filename,"rb"))) return(FH_ERROR_FILE);
+
+       ciptr->err=jpeg_std_error(&emgr.pub);
+       emgr.pub.error_exit=jpeg_cb_error_exit;
+       if(setjmp(emgr.envbuffer)==1)
+       {
+               // FATAL ERROR - Free the object and return...
+               jpeg_destroy_decompress(ciptr);
+               fclose(fh);
+//     dbout("jpeg_getsize } - FATAL ERROR\n");
+               return(FH_ERROR_FORMAT);
+       }
+
+       jpeg_create_decompress(ciptr);
+       jpeg_stdio_src(ciptr,fh);
+       jpeg_read_header(ciptr,TRUE);
+       ciptr->out_color_space=JCS_RGB;
+       // should be more flexible...
+       if((int)ciptr->image_width/8 >= wanted_width ||
+      (int)ciptr->image_height/8 >= wanted_height)
+               ciptr->scale_denom=8;
+       else if((int)ciptr->image_width/4 >= wanted_width ||
+      (int)ciptr->image_height/4 >= wanted_height)
+               ciptr->scale_denom=4;
+       else if((int)ciptr->image_width/2 >= wanted_width ||
+           (int)ciptr->image_height/2 >= wanted_height)
+               ciptr->scale_denom=2;
+       else
+               ciptr->scale_denom=1;
+
+       jpeg_start_decompress(ciptr);
+       px=ciptr->output_width; py=ciptr->output_height;
+       c=ciptr->output_components;
+       *x=px; 
+       *y=py;
+//     jpeg_finish_decompress(ciptr);
+       jpeg_destroy_decompress(ciptr);
+       fclose(fh);
+//      dbout("jpeg_getsize }\n");
+       return(FH_ERROR_OK);
+}
diff --git a/jpeg.h b/jpeg.h
new file mode 100644 (file)
index 0000000..7198476
--- /dev/null
+++ b/jpeg.h
@@ -0,0 +1,14 @@
+#ifndef __jpeg_h__
+#define __jpeg_h__
+
+
+int jpeg_load(const char *filename, unsigned char **buffer, int* x, int* y);
+int jpeg_getsize(const char *filename,int *x,int *y, int wanted_width, int wanted_height);
+
+#define FH_ERROR_OK 0
+#define FH_ERROR_FILE 1                /* read/access error */
+#define FH_ERROR_FORMAT 2      /* file format error */
+#define FH_ERROR_MALLOC 3      /* error during malloc */
+
+
+#endif // __jpeg_h__
diff --git a/logoview.cpp b/logoview.cpp
new file mode 100644 (file)
index 0000000..7980560
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+       logoview - Logoviewer for Coolstream
+
+       Copyright (C) 2011-2012 Michael Liebmann
+
+        License: GPL
+
+        This library is free software; you can redistribute it and/or
+       modify it under the terms of the GNU Library General Public
+       License as published by the Free Software Foundation; either
+       version 2 of the License, or (at your option) any later version.
+
+       This library 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
+       Library General Public License for more details.
+
+       You should have received a copy of the GNU Library General Public
+       License along with this library; if not, write to the
+       Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+       Boston, MA  02110-1301, USA.
+
+
+       NOTE for ignorant distributors:
+       It's not allowed to distribute any compiled parts of this code, if you don't accept the terms of GPL.
+       Please read it and understand it right!
+       This means for you: Hold it, if not, leave it! You could face legal action! 
+       Otherwise ask the copyright owners, anything else would be theft!
+
+       HINWEIS für ignorante Distributoren:
+       Es ist nicht gestattet, kompilierte Teile dieses Codes zu verteilen, 
+       wenn Sie nicht mit den Bedingungen der GPL einverstanden sind.
+       Bitte lesen und verstehen Sie die GPL richtig!
+       Das bedeutet für Sie: Halten Sie die GPL ein, wenn nicht, unterlassen Sie die Verteilung! 
+       Man kann ohne weiteres rechtliche Schritte gegen Sie unternehmen!
+       Ansonsten fragen Sie die Inhaber der Urheberrechte, alles andere wäre Diebstahl!
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <getopt.h>
+
+#include "logoview.h"
+#include "jpeg.h"
+
+#define LV_VERSION "1.01"
+#define VERSIONSTR "\n\
+      ------------------------------------------------------------\n\
+      -- logoview v" LV_VERSION " * (C)2011-2012, M. Liebmann (micha-bbg) --\n\
+      ------------------------------------------------------------\n\n"
+#define FLAG_FILE "/tmp/.logoview"
+#define NEUTRINO_CONF "/var/tuxbox/config/neutrino.conf"
+#define FB_DEVICE "/dev/fb/0"
+
+CLogoView* CLogoView::getInstance()
+{
+       static CLogoView* instance = NULL;
+       if(!instance)
+               instance = new CLogoView();
+       return instance;
+}
+
+CLogoView::CLogoView()
+{
+       fb            = 0;
+       screen_StartX = 0;
+       screen_StartY = 0;
+       screen_EndX   = 0;
+       screen_EndY   = 0;
+       screen_preset = 0;
+       lfb           = 0;
+       PicBuf        = 0;
+       TmpBuf        = 0;
+       ScBuf         = 0;
+       doneMode      = CLogoView::EMPTY;
+       timeout       = 0;
+       clearScreen   = false;
+       background    = false;
+       noconf            = false;
+       ScreenMode    = "lcd";
+       nomem         = "logoview <Out of memory>\n";
+       start_logo    = "/share/tuxbox/neutrino/icons/start.jpg";
+}
+
+CLogoView::~CLogoView()
+{
+       ClearThis();
+}
+
+void CLogoView::SetScreenBuf(unsigned char *buf, int r, int g, int b, int t)
+{
+TIMER_START();
+       for(unsigned int z = 0; z < var_screeninfo.yres; z++) {
+               unsigned int s1 = 0;
+               unsigned int z1 = z * fix_screeninfo.line_length;
+               for (unsigned int s = 0; s < var_screeninfo.xres; s++) {
+                       ScBuf[z1 + s1 + 3] = t; // transp
+                       ScBuf[z1 + s1 + 0] = b; // blue
+                       ScBuf[z1 + s1 + 1] = g; // green
+                       ScBuf[z1 + s1 + 2] = r; // red
+                       s1 += 4;
+               }
+       }
+       memcpy(buf, ScBuf, fix_screeninfo.line_length*var_screeninfo.yres);
+TIMER_STOP("[logoview] SetScreenBuf   ");
+}
+
+void CLogoView::ClearThis(bool ClearDisplay/*=true*/)
+{
+       unlink(FLAG_FILE);
+       if (lfb > 0) {
+               if (ClearDisplay)
+                       SetScreenBuf(lfb, 0x00, 0x00, 0x00, 0x00); // clear screen
+               munmap(lfb, fix_screeninfo.smem_len);
+       }
+       if (PicBuf > 0)
+               free(PicBuf);
+       if (TmpBuf > 0)
+               free(TmpBuf);
+       if (ScBuf > 0)
+               free(ScBuf);
+       if (fb > 0)
+               close(fb);
+
+        std::string msg = " with ";
+        switch (doneMode) {
+          case CLogoView::SIGHANDLER:
+                msg += "Sighandler";
+                break;
+          case CLogoView::TIMEOUT:
+                msg += "Timeout";
+                break;
+          case CLogoView::FLAGFILE:
+                msg += "Flagfile";
+                break;
+          default:
+                msg = "";
+                break;
+        }
+       printf("[logoview] done%s...\n", msg.c_str());
+}
+       
+bool CLogoView::ReadConfig()
+{
+       char buf1[512] = "";
+       char buf2[512] = "";
+       FILE *fv = fopen(NEUTRINO_CONF, "r");
+
+       screen_StartX=5;
+       screen_StartY=5;
+       screen_EndX=1275;
+       screen_EndY=715;
+
+       if(!noconf && fv) {
+               while(fgets(buf1, sizeof(buf1), fv) != NULL) {
+                       sscanf(buf1, "screen_preset=%2d", &screen_preset);
+               }
+               fclose(fv);
+               ScreenMode = (screen_preset) ? "lcd" : "crt";
+               fv = fopen(NEUTRINO_CONF, "r");
+               if(fv) {
+                       while(fgets(buf1, sizeof(buf1), fv) != NULL) {
+                               sprintf(buf2, "screen_StartX_%s=%%4d", ScreenMode.c_str());
+                               sscanf(buf1, buf2, &screen_StartX);
+                               sprintf(buf2, "screen_StartY_%s=%%4d", ScreenMode.c_str());
+                               sscanf(buf1, buf2, &screen_StartY);
+                               sprintf(buf2, "screen_EndX_%s=%%4d", ScreenMode.c_str());
+                               sscanf(buf1, buf2, &screen_EndX);
+                               sprintf(buf2, "screen_EndY_%s=%%4d", ScreenMode.c_str());
+                               sscanf(buf1, buf2, &screen_EndY);
+                       }
+                       fclose(fv);
+               }
+       }
+       return true;
+}
+
+bool CLogoView::CheckFile(std::string datei)
+{
+       FILE* f1 = fopen(datei.c_str(), "r");
+       if (f1) {
+               fclose(f1);
+               return true;
+       }
+       return false;
+}
+
+void CLogoView::PrintHelp()
+{
+       std::string msg = "\
+    logoview [LogoName] &\n\
+        LogoName   : Path to logofile (jpg only)\n\
+                     default = " + start_logo + "\n\
+\n\
+    logoview <Options>\n\
+        Options:\n\
+        --------\n\
+          -l | --logo         Path to logofile (jpg only)\n\
+          -b | --background   Run in background\n\
+          -t | --timeout      Timeout in sec. (default 0 = no timeout)\n\
+          -c | --clearscreen  Clear screen when timeout (default = no)\n\
+          -h | --help         This help\n\
+\n\
+    Example:\n\
+      logoview --background -t 3 --logo=/var/share/icons/logo.jpg\n\
+";
+       msg = VERSIONSTR + msg;
+       printf(msg.c_str());
+}
+
+static struct option long_options[] = {
+       {"help",        0, NULL, 'h'},
+       {"clearscreen", 0, NULL, 'c'},
+       {"background",  0, NULL, 'b'},
+       {"noconf",      0, NULL, 'n'},
+       {"timeout",     1, NULL, 't'},
+       {"logo",        1, NULL, 'l'},
+       {NULL,          0, NULL, 0}
+};
+
+int CLogoView::run(int argc, char* argv[])
+{
+#ifdef LV_DEBUG
+       printf(VERSIONSTR);
+#endif
+
+       int c, opt;
+       if ((argc == 2) && (argv[1][0] != '-') && (CheckFile(argv[1]))) {
+               start_logo = argv[1];
+       } else {
+               while ((opt = getopt_long(argc, argv, "t:h?cbnl:", long_options, &c)) >= 0)
+               {
+                       switch (opt) {
+                               case 't':
+                                       timeout = strtol(optarg, NULL, 0);
+                                       break;
+                               case 'c':
+                                       clearScreen = true;
+                                       break;
+                               case 'b':
+                                       background = true;
+                                       break;
+                               case 'n':
+                                       noconf = true;
+                                       break;
+                               case 'l':
+                                       if (CheckFile(optarg))
+                                               start_logo = optarg;
+                                       break;
+                               case '?':
+                               case 'h':
+                                       PrintHelp();
+                                       return (opt == '?') ? -1 : 0;
+                               default:
+                                       break;
+                       }
+               }
+       }
+
+       if (background) {
+               switch (fork()) {
+                       case -1: return -1;
+                       case 0:  break;
+                       default: return 0;
+               }
+       }
+
+       fb = open(FB_DEVICE, O_RDWR);
+       if(fb == -1) {
+               perror("[logoview] <open framebuffer device>");
+               exit(1);
+       }
+       if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1) {
+               perror("[logoview] <FBIOGET_FSCREENINFO>\n");
+               ClearThis();
+               return -1;
+       }
+       if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1) {
+               perror("[logoview] <FBIOGET_VSCREENINFO>\n");
+               ClearThis();
+               return -1;
+       }
+       if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0))) {
+               perror("[logoview] <mapping of Framebuffer>\n");
+               ClearThis();
+               return -1;
+       }
+       if (!CheckFile(start_logo)) {
+               perror("[logoview] <no logo file found>");
+               ClearThis();
+               return -1;
+       }
+       if (!ReadConfig()) {
+               perror("[logoview] <error read config>");
+               ClearThis();
+               return -1;
+       }
+
+#ifdef LV_DEBUG
+       printf("Framebuffer ID: %s\nResolution    : %dx%d\nScreenMode    : %s\n \n", 
+               fix_screeninfo.id, var_screeninfo.xres, var_screeninfo.yres, ScreenMode.c_str());
+#endif
+
+       if ((PicBuf = (unsigned char *)malloc(var_screeninfo.xres * var_screeninfo.yres * 3)) == NULL) {
+               perror(nomem.c_str());
+               ClearThis();
+               return -1;
+       }
+       if ((TmpBuf = (unsigned char *)malloc(fix_screeninfo.line_length * var_screeninfo.yres)) == NULL) {
+               perror(nomem.c_str());
+               ClearThis();
+               return -1;
+       }
+       if ((ScBuf = (unsigned char *)malloc(fix_screeninfo.line_length * var_screeninfo.yres)) == NULL) {
+               perror(nomem.c_str());
+               ClearThis();
+               return -1;
+       }
+
+       int x=0, y=0;
+TIMER_START();
+       if (jpeg_load(start_logo.c_str(), (unsigned char **)&PicBuf, &x, &y) != FH_ERROR_OK)
+       {
+               perror("[logoview] <error read logo file>");
+               ClearThis();
+               return -1;
+       }
+TIMER_STOP("[logoview] load pic       ");
+
+       int skalFaktor = 8;
+       int skalKorr   = 2;
+       unsigned int tmp_xres = (var_screeninfo.xres - (screen_StartX + (var_screeninfo.xres - screen_EndX)));
+       unsigned int tmp_yres = (var_screeninfo.yres - (screen_StartY + (var_screeninfo.yres - screen_EndY)));
+       unsigned int xres = (((var_screeninfo.xres - (screen_StartX + (var_screeninfo.xres - screen_EndX))) / skalFaktor) + skalKorr) * skalFaktor;
+       unsigned int yres = (((var_screeninfo.yres - (screen_StartY + (var_screeninfo.yres - screen_EndY))) / skalFaktor) + skalKorr) * skalFaktor;
+//printf("##### tmp_xres: %d, tmp_yres: %d, xres: %d, yres: %d\n", tmp_xres, tmp_yres, xres, yres);
+       tmp_xres = (xres - tmp_xres) / 2;
+       tmp_yres = (yres - tmp_yres) / 2;
+//printf("##### tmp_xres: %d, tmp_yres: %d, xres: %d, yres: %d\n", tmp_xres, tmp_yres, xres, yres);
+
+TIMER_START();
+       PicBuf = Resize(PicBuf, x, y, xres, yres, false);
+TIMER_STOP("[logoview] Resize         ");
+#ifdef LV_DEBUG
+       printf("[logoview] %s - %dx%d, resize to %dx%d\n", start_logo.c_str(), x, y, xres, yres);
+#endif
+
+       SetScreenBuf(TmpBuf, 0, 0, 0, 0xFF); // black screen
+
+TIMER_START();
+       for(unsigned int z = 0; z < yres; z++) {
+               unsigned int s1 = (screen_StartX - tmp_xres) * 4;
+               unsigned int s2 = 0;
+               unsigned int z1 = (z + screen_StartY - tmp_yres) * fix_screeninfo.line_length;
+               unsigned int z2 = z * 3 * xres;
+               for (unsigned int s = 0; s < xres; s++) {
+                       TmpBuf[z1 + s1 + 3] = 0xFF; // transp
+                       TmpBuf[z1 + s1 + 0] = PicBuf[z2 + s2 + 2]; // blue
+                       TmpBuf[z1 + s1 + 1] = PicBuf[z2 + s2 + 1]; // green
+                       TmpBuf[z1 + s1 + 2] = PicBuf[z2 + s2 + 0]; // red
+                       s1 += 4;
+                       s2 += 3;
+               }
+       }
+TIMER_STOP("[logoview] buffer         ");
+
+TIMER_START();
+       memcpy(lfb, TmpBuf, fix_screeninfo.line_length*var_screeninfo.yres);
+TIMER_STOP("[logoview] display screen ");
+
+       time_t startTime = time(NULL);
+       while (true)
+       {
+               if ((timeout > 0) && ((startTime + timeout) <= time(NULL))) {
+                       doneMode = CLogoView::TIMEOUT;
+                       ClearThis(clearScreen);
+                       return 0;
+               }
+               if (CheckFile(FLAG_FILE)) {
+                       doneMode = CLogoView::FLAGFILE;
+                       ClearThis();
+                       return 0;
+               }
+               usleep(100000);
+       }
+       ClearThis();
+       return 0;
+}
+
+unsigned char * CLogoView::Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, bool alpha)
+{
+       unsigned char * cr;
+       cr = (unsigned char*) malloc(dx * dy * ((alpha) ? 4 : 3));
+       if(cr == NULL) {
+               printf("Resize Error: malloc\n");
+               return(orgin);
+       }
+       unsigned char *p,*q;
+       int i,j,k,l,ya,yb;
+       int sq,r,g,b,a;
+       p=cr;
+       int xa_v[dx];
+       for(i=0;i<dx;i++)
+               xa_v[i] = i*ox/dx;
+       int xb_v[dx+1];
+       for(i=0;i<dx;i++) {
+               xb_v[i]= (i+1)*ox/dx;
+               if(xb_v[i]>=ox)
+                       xb_v[i]=ox-1;
+       }
+       if (alpha) {
+               for(j=0;j<dy;j++) {
+                       ya= j*oy/dy;
+                       yb= (j+1)*oy/dy; if(yb>=oy) yb=oy-1;
+                       for(i=0;i<dx;i++,p+=4) {
+                               for(l=ya,r=0,g=0,b=0,a=0,sq=0;l<=yb;l++) {
+                                       q=orgin+((l*ox+xa_v[i])*4);
+                                       for(k=xa_v[i];k<=xb_v[i];k++,q+=4,sq++) {
+                                               r+=q[0]; g+=q[1]; b+=q[2]; a+=q[3];
+                                       }
+                               }
+                               p[0]=r/sq; p[1]=g/sq; p[2]=b/sq; p[3]=a/sq;
+                       }
+               }
+       } else {
+               for(j=0;j<dy;j++) {
+                       ya= j*oy/dy;
+                       yb= (j+1)*oy/dy; if(yb>=oy) yb=oy-1;
+                       for(i=0;i<dx;i++,p+=3) {
+                               for(l=ya,r=0,g=0,b=0,sq=0;l<=yb;l++) {
+                                       q=orgin+((l*ox+xa_v[i])*3);
+                                       for(k=xa_v[i];k<=xb_v[i];k++,q+=3,sq++) {
+                                               r+=q[0]; g+=q[1]; b+=q[2];
+                                       }
+                               }
+                               p[0]=r/sq; p[1]=g/sq; p[2]=b/sq;
+                       }
+               }
+       }
+       free(orgin);
+       return(cr);
+}
+
+void sighandler(int signum)
+{
+// http://www.linux-praxis.de/linux1/prozess4.html
+        CLogoView * clv = CLogoView::getInstance();
+        switch (signum) {
+          case SIGTERM: //15
+          case SIGINT:  // 2
+               signal (signum, SIG_IGN);
+               clv->doneMode = CLogoView::SIGHANDLER;
+               clv->ClearThis();
+                exit(0);
+          case SIGUSR1: //10
+               signal (signum, SIG_IGN);
+               clv->doneMode = CLogoView::SIGHANDLER;
+               clv->ClearThis(false);
+                exit(0);
+          case SIGUSR2: //12
+               clv->PrintHelp();
+                break;
+          default:
+                break;
+        }
+}
+
+int main(int argc, char *argv[])
+{
+       signal(SIGTERM, sighandler);
+       signal(SIGINT,  sighandler);
+       signal(SIGUSR1, sighandler);
+       signal(SIGUSR2, sighandler);
+       signal(SIGHUP,  SIG_IGN);
+       return CLogoView::getInstance()->run(argc, argv);
+}
diff --git a/logoview.h b/logoview.h
new file mode 100644 (file)
index 0000000..0f7cb11
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+       logoview - Logoviewer for Coolstream
+
+       Copyright (C) 2011-2012 Michael Liebmann
+
+        License: GPL
+
+        This library is free software; you can redistribute it and/or
+       modify it under the terms of the GNU Library General Public
+       License as published by the Free Software Foundation; either
+       version 2 of the License, or (at your option) any later version.
+
+       This library 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
+       Library General Public License for more details.
+
+       You should have received a copy of the GNU Library General Public
+       License along with this library; if not, write to the
+       Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+       Boston, MA  02110-1301, USA.
+
+
+       NOTE for ignorant distributors:
+       It's not allowed to distribute any compiled parts of this code, if you don't accept the terms of GPL.
+       Please read it and understand it right!
+       This means for you: Hold it, if not, leave it! You could face legal action! 
+       Otherwise ask the copyright owners, anything else would be theft!
+
+       HINWEIS für ignorante Distributoren:
+       Es ist nicht gestattet, kompilierte Teile dieses Codes zu verteilen, 
+       wenn Sie nicht mit den Bedingungen der GPL einverstanden sind.
+       Bitte lesen und verstehen Sie die GPL richtig!
+       Das bedeutet für Sie: Halten Sie die GPL ein, wenn nicht, unterlassen Sie die Verteilung! 
+       Man kann ohne weiteres rechtliche Schritte gegen Sie unternehmen!
+       Ansonsten fragen Sie die Inhaber der Urheberrechte, alles andere wäre Diebstahl!
+*/
+
+#ifndef __logoview_h__
+#define __logoview_h__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/fb.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <string>
+
+//#define LV_DEBUG
+
+class CLogoView
+{
+       public:
+               static CLogoView* getInstance();
+               CLogoView();
+               ~CLogoView();
+               int run(int argc, char *argv[]);
+               void ClearThis(bool ClearDisplay=true);
+               void PrintHelp();
+               enum
+                       {
+                               EMPTY      = 0,
+                               SIGHANDLER = 1,
+                               TIMEOUT    = 2,
+                               FLAGFILE   = 3
+                       };
+               int doneMode;
+
+       private:
+               unsigned char *lfb, *PicBuf, *TmpBuf, *ScBuf;
+               struct fb_fix_screeninfo fix_screeninfo;
+               struct fb_var_screeninfo var_screeninfo;
+               std::string nomem, start_logo, ScreenMode;
+               unsigned int screen_StartX, screen_StartY, screen_EndX, screen_EndY;
+               int screen_preset, fb;
+               time_t timeout;
+               bool clearScreen, background, noconf;
+
+               bool CheckFile(std::string datei);
+               bool ReadConfig();
+               unsigned char * Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, bool alpha);
+               void SetScreenBuf(unsigned char *buf, int r, int g, int b, int t);
+};
+
+#ifdef LV_DEBUG
+static struct timeval timer_tv, timer_tv2;
+static unsigned int timer_msec;
+
+#define TIMER_START() gettimeofday(&timer_tv, NULL)
+
+#define TIMER_STOP(label)                                                                                              \
+       gettimeofday(&timer_tv2, NULL);                                                                                 \
+       timer_msec = ((timer_tv2.tv_sec - timer_tv.tv_sec) * 1000) + ((timer_tv2.tv_usec - timer_tv.tv_usec) / 1000);   \
+       printf("%s: %u msec\n", label, timer_msec)
+#else
+#define TIMER_START()
+#define TIMER_STOP(label)
+#endif
+
+
+#endif // __logoview_h__