source: titan/titan/fb.h @ 40424

Last change on this file since 40424 was 37252, checked in by obi, 8 years ago

fix

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