mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-28 16:01:10 +02:00
Origin commit data
------------------
Commit: 978fcedcbe
Author: TangoCash <eric@loxat.de>
Date: 2020-09-20 (Sun, 20 Sep 2020)
1036 lines
30 KiB
C++
1036 lines
30 KiB
C++
#include "config.h"
|
|
#include <global.h>
|
|
#include <neutrino.h>
|
|
#include "pictureviewer.h"
|
|
#include <gui/movieplayer.h>
|
|
#include <eitd/sectionsd.h>
|
|
#include "pv_config.h"
|
|
#include <system/debug.h>
|
|
#include <system/helpers.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <curl/curl.h>
|
|
#include <errno.h>
|
|
#include <cs_api.h>
|
|
#include <sys/sysinfo.h>
|
|
|
|
#ifdef FBV_SUPPORT_GIF
|
|
extern int fh_gif_getsize (const char *, int *, int *, int, int);
|
|
extern int fh_gif_load (const char *, unsigned char **, int *, int *);
|
|
extern int fh_gif_id (const char *);
|
|
#endif
|
|
#ifdef FBV_SUPPORT_JPEG
|
|
extern int fh_jpeg_getsize (const char *, int *, int *, int, int);
|
|
extern int fh_jpeg_load (const char *, unsigned char **, int *, int *);
|
|
extern int fh_jpeg_id (const char *);
|
|
#endif
|
|
#ifdef FBV_SUPPORT_PNG
|
|
extern int fh_png_getsize (const char *, int *, int *, int, int);
|
|
extern int fh_png_load (const char *, unsigned char **, int *, int *);
|
|
extern int png_load_ext (const char * name, unsigned char ** buffer, int * xp, int * yp, int * bpp);
|
|
extern int fh_png_id (const char *);
|
|
#endif
|
|
#ifdef FBV_SUPPORT_BMP
|
|
extern int fh_bmp_getsize (const char *, int *, int *, int, int);
|
|
extern int fh_bmp_load (const char *, unsigned char **, int *, int *);
|
|
extern int fh_bmp_id (const char *);
|
|
#endif
|
|
#ifdef FBV_SUPPORT_CRW
|
|
extern int fh_crw_getsize (const char *, int *, int *, int, int);
|
|
extern int fh_crw_load (const char *, unsigned char **, int *, int *);
|
|
extern int fh_crw_id (const char *);
|
|
#endif
|
|
|
|
double CPictureViewer::m_aspect_ratio_correction;
|
|
|
|
void CPictureViewer::add_format (int (*picsize) (const char *, int *, int *, int, int), int (*picread) (const char *, unsigned char **, int *, int *), int (*id) (const char *))
|
|
{
|
|
CFormathandler *fhn;
|
|
fhn = (CFormathandler *) malloc (sizeof (CFormathandler));
|
|
fhn->get_size = picsize;
|
|
fhn->get_pic = picread;
|
|
fhn->id_pic = id;
|
|
fhn->next = fh_root;
|
|
fh_root = fhn;
|
|
}
|
|
|
|
void CPictureViewer::getSupportedImageFormats(std::vector<std::string>& exts)
|
|
{
|
|
#ifdef FBV_SUPPORT_JPEG
|
|
exts.push_back(".jpg");
|
|
#endif
|
|
#ifdef FBV_SUPPORT_PNG
|
|
exts.push_back(".png");
|
|
#endif
|
|
#ifdef FBV_SUPPORT_GIF
|
|
exts.push_back(".gif");
|
|
#endif
|
|
#ifdef FBV_SUPPORT_JPEG
|
|
exts.push_back(".jpeg");
|
|
#endif
|
|
#ifdef FBV_SUPPORT_BMP
|
|
exts.push_back(".bmp");
|
|
#endif
|
|
#ifdef FBV_SUPPORT_CRW
|
|
exts.push_back(".crw");
|
|
#endif
|
|
}
|
|
|
|
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_BMP
|
|
add_format (fh_bmp_getsize, fh_bmp_load, fh_bmp_id);
|
|
#endif
|
|
#ifdef FBV_SUPPORT_CRW
|
|
add_format (fh_crw_getsize, fh_crw_load, fh_crw_id);
|
|
#endif
|
|
}
|
|
|
|
CPictureViewer::CFormathandler * CPictureViewer::fh_getsize (const char *name, int *x, int *y, int width_wanted, int height_wanted)
|
|
{
|
|
CFormathandler *fh;
|
|
for (fh = fh_root; fh != NULL; fh = fh->next) {
|
|
if (fh->id_pic (name))
|
|
if (fh->get_size (name, x, y, width_wanted, height_wanted) == FH_ERROR_OK)
|
|
return (fh);
|
|
}
|
|
return (NULL);
|
|
}
|
|
std::string CPictureViewer::DownloadImage(std::string url)
|
|
{
|
|
if (strstr(url.c_str(), "://")) {
|
|
std::string tmpname = "/tmp/pictureviewer" + url.substr(url.find_last_of("."));
|
|
FILE *tmpFile = fopen(tmpname.c_str(), "wb");
|
|
if (tmpFile) {
|
|
CURL *ch = curl_easy_init();
|
|
if(ch)
|
|
{
|
|
curl_easy_setopt(ch, CURLOPT_VERBOSE, 0L);
|
|
curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 1L);
|
|
curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
|
|
curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, NULL);
|
|
curl_easy_setopt(ch, CURLOPT_WRITEDATA, tmpFile);
|
|
curl_easy_setopt(ch, CURLOPT_FAILONERROR, 1L);
|
|
curl_easy_setopt(ch, CURLOPT_URL, url.c_str());
|
|
curl_easy_setopt(ch, CURLOPT_CONNECTTIMEOUT, 3);
|
|
curl_easy_setopt(ch, CURLOPT_TIMEOUT, 4);
|
|
curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
CURLcode res = curl_easy_perform(ch);
|
|
if (res != CURLE_OK){
|
|
printf("[%s] curl_easy_perform() failed:%s\n",__func__, curl_easy_strerror(res));
|
|
}
|
|
curl_easy_cleanup(ch);
|
|
}
|
|
fclose(tmpFile);
|
|
url = true;
|
|
}
|
|
url = tmpname;
|
|
}
|
|
return url;
|
|
}
|
|
|
|
bool CPictureViewer::DecodeImage (const std::string & _name, bool showBusySign, bool unscaled)
|
|
{
|
|
// dbout("DecodeImage {\n");
|
|
#if 0 // quick fix for issue #245. TODO more smart fix for this problem
|
|
if (name == m_NextPic_Name) {
|
|
// dbout("DecodeImage }\n");
|
|
return true;
|
|
}
|
|
#endif
|
|
int x, y, imx, imy;
|
|
|
|
// int xs = CFrameBuffer::getInstance()->getScreenWidth(true);
|
|
// int ys = CFrameBuffer::getInstance()->getScreenHeight(true);
|
|
|
|
// Show red block for "next ready" in view state
|
|
if (showBusySign)
|
|
showBusy (m_startx + 3, m_starty + 3, 10, 0xff, 00, 00);
|
|
|
|
bool url = false;
|
|
|
|
std::string name = DownloadImage(_name);
|
|
|
|
CFormathandler *fh;
|
|
if (unscaled)
|
|
fh = fh_getsize (name.c_str (), &x, &y, INT_MAX, INT_MAX);
|
|
else
|
|
fh = fh_getsize (name.c_str (), &x, &y, m_endx - m_startx, m_endy - m_starty);
|
|
if (fh) {
|
|
if (m_NextPic_Buffer != NULL) {
|
|
free (m_NextPic_Buffer);
|
|
m_NextPic_Buffer = NULL;
|
|
}
|
|
size_t bufsize = x * y * 3;
|
|
size_t resizeBuf = (m_endx - m_startx) * (m_endy - m_starty)*3;
|
|
if (!checkfreemem(bufsize + resizeBuf)){
|
|
return false;
|
|
}
|
|
m_NextPic_Buffer = (unsigned char *) malloc (bufsize);
|
|
if (m_NextPic_Buffer == NULL) {
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: malloc, %s\n", __func__, __LINE__, strerror(errno));
|
|
return false;
|
|
}
|
|
// dbout("---Decoding Start(%d/%d)\n",x,y);
|
|
if (fh->get_pic (name.c_str (), &m_NextPic_Buffer, &x, &y) == FH_ERROR_OK) {
|
|
// dbout("---Decoding Done\n");
|
|
if ((x > (m_endx - m_startx) || y > (m_endy - m_starty)) && m_scaling != NONE && !unscaled) {
|
|
if ((m_aspect_ratio_correction * y * (m_endx - m_startx) / x) <= (m_endy - m_starty)) {
|
|
imx = (m_endx - m_startx);
|
|
imy = (int) (m_aspect_ratio_correction * y * (m_endx - m_startx) / x);
|
|
} else {
|
|
imx = (int) ((1.0 / m_aspect_ratio_correction) * x * (m_endy - m_starty) / y);
|
|
imy = (m_endy - m_starty);
|
|
}
|
|
m_NextPic_Buffer = Resize(m_NextPic_Buffer, x, y, imx, imy, m_scaling);
|
|
x = imx;
|
|
y = imy;
|
|
}
|
|
m_NextPic_X = x;
|
|
m_NextPic_Y = y;
|
|
if (x < (m_endx - m_startx))
|
|
m_NextPic_XPos = (m_endx - m_startx - x) / 2 + m_startx;
|
|
else
|
|
m_NextPic_XPos = m_startx;
|
|
if (y < (m_endy - m_starty))
|
|
m_NextPic_YPos = (m_endy - m_starty - y) / 2 + m_starty;
|
|
else
|
|
m_NextPic_YPos = m_starty;
|
|
if (x > (m_endx - m_startx))
|
|
m_NextPic_XPan = (x - (m_endx - m_startx)) / 2;
|
|
else
|
|
m_NextPic_XPan = 0;
|
|
if (y > (m_endy - m_starty))
|
|
m_NextPic_YPan = (y - (m_endy - m_starty)) / 2;
|
|
else
|
|
m_NextPic_YPan = 0;
|
|
} else {
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: Unable to read file !, %s\n", __func__, __LINE__, strerror(errno));
|
|
free (m_NextPic_Buffer);
|
|
m_NextPic_Buffer = (unsigned char *) malloc (3);
|
|
if (m_NextPic_Buffer == NULL) {
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: malloc, %s\n", __func__, __LINE__, strerror(errno));
|
|
return false;
|
|
}
|
|
memset (m_NextPic_Buffer, 0, 3);
|
|
m_NextPic_X = 1;
|
|
m_NextPic_Y = 1;
|
|
m_NextPic_XPos = 0;
|
|
m_NextPic_YPos = 0;
|
|
m_NextPic_XPan = 0;
|
|
m_NextPic_YPan = 0;
|
|
}
|
|
} else {
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Unable to read file or format not recognized!\n", __func__, __LINE__);
|
|
if (m_NextPic_Buffer != NULL) {
|
|
free (m_NextPic_Buffer);
|
|
m_NextPic_Buffer = NULL;
|
|
}
|
|
m_NextPic_Buffer = (unsigned char *) malloc (3);
|
|
if (m_NextPic_Buffer == NULL) {
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: malloc, %s\n", __func__, __LINE__, strerror(errno));
|
|
return false;
|
|
}
|
|
memset (m_NextPic_Buffer, 0, 3);
|
|
m_NextPic_X = 1;
|
|
m_NextPic_Y = 1;
|
|
m_NextPic_XPos = 0;
|
|
m_NextPic_YPos = 0;
|
|
m_NextPic_XPan = 0;
|
|
m_NextPic_YPan = 0;
|
|
}
|
|
m_NextPic_Name = name;
|
|
if (url)
|
|
unlink(name.c_str());
|
|
hideBusy ();
|
|
// dbout("DecodeImage }\n");
|
|
return (m_NextPic_Buffer != NULL);
|
|
}
|
|
|
|
void CPictureViewer::SetVisible (int startx, int endx, int starty, int endy)
|
|
{
|
|
m_startx = startx;
|
|
m_endx = endx;
|
|
m_starty = starty;
|
|
m_endy = endy;
|
|
}
|
|
|
|
|
|
bool CPictureViewer::ShowImage (const std::string & filename, bool unscaled)
|
|
{
|
|
// dbout("Show Image {\n");
|
|
// Wird eh ueberschrieben ,also schonmal freigeben... (wenig speicher)
|
|
if (m_CurrentPic_Buffer != NULL) {
|
|
free (m_CurrentPic_Buffer);
|
|
m_CurrentPic_Buffer = NULL;
|
|
}
|
|
if (DecodeImage (filename, true, unscaled))
|
|
DisplayNextImage ();
|
|
// dbout("Show Image }\n");
|
|
return true;
|
|
}
|
|
|
|
bool CPictureViewer::DisplayNextImage ()
|
|
{
|
|
// dbout("DisplayNextImage {\n");
|
|
if (m_CurrentPic_Buffer != NULL) {
|
|
free (m_CurrentPic_Buffer);
|
|
m_CurrentPic_Buffer = NULL;
|
|
}
|
|
if (m_NextPic_Buffer != NULL)
|
|
//fb_display (m_NextPic_Buffer, m_NextPic_X, m_NextPic_Y, m_NextPic_XPan, m_NextPic_YPan, m_NextPic_XPos, m_NextPic_YPos);
|
|
CFrameBuffer::getInstance()->displayRGB(m_NextPic_Buffer, m_NextPic_X, m_NextPic_Y, m_NextPic_XPan, m_NextPic_YPan, m_NextPic_XPos, m_NextPic_YPos);
|
|
// dbout("DisplayNextImage fb_disp done\n");
|
|
m_CurrentPic_Buffer = m_NextPic_Buffer;
|
|
m_NextPic_Buffer = NULL;
|
|
m_CurrentPic_Name = m_NextPic_Name;
|
|
m_CurrentPic_X = m_NextPic_X;
|
|
m_CurrentPic_Y = m_NextPic_Y;
|
|
m_CurrentPic_XPos = m_NextPic_XPos;
|
|
m_CurrentPic_YPos = m_NextPic_YPos;
|
|
m_CurrentPic_XPan = m_NextPic_XPan;
|
|
m_CurrentPic_YPan = m_NextPic_YPan;
|
|
// dbout("DisplayNextImage }\n");
|
|
return true;
|
|
}
|
|
|
|
void CPictureViewer::Zoom (float factor)
|
|
{
|
|
// dbout("Zoom %f\n",factor);
|
|
showBusy (m_startx + 3, m_starty + 3, 10, 0xff, 0xff, 00);
|
|
|
|
int oldx = m_CurrentPic_X;
|
|
int oldy = m_CurrentPic_Y;
|
|
unsigned char *oldBuf = m_CurrentPic_Buffer;
|
|
m_CurrentPic_X = int(factor * (float)m_CurrentPic_X);
|
|
m_CurrentPic_Y = int(factor * (float)m_CurrentPic_Y);
|
|
|
|
m_CurrentPic_Buffer = Resize(m_CurrentPic_Buffer, oldx, oldy, m_CurrentPic_X, m_CurrentPic_Y, m_scaling);
|
|
|
|
if (m_CurrentPic_Buffer == oldBuf) {
|
|
// resize failed
|
|
m_CurrentPic_X = oldx;
|
|
m_CurrentPic_Y = oldy;
|
|
hideBusy ();
|
|
return;
|
|
}
|
|
|
|
if (m_CurrentPic_X < (m_endx - m_startx))
|
|
m_CurrentPic_XPos = (m_endx - m_startx - m_CurrentPic_X) / 2 + m_startx;
|
|
else
|
|
m_CurrentPic_XPos = m_startx;
|
|
if (m_CurrentPic_Y < (m_endy - m_starty))
|
|
m_CurrentPic_YPos = (m_endy - m_starty - m_CurrentPic_Y) / 2 + m_starty;
|
|
else
|
|
m_CurrentPic_YPos = m_starty;
|
|
if (m_CurrentPic_X > (m_endx - m_startx))
|
|
m_CurrentPic_XPan = (m_CurrentPic_X - (m_endx - m_startx)) / 2;
|
|
else
|
|
m_CurrentPic_XPan = 0;
|
|
if (m_CurrentPic_Y > (m_endy - m_starty))
|
|
m_CurrentPic_YPan = (m_CurrentPic_Y - (m_endy - m_starty)) / 2;
|
|
else
|
|
m_CurrentPic_YPan = 0;
|
|
//fb_display (m_CurrentPic_Buffer, m_CurrentPic_X, m_CurrentPic_Y, m_CurrentPic_XPan, m_CurrentPic_YPan, m_CurrentPic_XPos, m_CurrentPic_YPos);
|
|
CFrameBuffer::getInstance()->displayRGB(m_CurrentPic_Buffer, m_CurrentPic_X, m_CurrentPic_Y, m_CurrentPic_XPan, m_CurrentPic_YPan, m_CurrentPic_XPos, m_CurrentPic_YPos);
|
|
}
|
|
|
|
void CPictureViewer::Move (int dx, int dy)
|
|
{
|
|
int xs, ys;
|
|
|
|
// dbout("Move %d %d\n",dx,dy);
|
|
showBusy (m_startx + 3, m_starty + 3, 10, 0x00, 0xff, 00);
|
|
|
|
xs = CFrameBuffer::getInstance()->getScreenWidth(true);
|
|
ys = CFrameBuffer::getInstance()->getScreenHeight(true);
|
|
|
|
m_CurrentPic_XPan += dx;
|
|
if (m_CurrentPic_XPan + xs >= m_CurrentPic_X)
|
|
m_CurrentPic_XPan = m_CurrentPic_X - xs - 1;
|
|
if (m_CurrentPic_XPan < 0)
|
|
m_CurrentPic_XPan = 0;
|
|
|
|
m_CurrentPic_YPan += dy;
|
|
if (m_CurrentPic_YPan + ys >= m_CurrentPic_Y)
|
|
m_CurrentPic_YPan = m_CurrentPic_Y - ys - 1;
|
|
if (m_CurrentPic_YPan < 0)
|
|
m_CurrentPic_YPan = 0;
|
|
|
|
if (m_CurrentPic_X < (m_endx - m_startx))
|
|
m_CurrentPic_XPos = (m_endx - m_startx - m_CurrentPic_X) / 2 + m_startx;
|
|
else
|
|
m_CurrentPic_XPos = m_startx;
|
|
if (m_CurrentPic_Y < (m_endy - m_starty))
|
|
m_CurrentPic_YPos = (m_endy - m_starty - m_CurrentPic_Y) / 2 + m_starty;
|
|
else
|
|
m_CurrentPic_YPos = m_starty;
|
|
// dbout("Display x(%d) y(%d) xpan(%d) ypan(%d) xpos(%d) ypos(%d)\n",m_CurrentPic_X, m_CurrentPic_Y,
|
|
// m_CurrentPic_XPan, m_CurrentPic_YPan, m_CurrentPic_XPos, m_CurrentPic_YPos);
|
|
|
|
//fb_display (m_CurrentPic_Buffer, m_CurrentPic_X, m_CurrentPic_Y, m_CurrentPic_XPan, m_CurrentPic_YPan, m_CurrentPic_XPos, m_CurrentPic_YPos);
|
|
CFrameBuffer::getInstance()->displayRGB(m_CurrentPic_Buffer, m_CurrentPic_X, m_CurrentPic_Y, m_CurrentPic_XPan, m_CurrentPic_YPan, m_CurrentPic_XPos, m_CurrentPic_YPos);
|
|
}
|
|
|
|
CPictureViewer::CPictureViewer ()
|
|
{
|
|
int xs, ys;
|
|
|
|
fh_root = NULL;
|
|
m_scaling = COLOR;
|
|
//m_aspect = 4.0 / 3;
|
|
m_aspect = float(16.0 / 9.0);
|
|
m_CurrentPic_Name = "";
|
|
m_CurrentPic_Buffer = NULL;
|
|
m_CurrentPic_X = 0;
|
|
m_CurrentPic_Y = 0;
|
|
m_CurrentPic_XPos = 0;
|
|
m_CurrentPic_YPos = 0;
|
|
m_CurrentPic_XPan = 0;
|
|
m_CurrentPic_YPan = 0;
|
|
m_NextPic_Name = "";
|
|
m_NextPic_Buffer = NULL;
|
|
m_NextPic_X = 0;
|
|
m_NextPic_Y = 0;
|
|
m_NextPic_XPos = 0;
|
|
m_NextPic_YPos = 0;
|
|
m_NextPic_XPan = 0;
|
|
m_NextPic_YPan = 0;
|
|
|
|
xs = CFrameBuffer::getInstance()->getScreenWidth(true);
|
|
ys = CFrameBuffer::getInstance()->getScreenHeight(true);
|
|
|
|
m_startx = 0;
|
|
m_endx = xs - 1;
|
|
m_starty = 0;
|
|
m_endy = ys - 1;
|
|
m_aspect_ratio_correction = m_aspect / ((double) xs / ys);
|
|
|
|
m_busy_buffer = NULL;
|
|
|
|
init_handlers ();
|
|
}
|
|
|
|
CPictureViewer::~CPictureViewer ()
|
|
{
|
|
Cleanup();
|
|
CFormathandler *fh = fh_root;
|
|
while (fh) {
|
|
CFormathandler *tmp = fh->next;
|
|
free(fh);
|
|
fh = tmp;
|
|
}
|
|
}
|
|
|
|
void CPictureViewer::showBusy (int sx, int sy, int width, char r, char g, char b)
|
|
{
|
|
// dbout("Show Busy{\n");
|
|
unsigned char rgb_buffer[3];
|
|
unsigned char *fb_buffer;
|
|
unsigned char *busy_buffer_wrk;
|
|
int cpp = 4;
|
|
|
|
rgb_buffer[0] = r;
|
|
rgb_buffer[1] = g;
|
|
rgb_buffer[2] = b;
|
|
|
|
fb_buffer = (unsigned char *) CFrameBuffer::getInstance()->convertRGB2FB (rgb_buffer, 1, 1);
|
|
if (fb_buffer == NULL) {
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: malloc\n", __func__, __LINE__);
|
|
return;
|
|
}
|
|
if (m_busy_buffer != NULL) {
|
|
free (m_busy_buffer);
|
|
m_busy_buffer = NULL;
|
|
}
|
|
size_t bufsize = width * width * cpp;
|
|
if (!checkfreemem(bufsize)){
|
|
cs_free_uncached (fb_buffer);
|
|
return;
|
|
}
|
|
m_busy_buffer = (unsigned char *) malloc (bufsize);
|
|
if (m_busy_buffer == NULL) {
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: malloc\n", __func__, __LINE__);
|
|
cs_free_uncached (fb_buffer);
|
|
return;
|
|
}
|
|
busy_buffer_wrk = m_busy_buffer;
|
|
unsigned char *fb = (unsigned char *) CFrameBuffer::getInstance()->getFrameBufferPointer();
|
|
unsigned int stride = CFrameBuffer::getInstance ()->getStride ();
|
|
|
|
for (int y = sy; y < sy + width; y++) {
|
|
for (int x = sx; x < sx + width; x++) {
|
|
memmove (busy_buffer_wrk, fb + y * stride + x * cpp, cpp);
|
|
busy_buffer_wrk += cpp;
|
|
memmove (fb + y * stride + x * cpp, fb_buffer, cpp);
|
|
}
|
|
}
|
|
m_busy_x = sx;
|
|
m_busy_y = sy;
|
|
m_busy_width = width;
|
|
m_busy_cpp = cpp;
|
|
cs_free_uncached (fb_buffer);
|
|
// dbout("Show Busy}\n");
|
|
}
|
|
|
|
void CPictureViewer::hideBusy ()
|
|
{
|
|
// dbout("Hide Busy{\n");
|
|
if (m_busy_buffer != NULL) {
|
|
unsigned char *fb = (unsigned char *) CFrameBuffer::getInstance ()->getFrameBufferPointer ();
|
|
unsigned int stride = CFrameBuffer::getInstance ()->getStride ();
|
|
unsigned char *busy_buffer_wrk = m_busy_buffer;
|
|
|
|
for (int y = m_busy_y; y < m_busy_y + m_busy_width; y++) {
|
|
for (int x = m_busy_x; x < m_busy_x + m_busy_width; x++) {
|
|
memmove (fb + y * stride + x * m_busy_cpp, busy_buffer_wrk, m_busy_cpp);
|
|
busy_buffer_wrk += m_busy_cpp;
|
|
}
|
|
}
|
|
free (m_busy_buffer);
|
|
m_busy_buffer = NULL;
|
|
}
|
|
// dbout("Hide Busy}\n");
|
|
}
|
|
void CPictureViewer::Cleanup ()
|
|
{
|
|
if (m_busy_buffer != NULL) {
|
|
free (m_busy_buffer);
|
|
m_busy_buffer = NULL;
|
|
}
|
|
if (m_NextPic_Buffer != NULL) {
|
|
free (m_NextPic_Buffer);
|
|
m_NextPic_Buffer = NULL;
|
|
}
|
|
if (m_CurrentPic_Buffer != NULL) {
|
|
free (m_CurrentPic_Buffer);
|
|
m_CurrentPic_Buffer = NULL;
|
|
}
|
|
}
|
|
|
|
void CPictureViewer::getSize(const char* name, int* width, int *height)
|
|
{
|
|
CFormathandler *fh;
|
|
|
|
fh = fh_getsize(name, width, height, INT_MAX, INT_MAX);
|
|
if (fh == NULL) {
|
|
*width = 0;
|
|
*height = 0;
|
|
}
|
|
}
|
|
|
|
bool CPictureViewer::GetLogoName(const uint64_t &ChannelID, const std::string &ChannelName, std::string &name, int *width, int *height, bool lcd4l_mode, bool enable_event_logo)
|
|
{
|
|
std::string fileType[] = { ".png", ".jpg", ".gif" };
|
|
std::vector<std::string> v_path;
|
|
std::vector<std::string> v_file;
|
|
|
|
// create eventname for eventlogos; Note: We don't process channellogos if any eventlogo was found.
|
|
std::string EventName = "";
|
|
int mode = CNeutrinoApp::getInstance()->getMode();
|
|
if (!g_settings.channellist_show_eventlogo)
|
|
enable_event_logo = false;
|
|
if (enable_event_logo && (ChannelID || mode == NeutrinoModes::mode_ts))
|
|
{
|
|
// TODO: fix eventlogo in moviebrowser
|
|
|
|
if (mode == NeutrinoModes::mode_ts)
|
|
{
|
|
if (CMoviePlayerGui::getInstance().p_movie_info && !CMoviePlayerGui::getInstance().p_movie_info->epgTitle.empty())
|
|
EventName = CMoviePlayerGui::getInstance().p_movie_info->epgTitle;
|
|
}
|
|
else
|
|
{
|
|
CSectionsdClient::CurrentNextInfo CurrentNext;
|
|
CEitManager::getInstance()->getCurrentNextServiceKey(ChannelID, CurrentNext);
|
|
|
|
if (CurrentNext.flags & CSectionsdClient::epgflags::has_current && !CurrentNext.current_name.empty())
|
|
EventName = CurrentNext.current_name;
|
|
}
|
|
|
|
// add neccessary paths to v_path
|
|
v_path.clear();
|
|
if (lcd4l_mode)
|
|
v_path.push_back(g_settings.lcd4l_logodir);
|
|
v_path.push_back(g_settings.logo_hdd_dir);
|
|
if (g_settings.logo_hdd_dir != LOGODIR_VAR)
|
|
v_path.push_back(LOGODIR_VAR);
|
|
if (g_settings.logo_hdd_dir != LOGODIR)
|
|
v_path.push_back(LOGODIR);
|
|
|
|
EventName = GetSpecialName(EventName);
|
|
//printf("GetLogoName(): EventName \"%s\"\n", EventName.c_str());
|
|
|
|
for (size_t i = 0; i < (sizeof(fileType) / sizeof(fileType[0])); i++)
|
|
{
|
|
for (size_t j = 0; j < v_path.size(); j++)
|
|
{
|
|
for (size_t k = EventName.length(); k > 0; k--)
|
|
{
|
|
std::string EventLogo = v_path[j] + "/events/" + EventName.substr(0, k) + fileType[i];
|
|
//printf("GetLogoName(): EventLogo \"%s\"\n", EventLogo.c_str());
|
|
if (access(EventLogo.c_str(), R_OK) == 0)
|
|
{
|
|
if (width && height)
|
|
getSize(EventLogo.c_str(), width, height);
|
|
name = EventLogo;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// create special filename from channelname
|
|
std::string SpecialChannelName = GetSpecialName(ChannelName);
|
|
|
|
// create channel id as string
|
|
char strChnId[16];
|
|
snprintf(strChnId, 16, "%llx", ChannelID & 0xFFFFFFFFFFFFULL);
|
|
strChnId[15] = '\0';
|
|
|
|
// create E2 filenames
|
|
char e2filename1[255];
|
|
e2filename1[0] = '\0';
|
|
char e2filename2[255];
|
|
e2filename2[0] = '\0';
|
|
|
|
CZapitChannel * cc = NULL;
|
|
if (ChannelID && CNeutrinoApp::getInstance()->channelList)
|
|
cc = CNeutrinoApp::getInstance()->channelList->getChannel(ChannelID);
|
|
|
|
if (cc)
|
|
{
|
|
// create E2 filename1
|
|
snprintf(e2filename1, sizeof(e2filename1), "1_0_%X_%X_%X_%X_%X0000_0_0_0",
|
|
(u_int) cc->getServiceType(true),
|
|
(u_int) ChannelID & 0xFFFF,
|
|
(u_int) (ChannelID >> 32) & 0xFFFF,
|
|
(u_int) (ChannelID >> 16) & 0xFFFF,
|
|
(u_int) cc->getSatellitePosition());
|
|
|
|
// create E2 filename2
|
|
snprintf(e2filename2, sizeof(e2filename2), "1_0_%X_%X_%X_%X_%X0000_0_0_0",
|
|
(u_int) 1,
|
|
(u_int) ChannelID & 0xFFFF,
|
|
(u_int) (ChannelID >> 32) & 0xFFFF,
|
|
(u_int) (ChannelID >> 16) & 0xFFFF,
|
|
(u_int) cc->getSatellitePosition());
|
|
}
|
|
|
|
// add neccessary file masks to v_file
|
|
if (!ChannelName.empty())
|
|
v_file.push_back(ChannelName);
|
|
if (!SpecialChannelName.empty())
|
|
v_file.push_back(SpecialChannelName);
|
|
if (strcmp(strChnId, "0") != 0)
|
|
v_file.push_back(strChnId);
|
|
if (strcmp(e2filename1, "") != 0)
|
|
v_file.push_back(std::string(e2filename1));
|
|
if (strcmp(e2filename2, "") != 0)
|
|
v_file.push_back(std::string(e2filename2));
|
|
|
|
for (size_t i = 0; i < (sizeof(fileType) / sizeof(fileType[0])); i++)
|
|
{
|
|
v_path.clear();
|
|
|
|
for (size_t f = 0; f < v_file.size(); f++)
|
|
{
|
|
// process g_settings.lcd4l_logodir
|
|
if (lcd4l_mode)
|
|
v_path.push_back(g_settings.lcd4l_logodir + "/" + v_file[f] + fileType[i]);
|
|
// process g_settings.logo_hdd_dir
|
|
v_path.push_back(g_settings.logo_hdd_dir + "/" + v_file[f] + fileType[i]);
|
|
// process LOGODIR_VAR
|
|
if (g_settings.logo_hdd_dir != LOGODIR_VAR)
|
|
v_path.push_back(std::string(LOGODIR_VAR) + "/" + v_file[f] + fileType[i]);
|
|
// process LOGODIR
|
|
if (g_settings.logo_hdd_dir != LOGODIR)
|
|
v_path.push_back(std::string(LOGODIR) + "/" + v_file[f] + fileType[i]);
|
|
}
|
|
|
|
//check if file is available, name with real name is preferred, return true on success
|
|
for (size_t j = 0; j < v_path.size(); j++)
|
|
{
|
|
//printf("GetLogoName(): v_path[%d] \"%s\"\n", j, v_path[j].c_str());
|
|
if (access(v_path[j].c_str(), R_OK) != -1)
|
|
{
|
|
if (width && height)
|
|
getSize(v_path[j].c_str(), width, height);
|
|
name = v_path[j];
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (cc && (name.compare("m3u_loading_logos") != 0))
|
|
{
|
|
if (!cc->getAlternateLogo().empty())
|
|
{
|
|
std::string lname = downloadUrlToLogo(cc->getAlternateLogo(), LOGODIR_TMP, cc->getChannelID());
|
|
if (width && height)
|
|
getSize(lname.c_str(), width, height);
|
|
name = lname;
|
|
cc->setAlternateLogo(lname);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#if 0
|
|
bool CPictureViewer::DisplayLogo (uint64_t channel_id, int posx, int posy, int width, int height)
|
|
{
|
|
char fname[255];
|
|
bool ret = false;
|
|
|
|
sprintf(fname, "%s/%llx.jpg", g_settings.logo_hdd_dir.c_str(), channel_id & 0xFFFFFFFFFFFFULL);
|
|
// printf("logo file: %s\n", fname);
|
|
if(access(fname, F_OK))
|
|
sprintf(fname, "%s/%llx.gif", g_settings.logo_hdd_dir.c_str(), channel_id & 0xFFFFFFFFFFFFULL);
|
|
|
|
if(!access(fname, F_OK)) {
|
|
ret = DisplayImage(fname, posx, posy, width, height);
|
|
#if 0
|
|
//ret = DisplayImage(fname, posx, posy, width, height);
|
|
fb_pixel_t * data = getImage(fname, width, height);
|
|
//fb_pixel_t * data = getIcon(fname, &width, &height);
|
|
if(data) {
|
|
CFrameBuffer::getInstance()->blit2FB(data, width, height, posx, posy);
|
|
cs_free_uncached(data);
|
|
}
|
|
#endif
|
|
}
|
|
return ret;
|
|
}
|
|
#endif
|
|
void CPictureViewer::rescaleImageDimensions(int *width, int *height, const int max_width, const int max_height, bool upscale)
|
|
{
|
|
float aspect;
|
|
|
|
if ((!upscale) && (*width <= max_width) && (*height <= max_height))
|
|
return;
|
|
|
|
aspect = (float)(*width) / (float)(*height);
|
|
if (((float)(*width) / (float)max_width) > ((float)(*height) / (float)max_height)) {
|
|
*width = max_width;
|
|
*height = int((float)max_width / aspect);
|
|
}else{
|
|
*height = max_height;
|
|
*width = int((float)max_height * aspect);
|
|
}
|
|
}
|
|
|
|
bool CPictureViewer::DisplayImage(const std::string & name, int posx, int posy, int width, int height, int transp)
|
|
{
|
|
if(width < 1 || height < 1){
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: image [%s] width %i height %i \n", __func__, __LINE__, name.c_str(), width, height);
|
|
return false;
|
|
}
|
|
|
|
CFrameBuffer* frameBuffer = CFrameBuffer::getInstance();
|
|
if (transp > CFrameBuffer::TM_EMPTY)
|
|
frameBuffer->SetTransparent(transp);
|
|
|
|
/* TODO: cache or check for same */
|
|
fb_pixel_t * data = getImage(name, width, height);
|
|
|
|
if (data){
|
|
if (transp > CFrameBuffer::TM_EMPTY)
|
|
frameBuffer->SetTransparentDefault();
|
|
|
|
if(data) {
|
|
frameBuffer->blit2FB(data, width, height, posx, posy);
|
|
cs_free_uncached(data);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//NI
|
|
bool CPictureViewer::DisplayImage_unscaled(const std::string & name, int posx, int posy, int width, int height, int transp)
|
|
{
|
|
if(width < 1 || height < 1){
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: width %i height %i \n", __func__, __LINE__, width, height);
|
|
return false;
|
|
}
|
|
|
|
int unscaled_w = width;
|
|
int unscaled_h = height;
|
|
|
|
CFrameBuffer* frameBuffer = CFrameBuffer::getInstance();
|
|
if (transp > CFrameBuffer::TM_EMPTY)
|
|
frameBuffer->SetTransparent(transp);
|
|
|
|
/* TODO: cache or check for same */
|
|
fb_pixel_t * data = getIcon(name, &width, &height);
|
|
|
|
if (transp > CFrameBuffer::TM_EMPTY)
|
|
frameBuffer->SetTransparentDefault();
|
|
|
|
if(data) {
|
|
frameBuffer->blit2FB(data, width, height, posx, posy, 0, 0, transp, unscaled_w, unscaled_h);
|
|
cs_free_uncached(data);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
fb_pixel_t * CPictureViewer::int_getImage(const std::string & name, int *width, int *height, bool GetImage)
|
|
{
|
|
if (access(name.c_str(), R_OK) == -1)
|
|
return NULL;
|
|
|
|
int x = 0, y = 0, load_ret = 0, bpp = 0;
|
|
CFormathandler *fh = NULL;
|
|
unsigned char * buffer = NULL;
|
|
fb_pixel_t * ret = NULL;
|
|
std::string mode_str;
|
|
|
|
if (GetImage)
|
|
mode_str = "getImage";
|
|
else
|
|
mode_str = "getIcon";
|
|
|
|
fh = fh_getsize(name.c_str(), &x, &y, INT_MAX, INT_MAX);
|
|
if (x < 1 || y < 1){
|
|
return NULL;
|
|
}
|
|
|
|
size_t bufsize = x * y * 4;
|
|
if (!checkfreemem(bufsize))
|
|
return NULL;
|
|
|
|
if (fh)
|
|
{
|
|
buffer = (unsigned char *) malloc(bufsize);//x * y * 4
|
|
if (buffer == NULL)
|
|
{
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] mode %s: Error: malloc\n", __func__, __LINE__, mode_str.c_str());
|
|
return NULL;
|
|
}
|
|
#ifdef FBV_SUPPORT_PNG
|
|
if ((name.find(".png") == (name.length() - 4)) && (fh_png_id(name.c_str())))
|
|
load_ret = png_load_ext(name.c_str(), &buffer, &x, &y, &bpp);
|
|
else
|
|
#endif
|
|
load_ret = fh->get_pic(name.c_str (), &buffer, &x, &y);
|
|
dprintf(DEBUG_INFO, "[CPictureViewer] [%s - %d] load_result: %d \n", __func__, __LINE__, load_ret);
|
|
|
|
if (load_ret == FH_ERROR_OK)
|
|
{
|
|
dprintf(DEBUG_INFO, "[CPictureViewer] [%s - %d] mode %s, decoded %s, (Pos: %d %d) ,bpp = %d \n", __func__, __LINE__, mode_str.c_str(), name.c_str(), x, y, bpp);
|
|
// image size error
|
|
if((GetImage) && (*width < 1 || *height < 1)){
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] mode: %s, file: %s (Pos: %d %d, Dim: %d x %d)\n", __func__, __LINE__, mode_str.c_str(), name.c_str(), x, y, *width, *height);
|
|
free(buffer);
|
|
buffer = NULL;
|
|
return NULL;
|
|
}
|
|
// resize only getImage
|
|
if ((GetImage) && (x != *width || y != *height))
|
|
{
|
|
dprintf(DEBUG_INFO, "[CPictureViewer] [%s - %d] resize %s to %d x %d \n", __func__, __LINE__, name.c_str(), *width, *height);
|
|
if (bpp == 4)
|
|
buffer = ResizeA(buffer, x, y, *width, *height);
|
|
else
|
|
buffer = Resize(buffer, x, y, *width, *height, COLOR);
|
|
x = *width;
|
|
y = *height;
|
|
}
|
|
if (bpp == 4)
|
|
ret = (fb_pixel_t *) CFrameBuffer::getInstance()->convertRGBA2FB(buffer, x, y);
|
|
else
|
|
ret = (fb_pixel_t *) CFrameBuffer::getInstance()->convertRGB2FB(buffer, x, y, convertSetupAlpha2Alpha(g_settings.theme.infobar_alpha));
|
|
*width = x;
|
|
*height = y;
|
|
}else{
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] mode %s: Error decoding file %s\n", __func__, __LINE__, mode_str.c_str(), name.c_str());
|
|
free(buffer);
|
|
buffer = NULL;
|
|
return NULL;
|
|
}
|
|
free(buffer);
|
|
buffer = NULL;
|
|
}else
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] mode: %s, file: %s Error: %s, buffer = %p (Pos: %d %d, Dim: %d x %d)\n", __func__, __LINE__, mode_str.c_str(), name.c_str(), strerror(errno), buffer, x, y, *width, *height);
|
|
return ret;
|
|
}
|
|
|
|
fb_pixel_t * CPictureViewer::getImage(const std::string & name, int width, int height)
|
|
{
|
|
return int_getImage(name, &width, &height, true);
|
|
}
|
|
|
|
fb_pixel_t * CPictureViewer::getIcon(const std::string & name, int *width, int *height)
|
|
{
|
|
return int_getImage(name, width, height, false);
|
|
}
|
|
|
|
unsigned char * CPictureViewer::int_Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, ScalingMode type, unsigned char * dst, bool alpha)
|
|
{
|
|
unsigned char * cr;
|
|
if(dst == NULL)
|
|
{
|
|
int ai = ((alpha) ? 4 : 3);
|
|
if (dy <= 1 || dx <= 1 || (dx *ai > INT_MAX / dy))
|
|
return orgin;
|
|
|
|
size_t bufsize = dx * dy * ai;
|
|
if (!checkfreemem(bufsize)){
|
|
return orgin;
|
|
}
|
|
cr = (unsigned char*) malloc(bufsize);
|
|
if(cr == NULL)
|
|
{
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Resize Error: malloc\n", __func__, __LINE__);
|
|
return orgin;
|
|
}
|
|
}else
|
|
cr = dst;
|
|
|
|
if(type == SIMPLE)
|
|
{
|
|
unsigned char *p,*l;
|
|
int i,j,k,ip;
|
|
l=cr;
|
|
|
|
for(j=0;j<dy;j++,l+=dx*3)
|
|
{
|
|
p=orgin+(j*oy/dy*ox*3);
|
|
for(i=0,k=0;i<dx;i++,k+=3)
|
|
{
|
|
ip=i*ox/dx*3;
|
|
memmove(l+k, p+ip, 3);
|
|
}
|
|
}
|
|
}else
|
|
{
|
|
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];
|
|
}
|
|
}
|
|
int sq_tmp = sq ? sq : 1;//avoid division by zero
|
|
p[0]= uint8_t(r/sq_tmp);
|
|
p[1]= uint8_t(g/sq_tmp);
|
|
p[2]= uint8_t(b/sq_tmp);
|
|
p[3]= uint8_t(a/sq_tmp);
|
|
}
|
|
}
|
|
}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];
|
|
}
|
|
}
|
|
int sq_tmp = sq ? sq : 1;//avoid division by zero
|
|
p[0]= uint8_t(r/sq_tmp);
|
|
p[1]= uint8_t(g/sq_tmp);
|
|
p[2]= uint8_t(b/sq_tmp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
free(orgin);
|
|
orgin = NULL;
|
|
return(cr);
|
|
}
|
|
|
|
unsigned char * CPictureViewer::Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, ScalingMode type, unsigned char * dst)
|
|
{
|
|
return int_Resize(orgin, ox, oy, dx, dy, type, dst, false);
|
|
}
|
|
|
|
unsigned char * CPictureViewer::ResizeA(unsigned char *orgin, int ox, int oy, int dx, int dy)
|
|
{
|
|
return int_Resize(orgin, ox, oy, dx, dy, COLOR, NULL, true);
|
|
}
|
|
|
|
static size_t getCachedMemSize(void)
|
|
{
|
|
FILE *procmeminfo = fopen("/proc/meminfo", "r");
|
|
size_t cached = 0;
|
|
if (procmeminfo) {
|
|
char buf[80] = {0}, a[80] = {0};
|
|
size_t v = 0;
|
|
while (fgets(buf, sizeof(buf), procmeminfo)) {
|
|
char unit[10];
|
|
*unit = 0;
|
|
if ((3 == sscanf(buf, "%[^:]: %zu %s", a, &v, unit))
|
|
|| (2 == sscanf(buf, "%[^:]: %zu", a, &v))) {
|
|
if (*unit == 'k')
|
|
v <<= 10;
|
|
if (!strcasecmp(a, "Cached")){
|
|
cached = v;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
fclose(procmeminfo);
|
|
}
|
|
return cached;
|
|
}
|
|
|
|
bool CPictureViewer::checkfreemem(size_t bufsize)
|
|
{
|
|
struct sysinfo info;
|
|
sysinfo( &info );
|
|
size_t cached = getCachedMemSize();
|
|
if(bufsize + sysconf(_SC_PAGESIZE) > (size_t)info.freeram + (size_t)info.freeswap + (size_t)info.bufferram + cached){
|
|
dprintf(DEBUG_NORMAL, "[CPictureViewer] [%s - %d] Error: Out of memory: need %zu > free %zu\n", __func__, __LINE__,bufsize,(size_t)info.freeram + (size_t)info.freeswap + (size_t)info.bufferram + cached);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|