luat_lib_lcd_jpg.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. extern luat_color_t BACK_COLOR , FORE_COLOR ;
  22. extern luat_lcd_conf_t *lcd_dft_conf;
  23. extern void lcd_auto_flush(luat_lcd_conf_t *conf);
  24. #ifdef LUAT_USE_TJPGD
  25. #include "tjpgd.h"
  26. #include "tjpgdcnf.h"
  27. #define N_BPP (3 - JD_FORMAT)
  28. /* Session identifier for input/output functions (name, members and usage are as user defined) */
  29. typedef struct {
  30. FILE *fp; /* Input stream */
  31. int x;
  32. int y;
  33. // int width;
  34. // int height;
  35. uint16_t buff[16*16];
  36. } IODEV;
  37. static unsigned int file_in_func (JDEC* jd, uint8_t* buff, unsigned int nbyte){
  38. IODEV *dev = (IODEV*)jd->device; /* Device identifier for the session (5th argument of jd_prepare function) */
  39. if (buff) {
  40. /* Read bytes from input stream */
  41. return luat_fs_fread(buff, 1, nbyte, dev->fp);
  42. } else {
  43. /* Remove bytes from input stream */
  44. return luat_fs_fseek(dev->fp, nbyte, SEEK_CUR) ? 0 : nbyte;
  45. }
  46. }
  47. static int lcd_out_func (JDEC* jd, void* bitmap, JRECT* rect){
  48. IODEV *dev = (IODEV*)jd->device;
  49. uint16_t* tmp = (uint16_t*)bitmap;
  50. // rgb高低位swap
  51. uint16_t count = (rect->right - rect->left + 1) * (rect->bottom - rect->top + 1);
  52. for (size_t i = 0; i < count; i++){
  53. if (lcd_dft_conf->endianness_swap)
  54. dev->buff[i] = ((tmp[i] >> 8) & 0xFF)+ ((tmp[i] << 8) & 0xFF00);
  55. else
  56. dev->buff[i] = tmp[i];
  57. }
  58. // LLOGD("jpeg seg %dx%d %dx%d", rect->left, rect->top, rect->right, rect->bottom);
  59. // 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));
  60. luat_lcd_draw(lcd_dft_conf, dev->x + rect->left, dev->y + rect->top,
  61. dev->x + rect->right, dev->y + rect->bottom,
  62. dev->buff);
  63. return 1; /* Continue to decompress */
  64. }
  65. LUAT_WEAK int lcd_draw_jpeg(luat_lcd_conf_t* conf, const char* path, int16_t x, int16_t y){
  66. JRESULT res; /* Result code of TJpgDec API */
  67. JDEC jdec; /* Decompression object */
  68. void *work; /* Pointer to the decompressor work area */
  69. #if JD_FASTDECODE == 2
  70. size_t sz_work = 3500 * 3; /* Size of work area */
  71. #else
  72. size_t sz_work = 3500; /* Size of work area */
  73. #endif
  74. IODEV devid; /* User defined device identifier */
  75. FILE* fd = luat_fs_fopen(path, "r");
  76. if (fd == NULL) {
  77. LLOGW("no such file %s", path);
  78. return -1;
  79. }
  80. devid.fp = fd;
  81. work = luat_heap_malloc(sz_work);
  82. if (work == NULL) {
  83. LLOGE("out of memory when malloc jpeg decode workbuff");
  84. return -3;
  85. }
  86. res = jd_prepare(&jdec, file_in_func, work, sz_work, &devid);
  87. if (res != JDR_OK) {
  88. luat_heap_free(work);
  89. luat_fs_fclose(fd);
  90. LLOGW("jd_prepare file %s error %d", path, res);
  91. return -2;
  92. }
  93. devid.x = x;
  94. devid.y = y;
  95. // devid.width = jdec.width;
  96. // devid.height = jdec.height;
  97. res = jd_decomp(&jdec, lcd_out_func, 0);
  98. luat_heap_free(work);
  99. luat_fs_fclose(fd);
  100. if (res != JDR_OK) {
  101. LLOGW("jd_decomp file %s error %d", path, res);
  102. return -2;
  103. }else {
  104. lcd_auto_flush(lcd_dft_conf);
  105. return 0;
  106. }
  107. }
  108. #endif