Turn from: 50528190
BMP and JPEG graphics display program
1) Display the main flowchart of BMP or JPEG image on LCD
First, before the program starts. To create an LCD device node in the Nfs/dev directory, the device name is fb0, the device type is a character device, the main device number is 29, and the secondary device number is 0. The command is as follows:
Mknod fb0 C 29 0
The main flowchart for displaying the image on the LCD is shown in Figure 1. At the beginning of the program to call the Open function opened the device, and then call the IOCTL to obtain information about the device, the next is to read the graphics file data, the image of the RGB values mapped to video memory, which is the core of the image display. For images in JPEG format, JPEG decoding is required to get RGB data before the project can be decoded directly with a ready-made JPEG library. For images in BMP format, the RGB data can be extracted directly from the file. To extract the image data array from a BMP file, you must first know the format of the BMP file. The format of the BMP file is described in detail below.
Figure 1
2) BMP Bitmap format analysis
A bitmap file can be seen as consisting of four parts: a bitmap file header, a bitmap information header, a color table, and a byte array that defines a bitmap. As shown in 2.
Figure 2
The address of each segment in the file header and its contents 3.
Figure 3
The bitmap file header data structure contains BMP image file type, display content and other information. Its data structure is defined as follows:
Typedef struct
{
int bftype;//indicates the type of bitmap file, which must be BM
Long bfsize;//indicates the size of the bitmap file, in bytes
int bfreserved1;//belongs to reserved word, must be Ben 0
int bfreserved2;//is also reserved word, must be Ben 0
Long bfoffbits;//The starting position of the bitmap array, in bytes
} Bitmapfileheader;
2.1) The address of each segment in the information header and its contents 4 are shown.
Figure 4
The data structure of the bitmap information header contains information about the width, height, and compression of BMP images, and its C language data structure is as follows:
Typedef struct {
Long bisize;//Indicates the number of bytes required for this data structure
Long biwidth;//the width of the BMP image in pixels.
Long biheight;//the height of the BMP image in pixels.
The number of bits in an int biplanes;//output device must be set to 1
int bibitcount;//gives the number of bits per pixel
Long bicompress;//the type of compression for the bitmap
Long bisizeimage;//gives the number of image bytes
Long bixpelspermeter;//horizontal resolution of images
Vertical resolution of long biypelspermeter;//image
The number of colors actually used by the image in the long biclrused;//palette
Long biclrimportant;//The index value of the important color
} Bitmapinfoheader;
2.2) for images with pixels less than or equal to 16 bits, a color table is used to provide a color index to the image data array, where each piece of data is arranged in the order of B, G, R, and one is the reserved reserved bit. In the graph data region, the index values of each pixel point are stored. Its C language structure is shown in 5.
Figure 5 Color Table data structure
2.3) for 24-bit and 32-bit images, there is no color table, he in the image data area directly stored in the image of the RGB data, where each pixel point of data in B, G, R order. The data structure of each pixel point is shown in 6.
Figure 6 Data structure of an image array
2.4) Since the data in the image data array is stored from the last line of the picture, the image is displayed in a progressive scan from the lower left corner of the image, from left to right, bottom to top.
2.5) for the LCD on the s3c2410 or PXA255 board, they occupy 16 bits per pixel, and the 16 bits are divided by b:g:r=5:6:5, where B is at the highest level and R is at the lowest point. The R, G, and B data obtained from BMP images accounted for 8 bits per data, altogether 24 bits, so it is necessary to shift the R, G, b data into a 16-bit data. The shift method is as follows:
b >>= 3; G >>= 2; R >>= 3;
Rgbvalue = (r<<11 | g << 5 | b);
Based on the above analysis, the extraction of various types of BMP image Flow 7 is shown
Figure 7
3) Implement display of images of any size
The size of the LCD screen on the development Board is fixed and the LCD on the s3c2410 is: 640*480 on the 240*320,pxa255. Pictures that are smaller than the screen are displayed on the screen of course, but what if the picture is bigger than the screen? This requires that we use an algorithm to scale the image.
The basic idea of scaling is to divide the image into blocks, averaging the R, G, and b data in each block, and getting a new R, G, b value, which is the map of the block on the LCD screen.
The algorithm for scaling is described as follows:
(1), calculate the size of the image and the size of the LCD screen, as well as the size of the block. To accommodate various screen sizes, lcd_width and lcd_height are not directly assigned to 240 and 320. Instead, the standard interface is called to get parameters about the screen. Specific as follows:
Get Variable Screen information
if (IOCTL (FBFD, Fbioget_vscreeninfo, &vinfo)) {
printf ("Error reading variable information.");
Exit (3);
}
unsigned int lcd_width=vinfo.xres;
unsigned int lcd_height=vinfo.yres;
Calculate scale:
widthscale=bmpi->width/lcd_width;
heightscale=bmpi->height/lcd_height;
The size of the block in this program is determined in the following way:
unsigned int panewidth=
unsigned int paneheight=;
The symbol represents an upward rounding.
(2), starting from the upper left corner of the picture, to (i* widthscale,j* heightscale) bit starting point, with a wide panewidth high paneheight for a small square, the square of R, G, B values are averaged, the mapping point of R, G, B value, The point is stored as the point (I, j) to be displayed on the LCD.
The procedure for this section is as follows:
-------------averaging--------
for (i=0;i<now_height;i++)
{
for (j=0;j<now_width;j++)
{
color_sum_r=0;
color_sum_g=0;
color_sum_b=0;
for (m=i*heightscale;m<i*heightscale+paneheight;m++)
{
for (n=j*widthscale;n<j*widthscale+panewidth;n++)
{
COLOR_SUM_R+=POINTVALUE[M][N].R;
COLOR_SUM_G+=POINTVALUE[M][N].G;
color_sum_b+=pointvalue[m][n].b;
}
}
Rgbvalue_256->r=div_round (Color_sum_r,paneheight*panewidth);
Rgbvalue_256->g=div_round (Color_sum_g,paneheight*panewidth);
Rgbvalue_256->b=div_round (Color_sum_b,paneheight*panewidth);
}
}
4) Total flow of image data extraction and display
Through the above analysis, the entire picture data extraction and display of the total flow of 8 is shown.
Figure 8
Image Display Application:
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <string.h>
#include <malloc.h>
#include <linux/fb.h>
#include <jpeglib.h>
#include <jerror.h>
struct FB_DEV
{
For frame buffer
int FB;
void *fb_mem; Frame buffer Mmap
int Fb_width, Fb_height, Fb_line_len, fb_size;
int fb_bpp;
} Fbdev;
Get framebuffer length, Width and width, success returns 0, failure returns-1
int fb_stat (int fd)
{
struct Fb_fix_screeninfo fb_finfo;
struct Fb_var_screeninfo fb_vinfo;
if (IOCTL (FD, Fbioget_fscreeninfo, &fb_finfo))
{
Perror (__func__);
Return (-1);
}
if (IOCTL (FD, Fbioget_vscreeninfo, &fb_vinfo))
{
Perror (__func__);
Return (-1);
}
Fbdev.fb_width = Fb_vinfo.xres;
Fbdev.fb_height = Fb_vinfo.yres;
FBDEV.FB_BPP = Fb_vinfo.bits_per_pixel;
Fbdev.fb_line_len = Fb_finfo.line_length;
Fbdev.fb_size = Fb_finfo.smem_len;
return (0);
}
Convert RGB888 to RGB565 (because the current LCD is displayed in RGB565)
unsigned short rgb888torgb565 (unsigned char red, unsigned char green, unsigned char blue)
{
unsigned short B = (blue >> 3) & 0x001f;
unsigned short G = ((green >> 2) << 5) & 0x07e0;
unsigned short R = ((Red >> 3) << one) & 0xf800;
return (unsigned short) (R | G | B);
}
Releasing the mappings for Framebuffer
int Fb_munmap (void *start, size_t length)
{
Return (Munmap (start, length));
}
Displays an image of a pixel to the framebuffer.
int Fb_pixel (void *fbmem, int width, int height, int x, int y, unsigned short color)
{
if ((x > width) | | (Y > Height))
Return (-1);
unsigned short *DST = ((unsigned short *) Fbmem + y * width + x);
*DST = color;
return 0;
}
int main (int argc, char **argv)
{
int FB;
FILE *infile;
struct Jpeg_decompress_struct cinfo;
int x, y;
unsigned char *buffer;
Char s[15];
struct Jpeg_error_mgr jerr;
if (FB = open ("/dev/fb0", O_RDWR)) < 0)//turn on the graphics device
{
Perror (__func__);
Return (-1);
}
Get the status of Framebuffer
Fb_stat (FB); Get the length, width and width of the display in the graphics driver
printf ("Frame buffer:%dx%d,%DBPP, 0x%xbyte=%d\n",
Fbdev.fb_width, Fbdev.fb_height, FBDEV.FB_BPP, Fbdev.fb_size, fbdev.fb_size);
Address of Map Framebuffer
Fbdev.fb_mem = Mmap (NULL, Fbdev.fb_size, prot_read| prot_write,map_shared,fb,0);
if (infile = fopen ("Lcd.jpg", "rb") = = = NULL)
{
fprintf (stderr, "open%s failed\n", s);
Exit (-1);
}
IOCTL (FB, fbioblank,0); Turn on the LCD backlight
Cinfo.err = Jpeg_std_error (&jerr);
Jpeg_create_decompress (&cinfo);
Import the JPEG file to unzip infile
JPEG_STDIO_SRC (&cinfo, infile);
Read the file header of a JPEG file
Jpeg_read_header (&cinfo, TRUE);
Starts extracting the JPEG file, which is then allocated to the scanline buffer,
Jpeg_start_decompress (&cinfo);
Buffer = (unsigned char *) malloc (cinfo.output_width
* cinfo.output_components);
y = 0;
while (Cinfo.output_scanline < cinfo.output_height)
{
Jpeg_read_scanlines (&cinfo, &buffer, 1);
if (fbdev.fb_bpp = = 16)
{
unsigned short color;
for (x = 0; x < cinfo.output_width; × x + +)
{
color = rgb888torgb565 (BUFFER[X * 3],
BUFFER[X * 3 + 1], Buffer[x * 3 + 2]);
Fb_pixel (Fbdev.fb_mem, Fbdev.fb_width, Fbdev.fb_height, x, y, color);
}
}
else if (fbdev.fb_bpp = = 24)
{
memcpy ((unsigned char *) Fbdev.fb_mem + y * fbdev.fb_width * 3, buffer,
Cinfo.output_width * cinfo.output_components);
}
y++;
}
Complete JPEG decoding to release JPEG files
Jpeg_finish_decompress (&cinfo);
Jpeg_destroy_decompress (&cinfo);
Releasing the frame buffer
Free (buffer);
Close the JPEG input file
Fclose (infile);
Fb_munmap (Fbdev.fb_mem, fbdev.fb_size); Releasing Framebuffer mappings
Close (FB);
}
Article is I reprint of http://blog.chinaunix.net/uid-25120309-id-3794265.html
But the test found that the compilation failed to pass,
Error:
LCD. C: (. text+0x384): Undefined reference to ' Jpeg_std_error (jpeg_error_mgr*) '
LCD. C: (. text+0x3a0): Undefined reference to ' jpeg_createdecompress (jpeg_decompress_struct*, int, unsigned int) '
LCD. C: (. text+0x3b0): Undefined reference to ' jpeg_stdio_src (jpeg_decompress_struct*, _io_file*) '
LCD. C: (. text+0x3c0): Undefined reference to ' Jpeg_read_header (jpeg_decompress_struct*, int) '
LCD. C: (. text+0x3cc): Undefined reference to ' jpeg_start_decompress (jpeg_decompress_struct*) '
LCD. C: (. text+0x410): Undefined reference to ' jpeg_read_scanlines (jpeg_decompress_struct*, unsigned char**, unsigned int) '
LCD. C: (. text+0x59c): Undefined reference to ' jpeg_finish_decompress (jpeg_decompress_struct*) '
LCD. C: (. text+0x5a8): Undefined reference to ' jpeg_destroy_decompress (jpeg_decompress_struct*) '
Collect2:ld returned 1 exit status
After searching on the Internet to determine the JPEG decoding library problem, I first installed the JPEG library in Ubuntu
Installation of the Libjpeg library
In the source file, the
#include <jpeglib.h>
Change into
extern "C" {
#include <jpeglib.h>
}
Here is the problem, notice that GCC will lcd.c as C + + compile, and LCD.C as C language compiled, changed to LCD.C after the red part of the error
Because there is a JPEG decoding library, the link need to add the-LJPEG option
Use the command arm-linux-gcc-ljpeg LCD. C-o LCD #add-ljpeg option to compile the source file successfully,
Linux LCD Display image "Turn"