GUI_BMPfile.c (11311B)
1 /***************************************************************************** 2 * | File : GUI_BMPfile.h 3 * | Author : Waveshare team 4 * | Function : Hardware underlying interface 5 * | Info : 6 * Used to shield the underlying layers of each master 7 * and enhance portability 8 *---------------- 9 * | This version: V2.2 10 * | Date : 2020-07-08 11 * | Info : 12 * ----------------------------------------------------------------------------- 13 * V2.2(2020-07-08): 14 * 1.Add GUI_ReadBmp_RGB_7Color() 15 * V2.1(2019-10-10): 16 * 1.Add GUI_ReadBmp_4Gray() 17 * V2.0(2018-11-12): 18 * 1.Change file name: GUI_BMP.h -> GUI_BMPfile.h 19 * 2.fix: GUI_ReadBmp() 20 * Now Xstart and Xstart can control the position of the picture normally, 21 * and support the display of images of any size. If it is larger than 22 * the actual display range, it will not be displayed. 23 # 24 # Permission is hereby granted, free of charge, to any person obtaining a copy 25 # of this software and associated documnetation files (the "Software"), to deal 26 # in the Software without restriction, including without limitation the rights 27 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 # copies of the Software, and to permit persons to whom the Software is 29 # furished to do so, subject to the following conditions: 30 # 31 # The above copyright notice and this permission notice shall be included in 32 # all copies or substantial portions of the Software. 33 # 34 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 35 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 37 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 38 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 39 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 40 # THE SOFTWARE. 41 # 42 ******************************************************************************/ 43 44 #include "GUI_BMPfile.h" 45 #include "GUI_Paint.h" 46 #include "Debug.h" 47 48 #include <fcntl.h> 49 #include <unistd.h> 50 #include <stdint.h> 51 #include <stdlib.h> //exit() 52 #include <string.h> //memset() 53 #include <math.h> //memset() 54 #include <stdio.h> 55 56 UBYTE GUI_ReadBmp(const char *path, UWORD Xstart, UWORD Ystart) 57 { 58 FILE *fp; //Define a file pointer 59 BMPFILEHEADER bmpFileHeader; //Define a bmp file header structure 60 BMPINFOHEADER bmpInfoHeader; //Define a bmp info header structure 61 62 63 // Binary file open 64 if((fp = fopen(path, "rb")) == NULL) { 65 Debug("Cann't open the file!\n"); 66 exit(0); 67 } 68 69 // Set the file pointer from the beginning 70 fseek(fp, 0, SEEK_SET); 71 fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, fp); //sizeof(BMPFILEHEADER) must be 14 72 fread(&bmpInfoHeader, sizeof(BMPINFOHEADER), 1, fp); //sizeof(BMPFILEHEADER) must be 50 73 printf("pixel = %d * %d\r\n", bmpInfoHeader.biWidth, bmpInfoHeader.biHeight); 74 75 UWORD Image_Width_Byte = (bmpInfoHeader.biWidth % 8 == 0)? (bmpInfoHeader.biWidth / 8): (bmpInfoHeader.biWidth / 8 + 1); 76 UWORD Bmp_Width_Byte = (Image_Width_Byte % 4 == 0) ? Image_Width_Byte: ((Image_Width_Byte / 4 + 1) * 4); 77 UBYTE Image[Image_Width_Byte * bmpInfoHeader.biHeight]; 78 memset(Image, 0xFF, Image_Width_Byte * bmpInfoHeader.biHeight); 79 80 // Determine if it is a monochrome bitmap 81 int readbyte = bmpInfoHeader.biBitCount; 82 if(readbyte != 1) { 83 Debug("the bmp Image is not a monochrome bitmap!\n"); 84 exit(0); 85 } 86 87 // Determine black and white based on the palette 88 UWORD i; 89 UWORD Bcolor, Wcolor; 90 UWORD bmprgbquadsize = pow(2, bmpInfoHeader.biBitCount);// 2^1 = 2 91 BMPRGBQUAD bmprgbquad[bmprgbquadsize]; //palette 92 // BMPRGBQUAD bmprgbquad[2]; //palette 93 94 for(i = 0; i < bmprgbquadsize; i++){ 95 // for(i = 0; i < 2; i++) { 96 fread(&bmprgbquad[i * 4], sizeof(BMPRGBQUAD), 1, fp); 97 } 98 if(bmprgbquad[0].rgbBlue == 0xff && bmprgbquad[0].rgbGreen == 0xff && bmprgbquad[0].rgbRed == 0xff) { 99 Bcolor = BLACK; 100 Wcolor = WHITE; 101 } else { 102 Bcolor = WHITE; 103 Wcolor = BLACK; 104 } 105 106 // Read image data into the cache 107 UWORD x, y; 108 UBYTE Rdata; 109 fseek(fp, bmpFileHeader.bOffset, SEEK_SET); 110 for(y = 0; y < bmpInfoHeader.biHeight; y++) {//Total display column 111 for(x = 0; x < Bmp_Width_Byte; x++) {//Show a line in the line 112 if(fread((char *)&Rdata, 1, readbyte, fp) != readbyte) { 113 perror("get bmpdata:\r\n"); 114 break; 115 } 116 if(x < Image_Width_Byte) { //bmp 117 Image[x + (bmpInfoHeader.biHeight - y - 1) * Image_Width_Byte] = Rdata; 118 // printf("rdata = %d\r\n", Rdata); 119 } 120 } 121 } 122 fclose(fp); 123 124 // Refresh the image to the display buffer based on the displayed orientation 125 UBYTE color, temp; 126 for(y = 0; y < bmpInfoHeader.biHeight; y++) { 127 for(x = 0; x < bmpInfoHeader.biWidth; x++) { 128 if(x > Paint.Width || y > Paint.Height) { 129 break; 130 } 131 temp = Image[(x / 8) + (y * Image_Width_Byte)]; 132 color = (((temp << (x%8)) & 0x80) == 0x80) ?Bcolor:Wcolor; 133 Paint_SetPixel(Xstart + x, Ystart + y, color); 134 } 135 } 136 return 0; 137 } 138 /************************************************************************* 139 140 *************************************************************************/ 141 UBYTE GUI_ReadBmp_4Gray(const char *path, UWORD Xstart, UWORD Ystart) 142 { 143 FILE *fp; //Define a file pointer 144 BMPFILEHEADER bmpFileHeader; //Define a bmp file header structure 145 BMPINFOHEADER bmpInfoHeader; //Define a bmp info header structure 146 147 // Binary file open 148 if((fp = fopen(path, "rb")) == NULL) { 149 Debug("Cann't open the file!\n"); 150 exit(0); 151 } 152 153 // Set the file pointer from the beginning 154 fseek(fp, 0, SEEK_SET); 155 fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, fp); //sizeof(BMPFILEHEADER) must be 14 156 fread(&bmpInfoHeader, sizeof(BMPINFOHEADER), 1, fp); //sizeof(BMPFILEHEADER) must be 50 157 printf("pixel = %d * %d\r\n", bmpInfoHeader.biWidth, bmpInfoHeader.biHeight); 158 159 UWORD Image_Width_Byte = (bmpInfoHeader.biWidth % 4 == 0)? (bmpInfoHeader.biWidth / 4): (bmpInfoHeader.biWidth / 4 + 1); 160 UWORD Bmp_Width_Byte = (bmpInfoHeader.biWidth % 2 == 0)? (bmpInfoHeader.biWidth / 2): (bmpInfoHeader.biWidth / 2 + 1); 161 UBYTE Image[Image_Width_Byte * bmpInfoHeader.biHeight * 2]; 162 memset(Image, 0xFF, Image_Width_Byte * bmpInfoHeader.biHeight * 2); 163 164 // Determine if it is a monochrome bitmap 165 int readbyte = bmpInfoHeader.biBitCount; 166 printf("biBitCount = %d\r\n",readbyte); 167 if(readbyte != 4){ 168 Debug("Bmp image is not a 4-color bitmap!\n"); 169 exit(0); 170 } 171 // Read image data into the cache 172 UWORD x, y; 173 UBYTE Rdata; 174 fseek(fp, bmpFileHeader.bOffset, SEEK_SET); 175 176 for(y = 0; y < bmpInfoHeader.biHeight; y++) {//Total display column 177 for(x = 0; x < Bmp_Width_Byte; x++) {//Show a line in the line 178 if(fread((char *)&Rdata, 1, 1, fp) != 1) { 179 perror("get bmpdata:\r\n"); 180 break; 181 } 182 if(x < Image_Width_Byte*2) { //bmp 183 Image[x + (bmpInfoHeader.biHeight - y - 1) * Image_Width_Byte*2] = Rdata; 184 } 185 } 186 } 187 fclose(fp); 188 189 // Refresh the image to the display buffer based on the displayed orientation 190 UBYTE color, temp; 191 printf("bmpInfoHeader.biWidth = %d\r\n",bmpInfoHeader.biWidth); 192 printf("bmpInfoHeader.biHeight = %d\r\n",bmpInfoHeader.biHeight); 193 for(y = 0; y < bmpInfoHeader.biHeight; y++) { 194 for(x = 0; x < bmpInfoHeader.biWidth; x++) { 195 if(x > Paint.Width || y > Paint.Height) { 196 break; 197 } 198 temp = Image[x/2 + y * bmpInfoHeader.biWidth/2] >> ((x%2)? 0:4);//0xf 0x8 0x7 0x0 199 color = temp>>2; //11 10 01 00 200 Paint_SetPixel(Xstart + x, Ystart + y, color); 201 } 202 } 203 return 0; 204 } 205 206 207 UBYTE GUI_ReadBmp_RGB_7Color(const char *path, UWORD Xstart, UWORD Ystart) 208 { 209 FILE *fp; //Define a file pointer 210 BMPFILEHEADER bmpFileHeader; //Define a bmp file header structure 211 BMPINFOHEADER bmpInfoHeader; //Define a bmp info header structure 212 213 // Binary file open 214 if((fp = fopen(path, "rb")) == NULL) { 215 Debug("Cann't open the file!\n"); 216 exit(0); 217 } 218 219 // Set the file pointer from the beginning 220 fseek(fp, 0, SEEK_SET); 221 fread(&bmpFileHeader, sizeof(BMPFILEHEADER), 1, fp); //sizeof(BMPFILEHEADER) must be 14 222 fread(&bmpInfoHeader, sizeof(BMPINFOHEADER), 1, fp); //sizeof(BMPFILEHEADER) must be 50 223 printf("pixel = %d * %d\r\n", bmpInfoHeader.biWidth, bmpInfoHeader.biHeight); 224 225 UDOUBLE Image_Byte = bmpInfoHeader.biWidth * bmpInfoHeader.biHeight * 3; 226 UBYTE Image[Image_Byte]; 227 memset(Image, 0xFF, Image_Byte); 228 229 // Determine if it is a monochrome bitmap 230 int readbyte = bmpInfoHeader.biBitCount; 231 if(readbyte != 24){ 232 Debug("Bmp image is not 24 bitmap!\n"); 233 exit(0); 234 } 235 // Read image data into the cache 236 UWORD x, y; 237 UBYTE Rdata[3]; 238 fseek(fp, bmpFileHeader.bOffset, SEEK_SET); 239 240 for(y = 0; y < bmpInfoHeader.biHeight; y++) {//Total display column 241 for(x = 0; x < bmpInfoHeader.biWidth ; x++) {//Show a line in the line 242 if(fread((char *)Rdata, 1, 1, fp) != 1) { 243 perror("get bmpdata:\r\n"); 244 break; 245 } 246 if(fread((char *)Rdata+1, 1, 1, fp) != 1) { 247 perror("get bmpdata:\r\n"); 248 break; 249 } 250 if(fread((char *)Rdata+2, 1, 1, fp) != 1) { 251 perror("get bmpdata:\r\n"); 252 break; 253 } 254 255 if(Rdata[0] == 0 && Rdata[1] == 0 && Rdata[2] == 0){ 256 Image[x+(y* bmpInfoHeader.biWidth )] = 0;//Black 257 }else if(Rdata[0] == 255 && Rdata[1] == 255 && Rdata[2] == 255){ 258 Image[x+(y* bmpInfoHeader.biWidth )] = 1;//White 259 }else if(Rdata[0] == 0 && Rdata[1] == 255 && Rdata[2] == 0){ 260 Image[x+(y* bmpInfoHeader.biWidth )] = 2;//Green 261 }else if(Rdata[0] == 255 && Rdata[1] == 0 && Rdata[2] == 0){ 262 Image[x+(y* bmpInfoHeader.biWidth )] = 3;//Blue 263 }else if(Rdata[0] == 0 && Rdata[1] == 0 && Rdata[2] == 255){ 264 Image[x+(y* bmpInfoHeader.biWidth )] = 4;//Red 265 }else if(Rdata[0] == 0 && Rdata[1] == 255 && Rdata[2] == 255){ 266 Image[x+(y* bmpInfoHeader.biWidth )] = 5;//Yellow 267 }else if(Rdata[0] == 0 && Rdata[1] == 128 && Rdata[2] == 255){ 268 Image[x+(y* bmpInfoHeader.biWidth )] = 6;//Orange 269 } 270 } 271 } 272 fclose(fp); 273 274 // Refresh the image to the display buffer based on the displayed orientation 275 for(y = 0; y < bmpInfoHeader.biHeight; y++) { 276 for(x = 0; x < bmpInfoHeader.biWidth; x++) { 277 if(x > Paint.Width || y > Paint.Height) { 278 break; 279 } 280 Paint_SetPixel(Xstart + x, Ystart + y, Image[bmpInfoHeader.biHeight * bmpInfoHeader.biWidth - 1 -(bmpInfoHeader.biWidth-x-1+(y* bmpInfoHeader.biWidth))]); 281 } 282 } 283 return 0; 284 } 285 286