- add support for 24bit PNGs with alpha-channel in function CPictureViewer::getIcon

- code optimized pictureviewer.cpp (CPictureViewer::getIcon / CPictureViewer::getImage)
- code optimized png.cpp (fh_png_load / png_load_ext)


git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@1753 e54a6e83-5905-42d5-8d5c-058d10e6a962
This commit is contained in:
micha-bbg
2011-10-08 02:55:04 +00:00
parent 8041efac14
commit ccb9fceec7
3 changed files with 82 additions and 177 deletions

View File

@@ -523,21 +523,26 @@ bool CPictureViewer::DisplayImage (const std::string & name, int posx, int posy,
return false; return false;
} }
fb_pixel_t * CPictureViewer::getImage(const std::string & name, int width, int height) fb_pixel_t * CPictureViewer::int_getImage(const std::string & name, int *width, int *height, bool GetImage)
{ {
int x, y, bpp = 0; int x, y, load_ret, bpp = 0;
CFormathandler *fh; CFormathandler *fh;
unsigned char * buffer; unsigned char * buffer;
fb_pixel_t * ret = NULL; fb_pixel_t * ret = NULL;
int load_ret; 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); fh = fh_getsize(name.c_str(), &x, &y, INT_MAX, INT_MAX);
if (fh) if (fh)
{ {
buffer = (unsigned char *) malloc (x * y * 4); buffer = (unsigned char *) malloc(x * y * 4);
if (buffer == NULL) if (buffer == NULL)
{ {
printf ("getImage: Error: malloc\n"); printf("%s: Error: malloc\n", mode_str.c_str());
return false; return false;
} }
#ifdef FBV_SUPPORT_PNG #ifdef FBV_SUPPORT_PNG
@@ -548,70 +553,40 @@ fb_pixel_t * CPictureViewer::getImage(const std::string & name, int width, int h
load_ret = fh->get_pic(name.c_str (), &buffer, &x, &y); load_ret = fh->get_pic(name.c_str (), &buffer, &x, &y);
if (load_ret == FH_ERROR_OK) if (load_ret == FH_ERROR_OK)
{ {
printf("getImage: decoded %s, %d x %d \n", name.c_str(), x, y); printf("%s: decoded %s, %d x %d \n", mode_str.c_str(), name.c_str(), x, y);
if(x != width || y != height) // resize only getImage
if ((GetImage) && (x != *width || y != *height))
{ {
printf("getImage: resize %s to %d x %d \n", name.c_str(), width, height); printf("%s: resize %s to %d x %d \n", mode_str.c_str(), name.c_str(), *width, *height);
if (bpp == 4) if (bpp == 4)
buffer = ResizeA(buffer, x, y, width, height); buffer = ResizeA(buffer, x, y, *width, *height);
else else
buffer = Resize(buffer, x, y, width, height, COLOR); buffer = Resize(buffer, x, y, *width, *height, COLOR);
x = width; x = *width;
y = height; y = *height;
} }
if (bpp == 4) if (bpp == 4)
ret = (fb_pixel_t *) CFrameBuffer::getInstance()->convertRGBA2FB(buffer, x, y); ret = (fb_pixel_t *) CFrameBuffer::getInstance()->convertRGBA2FB(buffer, x, y);
else else
ret = (fb_pixel_t *) CFrameBuffer::getInstance()->convertRGB2FB(buffer, x, y, convertSetupAlpha2Alpha(g_settings.infobar_alpha)); ret = (fb_pixel_t *) CFrameBuffer::getInstance()->convertRGB2FB(buffer, x, y, convertSetupAlpha2Alpha(g_settings.infobar_alpha));
*width = x;
*height = y;
}else }else
printf ("getImage: Error decoding file %s\n", name.c_str ()); printf("%s: Error decoding file %s\n", mode_str.c_str(), name.c_str());
free(buffer); free(buffer);
}else }else
printf("getImage: Error open file %s\n", name.c_str ()); printf("%s: Error open file %s\n", mode_str.c_str(), name.c_str());
return ret; return ret;
} }
fb_pixel_t * CPictureViewer::getIcon (const std::string & name, int *width, int *height) fb_pixel_t * CPictureViewer::getImage(const std::string & name, int width, int height)
{ {
int x, y; return int_getImage(name, &width, &height, true);
CFormathandler *fh; }
unsigned char * rgbbuff;
fb_pixel_t * fbbuff = NULL;
fh = fh_getsize (name.c_str (), &x, &y, INT_MAX, INT_MAX); fb_pixel_t * CPictureViewer::getIcon(const std::string & name, int *width, int *height)
if (!fh) { {
return NULL; return int_getImage(name, width, height, false);
}
rgbbuff = (unsigned char *) malloc (x * y * 3);
if (rgbbuff == NULL) {
printf ("getIcon: 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));
fbbuff = (fb_pixel_t *) cs_malloc_uncached(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;
} }
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 * CPictureViewer::int_Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, ScalingMode type, unsigned char * dst, bool alpha)

View File

@@ -107,6 +107,7 @@ class CPictureViewer
void init_handlers(void); 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*)); 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); unsigned char * int_Resize(unsigned char *orgin, int ox, int oy, int dx, int dy, ScalingMode type, unsigned char * dst, bool alpha);
fb_pixel_t * int_getImage(const std::string & name, int *width, int *height, bool GetImage);
}; };

View File

@@ -23,23 +23,22 @@ int fh_png_id(const char *name)
return(0); return(0);
} }
int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp);
int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/) int int_png_load(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp, bool alpha)
{ {
static const png_color_16 my_background = {0, 0, 0, 0, 0}; static const png_color_16 my_background = {0, 0, 0, 0, 0};
png_structp png_ptr; png_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
png_uint_32 width, height; png_uint_32 width, height;
unsigned int i; unsigned int i;
int bit_depth, color_type, interlace_type; int bit_depth, color_type, interlace_type, number_passes, pass, int_bpp = 3;
int number_passes,pass;
png_byte * fbptr; png_byte * fbptr;
FILE * fh; FILE * fh;
if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE); if(!(fh=fopen(name,"rb")))
return(FH_ERROR_FILE);
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(png_ptr == NULL) { if(png_ptr == NULL) {
fclose(fh); fclose(fh);
return(FH_ERROR_FORMAT); return(FH_ERROR_FORMAT);
@@ -51,7 +50,6 @@ int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
fclose(fh); fclose(fh);
return(FH_ERROR_FORMAT); return(FH_ERROR_FORMAT);
} }
#if (PNG_LIBPNG_VER < 10500) #if (PNG_LIBPNG_VER < 10500)
if (setjmp(png_ptr->jmpbuf)) if (setjmp(png_ptr->jmpbuf))
#else #else
@@ -62,26 +60,39 @@ int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
fclose(fh); fclose(fh);
return(FH_ERROR_FORMAT); return(FH_ERROR_FORMAT);
} }
png_init_io(png_ptr,fh); png_init_io(png_ptr,fh);
png_read_info(png_ptr, info_ptr); png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
if (alpha)
{
*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);
}
// 24bit PNGs with alpha-channel
int_bpp = 4;
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);
}else // All other PNGs
{
if (color_type == PNG_COLOR_TYPE_PALETTE) if (color_type == PNG_COLOR_TYPE_PALETTE)
{ {
png_set_palette_to_rgb(png_ptr); png_set_palette_to_rgb(png_ptr);
png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
/* other possibility for png_set_background: use png_get_bKGD */ /* other possibility for png_set_background: use png_get_bKGD */
} }
if (color_type == PNG_COLOR_TYPE_GRAY || if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA) color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{ {
png_set_gray_to_rgb(png_ptr); png_set_gray_to_rgb(png_ptr);
png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
} }
printf("##### [png.cpp]: Image: %s, bit_depth: %d\n", name, bit_depth);
/* this test does not trigger for 8bit-paletted PNGs with newer libpng (1.2.36 at least), /* this test does not trigger for 8bit-paletted PNGs with newer libpng (1.2.36 at least),
but the data delivered is with alpha channel anyway, so always strip alpha for now but the data delivered is with alpha channel anyway, so always strip alpha for now
*/ */
@@ -89,37 +100,27 @@ int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
if (color_type & PNG_COLOR_MASK_ALPHA) if (color_type & PNG_COLOR_MASK_ALPHA)
#endif #endif
png_set_strip_alpha(png_ptr); png_set_strip_alpha(png_ptr);
if (bit_depth < 8) if (bit_depth < 8)
png_set_packing(png_ptr); png_set_packing(png_ptr);
}
if (bit_depth == 16) if (bit_depth == 16)
png_set_strip_16(png_ptr); png_set_strip_16(png_ptr);
/* on Intel PC ?:
if (bit_depth == 16)
png_set_swap(png_ptr);
*/
number_passes = png_set_interlace_handling(png_ptr); number_passes = png_set_interlace_handling(png_ptr);
png_read_update_info(png_ptr,info_ptr); png_read_update_info(png_ptr,info_ptr);
unsigned long rowbytes = png_get_rowbytes(png_ptr, info_ptr);
if (width * 3 != png_get_rowbytes(png_ptr, info_ptr)) if (width * int_bpp != rowbytes)
{ {
printf("[png.cpp]: Error processing %s - please report (including image).\n", name); printf("[png.cpp]: Error processing %s - please report (including image).\n", name);
printf(" width: %lu rowbytes: %lu\n", (unsigned long)width, (unsigned long)png_get_rowbytes(png_ptr, info_ptr)); printf(" width: %lu rowbytes: %lu\n", (unsigned long)width, (unsigned long)rowbytes);
fclose(fh); fclose(fh);
return(FH_ERROR_FORMAT); return(FH_ERROR_FORMAT);
} }
for (pass = 0; pass < number_passes; pass++)
for(pass = 0; pass < number_passes; pass++)
{ {
fbptr = (png_byte *)(*buffer); fbptr = (png_byte *)(*buffer);
for (i = 0; i < height; i++, fbptr += width * 3) for (i = 0; i < height; i++, fbptr += width * int_bpp)
{
png_read_row(png_ptr, fbptr, NULL); png_read_row(png_ptr, fbptr, NULL);
} }
}
png_read_end(png_ptr, info_ptr); png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
fclose(fh); fclose(fh);
@@ -128,84 +129,12 @@ int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
int png_load_ext(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp) int png_load_ext(const char *name, unsigned char **buffer, int* xp, int* yp, int* bpp)
{ {
png_structp png_ptr; return int_png_load(name, buffer, xp, yp, bpp, true);
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); int fh_png_load(const char *name, unsigned char **buffer, int* xp, int* yp)
{
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); return int_png_load(name, buffer, xp, yp, NULL, false);
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*/) int fh_png_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*wanted_height*/)