[Feature][MD310EU][task-view-1009] Create MD310EU project code directory
Change-Id: I57cd3c474efe4493ae8a242d7e2fa643ad8ecbde
diff --git a/lynq/MD310EU/ap/app/qrencode/fb.c b/lynq/MD310EU/ap/app/qrencode/fb.c
new file mode 100755
index 0000000..b46a197
--- /dev/null
+++ b/lynq/MD310EU/ap/app/qrencode/fb.c
@@ -0,0 +1,196 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+
+#pragma pack(1)
+typedef struct {
+ unsigned short bfType;
+ unsigned int bfSize;
+ unsigned short bfReserved1;
+ unsigned short bfReserved2;
+ unsigned int bfOffBits;
+} BMPFILEHEADER;
+
+typedef struct {
+ unsigned int biSize;
+ int biWidth;
+ int biHeight;
+ unsigned short biPlanes;
+ unsigned short biBitCount;
+ unsigned int biCompression;
+ unsigned int biSizeImage;
+ int biXPelsPerMeter;
+ int biYPelsPerMeter;
+ unsigned int biClrUsed;
+ unsigned int biClrImportant;
+} BMPINFOHEADER;
+#pragma pack()
+
+#define SWAP_ENDIAN_USHORT(value) ((unsigned short)((((unsigned short)(value) & 0xFF) << 8) | (((unsigned short)(value) & 0xFF00) >> 8)))
+
+// Convert 24-bit RGB to 16-bit RGB565
+unsigned short rgb24_to_rgb565(unsigned char r, unsigned char g, unsigned char b) {
+ unsigned short color = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
+ unsigned short swapped = SWAP_ENDIAN_USHORT(color);
+ return swapped;
+}
+
+int main(int argc, char *argv[]) {
+ FILE *fp = NULL;
+ unsigned char *line = NULL;
+ BMPFILEHEADER fileHeader;
+ BMPINFOHEADER infoHeader;
+
+ if (argc < 2) {
+ printf("No para. Please input bmp filepath.\n");
+ return;
+ }
+
+ // Open BMP file
+ fp = fopen(argv[1], "rb");
+ if (!fp) {
+ perror("Cannot open BMP file");
+ return -1;
+ }
+
+ // Read BMP headers
+ if (fread(&fileHeader, sizeof(BMPFILEHEADER), 1, fp) != 1) {
+ perror("Failed to read file header");
+ fclose(fp);
+ return -1;
+ }
+ printf("fileHeader: bfType=%x, bfSize=%u, bfOffBits=%u\n",
+ fileHeader.bfType, fileHeader.bfSize, fileHeader.bfOffBits);
+
+ if (fread(&infoHeader, sizeof(BMPINFOHEADER), 1, fp) != 1) {
+ perror("Failed to read info header");
+ fclose(fp);
+ return -1;
+ }
+ printf("infoHeader: biSize=%u, biWidth=%d, biHeight=%d\n",
+ infoHeader.biSize, infoHeader.biWidth, infoHeader.biHeight);
+ printf("infoHeader: biPlanes=%u, biBitCount=%u, biCompression=%u\n",
+ infoHeader.biPlanes, infoHeader.biBitCount, infoHeader.biCompression);
+ printf("infoHeader: biSizeImage=%u, biXPelsPerMeter=%d, biYPelsPerMeter=%d\n",
+ infoHeader.biSizeImage, infoHeader.biXPelsPerMeter, infoHeader.biYPelsPerMeter);
+ printf("infoHeader: biClrUsed=%u, biClrImportant=%d\n",
+ infoHeader.biClrUsed, infoHeader.biClrImportant);
+
+ // Check BMP format
+ if (fileHeader.bfType != 0x4D42) { // ASCII code for "BM"
+ printf("Not a valid BMP file\n");
+ fclose(fp);
+ return -1;
+ }
+
+ // Check bit depth
+ if (infoHeader.biBitCount != 24 && infoHeader.biBitCount != 16) {
+ printf("Only 16-bit or 24-bit BMP supported, current image is %d-bit\n", infoHeader.biBitCount);
+ fclose(fp);
+ return -1;
+ }
+
+ // Open framebuffer device
+ int fbfd = open("/dev/fb0", O_RDWR);
+ if (fbfd < 0) {
+ perror("Cannot open framebuffer device");
+ fclose(fp);
+ return -1;
+ }
+
+ // Get screen information
+ struct fb_var_screeninfo vinfo;
+ if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
+ perror("Cannot get screen info");
+ close(fbfd);
+ fclose(fp);
+ return -1;
+ }
+
+ // Check screen color depth
+ if (vinfo.bits_per_pixel != 16) {
+ printf("This program only supports 16-bit color depth display\n");
+ close(fbfd);
+ fclose(fp);
+ return -1;
+ }
+
+ // Calculate screen size and map framebuffer
+ long screensize = vinfo.xres * vinfo.yres * 2; // 16-bit = 2 bytes
+ unsigned char *fbp = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
+ if (fbp == MAP_FAILED) {
+ perror("Cannot map framebuffer");
+ close(fbfd);
+ fclose(fp);
+ return -1;
+ }
+
+ // Move file pointer to image data
+ fseek(fp, fileHeader.bfOffBits, SEEK_SET);
+
+ // Prepare to read image data
+ unsigned short *fb16 = (unsigned short *)fbp;
+ int bytes_per_pixel = infoHeader.biBitCount / 8;
+ int padding = (4 - (infoHeader.biWidth * bytes_per_pixel) % 4) % 4;
+ line = malloc(infoHeader.biWidth * bytes_per_pixel + padding);
+
+ if (line == NULL) {
+ perror("Memory allocation failed");
+ munmap(fbp, screensize);
+ close(fbfd);
+ fclose(fp);
+ return -1;
+ }
+
+ // Read and display image data
+ int y = 0;
+ for (y = infoHeader.biHeight - 1; y >= 0; y--) {
+ if (fread(line, infoHeader.biWidth * bytes_per_pixel + padding, 1, fp) != 1) {
+ printf("Failed to read image data\n");
+ free(line);
+ munmap(fbp, screensize);
+ close(fbfd);
+ fclose(fp);
+ return -1;
+ }
+ int x = 0;
+ for (x = 0; x < infoHeader.biWidth; x++) {
+ unsigned short pixel;
+ int location = x + y * vinfo.xres;
+
+ if (infoHeader.biBitCount == 24) {
+ // 24-bit BMP (BGR format)
+ unsigned char b = line[x * 3];
+ unsigned char g = line[x * 3 + 1];
+ unsigned char r = line[x * 3 + 2];
+ pixel = rgb24_to_rgb565(r, g, b);
+ } else {
+ // 16-bit BMP (already in RGB565 format)
+ pixel = *(unsigned short*)&line[x * 2];
+ }
+
+ // Check if within display bounds
+ if (x < vinfo.xres && y < vinfo.yres) {
+ fb16[location] = pixel;
+ }
+ }
+ }
+
+ // To display
+ write(fbfd, "1", 1);
+ usleep(1000*100);
+
+ // Cleanup resources
+ free(line);
+ fclose(fp);
+ munmap(fbp, screensize);
+ close(fbfd);
+
+ printf("Image display completed\n");
+ return 0;
+}
\ No newline at end of file