lvgl_img_decoder.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /**
  2. * @file lvgl_img_decoder_acts.c
  3. *
  4. */
  5. /*
  6. * Copyright (c) 2020 Actions Technology Co., Ltd
  7. *
  8. * SPDX-License-Identifier: Apache-2.0
  9. */
  10. /*********************
  11. * INCLUDES
  12. *********************/
  13. #include <os_common_api.h>
  14. #include <compress_api.h>
  15. #include <lvgl/lvgl_img_decoder.h>
  16. #include <lvgl/src/draw/lv_img_decoder.h>
  17. #include <lvgl/src/draw/lv_draw_img.h>
  18. #include <lvgl/porting/decoder/lv_img_decoder_acts.h>
  19. #ifdef CONFIG_JPEG_HAL
  20. # include <jpeg_hal.h>
  21. #endif
  22. /*********************
  23. * DEFINES
  24. *********************/
  25. /* Meet cache line (32 bytes) alignment and VG-Lite requirement */
  26. #define DECODE_CACHE_BUF_SIZE CONFIG_LVGL_DECODE_CACHE_BUF_SIZE
  27. /**********************
  28. * TYPEDEFS
  29. **********************/
  30. typedef struct {
  31. const uint8_t *src_raw;
  32. lv_img_dsc_t src_dsc;
  33. lv_area_t src_area;
  34. uint8_t src_px_bytes;
  35. uint32_t max_bytes;
  36. } decoder_cache_acts_t;
  37. /**********************
  38. * STATIC PROTOTYPES
  39. **********************/
  40. static lv_res_t _img_decoder_acts_info(lv_img_decoder_t * decoder, const void * src,
  41. lv_img_header_t * header);
  42. static lv_res_t _img_decoder_acts_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
  43. static lv_res_t _img_decoder_acts_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc,
  44. lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf);
  45. static void _img_decoder_acts_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
  46. static bool _is_jpeg(const void *data);
  47. static lv_img_cf_t _get_decoded_img_cf(const lv_img_dsc_t *src);
  48. static int _img_decoder_decode(void * buf, uint32_t buf_size,
  49. const lv_img_dsc_t *src, const lv_area_t *area);
  50. /**********************
  51. * STATIC VARIABLES
  52. **********************/
  53. #ifndef _WIN32
  54. __attribute__((__aligned__(64))) __in_section_unique(decompress.bss.cache)
  55. #endif
  56. static uint8_t s_decoder_cache_buf[DECODE_CACHE_BUF_SIZE];
  57. static decoder_cache_acts_t s_decoder_cache;
  58. /**********************
  59. * GLOBAL FUNCTIONS
  60. **********************/
  61. void lvgl_img_decoder_acts_init(void)
  62. {
  63. lv_img_decoder_t * decoder = lv_img_decoder_create();
  64. LV_ASSERT_MALLOC(decoder);
  65. if(decoder == NULL) {
  66. LV_LOG_WARN("lvgl_img_decoder_acts_init: out of memory");
  67. return;
  68. }
  69. lv_img_decoder_set_info_cb(decoder, _img_decoder_acts_info);
  70. lv_img_decoder_set_open_cb(decoder, _img_decoder_acts_open);
  71. lv_img_decoder_set_read_line_cb(decoder, _img_decoder_acts_read_line);
  72. lv_img_decoder_set_close_cb(decoder, _img_decoder_acts_close);
  73. }
  74. const void * lvgl_img_decoder_acts_read_area(const lv_img_dsc_t * src, const lv_area_t * area,
  75. lv_coord_t * stride, lv_img_cf_t * cf)
  76. {
  77. decoder_cache_acts_t *cache = &s_decoder_cache;
  78. if (src->data != cache->src_raw || _lv_area_is_in(area, &cache->src_area, 0) == false) {
  79. compress_pic_head_t *pic_head = (compress_pic_head_t *)src->data;
  80. int len;
  81. cache->src_dsc.header.cf = _get_decoded_img_cf(src);
  82. if (cache->src_dsc.header.cf == LV_IMG_CF_UNKNOWN)
  83. return NULL;
  84. len = _img_decoder_decode(s_decoder_cache_buf, sizeof(s_decoder_cache_buf), src, area);
  85. if (len < 0)
  86. return NULL;
  87. if (len > cache->max_bytes) {
  88. SYS_LOG_INF("img dec max %u bytes", len);
  89. cache->max_bytes = len;
  90. }
  91. cache->src_dsc.data = s_decoder_cache_buf;
  92. cache->src_dsc.data_size = len;
  93. cache->src_dsc.header.w = lv_area_get_width(area);
  94. cache->src_dsc.header.h = lv_area_get_height(area);
  95. lv_area_copy(&cache->src_area, area);
  96. cache->src_raw = src->data;
  97. cache->src_px_bytes = pic_head->bytes_per_pixel;
  98. }
  99. *stride = cache->src_dsc.header.w;
  100. *cf = cache->src_dsc.header.cf;
  101. return cache->src_dsc.data + ((area->y1 - cache->src_area.y1) * (*stride) +
  102. (area->x1 - cache->src_area.x1)) * cache->src_px_bytes;
  103. }
  104. /**********************
  105. * STATIC FUNCTIONS
  106. **********************/
  107. static lv_res_t _img_decoder_acts_info(lv_img_decoder_t * decoder, const void * src,
  108. lv_img_header_t * header)
  109. {
  110. LV_UNUSED(decoder);
  111. lv_img_src_t src_type = lv_img_src_get_type(src);
  112. if (src_type == LV_IMG_SRC_VARIABLE) {
  113. const lv_img_dsc_t * img_dsc = src;
  114. if (img_dsc->header.cf != LV_IMG_CF_RAW && img_dsc->header.cf != LV_IMG_CF_RAW_ALPHA)
  115. return LV_RES_INV;
  116. if (img_dsc->data_size < sizeof(compress_pic_head_t))
  117. return LV_RES_INV;
  118. const compress_pic_head_t * head = (compress_pic_head_t *)img_dsc->data;
  119. if (!_is_jpeg(head)) {
  120. header->always_zero = 0;
  121. header->w = head->width;
  122. header->h = head->height;
  123. header->cf = (head->format == COMPRESSED_PIC_CF_RGB_565) ?
  124. LV_IMG_CF_RAW : LV_IMG_CF_RAW_ALPHA;
  125. return LV_RES_OK;
  126. } else {
  127. #ifdef CONFIG_JPEG_HAL
  128. uint32_t pic_w = 0, pic_h = 0;
  129. if (hal_jpeg_get_picture_info((void *)img_dsc->data, img_dsc->data_size, &pic_w, &pic_h) == 0) {
  130. header->always_zero = 0;
  131. header->cf = LV_IMG_CF_RAW;
  132. header->w = pic_w;
  133. header->h = pic_h;
  134. return LV_RES_OK;
  135. }
  136. #endif /* CONFIG_JPEG_HAL */
  137. }
  138. }
  139. return LV_RES_INV;
  140. }
  141. static lv_res_t _img_decoder_acts_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
  142. {
  143. LV_UNUSED(decoder);
  144. LV_UNUSED(dsc);
  145. return LV_RES_OK;
  146. }
  147. static lv_res_t _img_decoder_acts_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc,
  148. lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf)
  149. {
  150. LV_UNUSED(decoder);
  151. lv_area_t area = { x, y, x + len - 1, y };
  152. lv_coord_t stride = 0;
  153. lv_img_cf_t cf = LV_IMG_CF_UNKNOWN;
  154. const uint8_t * data = lvgl_img_decoder_acts_read_area(dsc->src, &area, &stride, &cf);
  155. if (data == NULL)
  156. return LV_RES_INV;
  157. return lv_img_decode_acts_rgb_color(buf, data, len, cf);
  158. }
  159. static void _img_decoder_acts_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
  160. {
  161. LV_UNUSED(decoder);
  162. LV_UNUSED(dsc);
  163. }
  164. static bool _is_jpeg(const void *data)
  165. {
  166. const compress_pic_head_t *pic_head = (compress_pic_head_t *)data;
  167. if (pic_head->magic != LZ4_PIC_MAGIC &&
  168. pic_head->magic != RLE_PIC_MAGIC &&
  169. pic_head->magic != RAW_PIC_MAGIC) {
  170. return true;
  171. }
  172. return false;
  173. }
  174. static lv_img_cf_t _get_decoded_img_cf(const lv_img_dsc_t *src)
  175. {
  176. compress_pic_head_t *pic_head = (compress_pic_head_t *)src->data;
  177. if (_is_jpeg(pic_head))
  178. return LV_IMG_CF_RGB_565; /* should be JPEG */
  179. switch (pic_head->format) {
  180. case COMPRESSED_PIC_CF_RGB_565:
  181. return LV_IMG_CF_RGB_565;
  182. case COMPRESSED_PIC_CF_ARGB_8565:
  183. return LV_IMG_CF_ARGB_8565;
  184. case COMPRESSED_PIC_CF_ARGB_6666:
  185. return LV_IMG_CF_ARGB_6666;
  186. case COMPRESSED_PIC_CF_ARGB_8888:
  187. return LV_IMG_CF_ARGB_8888;
  188. default:
  189. LV_LOG_ERROR("pic %p compressed format %d", pic_head, pic_head->format);
  190. return LV_IMG_CF_UNKNOWN;
  191. }
  192. }
  193. static int _img_decoder_decode(void * buf, uint32_t buf_size,
  194. const lv_img_dsc_t *src, const lv_area_t *area)
  195. {
  196. compress_pic_head_t *pic_head = (compress_pic_head_t *)src->data;
  197. bool is_jpg = _is_jpeg(pic_head);
  198. int dec_len = (is_jpg ? sizeof(lv_color_t) : pic_head->bytes_per_pixel) * lv_area_get_size(area);
  199. int len;
  200. if (dec_len > buf_size) {
  201. LV_LOG_WARN("pic %p dec buf too small (%u < %d), area (%d %d %d %d)",
  202. pic_head, buf_size, dec_len, area->x1, area->y1, area->x2, area->y2);
  203. return -ENOMEM;
  204. }
  205. os_strace_u32x4(SYS_TRACE_ID_IMG_DECODE, pic_head->magic, (uint32_t)src,
  206. lv_area_get_width(area), lv_area_get_height(area));
  207. if (is_jpg == false) {
  208. len = pic_decompress((void *)src->data, buf,
  209. src->data_size, buf_size, 0, area->x1, area->y1,
  210. lv_area_get_width(area), lv_area_get_height(area));
  211. } else { /* JPEG */
  212. #ifdef CONFIG_JPEG_HAL
  213. len = jpg_decode((void *)src->data, (int)src->data_size, buf,
  214. (LV_COLOR_DEPTH == 16) ? 1 : 0, lv_area_get_width(area),
  215. area->x1, area->y1, lv_area_get_width(area), lv_area_get_height(area));
  216. #else
  217. LV_LOG_ERROR("pic %p magic 0x%08x invalid", pic_head, pic_head->magic);
  218. return -EINVAL;
  219. #endif
  220. }
  221. os_strace_end_call(SYS_TRACE_ID_IMG_DECODE);
  222. if (len != dec_len) {
  223. LV_LOG_ERROR("pic %p decompress error %d %d", pic_head, len, dec_len);
  224. return -EINVAL;
  225. }
  226. return len;
  227. }