mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-29 16:31:05 +02:00
add support for 24bit PNGs with alpha-channel
- modify resize function
If you encounter problems please report here including a log: http://www.dbox2world.net/board293-coolstream-hd1/board314-coolstream-development/10561-transparente-senderlogos/?s=d3381092abb5a81271ebfa0c4219f73f0ba7b8ca
THX micha_bbg!
git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@1715 e54a6e83-5905-42d5-8d5c-058d10e6a962
Origin commit data
------------------
Commit: d8f8a99d86
Author: gixxpunk <thomas.harfmann@gmail.com>
Date: 2011-09-27 (Tue, 27 Sep 2011)
Origin message was:
------------------
- add support for 24bit PNGs with alpha-channel
- modify resize function
If you encounter problems please report here including a log: http://www.dbox2world.net/board293-coolstream-hd1/board314-coolstream-development/10561-transparente-senderlogos/?s=d3381092abb5a81271ebfa0c4219f73f0ba7b8ca
THX micha_bbg!
git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@1715 e54a6e83-5905-42d5-8d5c-058d10e6a962
This commit is contained in:
@@ -1618,32 +1618,49 @@ void CFrameBuffer::Unlock()
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void * CFrameBuffer::convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp)
|
||||
void * CFrameBuffer::int_convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp, bool alpha)
|
||||
{
|
||||
unsigned long i;
|
||||
unsigned int *fbbuff;
|
||||
unsigned long count = x * y;
|
||||
|
||||
//fbbuff = (unsigned int *) malloc(count * sizeof(unsigned int));
|
||||
fbbuff = (unsigned int *) cs_malloc_uncached(count * sizeof(unsigned int));
|
||||
if(fbbuff == NULL)
|
||||
{
|
||||
printf("convertRGB2FB: Error: malloc\n");
|
||||
printf("convertRGB2FB%s: Error: cs_malloc_uncached\n", ((alpha) ? " (Alpha)" : ""));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < count ; i++) {
|
||||
if (alpha)
|
||||
{
|
||||
for(i = 0; i < count ; i++)
|
||||
fbbuff[i] = ((rgbbuff[i*4+3] << 24) & 0xFF000000) |
|
||||
((rgbbuff[i*4] << 16) & 0x00FF0000) |
|
||||
((rgbbuff[i*4+1] << 8) & 0x0000FF00) |
|
||||
((rgbbuff[i*4+2]) & 0x000000FF);
|
||||
}else
|
||||
{
|
||||
for(i = 0; i < count ; i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
return (void *) fbbuff;
|
||||
}
|
||||
|
||||
void * CFrameBuffer::convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp)
|
||||
{
|
||||
return int_convertRGB2FB(rgbbuff, x, y, transp, false);
|
||||
}
|
||||
|
||||
void * CFrameBuffer::convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y)
|
||||
{
|
||||
return int_convertRGB2FB(rgbbuff, x, y, 0, true);
|
||||
}
|
||||
|
||||
void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
|
||||
{
|
||||
int xc, yc;
|
||||
|
@@ -114,6 +114,8 @@ class CFrameBuffer
|
||||
bool locked;
|
||||
std::map<std::string, rawIcon> icon_cache;
|
||||
int cache_size;
|
||||
void * int_convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp, bool alpha);
|
||||
|
||||
public:
|
||||
fb_pixel_t realcolor[256];
|
||||
|
||||
@@ -213,6 +215,7 @@ class CFrameBuffer
|
||||
inline void waitForIdle(void) {};
|
||||
#endif
|
||||
void* convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp = 0xFF);
|
||||
void* convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y);
|
||||
void displayRGB(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, bool clearfb = true, int transp = 0xFF);
|
||||
void blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp = 0, uint32_t yp = 0, bool transp = false);
|
||||
bool blitToPrimary(unsigned int * data, int dx, int dy, int sw, int sh);
|
||||
|
@@ -25,6 +25,7 @@ extern int fh_jpeg_id (const char *);
|
||||
#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
|
||||
@@ -450,8 +451,8 @@ bool CPictureViewer::GetLogoName(uint64_t channel_id, std::string ChannelName, s
|
||||
sprintf(strChanId, "%llx", channel_id & 0xFFFFFFFFFFFFULL);
|
||||
/* first the channel-id, then the channelname */
|
||||
std::string strLogoName[2] = { (std::string)strChanId, ChannelName };
|
||||
/* first jpg, then gif */
|
||||
std::string strLogoExt[3] = { ".jpg", ".gif" , ".png" };
|
||||
/* first png, then jpg, then gif */
|
||||
std::string strLogoExt[3] = { ".png", ".jpg" , ".gif" };
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
@@ -524,35 +525,49 @@ bool CPictureViewer::DisplayImage (const std::string & name, int posx, int posy,
|
||||
|
||||
fb_pixel_t * CPictureViewer::getImage(const std::string & name, int width, int height)
|
||||
{
|
||||
int x, y;
|
||||
int x, y, bpp = 0;
|
||||
CFormathandler *fh;
|
||||
unsigned char * buffer;
|
||||
fb_pixel_t * ret = NULL;
|
||||
int load_ret;
|
||||
|
||||
fh = fh_getsize(name.c_str(), &x, &y, INT_MAX, INT_MAX);
|
||||
if (fh) {
|
||||
|
||||
buffer = (unsigned char *) malloc (x * y * 3);
|
||||
if (buffer == NULL) {
|
||||
if (fh)
|
||||
{
|
||||
buffer = (unsigned char *) malloc (x * y * 4);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
printf ("getImage: Error: malloc\n");
|
||||
return false;
|
||||
}
|
||||
if (fh->get_pic (name.c_str (), &buffer, &x, &y) == FH_ERROR_OK) {
|
||||
#ifdef FBV_SUPPORT_PNG
|
||||
if (name.find(".png")) // FIXME
|
||||
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);
|
||||
if (load_ret == FH_ERROR_OK)
|
||||
{
|
||||
printf("getImage: decoded %s, %d x %d \n", name.c_str(), x, y);
|
||||
if(x != width || y != height)
|
||||
{
|
||||
printf("getImage: resize %s to %d x %d \n", 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.infobar_alpha));
|
||||
} else {
|
||||
printf ("Error decoding file %s\n", name.c_str ());
|
||||
}
|
||||
}else
|
||||
printf ("getImage: Error decoding file %s\n", name.c_str ());
|
||||
free(buffer);
|
||||
}else
|
||||
printf("Error open file %s\n", name.c_str ());
|
||||
printf("getImage: Error open file %s\n", name.c_str ());
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -599,21 +614,23 @@ fb_pixel_t * CPictureViewer::getIcon (const std::string & name, int *width, int
|
||||
return fbbuff;
|
||||
}
|
||||
|
||||
unsigned char * CPictureViewer::Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, ScalingMode type, unsigned char * dst)
|
||||
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) {
|
||||
cr = (unsigned char*) malloc(dx*dy*3);
|
||||
if(dst == NULL)
|
||||
{
|
||||
cr = (unsigned char*) malloc(dx * dy * ((alpha) ? 4 : 3));
|
||||
|
||||
if(cr == NULL)
|
||||
{
|
||||
printf("Error: malloc\n");
|
||||
printf("Resize Error: malloc\n");
|
||||
return(orgin);
|
||||
}
|
||||
}else
|
||||
cr = dst;
|
||||
|
||||
if(type == SIMPLE) {
|
||||
if(type == SIMPLE)
|
||||
{
|
||||
unsigned char *p,*l;
|
||||
int i,j,k,ip;
|
||||
l=cr;
|
||||
@@ -627,10 +644,11 @@ unsigned char * CPictureViewer::Resize(unsigned char *orgin, int ox, int oy, int
|
||||
memmove(l+k, p+ip, 3);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}else
|
||||
{
|
||||
unsigned char *p,*q;
|
||||
int i,j,k,l,ya,yb;
|
||||
int sq,r,g,b;
|
||||
int sq,r,g,b,a;
|
||||
|
||||
p=cr;
|
||||
|
||||
@@ -644,6 +662,28 @@ unsigned char * CPictureViewer::Resize(unsigned char *orgin, int ox, int oy, int
|
||||
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;
|
||||
@@ -662,6 +702,17 @@ unsigned char * CPictureViewer::Resize(unsigned char *orgin, int ox, int oy, int
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(orgin);
|
||||
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);
|
||||
}
|
||||
|
@@ -69,6 +69,7 @@ class CPictureViewer
|
||||
fb_pixel_t * getIcon (const std::string & name, int *width, int *height);
|
||||
void getSize(const char *name, int* width, int *height);
|
||||
unsigned char * Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, ScalingMode type, unsigned char * dst = NULL);
|
||||
unsigned char * ResizeA(unsigned char *orgin, int ox, int oy, int dx, int dy);
|
||||
|
||||
private:
|
||||
CFormathandler *fh_root;
|
||||
@@ -105,6 +106,7 @@ class CPictureViewer
|
||||
CFormathandler * fh_getsize(const char *name,int *x,int *y, int width_wanted, int height_wanted);
|
||||
void init_handlers(void);
|
||||
void add_format(int (*picsize)(const char *,int *,int*,int,int),int (*picread)(const char *,unsigned char **,int*,int*), int (*id)(const char*));
|
||||
unsigned char * int_Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, ScalingMode type, unsigned char * dst, bool alpha);
|
||||
};
|
||||
|
||||
|
||||
|
@@ -126,6 +126,88 @@ int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
|
||||
return(FH_ERROR_OK);
|
||||
}
|
||||
|
||||
int png_load_ext(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_uint_32 width, height;
|
||||
unsigned int i;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
int number_passes,pass;
|
||||
png_byte * fbptr;
|
||||
FILE * fh;
|
||||
|
||||
if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE);
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
|
||||
if(png_ptr == NULL) {
|
||||
fclose(fh);
|
||||
return(FH_ERROR_FORMAT);
|
||||
}
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if(info_ptr == NULL)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
|
||||
fclose(fh);
|
||||
return(FH_ERROR_FORMAT);
|
||||
}
|
||||
|
||||
#if (PNG_LIBPNG_VER < 10500)
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
#else
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
#endif
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
fclose(fh);
|
||||
return(FH_ERROR_FORMAT);
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fh);
|
||||
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
|
||||
|
||||
*bpp = png_get_channels(png_ptr, info_ptr);
|
||||
if ((*bpp != 4) || !(color_type & PNG_COLOR_MASK_ALPHA))
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
fclose(fh);
|
||||
return fh_png_load(name, buffer, xp, yp);
|
||||
}
|
||||
|
||||
printf("##### [png.cpp]: Image: %s, bit_depth: %d, bpp: %d\n", name, bit_depth, *bpp);
|
||||
// png_set_swap_alpha(png_ptr);
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
number_passes = png_set_interlace_handling(png_ptr);
|
||||
png_read_update_info(png_ptr,info_ptr);
|
||||
unsigned long rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
if (width * 4 != rowbytes)
|
||||
{
|
||||
printf("[png.cpp]: Error processing %s - please report (including image).\n", name);
|
||||
printf(" width: %lu rowbytes: %lu\n", (unsigned long)width, (unsigned long)rowbytes);
|
||||
fclose(fh);
|
||||
return(FH_ERROR_FORMAT);
|
||||
}
|
||||
|
||||
for(pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
fbptr = (png_byte *)(*buffer);
|
||||
for (i = 0; i < height; i++, fbptr += width * 4)
|
||||
png_read_row(png_ptr, fbptr, NULL);
|
||||
}
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
fclose(fh);
|
||||
|
||||
return(FH_ERROR_OK);
|
||||
}
|
||||
|
||||
int fh_png_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*wanted_height*/)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
|
Reference in New Issue
Block a user