SWM341_jpeg.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /******************************************************************************************************************************************
  2. * 文件名称: SWM341_jpeg.c
  3. * 功能说明: SWM341单片机的JPEG解码器驱动库
  4. * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
  5. * 注意事项:
  6. * 版本日期: V1.1.0 2017年10月25日
  7. * 升级记录:
  8. *
  9. *
  10. *******************************************************************************************************************************************
  11. * @attention
  12. *
  13. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
  14. * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
  15. * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
  16. * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
  17. * -ECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2012 Synwit Technology
  20. *******************************************************************************************************************************************/
  21. #include "SWM341.h"
  22. #include "SWM341_jpeg.h"
  23. #include <math.h>
  24. #include <string.h>
  25. /******************************************************************************************************************************************
  26. * 函数名称: JPEG_Init()
  27. * 功能说明: JPEG解码器初始化
  28. * 输 入: JPEG_TypeDef * JPEGx 指定要被设置的JPEG解码器,有效值包括JPEG
  29. * JPEG_InitStructure * initStruct 包含JPEG解码器相关设定值的结构体
  30. * 输 出: 无
  31. * 注意事项: 无
  32. ******************************************************************************************************************************************/
  33. void JPEG_Init(JPEG_TypeDef * JPEGx, JPEG_InitStructure * initStruct)
  34. {
  35. switch((uint32_t)JPEGx)
  36. {
  37. case ((uint32_t)JPEG):
  38. SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_JPEG_Pos);
  39. break;
  40. }
  41. JPEGx->IR = JPEG_IR_ICDONE_Msk |
  42. JPEG_IR_ICERROR_Msk;
  43. JPEGx->IR = ((initStruct->DoneIEn ? 1 : 0) << JPEG_IR_IEDONE_Pos) |
  44. ((initStruct->ErrorIEn ? 1 : 0) << JPEG_IR_IEERROR_Pos);
  45. switch((uint32_t)JPEGx)
  46. {
  47. case ((uint32_t)JPEG):
  48. if(initStruct->DoneIEn | initStruct->ErrorIEn)
  49. {
  50. NVIC_EnableIRQ(JPEG_IRQn);
  51. }
  52. else
  53. {
  54. NVIC_DisableIRQ(JPEG_IRQn);
  55. }
  56. break;
  57. }
  58. }
  59. /******************************************************************************************************************************************
  60. * 函数名称: JPEG_Decode()
  61. * 功能说明: JPEG解码器解码
  62. * 输 入: JPEG_TypeDef * JPEGx 指定要被设置的JPEG解码器,有效值包括JPEG
  63. * jfif_info_t * jfif_info 要解码图像的信息
  64. * jpeg_outset_t * jpeg_outset 解码输出设定
  65. * 输 出: 无
  66. * 注意事项: 无
  67. ******************************************************************************************************************************************/
  68. void JPEG_Decode(JPEG_TypeDef * JPEGx, jfif_info_t * jfif_info, jpeg_outset_t * jpeg_outset)
  69. {
  70. int32_t i, j;
  71. uint8_t hxvx;
  72. uint8_t out_rgb = ((jpeg_outset->format & 7) > 1 ? 1 : 0); // output rgb ?
  73. switch((jfif_info->CompInfo[0].hfactor << 4) | jfif_info->CompInfo[0].vfactor)
  74. {
  75. case 0x11: hxvx = JPEG_FMT_H1V1; break;
  76. case 0x21: hxvx = JPEG_FMT_H2V1; break;
  77. case 0x22: hxvx = JPEG_FMT_H2V2; break;
  78. default: return;
  79. }
  80. JPEGx->CFG = (hxvx << JPEG_CFG_SRCFMT_Pos) |
  81. (0 << JPEG_CFG_SCANMOD_Pos) |
  82. (0 << JPEG_CFG_NISCOMP_Pos) |
  83. (jfif_info->CompInfo[0].htab_id_dc << JPEG_CFG_HT1COMP_Pos) |
  84. (jfif_info->CompInfo[1].htab_id_dc << JPEG_CFG_HT2COMP_Pos) |
  85. (jfif_info->CompInfo[2].htab_id_dc << JPEG_CFG_HT3COMP_Pos) |
  86. (jfif_info->CompInfo[0].qtab_id << JPEG_CFG_QT1COMP_Pos) |
  87. (jfif_info->CompInfo[1].qtab_id << JPEG_CFG_QT2COMP_Pos) |
  88. (jfif_info->CompInfo[2].qtab_id << JPEG_CFG_QT3COMP_Pos) |
  89. (jpeg_outset->format << JPEG_CFG_OUTFMT_Pos) |
  90. (out_rgb << JPEG_CFG_YUV2RGB_Pos) |
  91. (jpeg_outset->dither << JPEG_CFG_565DITH_Pos);
  92. JPEGx->IMGSIZ = ((jfif_info->Width - 1) << JPEG_IMGSIZ_HPIX_Pos) |
  93. ((jfif_info->Height - 1) << JPEG_IMGSIZ_VPIX_Pos);
  94. JPEGx->CSBASE = jfif_info->CodeAddr;
  95. JPEGx->CODLEN = jfif_info->CodeLen - 1;
  96. if(out_rgb)
  97. {
  98. JPEGx->RGBASE = jpeg_outset->RGBAddr;
  99. switch(jpeg_outset->format & 7)
  100. {
  101. case JPEG_OUT_XRGB888:
  102. JPEG->IMGSTR = jfif_info->Width << JPEG_IMGSTR_RGBLINE_Pos;
  103. break;
  104. case JPEG_OUT_RGB888:
  105. JPEG->IMGSTR = (int)ceil(jfif_info->Width*3/4.0) << JPEG_IMGSTR_RGBLINE_Pos;
  106. break;
  107. case JPEG_OUT_RGB565:
  108. JPEG->IMGSTR = (int)ceil(jfif_info->Width / 2.0) << JPEG_IMGSTR_RGBLINE_Pos;
  109. break;
  110. }
  111. }
  112. else
  113. {
  114. JPEGx->YBASE = jpeg_outset->YAddr;
  115. JPEGx->UBASE = jpeg_outset->CbAddr;
  116. JPEGx->VBASE = jpeg_outset->CrAddr;
  117. switch(((jpeg_outset->format & 7) << 4) | hxvx)
  118. {
  119. case (JPEG_OUT_YUV << 4) | JPEG_FMT_H1V1:
  120. JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
  121. ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_UVLINE_Pos);
  122. break;
  123. case (JPEG_OUT_YUV << 4) | JPEG_FMT_H2V1:
  124. case (JPEG_OUT_YUV << 4) | JPEG_FMT_H2V2:
  125. JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
  126. ((int)ceil(jfif_info->Width / 8.0) << JPEG_IMGSTR_UVLINE_Pos);
  127. break;
  128. case (JPEG_OUT_YUVsp << 4) | JPEG_FMT_H1V1:
  129. JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
  130. ((int)ceil(jfif_info->Width / 2.0) << JPEG_IMGSTR_UVLINE_Pos);
  131. break;
  132. case (JPEG_OUT_YUVsp << 4) | JPEG_FMT_H2V1:
  133. case (JPEG_OUT_YUVsp << 4) | JPEG_FMT_H2V2:
  134. JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
  135. ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_UVLINE_Pos);
  136. break;
  137. }
  138. }
  139. for(i = 0; i < jfif_info->QTableCnt; i++)
  140. {
  141. for(j = 0; j < 16; j++)
  142. {
  143. JPEGx->QTABLE[i][j] = ((uint32_t *)&jfif_info->QTable[i])[j];
  144. }
  145. }
  146. for(i = 0; i < jfif_info->HTableCnt; i++)
  147. {
  148. /* DC Haffman Table */
  149. for(j = 0; j < 12; j += 2)
  150. {
  151. JPEGx->HTABLE[i].DC_CODEWORD[j/2] = (jfif_info->HTable[i].DC.codeWord[j] << (16 - jfif_info->HTable[i].DC.codeLen[j])) |
  152. (jfif_info->HTable[i].DC.codeWord[j+1] << (32 - jfif_info->HTable[i].DC.codeLen[j+1]));
  153. }
  154. for(j = 10; j > 1; j -= 2)
  155. {
  156. if((jfif_info->HTable[i].DC.codeWord[j+1] == 0) && (jfif_info->HTable[i].DC.codeWord[j] == 0))
  157. JPEGx->HTABLE[i].DC_CODEWORD[j/2] = 0xFFFFFFFF;
  158. else if(jfif_info->HTable[i].DC.codeWord[j+1] == 0)
  159. JPEGx->HTABLE[i].DC_CODEWORD[j/2] = 0xFFFF0000 | (jfif_info->HTable[i].DC.codeWord[j] << (16 - jfif_info->HTable[i].DC.codeLen[j]));
  160. else
  161. break;
  162. }
  163. JPEGx->HTABLE[i].DC_CODELEN[0] = ((jfif_info->HTable[i].DC.codeLen[0] ? jfif_info->HTable[i].DC.codeLen[0] - 1 : 0) << 0) |
  164. ((jfif_info->HTable[i].DC.codeLen[1] ? jfif_info->HTable[i].DC.codeLen[1] - 1 : 0) << 4) |
  165. ((jfif_info->HTable[i].DC.codeLen[2] ? jfif_info->HTable[i].DC.codeLen[2] - 1 : 0) << 8) |
  166. ((jfif_info->HTable[i].DC.codeLen[3] ? jfif_info->HTable[i].DC.codeLen[3] - 1 : 0) << 12) |
  167. ((jfif_info->HTable[i].DC.codeLen[4] ? jfif_info->HTable[i].DC.codeLen[4] - 1 : 0) << 16) |
  168. ((jfif_info->HTable[i].DC.codeLen[5] ? jfif_info->HTable[i].DC.codeLen[5] - 1 : 0) << 20) |
  169. ((jfif_info->HTable[i].DC.codeLen[6] ? jfif_info->HTable[i].DC.codeLen[6] - 1 : 0) << 24) |
  170. ((jfif_info->HTable[i].DC.codeLen[7] ? jfif_info->HTable[i].DC.codeLen[7] - 1 : 0) << 28);
  171. JPEGx->HTABLE[i].DC_CODELEN[1] = ((jfif_info->HTable[i].DC.codeLen[8] ? jfif_info->HTable[i].DC.codeLen[8] - 1 : 0) << 0) |
  172. ((jfif_info->HTable[i].DC.codeLen[9] ? jfif_info->HTable[i].DC.codeLen[9] - 1 : 0) << 4) |
  173. ((jfif_info->HTable[i].DC.codeLen[10] ? jfif_info->HTable[i].DC.codeLen[10]- 1 : 0) << 8) |
  174. ((jfif_info->HTable[i].DC.codeLen[11] ? jfif_info->HTable[i].DC.codeLen[11]- 1 : 0) << 12);
  175. JPEGx->HTABLE[i].DC_CODEVAL[0] = (jfif_info->HTable[i].DC.codeVal[0] << 0) |
  176. (jfif_info->HTable[i].DC.codeVal[1] << 4) |
  177. (jfif_info->HTable[i].DC.codeVal[2] << 8) |
  178. (jfif_info->HTable[i].DC.codeVal[3] << 12) |
  179. (jfif_info->HTable[i].DC.codeVal[4] << 16) |
  180. (jfif_info->HTable[i].DC.codeVal[5] << 20) |
  181. (jfif_info->HTable[i].DC.codeVal[6] << 24) |
  182. (jfif_info->HTable[i].DC.codeVal[7] << 28);
  183. JPEGx->HTABLE[i].DC_CODEVAL[1] = (jfif_info->HTable[i].DC.codeVal[8] << 0) |
  184. (jfif_info->HTable[i].DC.codeVal[9] << 4) |
  185. (jfif_info->HTable[i].DC.codeVal[10]<< 8) |
  186. (jfif_info->HTable[i].DC.codeVal[11]<< 12);
  187. /* AC Haffman Table */
  188. uint16_t minCode[16]; // mini code word for each lenght
  189. uint8_t minIndx[16]; // index of mincode
  190. uint8_t prelen; // preiou Len
  191. memset(minCode, 0, sizeof(minCode));
  192. memset(minIndx, 0, sizeof(minIndx));
  193. for(j = 0, prelen = 0; j < 162; j++)
  194. {
  195. if(jfif_info->HTable[i].AC.codeLen[j] == 0) break;
  196. if(jfif_info->HTable[i].AC.codeLen[j] != prelen)
  197. {
  198. minCode[jfif_info->HTable[i].AC.codeLen[j] - 1] = jfif_info->HTable[i].AC.codeWord[j] << (16 - jfif_info->HTable[i].AC.codeLen[j]);
  199. minIndx[jfif_info->HTable[i].AC.codeLen[j] - 1] = j;
  200. prelen = jfif_info->HTable[i].AC.codeLen[j];
  201. }
  202. }
  203. if(minCode[15] == 0) minCode[15] = 0xFFFF;
  204. for(j = 14; j > jfif_info->HTable[i].AC.codeLen[0] - 1; j--)
  205. {
  206. if(minCode[j] == 0) minCode[j] = minCode[j+1];
  207. }
  208. for(j = 0; j < 16; j += 2)
  209. {
  210. JPEGx->HTABLE[i].AC_CODEWORD[j/2] = (minCode[j] << 0) |
  211. (minCode[j+1] << 16);
  212. }
  213. for(j = 0; j < 16; j += 4)
  214. {
  215. JPEGx->HTABLE[i].AC_CODEADDR[j/4] = (minIndx[j] << 0) |
  216. (minIndx[j+1] << 8) |
  217. (minIndx[j+2] << 16) |
  218. (minIndx[j+3] << 24);
  219. }
  220. for(j = 0; j < 164; j += 4)
  221. {
  222. JPEGx->HTABLE[i].AC_CODEVAL[j/4] = (jfif_info->HTable[i].AC.codeVal[j] << 0) |
  223. (jfif_info->HTable[i].AC.codeVal[j+1] << 8) |
  224. (jfif_info->HTable[i].AC.codeVal[j+2] << 16) |
  225. (jfif_info->HTable[i].AC.codeVal[j+3] << 24);
  226. }
  227. }
  228. JPEGx->CR = (1 << JPEG_CR_LASTBUF_Pos) |
  229. (1 << JPEG_CR_START_Pos);
  230. }
  231. /******************************************************************************************************************************************
  232. * 函数名称: JPEG_DecodeBusy()
  233. * 功能说明: JPEG解码器忙查询
  234. * 输 入: JPEG_TypeDef * JPEGx 指定要被设置的JPEG解码器,有效值包括JPEG
  235. * 输 出: uint32_t 1 正在解码 0 空闲,未在解码
  236. * 注意事项: 无
  237. ******************************************************************************************************************************************/
  238. uint32_t JPEG_DecodeBusy(JPEG_TypeDef * JPEGx)
  239. {
  240. return (JPEGx->SR & JPEG_SR_BUSY_Msk) ? 1 : 0;
  241. }