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 
24 #include <math.h>
25 #include <string.h>
26 
27 
28 /******************************************************************************************************************************************
29 * 函数名称: JPEG_Init()
30 * 功能说明: JPEG解码器初始化
31 * 输    入: JPEG_TypeDef * JPEGx  指定要被设置的JPEG解码器,有效值包括JPEG
32 *           JPEG_InitStructure * initStruct    包含JPEG解码器相关设定值的结构体
33 * 输    出: 无
34 * 注意事项: 无
35 ******************************************************************************************************************************************/
JPEG_Init(JPEG_TypeDef * JPEGx,JPEG_InitStructure * initStruct)36 void JPEG_Init(JPEG_TypeDef * JPEGx, JPEG_InitStructure * initStruct)
37 {
38     switch((uint32_t)JPEGx)
39     {
40     case ((uint32_t)JPEG):
41         SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_JPEG_Pos);
42         break;
43     }
44 
45     JPEGx->IR = JPEG_IR_ICDONE_Msk |
46                 JPEG_IR_ICERROR_Msk;
47     JPEGx->IR = ((initStruct->DoneIEn  ? 1 : 0) << JPEG_IR_IEDONE_Pos) |
48                 ((initStruct->ErrorIEn ? 1 : 0) << JPEG_IR_IEERROR_Pos);
49 
50     switch((uint32_t)JPEGx)
51     {
52     case ((uint32_t)JPEG):
53         if(initStruct->DoneIEn | initStruct->ErrorIEn)
54         {
55             NVIC_EnableIRQ(JPEG_IRQn);
56         }
57         else
58         {
59             NVIC_DisableIRQ(JPEG_IRQn);
60         }
61         break;
62     }
63 }
64 
65 
66 /******************************************************************************************************************************************
67 * 函数名称: JPEG_Decode()
68 * 功能说明: JPEG解码器解码
69 * 输    入: JPEG_TypeDef * JPEGx  指定要被设置的JPEG解码器,有效值包括JPEG
70 *           jfif_info_t * jfif_info     要解码图像的信息
71 *           jpeg_outset_t * jpeg_outset 解码输出设定
72 * 输    出: 无
73 * 注意事项: 无
74 ******************************************************************************************************************************************/
JPEG_Decode(JPEG_TypeDef * JPEGx,jfif_info_t * jfif_info,jpeg_outset_t * jpeg_outset)75 void JPEG_Decode(JPEG_TypeDef * JPEGx, jfif_info_t * jfif_info, jpeg_outset_t * jpeg_outset)
76 {
77     int32_t i, j;
78     uint8_t hxvx;
79     uint8_t out_rgb = ((jpeg_outset->format & 7) > 1 ? 1 : 0);  // output rgb ?
80 
81     switch((jfif_info->CompInfo[0].hfactor << 4) | jfif_info->CompInfo[0].vfactor)
82     {
83     case 0x11: hxvx = JPEG_FMT_H1V1;  break;
84     case 0x21: hxvx = JPEG_FMT_H2V1;  break;
85     case 0x22: hxvx = JPEG_FMT_H2V2;  break;
86     default:   return;
87     }
88 
89     JPEGx->CFG = (hxvx << JPEG_CFG_SRCFMT_Pos)  |
90                  (0    << JPEG_CFG_SCANMOD_Pos) |
91                  (0    << JPEG_CFG_NISCOMP_Pos) |
92                  (jfif_info->CompInfo[0].htab_id_dc << JPEG_CFG_HT1COMP_Pos) |
93                  (jfif_info->CompInfo[1].htab_id_dc << JPEG_CFG_HT2COMP_Pos) |
94                  (jfif_info->CompInfo[2].htab_id_dc << JPEG_CFG_HT3COMP_Pos) |
95                  (jfif_info->CompInfo[0].qtab_id    << JPEG_CFG_QT1COMP_Pos) |
96                  (jfif_info->CompInfo[1].qtab_id    << JPEG_CFG_QT2COMP_Pos) |
97                  (jfif_info->CompInfo[2].qtab_id    << JPEG_CFG_QT3COMP_Pos) |
98                  (jpeg_outset->format << JPEG_CFG_OUTFMT_Pos)  |
99                  (out_rgb             << JPEG_CFG_YUV2RGB_Pos) |
100                  (jpeg_outset->dither << JPEG_CFG_565DITH_Pos);
101 
102     JPEGx->IMGSIZ = ((jfif_info->Width  - 1) << JPEG_IMGSIZ_HPIX_Pos) |
103                     ((jfif_info->Height - 1) << JPEG_IMGSIZ_VPIX_Pos);
104 
105     JPEGx->CSBASE = jfif_info->CodeAddr;
106     JPEGx->CODLEN = jfif_info->CodeLen - 1;
107 
108     if(out_rgb)
109     {
110         JPEGx->RGBASE = jpeg_outset->RGBAddr;
111 
112         switch(jpeg_outset->format & 7)
113         {
114         case JPEG_OUT_XRGB888:
115             JPEG->IMGSTR = jfif_info->Width << JPEG_IMGSTR_RGBLINE_Pos;
116             break;
117 
118         case JPEG_OUT_RGB888:
119             JPEG->IMGSTR = (int)ceil(jfif_info->Width*3/4.0) << JPEG_IMGSTR_RGBLINE_Pos;
120             break;
121 
122         case JPEG_OUT_RGB565:
123             JPEG->IMGSTR = (int)ceil(jfif_info->Width / 2.0) << JPEG_IMGSTR_RGBLINE_Pos;
124             break;
125         }
126     }
127     else
128     {
129         JPEGx->YBASE  = jpeg_outset->YAddr;
130         JPEGx->UBASE  = jpeg_outset->CbAddr;
131         JPEGx->VBASE  = jpeg_outset->CrAddr;
132 
133         switch(((jpeg_outset->format & 7) << 4) | hxvx)
134         {
135         case (JPEG_OUT_YUV << 4) | JPEG_FMT_H1V1:
136             JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
137                            ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_UVLINE_Pos);
138             break;
139 
140         case (JPEG_OUT_YUV << 4) | JPEG_FMT_H2V1:
141         case (JPEG_OUT_YUV << 4) | JPEG_FMT_H2V2:
142             JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
143                            ((int)ceil(jfif_info->Width / 8.0) << JPEG_IMGSTR_UVLINE_Pos);
144             break;
145 
146         case (JPEG_OUT_YUVsp << 4) | JPEG_FMT_H1V1:
147             JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
148                            ((int)ceil(jfif_info->Width / 2.0) << JPEG_IMGSTR_UVLINE_Pos);
149             break;
150 
151         case (JPEG_OUT_YUVsp << 4) | JPEG_FMT_H2V1:
152         case (JPEG_OUT_YUVsp << 4) | JPEG_FMT_H2V2:
153             JPEG->IMGSTR = ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_YLINE_Pos) |
154                            ((int)ceil(jfif_info->Width / 4.0) << JPEG_IMGSTR_UVLINE_Pos);
155             break;
156         }
157     }
158 
159     for(i = 0; i < jfif_info->QTableCnt; i++)
160     {
161         for(j = 0; j < 16; j++)
162         {
163             JPEGx->QTABLE[i][j] = ((uint32_t *)&jfif_info->QTable[i])[j];
164         }
165     }
166 
167     for(i = 0; i < jfif_info->HTableCnt; i++)
168     {
169         /* DC Haffman Table */
170         for(j = 0; j < 12; j += 2)
171         {
172             JPEGx->HTABLE[i].DC_CODEWORD[j/2] = (jfif_info->HTable[i].DC.codeWord[j]   << (16 - jfif_info->HTable[i].DC.codeLen[j])) |
173                                                 (jfif_info->HTable[i].DC.codeWord[j+1] << (32 - jfif_info->HTable[i].DC.codeLen[j+1]));
174         }
175         for(j = 10; j > 1; j -= 2)
176         {
177             if((jfif_info->HTable[i].DC.codeWord[j+1] == 0) && (jfif_info->HTable[i].DC.codeWord[j] == 0))
178                 JPEGx->HTABLE[i].DC_CODEWORD[j/2] = 0xFFFFFFFF;
179             else if(jfif_info->HTable[i].DC.codeWord[j+1] == 0)
180                 JPEGx->HTABLE[i].DC_CODEWORD[j/2] = 0xFFFF0000 | (jfif_info->HTable[i].DC.codeWord[j] << (16 - jfif_info->HTable[i].DC.codeLen[j]));
181             else
182                 break;
183         }
184 
185         JPEGx->HTABLE[i].DC_CODELEN[0] = ((jfif_info->HTable[i].DC.codeLen[0]  ? jfif_info->HTable[i].DC.codeLen[0] - 1 : 0) <<  0) |
186                                          ((jfif_info->HTable[i].DC.codeLen[1]  ? jfif_info->HTable[i].DC.codeLen[1] - 1 : 0) <<  4) |
187                                          ((jfif_info->HTable[i].DC.codeLen[2]  ? jfif_info->HTable[i].DC.codeLen[2] - 1 : 0) <<  8) |
188                                          ((jfif_info->HTable[i].DC.codeLen[3]  ? jfif_info->HTable[i].DC.codeLen[3] - 1 : 0) << 12) |
189                                          ((jfif_info->HTable[i].DC.codeLen[4]  ? jfif_info->HTable[i].DC.codeLen[4] - 1 : 0) << 16) |
190                                          ((jfif_info->HTable[i].DC.codeLen[5]  ? jfif_info->HTable[i].DC.codeLen[5] - 1 : 0) << 20) |
191                                          ((jfif_info->HTable[i].DC.codeLen[6]  ? jfif_info->HTable[i].DC.codeLen[6] - 1 : 0) << 24) |
192                                          ((jfif_info->HTable[i].DC.codeLen[7]  ? jfif_info->HTable[i].DC.codeLen[7] - 1 : 0) << 28);
193         JPEGx->HTABLE[i].DC_CODELEN[1] = ((jfif_info->HTable[i].DC.codeLen[8]  ? jfif_info->HTable[i].DC.codeLen[8] - 1 : 0) <<  0) |
194                                          ((jfif_info->HTable[i].DC.codeLen[9]  ? jfif_info->HTable[i].DC.codeLen[9] - 1 : 0) <<  4) |
195                                          ((jfif_info->HTable[i].DC.codeLen[10] ? jfif_info->HTable[i].DC.codeLen[10]- 1 : 0) <<  8) |
196                                          ((jfif_info->HTable[i].DC.codeLen[11] ? jfif_info->HTable[i].DC.codeLen[11]- 1 : 0) << 12);
197 
198         JPEGx->HTABLE[i].DC_CODEVAL[0] = (jfif_info->HTable[i].DC.codeVal[0] <<  0) |
199                                          (jfif_info->HTable[i].DC.codeVal[1] <<  4) |
200                                          (jfif_info->HTable[i].DC.codeVal[2] <<  8) |
201                                          (jfif_info->HTable[i].DC.codeVal[3] << 12) |
202                                          (jfif_info->HTable[i].DC.codeVal[4] << 16) |
203                                          (jfif_info->HTable[i].DC.codeVal[5] << 20) |
204                                          (jfif_info->HTable[i].DC.codeVal[6] << 24) |
205                                          (jfif_info->HTable[i].DC.codeVal[7] << 28);
206         JPEGx->HTABLE[i].DC_CODEVAL[1] = (jfif_info->HTable[i].DC.codeVal[8] <<  0) |
207                                          (jfif_info->HTable[i].DC.codeVal[9] <<  4) |
208                                          (jfif_info->HTable[i].DC.codeVal[10]<<  8) |
209                                          (jfif_info->HTable[i].DC.codeVal[11]<< 12);
210 
211         /* AC Haffman Table */
212         uint16_t minCode[16];       // mini code word for each lenght
213         uint8_t  minIndx[16];       // index of mincode
214         uint8_t  prelen;            // preiou Len
215 
216         memset(minCode, 0, sizeof(minCode));
217         memset(minIndx, 0, sizeof(minIndx));
218         for(j = 0, prelen = 0; j < 162; j++)
219         {
220             if(jfif_info->HTable[i].AC.codeLen[j] == 0) break;
221 
222             if(jfif_info->HTable[i].AC.codeLen[j] != prelen)
223             {
224                 minCode[jfif_info->HTable[i].AC.codeLen[j] - 1] = jfif_info->HTable[i].AC.codeWord[j] << (16 - jfif_info->HTable[i].AC.codeLen[j]);
225                 minIndx[jfif_info->HTable[i].AC.codeLen[j] - 1] = j;
226 
227                 prelen = jfif_info->HTable[i].AC.codeLen[j];
228             }
229         }
230 
231         if(minCode[15] == 0) minCode[15] = 0xFFFF;
232         for(j = 14; j > jfif_info->HTable[i].AC.codeLen[0] - 1; j--)
233         {
234             if(minCode[j] == 0) minCode[j] = minCode[j+1];
235         }
236 
237         for(j = 0; j < 16; j += 2)
238         {
239             JPEGx->HTABLE[i].AC_CODEWORD[j/2] = (minCode[j]   << 0)  |
240                                                 (minCode[j+1] << 16);
241         }
242 
243         for(j = 0; j < 16; j += 4)
244         {
245             JPEGx->HTABLE[i].AC_CODEADDR[j/4] = (minIndx[j]   << 0)  |
246                                                 (minIndx[j+1] << 8)  |
247                                                 (minIndx[j+2] << 16) |
248                                                 (minIndx[j+3] << 24);
249         }
250 
251         for(j = 0; j < 164; j += 4)
252         {
253             JPEGx->HTABLE[i].AC_CODEVAL[j/4] = (jfif_info->HTable[i].AC.codeVal[j]   <<  0) |
254                                                (jfif_info->HTable[i].AC.codeVal[j+1] <<  8) |
255                                                (jfif_info->HTable[i].AC.codeVal[j+2] << 16) |
256                                                (jfif_info->HTable[i].AC.codeVal[j+3] << 24);
257         }
258     }
259 
260     JPEGx->CR = (1 << JPEG_CR_LASTBUF_Pos) |
261                 (1 << JPEG_CR_START_Pos);
262 }
263 
264 
265 /******************************************************************************************************************************************
266 * 函数名称: JPEG_DecodeBusy()
267 * 功能说明: JPEG解码器忙查询
268 * 输    入: JPEG_TypeDef * JPEGx  指定要被设置的JPEG解码器,有效值包括JPEG
269 * 输    出: uint32_t              1 正在解码    0 空闲,未在解码
270 * 注意事项: 无
271 ******************************************************************************************************************************************/
JPEG_DecodeBusy(JPEG_TypeDef * JPEGx)272 uint32_t JPEG_DecodeBusy(JPEG_TypeDef * JPEGx)
273 {
274     return (JPEGx->SR & JPEG_SR_BUSY_Msk) ? 1 : 0;
275 }
276