diff --git a/src/driver/framebuffer.cpp b/src/driver/framebuffer.cpp index 81edc51c3..7ef8fae20 100644 --- a/src/driver/framebuffer.cpp +++ b/src/driver/framebuffer.cpp @@ -48,6 +48,8 @@ extern cVideo * videoDecoder; extern CPictureViewer * g_PicViewer; +#define ICON_CACHE_SIZE 1024*1024*2 // 2mb + #define BACKGROUNDIMAGEWIDTH 720 //#undef USE_NEVIS_GXA //FIXME @@ -240,6 +242,7 @@ void CFrameBuffer::init(const char * const fbDevice) _write_gxa(gxa_base, GXA_BMP2_ADDR_REG, (unsigned int) fix.smem_start); _write_gxa(gxa_base, GXA_CONTENT_ID_REG, 0); #endif + cache_size = 0; #if 0 if ((tty=open("/dev/vc/0", O_RDWR))<0) { @@ -903,53 +906,61 @@ bool CFrameBuffer::paintIcon8(const std::string & filename, const int x, const i bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const int y, const int h, const unsigned char offset) { + struct rawHeader header; + int width, height; + int lfd; + fb_pixel_t * data; + uint8_t transp; + struct rawIcon tmpIcon; + std::map::iterator it; + int dsize; + if (!getActive()) return false; - //printf("%s(file, %d, %d, %d)\n", __FUNCTION__, x, y, offset); int yy = y; + //printf("CFrameBuffer::paintIcon: load %s\n", filename.c_str());fflush(stdout); - char * ptr = rindex(filename.c_str(), '.'); - if(ptr) { - *ptr = 0; - std::string newname = iconBasePath + filename.c_str() + ".gif"; - *ptr = '.'; - if(!access(newname.c_str(), F_OK)) - { - if (h != 0) - yy += (h - g_PicViewer->getHeight(newname.c_str())) / 2; - return g_PicViewer->DisplayImage(newname, x, yy, 0, 0); - } - } - struct rawHeader header; - uint16_t width, height; - int lfd; -#if 0 // no need if we have whole / as r/w - std::string iconBasePath1 = "/var/share/icons/"; - lfd = open((iconBasePath1 + filename).c_str(), O_RDONLY); - if (lfd == -1) - lfd = open((iconBasePath + filename).c_str(), O_RDONLY); -#endif - uint8_t * data; - uint8_t transp; - - std::map::iterator it; - it = icon_cache.find((iconBasePath + filename).c_str()); + /* we cache and check original name */ + it = icon_cache.find(iconBasePath + filename); if(it == icon_cache.end()) { - struct rawIcon tmpIcon; + char * ptr = rindex(filename.c_str(), '.'); + if(ptr) { + *ptr = 0; + std::string newname = iconBasePath + filename.c_str() + ".png"; + *ptr = '.'; + //printf("CFrameBuffer::paintIcon: check for %s\n", newname.c_str());fflush(stdout); + + data = g_PicViewer->getIcon(newname, &width, &height); + + if(data) { + dsize = width*height*sizeof(fb_pixel_t); + //printf("CFrameBuffer::paintIcon: %s found, data %x size %d x %d\n", newname.c_str(), data, width, height);fflush(stdout); + if(cache_size+dsize < ICON_CACHE_SIZE) { + cache_size += dsize; + tmpIcon.width = width; + tmpIcon.height = height; + tmpIcon.data = data; + icon_cache.insert(std::pair (iconBasePath + filename, tmpIcon)); + //printf("Cached %s, cache size %d\n", newname.c_str(), cache_size); + } + goto _display; + } + } lfd = open((iconBasePath + filename).c_str(), O_RDONLY); if (lfd == -1) { - printf("paintIcon: error while loading icon: %s%s\n", iconBasePath.c_str(), filename.c_str()); + //printf("paintIcon: error while loading icon: %s%s\n", iconBasePath.c_str(), filename.c_str()); return false; } read(lfd, &header, sizeof(struct rawHeader)); tmpIcon.width = width = (header.width_hi << 8) | header.width_lo; tmpIcon.height = height = (header.height_hi << 8) | header.height_lo; - tmpIcon.transp = transp = header.transp; - tmpIcon.data = (uint8_t*) malloc(width*height); + + dsize = width*height*sizeof(fb_pixel_t); + tmpIcon.data = (fb_pixel_t*) malloc(dsize); data = tmpIcon.data; unsigned char pixbuf[768]; @@ -960,8 +971,14 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in unsigned char compressed = *pixpos; unsigned char pix1 = (compressed & 0xf0) >> 4; unsigned char pix2 = (compressed & 0x0f); - *data++ = pix1; - *data++ = pix2; + if (pix1 != header.transp) + *data++ = realcolor[pix1+offset]; + else + *data++ = 0; + if (pix2 != header.transp) + *data++ = realcolor[pix2+offset]; + else + *data++ = 0; pixpos++; } } @@ -969,14 +986,18 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in data = tmpIcon.data; - icon_cache.insert(std::pair (iconBasePath + filename, tmpIcon)); + if(cache_size+dsize < ICON_CACHE_SIZE) { + cache_size += dsize; + icon_cache.insert(std::pair (iconBasePath + filename, tmpIcon)); + //printf("Cached %s, cache size %d\n", (iconBasePath + filename).c_str(), cache_size); + } } else { data = it->second.data; width = it->second.width; height = it->second.height; - transp = it->second.transp; - //printf("paintIcon: cached %s %d x %d\n", (iconBasePath + filename).c_str(), width, height); + //printf("paintIcon: already cached %s %d x %d\n", (iconBasePath + filename).c_str(), width, height); } +_display: if (h != 0) yy += (h - height) / 2; @@ -984,12 +1005,12 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in fb_pixel_t * d2; for (int count = 0; count < height; count++ ) { - unsigned char *pixpos = &data[count * width]; + fb_pixel_t *pixpos = &data[count * width]; d2 = (fb_pixel_t *) d; for (int count2 = 0; count2 < width; count2++ ) { - unsigned char pix = *pixpos; - if (pix != transp) { - paintPixel(d2, pix + offset); + fb_pixel_t pix = *pixpos; + if (pix != 0) { + *d2 = pix; } d2++; pixpos++; @@ -997,41 +1018,6 @@ bool CFrameBuffer::paintIcon(const std::string & filename, const int x, const in d += stride; } -#if 0 - read(lfd, &header, sizeof(struct rawHeader)); - - width = (header.width_hi << 8) | header.width_lo; - height = (header.height_hi << 8) | header.height_lo; - - if (h != 0) - yy += (h - height) / 2; - - unsigned char pixbuf[768]; - uint8_t * d = ((uint8_t *)getFrameBufferPointer()) + x * sizeof(fb_pixel_t) + stride * yy; - fb_pixel_t * d2; - for (int count=0; count> 1 ); - unsigned char *pixpos = &pixbuf[0]; - d2 = (fb_pixel_t *) d; - for (int count2=0; count2> 1; count2 ++ ) { - unsigned char compressed = *pixpos; - unsigned char pix1 = (compressed & 0xf0) >> 4; - unsigned char pix2 = (compressed & 0x0f); - if (pix1 != header.transp) { - paintPixel(d2, pix1 + offset); - } - d2++; - if (pix2 != header.transp) { - paintPixel(d2, pix2 + offset); - } - d2++; - pixpos++; - } - d += stride; - } - - close(lfd); -#endif return true; } diff --git a/src/driver/framebuffer.h b/src/driver/framebuffer.h index 62bd0c9dc..ef9a0bf63 100644 --- a/src/driver/framebuffer.h +++ b/src/driver/framebuffer.h @@ -81,7 +81,7 @@ class CFrameBuffer uint16_t width; uint16_t height; uint8_t transp; - uint8_t * data; + fb_pixel_t * data; }; std::string iconBasePath; @@ -113,6 +113,7 @@ class CFrameBuffer #endif /* USE_NEVIS_GXA */ bool locked; std::map icon_cache; + int cache_size; public: #ifndef FB_USE_PALETTE diff --git a/src/driver/pictureviewer/pictureviewer.cpp b/src/driver/pictureviewer/pictureviewer.cpp index 96ff6def2..30bdf9fa2 100644 --- a/src/driver/pictureviewer/pictureviewer.cpp +++ b/src/driver/pictureviewer/pictureviewer.cpp @@ -56,15 +56,15 @@ void CPictureViewer::add_format (int (*picsize) (const char *, int *, int *, int void CPictureViewer::init_handlers (void) { +#ifdef FBV_SUPPORT_PNG + add_format (fh_png_getsize, fh_png_load, fh_png_id); +#endif #ifdef FBV_SUPPORT_GIF add_format (fh_gif_getsize, fh_gif_load, fh_gif_id); #endif #ifdef FBV_SUPPORT_JPEG add_format (fh_jpeg_getsize, fh_jpeg_load, fh_jpeg_id); #endif -#ifdef FBV_SUPPORT_PNG - add_format (fh_png_getsize, fh_png_load, fh_png_id); -#endif #ifdef FBV_SUPPORT_BMP add_format (fh_bmp_getsize, fh_bmp_load, fh_bmp_id); #endif @@ -547,14 +547,53 @@ printf("getImage: decoded %s, %d x %d \n", name.c_str (), x, y); int bp; ret = (fb_pixel_t *) convertRGB2FB(buffer, x, y, var->bits_per_pixel, &bp, 0); free(buffer); - //fb_display (buffer, x, y, 0, 0, posx, posy, false, convertSetupAlpha2Alpha(g_settings.infobar_alpha)); } else { printf ("Error decoding file %s\n", name.c_str ()); free (buffer); buffer = NULL; } - } else + } printf("Error open file %s\n", name.c_str ()); return ret; } + +fb_pixel_t * CPictureViewer::getIcon (const std::string & name, int *width, int *height) +{ + int x, y; + CFormathandler *fh; + unsigned char * rgbbuff; + fb_pixel_t * fbbuff = NULL; + + fh = fh_getsize (name.c_str (), &x, &y, INT_MAX, INT_MAX); + if (!fh) { + return NULL; + } + rgbbuff = (unsigned char *) malloc (x * y * 3); + if (rgbbuff == NULL) { + printf ("Error: malloc\n"); + return NULL; + } + if (fh->get_pic (name.c_str (), &rgbbuff, &x, &y) == FH_ERROR_OK) { + int count = x*y; + fbbuff = (fb_pixel_t *) malloc(count * sizeof(fb_pixel_t)); + //printf("getIcon: decoded %s, %d x %d buf %x\n", name.c_str (), x, y, fbbuff); + + for(int i = 0; i < count ; i++) { + int transp = 0; + + if(rgbbuff[i*3] || rgbbuff[i*3+1] || rgbbuff[i*3+2]) + transp = 0xFF; + + fbbuff[i] = (transp << 24) | ((rgbbuff[i*3] << 16) & 0xFF0000) | ((rgbbuff[i*3+1] << 8) & 0xFF00) | (rgbbuff[i*3+2] & 0xFF); + } + + *width = x; + *height = y; + } else + printf ("Error decoding file %s\n", name.c_str ()); + + free (rgbbuff); + + return fbbuff; +} diff --git a/src/driver/pictureviewer/pictureviewer.h b/src/driver/pictureviewer/pictureviewer.h index 8cde6c92b..9cff87429 100644 --- a/src/driver/pictureviewer/pictureviewer.h +++ b/src/driver/pictureviewer/pictureviewer.h @@ -65,6 +65,7 @@ class CPictureViewer bool DisplayImage (const std::string & name, int posx, int posy, int width, int height); bool DisplayLogo (uint64_t channel_id, int posx, int posy, int width, int height); fb_pixel_t * getImage (const std::string & name, int width, int height); + fb_pixel_t * getIcon (const std::string & name, int *width, int *height); int getWidth(const char *name); int getHeight(const char *name); diff --git a/src/gui/epgplus.cpp b/src/gui/epgplus.cpp index 21be0edb6..75cb35d35 100644 --- a/src/gui/epgplus.cpp +++ b/src/gui/epgplus.cpp @@ -1023,7 +1023,7 @@ int EpgPlus::exec (CChannelList * pchannelList, int selectedChannelIndex, CBouqu this->selectedChannelEntry->paint (true, this->selectedTime); } else { this->startTime += this->duration; - this->createChannelEntries (this->selectedChannelEntry->index); + /*this->createChannelEntries (this->selectedChannelEntry->index);*/ this->selectedTime = this->startTime; this->createChannelEntries (this->selectedChannelEntry->index); @@ -1082,13 +1082,20 @@ int EpgPlus::exec (CChannelList * pchannelList, int selectedChannelIndex, CBouqu } this->hide (); +#if 0 for (TChannelEntries::iterator It = this->displayedChannelEntries.begin (); It != this->displayedChannelEntries.end (); It++) { delete *It; } this->displayedChannelEntries.clear (); +#endif } while (this->refreshAll); + for (TChannelEntries::iterator It = this->displayedChannelEntries.begin (); + It != this->displayedChannelEntries.end (); It++) { + delete *It; + } + this->displayedChannelEntries.clear (); return res; } diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 088f48714..f9924af85 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -2298,6 +2298,7 @@ int CNeutrinoApp::run(int argc, char **argv) SetupFonts(); SetupTiming(); + g_PicViewer = new CPictureViewer(); colorSetupNotifier = new CColorSetupNotifier; colorSetupNotifier->changeNotify(NONEXISTANT_LOCALE, NULL); hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_NEUTRINO_STARTING)); @@ -2382,7 +2383,6 @@ int CNeutrinoApp::run(int argc, char **argv) g_PluginList = new CPlugins; g_PluginList->setPluginDir(PLUGINDIR); - g_PicViewer = new CPictureViewer(); // mount shares before scanning for plugins CFSMounter::automount(); //load Pluginlist before main menu (only show script menu if at least one script is available