Hi Spezialisten.
Ich brauche mal wieder Hilfe. Habe einen C-Schnippsel im Netz gefunden und für mich angepasst um PNG Dateien auf dem Framebuffer auszugeben.
Leider wird der Speicher im nachhinein nicht mehr freigegeben, so das nach einigen Grafiken der Speicher irgendwann mal mau wird
Leider steige ich da mit meinen Kenntnissen nicht so ganz dahinter welche Variable separat geleert werden muss.
Vielleicht kann mir da jemand mit mehr Ahnung nen Tipp geben.
Hier der Code:
[spoiler]
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <stdint.h>
#include <png.h>
#include <sys/types.h>
#include <fcntl.h>
/************ Function implementation ********************/
int png2fb(const char *inputFile, void *fbmem, unsigned int fb_width, unsigned int fb_height, unsigned int fb_depth)
{
static unsigned int color;
FILE*fp;
uint8_t header[8];
int is_png;
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 iwidth, iheight;
png_bytepp row_pointers;
int bit_depth, color_type;
int i,ii,j;
uint16_t bg;
uint16_t**buf;
int kh,kw;
uint32_t red,green,blue;
buf=(uint16_t**)malloc(fb_height*sizeof(uint16_t*));
if(!buf)
{
perror("Memory");
return 0;
}
// open png file
fp=fopen(inputFile, "r");
if(!fp)
{
fclose(fp);
perror("Source PNG:");
return 0;
}
// header lesen
fread(header, 1, 8, fp);
is_png=!png_sig_cmp(header, 0, 8);
if (!is_png)
{
// fprintf(stderr,"Invalid PNG\n");
fclose(fp);
return 0;
}
png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,(png_voidp)NULL,NULL,NULL);
if (!png_ptr)
{
// fprintf(stderr,"Error creating png read struct");
fclose(fp);
return 0;
}
info_ptr=png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr,(png_infopp)NULL, (png_infopp)NULL);
// fprintf(stderr,"Error creating png info struct");
fclose(fp);
return 0;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
// fprintf(stderr,"libpng setjmp error");
png_destroy_read_struct(&png_ptr, &info_ptr,NULL);
fclose(fp);
return 0;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
png_read_info (png_ptr, info_ptr); /* read all PNG info up to image data */
png_get_IHDR (png_ptr, info_ptr, &iwidth, &iheight, &bit_depth, &color_type, NULL, NULL, NULL);
//fprintf(stderr,"PNG image %s width %d height %d color type %d fb_width %d fb_height %d screensize%d\n",inputFile, (int)iwidth, (int)iheight, color_type, fb_width, fb_height, fb_width*fb_height*fb_depth/8);
if(color_type==PNG_COLOR_TYPE_PALETTE)
{
png_set_palette_to_rgb(png_ptr);
}
if(color_type==PNG_COLOR_TYPE_GRAY||color_type==PNG_COLOR_TYPE_GRAY_ALPHA)
{
if(bit_depth<8)
png_set_expand_gray_1_2_4_to_8(png_ptr);
png_set_gray_to_rgb(png_ptr);
}
if(bit_depth<8)
{
png_set_packing(png_ptr);
}
if(color_type & PNG_COLOR_MASK_ALPHA)
{
png_set_strip_alpha(png_ptr);
}
png_read_update_info(png_ptr, info_ptr);
row_pointers=png_malloc(png_ptr, iheight*sizeof(png_bytep));
if(!row_pointers)
{
perror("PNG memory");
fclose(fp);
return 0;
}
for (i=0; i<iheight; i++)
row_pointers[i]=NULL; /* security precaution */
for (i=0; i<iheight;i++)
row_pointers[i]=png_malloc(png_ptr,iwidth*8);//pixel size
png_set_rows(png_ptr, info_ptr, row_pointers);
png_read_image(png_ptr, row_pointers);
blue=(color<<24)>>27;
green=(color<<16)>>26;
red=(color<<8)>>27;
bg=blue|green<<5|red<<11;
for(i=0;i<fb_height;i++)
{
buf[i]=(uint16_t*)malloc(fb_width*sizeof(uint16_t));
if(!buf[i])
{
perror("Memory");
fclose(fp);
return 0;
}
if((iheight<fb_height)||(iwidth<fb_width))
{
for(ii=0;ii<fb_width;ii++)
buf[i][ii]=bg;
}
}
kh=abs(fb_height-iheight)/2;
kw=abs(fb_width-iwidth)/2;
if(iheight<fb_height)
{
for(i=kh;i<kh+iheight;i++)
{
if(iwidth>=fb_width)
{
for(ii=0,j=kw*3;ii<fb_width;ii++)
{
buf[i][ii]=((((row_pointers[i-kh][j])>>3)<<11)|(((row_pointers[i-kh][j+1])>>2)<<5)|((row_pointers[i-kh][j+2])>>3));
j+=3;
}
}
else {
for(ii=kw,j=0;ii<(kw+iwidth);ii++)
{
buf[i][ii]=((((row_pointers[i-kh][j])>>3)<<11)|(((row_pointers[i-kh][j+1])>>2)<<5)|((row_pointers[i-kh][j+2])>>3));
j+=3;
}
}
}
}
else {
for(i=0;i<fb_height;i++)
{
if(iwidth>=fb_width)
{
for(ii=0,j=kw*3;ii<fb_width;ii++)
{
buf[i][ii]=((((row_pointers[i+kh][j])>>3)<<11)|(((row_pointers[i+kh][j+1])>>2)<<5)|((row_pointers[i+kh][j+2])>>3));
j+=3;
}
}
else {
for(ii=kw,j=0;ii<(kw+iwidth);ii++)
{
buf[i][ii]=((((row_pointers[i+kh][j])>>3)<<11)|(((row_pointers[i+kh][j+1])>>2)<<5)|((row_pointers[i+kh][j+2])>>3));
j+=3;
}
}
}
}
// buffer in fb schreiben
for(i=0;i<fb_height;i++)
{
//printf("line %d size %d\n", i, i*width*(fb_depth/8));
memcpy(fbmem + i * fb_width*2, buf[i], 2*fb_width);
}
// destroy png
png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL);
fclose(fp);
for(i=0;i<fb_height;i++)
{
free(buf[i]);
}
free(buf);
return 1;
}
Display More
/spoiler]
Danke im vorraus