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:
gixxpunk
2011-09-27 15:41:31 +00:00
parent dfa7862ab5
commit 55de6ee192
5 changed files with 205 additions and 50 deletions

View File

@@ -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;
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++) {
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);
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;

View File

@@ -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);

View File

@@ -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++)
{
@@ -522,37 +523,51 @@ bool CPictureViewer::DisplayImage (const std::string & name, int posx, int posy,
return false;
}
fb_pixel_t * CPictureViewer::getImage (const std::string & name, int width, int height)
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) {
fh = fh_getsize(name.c_str(), &x, &y, INT_MAX, INT_MAX);
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) {
printf("getImage: decoded %s, %d x %d \n", name.c_str (), x, y);
#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);
buffer = Resize(buffer, x, y, width, height, COLOR);
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;
}
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 ());
}
}
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 ("getImage: Error decoding file %s\n", name.c_str ());
free(buffer);
} else
printf("Error open file %s\n", name.c_str ());
}else
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)
if(cr == NULL)
{
printf("Error: malloc\n");
printf("Resize Error: malloc\n");
return(orgin);
}
} else
}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,24 +662,57 @@ unsigned char * CPictureViewer::Resize(unsigned char *orgin, int ox, int oy, int
if(xb_v[i]>=ox)
xb_v[i]=ox-1;
}
for(j=0;j<dy;j++)
if (alpha)
{
ya= j*oy/dy;
yb= (j+1)*oy/dy; if(yb>=oy) yb=oy-1;
for(i=0;i<dx;i++,p+=3)
for(j=0;j<dy;j++)
{
for(l=ya,r=0,g=0,b=0,sq=0;l<=yb;l++)
ya= j*oy/dy;
yb= (j+1)*oy/dy; if(yb>=oy) yb=oy-1;
for(i=0;i<dx;i++,p+=4)
{
q=orgin+((l*ox+xa_v[i])*3);
for(k=xa_v[i];k<=xb_v[i];k++,q+=3,sq++)
for(l=ya,r=0,g=0,b=0,a=0,sq=0;l<=yb;l++)
{
r+=q[0]; g+=q[1]; b+=q[2];
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;
}
p[0]=r/sq; p[1]=g/sq; p[2]=b/sq;
}
}
}
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);
}

View File

@@ -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);
};

View File

@@ -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;