luat_lib_tjpgd.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*------------------------------------------------*/
  2. /* TJpgDec Quick Evaluation Program for PCs */
  3. /*------------------------------------------------*/
  4. #include "luat_base.h"
  5. #include "luat_malloc.h"
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "tjpgd.h"
  9. #include "luat_tjpgd.h"
  10. #define LUAT_LOG_TAG "tjpgd"
  11. #include "luat_log.h"
  12. /* Bytes per pixel of image output */
  13. #define N_BPP (3 - JD_FORMAT)
  14. /* Session identifier for input/output functions (name, members and usage are as user defined) */
  15. typedef struct {
  16. FILE *fp; /* Input stream */
  17. uint8_t *fbuf; /* Output frame buffer */
  18. unsigned int wfbuf; /* Width of the frame buffer [pix] */
  19. } IODEV;
  20. /*------------------------------*/
  21. /* User defined input funciton */
  22. /*------------------------------*/
  23. unsigned int in_func (JDEC* jd, uint8_t* buff, unsigned int nbyte){
  24. IODEV *dev = (IODEV*)jd->device; /* Device identifier for the session (5th argument of jd_prepare function) */
  25. if (buff) {
  26. /* Read bytes from input stream */
  27. return luat_fs_fread(buff, 1, nbyte, dev->fp);
  28. } else {
  29. /* Remove bytes from input stream */
  30. return luat_fs_fseek(dev->fp, nbyte, SEEK_CUR) ? 0 : nbyte;
  31. }
  32. }
  33. /*------------------------------*/
  34. /* User defined output funciton */
  35. /*------------------------------*/
  36. int out_func (JDEC* jd, void* bitmap, JRECT* rect){
  37. IODEV *dev = (IODEV*)jd->device;
  38. uint8_t *src, *dst;
  39. uint16_t y, bws, bwd;
  40. /* Put progress indicator */
  41. if (rect->left == 0) {
  42. LLOGI("%lu%%", (rect->top << jd->scale) * 100UL / jd->height);
  43. }
  44. /* Copy the output image rectanglar to the frame buffer */
  45. src = (uint8_t*)bitmap;
  46. dst = dev->fbuf + N_BPP * (rect->top * dev->wfbuf + rect->left); /* Left-top of destination rectangular */
  47. bws = N_BPP * (rect->right - rect->left + 1); /* Width of source rectangular [byte] */
  48. bwd = N_BPP * dev->wfbuf; /* Width of frame buffer [byte] */
  49. for (y = rect->top; y <= rect->bottom; y++) {
  50. memcpy(dst, src, bws); /* Copy a line */
  51. src += bws; dst += bwd; /* Next line */
  52. }
  53. return 1; /* Continue to decompress */
  54. }
  55. /*------------------------------*/
  56. /* Program Jpeg_Dec */
  57. /*------------------------------*/
  58. uint8_t * luat_tjpgd(const char* input_file){
  59. JRESULT res; /* Result code of TJpgDec API */
  60. JDEC jdec; /* Decompression object */
  61. void *work; /* Pointer to the decompressor work area */
  62. size_t sz_work = 3500; /* Size of work area */
  63. IODEV devid; /* User defined device identifier */
  64. devid.fp = luat_fs_fopen(input_file, "rb");
  65. if (!devid.fp){
  66. LLOGI("Jpeg_Dec open the file failed...");
  67. return NULL;
  68. }
  69. /* Allocate a work area for TJpgDec */
  70. work = luat_heap_malloc(sz_work);
  71. if(work == NULL){
  72. LLOGI("Jpeg_Dec work malloc failed...");
  73. res = -1;
  74. goto __exit;
  75. }
  76. /* Prepare to decompress */
  77. res = jd_prepare(&jdec, in_func, work, sz_work, &devid);
  78. if (res == JDR_OK){
  79. /* It is ready to dcompress and image info is available here */
  80. LLOGI("Image size is %u x %u.\n%u bytes of work ares is used.\n", jdec.width, jdec.height, sz_work - jdec.sz_pool);
  81. devid.fbuf = luat_heap_malloc(N_BPP * jdec.width * jdec.height); /* Frame buffer for output image */
  82. if(devid.fbuf == NULL)
  83. {
  84. LLOGI("Jpeg_Dec devid.fbuf malloc failed, need to use %d Bytes ...", N_BPP * jdec.width * jdec.height);
  85. res = -1;
  86. goto __exit;
  87. }
  88. devid.wfbuf = jdec.width;
  89. res = jd_decomp(&jdec, out_func, 0); /* Start to decompress with 1/1 scaling */
  90. if (res == JDR_OK) {
  91. /* Decompression succeeded. You have the decompressed image in the frame buffer here. */
  92. return devid.fbuf;
  93. LLOGI("Decompression succeeded.");
  94. }
  95. else{
  96. LLOGI("jd_decomp() failed (rc=%d)", res);
  97. }
  98. }
  99. else{
  100. LLOGI("jd_prepare() failed (rc=%d)", res);
  101. }
  102. __exit:
  103. if(work != NULL){
  104. luat_heap_free(work); /* Discard work area */
  105. }
  106. luat_fs_fclose(devid.fp); /* Close the JPEG file */
  107. return NULL;
  108. }