luat_lib_lcd_jpg.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. @module lcd
  3. @summary lcd驱动模块
  4. @version 1.0
  5. @date 2021.06.16
  6. @demo lcd
  7. @tag LUAT_USE_LCD
  8. */
  9. #include "luat_base.h"
  10. #include "luat_lcd.h"
  11. #include "luat_mem.h"
  12. #include "luat_zbuff.h"
  13. #include "luat_fs.h"
  14. #include "luat_gpio.h"
  15. #define LUAT_LOG_TAG "lcd"
  16. #include "luat_log.h"
  17. #include "u8g2.h"
  18. #include "u8g2_luat_fonts.h"
  19. #include "luat_u8g2.h"
  20. #include "qrcodegen.h"
  21. int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cnt);
  22. uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t cnt);
  23. extern luat_color_t BACK_COLOR , FORE_COLOR ;
  24. extern const luat_lcd_opts_t lcd_opts_custom;
  25. extern luat_lcd_conf_t *lcd_dft_conf;
  26. extern void lcd_auto_flush(luat_lcd_conf_t *conf);
  27. #ifdef LUAT_USE_TJPGD
  28. #include "tjpgd.h"
  29. #include "tjpgdcnf.h"
  30. #define N_BPP (3 - JD_FORMAT)
  31. /* Session identifier for input/output functions (name, members and usage are as user defined) */
  32. typedef struct {
  33. FILE *fp; /* Input stream */
  34. int x;
  35. int y;
  36. // int width;
  37. // int height;
  38. uint16_t buff[16*16];
  39. } IODEV;
  40. static unsigned int file_in_func (JDEC* jd, uint8_t* buff, unsigned int nbyte){
  41. IODEV *dev = (IODEV*)jd->device; /* Device identifier for the session (5th argument of jd_prepare function) */
  42. if (buff) {
  43. /* Read bytes from input stream */
  44. return luat_fs_fread(buff, 1, nbyte, dev->fp);
  45. } else {
  46. /* Remove bytes from input stream */
  47. return luat_fs_fseek(dev->fp, nbyte, SEEK_CUR) ? 0 : nbyte;
  48. }
  49. }
  50. static int lcd_out_func (JDEC* jd, void* bitmap, JRECT* rect){
  51. IODEV *dev = (IODEV*)jd->device;
  52. uint16_t* tmp = (uint16_t*)bitmap;
  53. // rgb高低位swap
  54. uint16_t count = (rect->right - rect->left + 1) * (rect->bottom - rect->top + 1);
  55. for (size_t i = 0; i < count; i++){
  56. if (lcd_dft_conf->endianness_swap)
  57. dev->buff[i] = ((tmp[i] >> 8) & 0xFF)+ ((tmp[i] << 8) & 0xFF00);
  58. else
  59. dev->buff[i] = tmp[i];
  60. }
  61. // LLOGD("jpeg seg %dx%d %dx%d", rect->left, rect->top, rect->right, rect->bottom);
  62. // LLOGD("jpeg seg size %d %d %d", rect->right - rect->left + 1, rect->bottom - rect->top + 1, (rect->right - rect->left + 1) * (rect->bottom - rect->top + 1));
  63. luat_lcd_draw(lcd_dft_conf, dev->x + rect->left, dev->y + rect->top,
  64. dev->x + rect->right, dev->y + rect->bottom,
  65. dev->buff);
  66. return 1; /* Continue to decompress */
  67. }
  68. static int lcd_draw_jpeg(const char* path, int xpos, int ypos) {
  69. JRESULT res; /* Result code of TJpgDec API */
  70. JDEC jdec; /* Decompression object */
  71. void *work; /* Pointer to the decompressor work area */
  72. #if JD_FASTDECODE == 2
  73. size_t sz_work = 3500 * 3; /* Size of work area */
  74. #else
  75. size_t sz_work = 3500; /* Size of work area */
  76. #endif
  77. IODEV devid; /* User defined device identifier */
  78. FILE* fd = luat_fs_fopen(path, "r");
  79. if (fd == NULL) {
  80. LLOGW("no such file %s", path);
  81. return -1;
  82. }
  83. devid.fp = fd;
  84. work = luat_heap_malloc(sz_work);
  85. if (work == NULL) {
  86. LLOGE("out of memory when malloc jpeg decode workbuff");
  87. return -3;
  88. }
  89. res = jd_prepare(&jdec, file_in_func, work, sz_work, &devid);
  90. if (res != JDR_OK) {
  91. luat_heap_free(work);
  92. luat_fs_fclose(fd);
  93. LLOGW("jd_prepare file %s error %d", path, res);
  94. return -2;
  95. }
  96. devid.x = xpos;
  97. devid.y = ypos;
  98. // devid.width = jdec.width;
  99. // devid.height = jdec.height;
  100. res = jd_decomp(&jdec, lcd_out_func, 0);
  101. luat_heap_free(work);
  102. luat_fs_fclose(fd);
  103. if (res != JDR_OK) {
  104. LLOGW("jd_decomp file %s error %d", path, res);
  105. return -2;
  106. }else {
  107. lcd_auto_flush(lcd_dft_conf);
  108. return 0;
  109. }
  110. }
  111. /*
  112. 显示图片,当前只支持jpg,jpeg
  113. @api lcd.showImage(x, y, file)
  114. @int X坐标
  115. @int y坐标
  116. @string 文件路径
  117. @usage
  118. lcd.showImage(0,0,"/luadb/logo.jpg")
  119. */
  120. int l_lcd_showimage(lua_State *L) {
  121. size_t size = 0;
  122. int ret = 0;
  123. int x = luaL_checkinteger(L, 1);
  124. int y = luaL_checkinteger(L, 2);
  125. const char* input_file = luaL_checklstring(L, 3, &size);
  126. if (memcmp(input_file+size-4, ".jpg", 5) == 0 || memcmp(input_file+size-4, ".JPG", 5) == 0 || memcmp(input_file+size-5, ".jpeg", 6) == 0 || memcmp(input_file+size-5, ".JPEG", 6) == 0){
  127. ret = lcd_draw_jpeg(input_file, x, y);
  128. lua_pushboolean(L, ret == 0 ? 1 : 0);
  129. } else{
  130. LLOGE("input_file not support");
  131. lua_pushboolean(L, 0);
  132. }
  133. return 1;
  134. }
  135. #endif