GUI_BMPfile.c 16 KB

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