luat_lib_lcd_jpg.c 3.6 KB

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