source: titan/titan/fb.h @ 15345

Last change on this file since 15345 was 15344, checked in by nit, 12 years ago

fix memleak

File size: 10.2 KB
Line 
1#ifndef FB_H
2#define FB_H
3
4struct fb* getfb(char *name)
5{
6        debug(1000, "in");
7        struct fb *node = fb;
8
9        while(node != NULL)
10        {
11                if(strstr(node->name, name) != NULL)
12                {
13                        debug(1000, "out");
14                        return node;
15                }
16
17                node = node->next;
18        }
19        debug(100, "framebuffer not found (%s)", name);
20        return NULL;
21}
22
23long getfbsize(int dev)
24{
25        debug(1000, "in");
26        struct fb* node = fb;
27        unsigned long fbmemcount = 0;
28        struct fb_fix_screeninfo fix_screeninfo;
29
30        if(fb == NULL)
31        {
32                debug(1000, "out -> NULL dedect");
33                return 0;
34        }
35
36#ifndef NOFB
37        if(ioctl(fb->fd, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1)
38        {
39                perr("ioctl FBIOGET_FSCREENINFO failed");
40                return 0;
41        }
42#else
43        fix_screeninfo.smem_len = 16*1024*1024;
44#endif
45
46        while(node != NULL)
47        {
48                if(node->dev == dev)
49                        fbmemcount = fbmemcount + node->varfbsize;
50                node = node->next;
51        }
52
53        debug(1000, "out");
54        return fix_screeninfo.smem_len - fbmemcount;
55}
56
57struct fb* addfb(char *fbname, int dev, int width, int height, int colbytes, int fd, unsigned char* mmapfb, unsigned long fixfbsize)
58{
59        debug(1000, "in");
60        struct fb *newnode = NULL, *node = fb;
61        char *name = NULL;
62        long ret = 0;
63
64        name = ostrcat(fbname, "", 0, 0);
65        if(name == NULL)
66        {
67                err("no memory");
68                return NULL;
69        }
70
71        newnode = (struct fb*)malloc(sizeof(struct fb));       
72        if(newnode == NULL)
73        {
74                err("no memory");
75                free(name);
76                return NULL;
77        }
78
79        memset(newnode, 0, sizeof(struct fb));
80        newnode->name = name;
81        newnode->dev = dev;
82        newnode->width = width;
83        newnode->height = height;
84        newnode->colbytes = colbytes;
85        newnode->pitch = newnode->width * newnode->colbytes;
86        newnode->fb = mmapfb;
87        newnode->fblong = (unsigned long*)newnode->fb;
88        newnode->fd = fd;
89        newnode->fixfbsize = fixfbsize;
90       
91        if(ostrcmp(name, FB) == 0)
92                setfbvarsize(newnode);
93        else if(ostrcmp(name, FB1) == 0)
94                newnode->varfbsize = 720 * 576 * newnode->colbytes;
95        else
96                newnode->varfbsize = width * height * newnode->colbytes;
97       
98        if(node != NULL)
99        {
100                while(node->next != NULL)
101                        node = node->next;
102                node->next = newnode;
103        }
104        else
105                fb = newnode;
106               
107        /*eigener Buffer zB fuer LCD*/
108        if(dev == 999)
109                return newnode;
110
111        ret = getfbsize(dev);
112        if(ret < 0)
113        {
114                err("framebuffermem (%s) to small, needed = %ld", name, ret * -1);
115                free(name);
116                free(newnode);
117                if(newnode == fb) fb = NULL;
118                return NULL;
119        }
120
121        debug(100, "fbname=%s, fbwidth=%d, fbheight=%d, fbcol=%d, fbsize=%ld", newnode->name, newnode->width, newnode->height, newnode->colbytes, newnode->varfbsize);
122        debug(1000, "out");
123        return newnode;
124}
125
126void fb2png_thread()
127{
128        while (writeFBfile.buf1 != NULL || writeFBfile.buf2 != NULL) {
129                if(writeFBfile.buf1 != NULL) {
130                        writeFBfile.ActBuf = writeFBfile.buf1;
131                        fb2png(writeFBfile.buf1, 320, 240, "/tmp/titanlcd.png");
132                        free(writeFBfile.buf1); writeFBfile.buf1 = NULL;
133                        if(writeFBfile.buf2 != NULL)
134                                usleep(500000);
135                }
136                if(writeFBfile.buf2 != NULL) {
137                        writeFBfile.ActBuf = writeFBfile.buf2;
138                        fb2png(writeFBfile.buf2, 320, 240, "/tmp/titanlcd.png");
139                        free(writeFBfile.buf2); writeFBfile.buf2 = NULL;
140                        if(writeFBfile.buf1 != NULL)
141                                usleep(500000);
142                }
143        }
144        writeFBfile.ActBuf = NULL;
145}
146
147void delfb(char *name)
148{
149        debug(1000, "in");
150        struct fb *node = fb, *prev = fb;
151
152        while(node != NULL)
153        {
154                if(ostrcmp(node->name, name) == 0)
155                {
156                        if(node == fb)
157                                fb = node->next;
158                        else
159                                prev->next = node->next;
160
161                        free(node->name);
162                        node->name = NULL;
163
164                        free(node);
165                        node = NULL;
166                        break;
167                }
168
169                prev = node;
170                node = node->next;
171        }
172        debug(1000, "out");
173}
174
175void freefb()
176{
177        debug(1000, "in");
178        struct fb *node = fb, *prev = fb;
179
180        while(node != NULL)
181        {
182                prev = node;
183                node = node->next;
184                if(prev != NULL)
185                        delfb(prev->name);
186        }
187        debug(1000, "out");
188}
189
190struct fb* openfb(char *fbdev, int devnr)
191{
192        debug(1000, "in");
193        int fd = -1;
194        unsigned char *mmapfb = NULL;
195        struct fb_var_screeninfo var_screeninfo;
196        struct fb_fix_screeninfo fix_screeninfo;
197        struct fb* node = NULL;
198
199        if(fbdev == NULL)
200        {
201                err("failed to find fbdev in config file");
202                return NULL;
203        }
204
205#ifndef NOFB
206        fd = open(fbdev, O_RDWR);
207        if(fd == -1)
208        {
209                perr("failed to open %s", fbdev);
210                return NULL;
211        }
212        closeonexec(fd);
213
214        if(ioctl(fd, FBIOGET_VSCREENINFO, &var_screeninfo) == -1)
215        {
216                perr("ioctl FBIOGET_VSCREENINFO failed");
217                close(fd);
218                return NULL;
219        }
220
221        if(ioctl(fd, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1)
222        {
223                perr("ioctl FBIOGET_FSCREENINFO failed");
224                close(fd);
225                return NULL;
226        }
227
228        if(!(mmapfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)))
229        {
230                perr("mmap framebuffer");
231                close(fd);
232                return NULL;
233        }
234
235        if(devnr == 0)
236                node = addfb(FB, devnr, var_screeninfo.xres, var_screeninfo.yres, var_screeninfo.bits_per_pixel / 8, fd, mmapfb, fix_screeninfo.smem_len);
237        if(devnr == 1)
238                node = addfb(FB1, devnr, var_screeninfo.xres, var_screeninfo.yres, var_screeninfo.bits_per_pixel / 8, fd, mmapfb, fix_screeninfo.smem_len);
239
240#else
241
242        mmapfb = malloc(16 * 1024 * 1024);
243        if(devnr == 0)
244                node = addfb(FB, devnr, getconfigint("skinfbwidth", NULL), getconfigint("skinfbheight", NULL), 4, -1, mmapfb, 16*1024*1024);
245        if(devnr == 1)
246                node = addfb(FB1, devnr, getconfigint("skinfbwidth", NULL), getconfigint("skinfbheight", NULL), 4, -1, mmapfb, 16*1024*1024);
247
248#endif
249
250        debug(1000, "out");
251        return node;
252}
253
254void closefb()
255{
256        if(fb != NULL)
257        {
258                if(fb->fb != NULL)
259                        munmap(fb->fb, fb->fixfbsize);
260                if(fb->fd != -1)
261                        close(fb->fd);
262#ifdef NOFB
263                free(fb->fb);
264#endif
265        }
266}
267
268void clearfball()
269{
270        if(fb != NULL && fb->fb != NULL)
271                memset(fb->fb, 0, fb->fixfbsize);
272}
273
274void clearfb(struct fb *node)
275{
276        if(node != NULL)
277                memset(node->fb, 0, node->varfbsize);
278}
279
280void blitfb(int flag)
281{
282        blitfb2(skinfb, flag);
283}
284
285void changefbresolution(char *value)
286{
287        if(ostrcmp("pal", value) == 0)
288        {
289                fb->width = 720;
290                fb->height = 576;
291                fb->pitch = fb->width * fb->colbytes;
292        }
293        else if(ostrncmp("576", value, 3) == 0)
294        {
295                fb->width = 720;
296                fb->height = 576;
297                fb->pitch = fb->width * fb->colbytes;
298        }
299        else if(ostrncmp("720", value, 3) == 0)
300        {
301                fb->width = 1280;
302                fb->height = 720;
303                fb->pitch = fb->width * fb->colbytes;
304        }
305        else if(ostrncmp("1080", value, 4) == 0)
306        {
307                fb->width = 1920;
308                fb->height = 1080;
309                fb->pitch = fb->width * fb->colbytes;
310        }
311        if(skinfb == fb)
312        {
313                skin->width = skinfb->width;
314                skin->height = skinfb->height;
315                skin->iwidth = skinfb->width;
316                skin->iheight = skinfb->height;
317                skin->rwidth = skinfb->width;
318                skin->rheight = skinfb->height;
319        }
320        clearfb(fb);
321        clearfb(skinfb);
322}
323
324static void write_PNG(unsigned char *outbuffer, char *filename,
325                                int width, int height, int interlace)
326{
327        int i;
328        int bit_depth=0, color_type;
329        png_bytep row_pointers[height];
330        png_structp png_ptr;
331        png_infop info_ptr;
332        FILE *outfile = fopen(filename, "wb");
333
334        for (i=0; i<height; i++)
335                row_pointers[i] = outbuffer + i * 4 * width;
336               
337        if (!outfile)
338        {
339                fprintf (stderr, "Error: Couldn't fopen %s.\n", filename);
340                exit(EXIT_FAILURE);
341        }
342   
343        png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
344        (png_voidp) NULL, (png_error_ptr) NULL, (png_error_ptr) NULL);
345   
346        if (!png_ptr)
347                err("Error: Couldn't create PNG write struct.");
348   
349        info_ptr = png_create_info_struct(png_ptr);
350        if (!info_ptr)
351        {
352                png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
353                err("Error: Couldn't create PNG info struct.");
354        }
355   
356        png_init_io(png_ptr, outfile);
357   
358        png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
359   
360        bit_depth = 8;
361        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
362        //color_type = PNG_COLOR_TYPE_RGB;
363        png_set_invert_alpha(png_ptr);
364        png_set_bgr(png_ptr);
365
366        png_set_IHDR(png_ptr, info_ptr, width, height,
367        bit_depth, color_type, interlace,
368        PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
369   
370        png_write_info(png_ptr, info_ptr);
371   
372        printf ("Now writing PNG file\n");
373   
374        png_write_image(png_ptr, row_pointers);
375   
376        png_write_end(png_ptr, info_ptr);
377        /* puh, done, now freeing memory... */
378        png_destroy_write_struct(&png_ptr, &info_ptr);
379   
380        if (outfile != NULL)
381                (void) fclose(outfile);
382}
383
384static void convert_and_write(unsigned char *inbuffer, char *filename,
385                                int width, int height, int bits, int interlace)
386{
387        size_t bufsize = (size_t) width * height * 4;
388
389        unsigned char *outbuffer = malloc(bufsize);
390
391        if (outbuffer == NULL)
392                err("Not enough memory");
393       
394        memset(outbuffer, 0, bufsize);
395        write_PNG(inbuffer, filename, width, height, interlace);
396        (void) free(outbuffer);
397}
398
399int fb2png(unsigned char *buf_p, int width, int height, char *outfile)
400{
401        int interlace = PNG_INTERLACE_ADAM7;
402        int bitdepth = 32;
403               
404        size_t help = 0;
405        while(help <= (width * height * 4))
406        {
407                buf_p[help+3] = 0x00;
408                help = help + 4;
409        }
410               
411        convert_and_write(buf_p, outfile, width, height, bitdepth, interlace);
412   
413
414    return 0;
415}
416
417void pngforlcd()
418{
419        fb2png(skinfb->fb, 320, 240, "/tmp/titanlcd.png");
420       
421/*      FILE *fd;
422        fd=fopen("/tmp/titanlcd.raw", "w");
423        int help = 0;
424        int i = 0;
425        while (i < 240) {
426                fwrite(skinfb->fb+help,320*4,1,fd);
427                help = help + (skinfb->width * 4);
428                i++;
429        }
430        fclose(fd);*/
431}
432
433void write_FB_to_JPEG_file(unsigned char *inbuffer, int image_width, int image_height, char * filename, int quality)
434{
435       
436               
437        size_t helpb = 0;
438        size_t help = 0;
439        unsigned char *helpbuffer = malloc(image_width*image_height*3);
440       
441        //delete alpha byte
442        while(help <= (image_width*image_height*4))
443        {
444                helpbuffer[helpb+0] = inbuffer[help+0];
445                helpbuffer[helpb+1] = inbuffer[help+1];
446                helpbuffer[helpb+2] = inbuffer[help+2];
447                help = help + 4;
448                helpb = helpb + 3;
449        }
450       
451        JSAMPLE *image_buffer = helpbuffer;
452        struct jpeg_compress_struct cinfo;
453        struct jpeg_error_mgr jerr;
454        FILE * outfile;
455       
456        JSAMPROW row_pointer[1];
457        int row_stride;
458       
459        cinfo.err = jpeg_std_error(&jerr);
460        jpeg_create_compress(&cinfo);
461        if ((outfile = fopen(filename, "wb")) == NULL) {
462                fprintf(stderr, "can't open %s\n", filename);
463                exit(1);
464        }
465        jpeg_stdio_dest(&cinfo, outfile);
466        cinfo.image_width = image_width;        /* image width and height, in pixels */
467        cinfo.image_height = image_height;
468        cinfo.input_components = 3;             /* # of color components per pixel */
469        cinfo.in_color_space = JCS_RGB;
470
471        jpeg_set_defaults(&cinfo);
472        jpeg_set_quality(&cinfo, quality, TRUE);
473
474        jpeg_start_compress(&cinfo, TRUE);
475        row_stride = image_width * 3;
476
477        while (cinfo.next_scanline < cinfo.image_height) {
478                row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
479                (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
480        }
481
482        jpeg_finish_compress(&cinfo);
483        fclose(outfile);
484        jpeg_destroy_compress(&cinfo);
485   
486        free(helpbuffer);
487}
488
489#endif
Note: See TracBrowser for help on using the repository browser.