mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-26 15:02:56 +02:00
- 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:
@@ -523,21 +523,26 @@ 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::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;
|
||||
unsigned char * buffer;
|
||||
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);
|
||||
if (fh)
|
||||
{
|
||||
buffer = (unsigned char *) malloc (x * y * 4);
|
||||
buffer = (unsigned char *) malloc(x * y * 4);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
printf ("getImage: Error: malloc\n");
|
||||
printf("%s: Error: malloc\n", mode_str.c_str());
|
||||
return false;
|
||||
}
|
||||
#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);
|
||||
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("%s: decoded %s, %d x %d \n", mode_str.c_str(), name.c_str(), x, y);
|
||||
// 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)
|
||||
buffer = ResizeA(buffer, x, y, width, height);
|
||||
buffer = ResizeA(buffer, x, y, *width, *height);
|
||||
else
|
||||
buffer = Resize(buffer, x, y, width, height, COLOR);
|
||||
x = width;
|
||||
y = height;
|
||||
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));
|
||||
*width = x;
|
||||
*height = y;
|
||||
}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);
|
||||
}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;
|
||||
}
|
||||
|
||||
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;
|
||||
CFormathandler *fh;
|
||||
unsigned char * rgbbuff;
|
||||
fb_pixel_t * fbbuff = NULL;
|
||||
return int_getImage(name, &width, &height, true);
|
||||
}
|
||||
|
||||
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 ("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;
|
||||
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)
|
||||
|
@@ -107,6 +107,7 @@ class CPictureViewer
|
||||
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);
|
||||
fb_pixel_t * int_getImage(const std::string & name, int *width, int *height, bool GetImage);
|
||||
};
|
||||
|
||||
|
||||
|
@@ -23,23 +23,22 @@ int fh_png_id(const char *name)
|
||||
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};
|
||||
|
||||
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;
|
||||
int bit_depth, color_type, interlace_type, number_passes, pass, int_bpp = 3;
|
||||
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(!(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);
|
||||
@@ -51,7 +50,6 @@ int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
|
||||
fclose(fh);
|
||||
return(FH_ERROR_FORMAT);
|
||||
}
|
||||
|
||||
#if (PNG_LIBPNG_VER < 10500)
|
||||
if (setjmp(png_ptr->jmpbuf))
|
||||
#else
|
||||
@@ -62,63 +60,66 @@ int fh_png_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/)
|
||||
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);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
|
||||
if (alpha)
|
||||
{
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
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 */
|
||||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_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
|
||||
{
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
png_set_background(png_ptr, (png_color_16*)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
|
||||
}
|
||||
|
||||
/* 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
|
||||
*/
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
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 */
|
||||
}
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
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),
|
||||
but the data delivered is with alpha channel anyway, so always strip alpha for now
|
||||
*/
|
||||
#if PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR <= 2 && PNG_LIBPNG_VER_RELEASE < 36
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA)
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA)
|
||||
#endif
|
||||
png_set_strip_alpha(png_ptr);
|
||||
|
||||
if (bit_depth < 8)
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
png_set_strip_alpha(png_ptr);
|
||||
if (bit_depth < 8)
|
||||
png_set_packing(png_ptr);
|
||||
}
|
||||
if (bit_depth == 16)
|
||||
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);
|
||||
png_read_update_info(png_ptr,info_ptr);
|
||||
|
||||
if (width * 3 != png_get_rowbytes(png_ptr, info_ptr))
|
||||
unsigned long rowbytes = 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(" 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);
|
||||
return(FH_ERROR_FORMAT);
|
||||
}
|
||||
|
||||
for(pass = 0; pass < number_passes; pass++)
|
||||
for (pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
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_end(png_ptr, info_ptr);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
return int_png_load(name, buffer, xp, yp, bpp, true);
|
||||
}
|
||||
|
||||
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_load(const char *name, unsigned char **buffer, int* xp, int* yp)
|
||||
{
|
||||
return int_png_load(name, buffer, xp, yp, NULL, false);
|
||||
}
|
||||
|
||||
int fh_png_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*wanted_height*/)
|
||||
|
Reference in New Issue
Block a user