xref: /rockchip-linux_mpp/mpp/codec/dec/jpeg/jpegd_parser.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  *
3*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
4*437bfbebSnyanmisaka  *
5*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
6*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
7*437bfbebSnyanmisaka  * You may obtain a copy of the License at
8*437bfbebSnyanmisaka  *
9*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
10*437bfbebSnyanmisaka  *
11*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
12*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
13*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
15*437bfbebSnyanmisaka  * limitations under the License.
16*437bfbebSnyanmisaka  */
17*437bfbebSnyanmisaka 
18*437bfbebSnyanmisaka #define MODULE_TAG "jpegd_parser"
19*437bfbebSnyanmisaka 
20*437bfbebSnyanmisaka #include <string.h>
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #include "mpp_env.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_soc.h"
25*437bfbebSnyanmisaka #include "mpp_debug.h"
26*437bfbebSnyanmisaka #include "mpp_bitread.h"
27*437bfbebSnyanmisaka #include "mpp_packet_impl.h"
28*437bfbebSnyanmisaka 
29*437bfbebSnyanmisaka #include "jpegd_api.h"
30*437bfbebSnyanmisaka #include "jpegd_parser.h"
31*437bfbebSnyanmisaka #include "mpp_dec_cb_param.h"
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka RK_U32 jpegd_debug = 0x0;
34*437bfbebSnyanmisaka 
35*437bfbebSnyanmisaka /* return the 8 bit start code value and update the search
36*437bfbebSnyanmisaka    state. Return 0 if no start code found */
jpegd_find_marker(const RK_U8 ** pbuf_ptr,const RK_U8 * buf_end)37*437bfbebSnyanmisaka static RK_U8 jpegd_find_marker(const RK_U8 **pbuf_ptr, const RK_U8 *buf_end)
38*437bfbebSnyanmisaka {
39*437bfbebSnyanmisaka     const RK_U8 *buf_ptr = NULL;
40*437bfbebSnyanmisaka     RK_U8 val = 0;
41*437bfbebSnyanmisaka     RK_U8 start_code = 0xff;
42*437bfbebSnyanmisaka     RK_U32 strm_len = buf_end - *pbuf_ptr + 1;
43*437bfbebSnyanmisaka 
44*437bfbebSnyanmisaka     while (*pbuf_ptr < buf_end) {
45*437bfbebSnyanmisaka         buf_ptr = memchr(*pbuf_ptr, start_code, strm_len);
46*437bfbebSnyanmisaka 
47*437bfbebSnyanmisaka         if (!buf_ptr) {
48*437bfbebSnyanmisaka             mpp_err("Start codec not found!\n");
49*437bfbebSnyanmisaka             return 0;
50*437bfbebSnyanmisaka         }
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka         RK_U8 marker = *(buf_ptr + 1);
53*437bfbebSnyanmisaka         if (marker >= 0xc0 && marker <= 0xfe) {
54*437bfbebSnyanmisaka             val = *(buf_ptr + 1);
55*437bfbebSnyanmisaka             jpegd_dbg_marker("find_marker skipped %d bytes\n", buf_ptr - *pbuf_ptr);
56*437bfbebSnyanmisaka             *pbuf_ptr = buf_ptr;
57*437bfbebSnyanmisaka             return val;
58*437bfbebSnyanmisaka         } else {
59*437bfbebSnyanmisaka             jpegd_dbg_marker("0x%x is not a marker\n", marker);
60*437bfbebSnyanmisaka             (*pbuf_ptr)++;
61*437bfbebSnyanmisaka         }
62*437bfbebSnyanmisaka     }
63*437bfbebSnyanmisaka     return 0;
64*437bfbebSnyanmisaka }
65*437bfbebSnyanmisaka 
jpegd_find_eoi(const RK_U8 ** pbuf_ptr,const RK_U8 * buf_end)66*437bfbebSnyanmisaka static MPP_RET jpegd_find_eoi(const RK_U8 **pbuf_ptr, const RK_U8 *buf_end)
67*437bfbebSnyanmisaka {
68*437bfbebSnyanmisaka     const RK_U8 *buf_ptr = NULL;
69*437bfbebSnyanmisaka     RK_S32 eoi = 0xffd9;
70*437bfbebSnyanmisaka     RK_U32 strm_len = buf_end - *pbuf_ptr + 1;
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka     if (*pbuf_ptr >= buf_end) {
73*437bfbebSnyanmisaka         mpp_err("buf ptr %p is overflow the buf end %p.", *pbuf_ptr, buf_end);
74*437bfbebSnyanmisaka         return MPP_NOK;
75*437bfbebSnyanmisaka     }
76*437bfbebSnyanmisaka 
77*437bfbebSnyanmisaka     buf_ptr = memchr(*pbuf_ptr, eoi, strm_len);
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka     if (buf_ptr && (buf_end > buf_ptr)) {
80*437bfbebSnyanmisaka         return MPP_OK;
81*437bfbebSnyanmisaka     }
82*437bfbebSnyanmisaka 
83*437bfbebSnyanmisaka     return MPP_NOK;
84*437bfbebSnyanmisaka }
85*437bfbebSnyanmisaka 
jpeg_judge_yuv_mode(JpegdCtx * ctx)86*437bfbebSnyanmisaka static MPP_RET jpeg_judge_yuv_mode(JpegdCtx *ctx)
87*437bfbebSnyanmisaka {
88*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
89*437bfbebSnyanmisaka     JpegdSyntax *s = ctx->syntax;
90*437bfbebSnyanmisaka 
91*437bfbebSnyanmisaka     /*  check input format */
92*437bfbebSnyanmisaka     if (s->nb_components == 3) {
93*437bfbebSnyanmisaka         if (s->h_count[0] == 2 && s->v_count[0] == 2 &&
94*437bfbebSnyanmisaka             s->h_count[1] == 1 && s->v_count[1] == 1 &&
95*437bfbebSnyanmisaka             s->h_count[2] == 1 && s->v_count[2] == 1) {
96*437bfbebSnyanmisaka             jpegd_dbg_marker("YCbCr Format: YUV420(2*2:1*1:1*1)\n");
97*437bfbebSnyanmisaka             s->yuv_mode = JPEGDEC_YUV420;
98*437bfbebSnyanmisaka             s->output_fmt = MPP_FMT_YUV420SP;
99*437bfbebSnyanmisaka         } else if (s->h_count[0] == 2 && s->v_count[0] == 1 &&
100*437bfbebSnyanmisaka                    s->h_count[1] == 1 && s->v_count[1] == 1 &&
101*437bfbebSnyanmisaka                    s->h_count[2] == 1 && s->v_count[2] == 1) {
102*437bfbebSnyanmisaka             jpegd_dbg_marker("YCbCr Format: YUV422(2*1:1*1:1*1)\n");
103*437bfbebSnyanmisaka             s->yuv_mode = JPEGDEC_YUV422;
104*437bfbebSnyanmisaka             s->output_fmt = MPP_FMT_YUV422SP;
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka             /* check if fill needed */
107*437bfbebSnyanmisaka             if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
108*437bfbebSnyanmisaka                 s->fill_bottom = 1;
109*437bfbebSnyanmisaka             }
110*437bfbebSnyanmisaka         } else if (s->h_count[0] == 1 && s->v_count[0] == 2 &&
111*437bfbebSnyanmisaka                    s->h_count[1] == 1 && s->v_count[1] == 1 &&
112*437bfbebSnyanmisaka                    s->h_count[2] == 1 && s->v_count[2] == 1) {
113*437bfbebSnyanmisaka             jpegd_dbg_marker("YCbCr Format: YUV440(1*2:1*1:1*1)\n");
114*437bfbebSnyanmisaka             s->yuv_mode = JPEGDEC_YUV440;
115*437bfbebSnyanmisaka             s->output_fmt = MPP_FMT_YUV440SP;
116*437bfbebSnyanmisaka 
117*437bfbebSnyanmisaka             /* check if fill needed */
118*437bfbebSnyanmisaka             if ((s->width & 0xf) && ((s->width & 0xf) <= 8)) {
119*437bfbebSnyanmisaka                 s->fill_right = 1;
120*437bfbebSnyanmisaka             }
121*437bfbebSnyanmisaka         } else if (s->h_count[0] == 1 && s->v_count[0] == 1 &&
122*437bfbebSnyanmisaka                    s->h_count[1] == 1 && s->v_count[1] == 1 &&
123*437bfbebSnyanmisaka                    s->h_count[2] == 1 && s->v_count[2] == 1) {
124*437bfbebSnyanmisaka             jpegd_dbg_marker("YCbCr Format: YUV444(1*1:1*1:1*1)\n");
125*437bfbebSnyanmisaka             s->yuv_mode = JPEGDEC_YUV444;
126*437bfbebSnyanmisaka             s->output_fmt = MPP_FMT_YUV444SP;
127*437bfbebSnyanmisaka 
128*437bfbebSnyanmisaka             /* check if fill needed */
129*437bfbebSnyanmisaka             if ((s->width & 0xf) && ((s->width & 0xf) <= 8)) {
130*437bfbebSnyanmisaka                 s->fill_right = 1;
131*437bfbebSnyanmisaka             }
132*437bfbebSnyanmisaka 
133*437bfbebSnyanmisaka             if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
134*437bfbebSnyanmisaka                 s->fill_bottom = 1;
135*437bfbebSnyanmisaka             }
136*437bfbebSnyanmisaka         } else if (s->h_count[0] == 4 && s->v_count[0] == 1 &&
137*437bfbebSnyanmisaka                    s->h_count[1] == 1 && s->v_count[1] == 1 &&
138*437bfbebSnyanmisaka                    s->h_count[2] == 1 && s->v_count[2] == 1) {
139*437bfbebSnyanmisaka             jpegd_dbg_marker("YCbCr Format: YUV411(4*1:1*1:1*1)\n");
140*437bfbebSnyanmisaka             s->yuv_mode = JPEGDEC_YUV411;
141*437bfbebSnyanmisaka             s->output_fmt = MPP_FMT_YUV411SP;
142*437bfbebSnyanmisaka 
143*437bfbebSnyanmisaka             /* check if fill needed */
144*437bfbebSnyanmisaka             if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
145*437bfbebSnyanmisaka                 s->fill_bottom = 1;
146*437bfbebSnyanmisaka             }
147*437bfbebSnyanmisaka         } else {
148*437bfbebSnyanmisaka             mpp_err_f("Unsupported YCbCr Format: (%d*%d:%d*%d:%d*%d)\n",
149*437bfbebSnyanmisaka                       s->h_count[0], s->v_count[0],
150*437bfbebSnyanmisaka                       s->h_count[1], s->v_count[1],
151*437bfbebSnyanmisaka                       s->h_count[2], s->v_count[2]);
152*437bfbebSnyanmisaka             ret = MPP_ERR_STREAM;
153*437bfbebSnyanmisaka         }
154*437bfbebSnyanmisaka     } else if (s->nb_components == 1) {
155*437bfbebSnyanmisaka         if (s->h_count[0] == s->v_count[0] && s->h_count[0] != 0) {
156*437bfbebSnyanmisaka             s->yuv_mode = JPEGDEC_YUV400;
157*437bfbebSnyanmisaka             s->output_fmt = MPP_FMT_YUV400;
158*437bfbebSnyanmisaka             /* check if fill needed */
159*437bfbebSnyanmisaka             if ((s->width & 0xf) && ((s->width & 0xf) <= 8)) {
160*437bfbebSnyanmisaka                 s->fill_right = 1;
161*437bfbebSnyanmisaka             }
162*437bfbebSnyanmisaka 
163*437bfbebSnyanmisaka             if ((s->height & 0xf) && ((s->height & 0xf) <= 8)) {
164*437bfbebSnyanmisaka                 s->fill_bottom = 1;
165*437bfbebSnyanmisaka             }
166*437bfbebSnyanmisaka         } else {
167*437bfbebSnyanmisaka             mpp_err_f("unsupported format(%d*%d)\n", s->h_count[0],
168*437bfbebSnyanmisaka                       s->v_count[0]);
169*437bfbebSnyanmisaka             ret = MPP_ERR_STREAM;
170*437bfbebSnyanmisaka         }
171*437bfbebSnyanmisaka     } else {
172*437bfbebSnyanmisaka         mpp_err_f("unsupported format, nb_components=%d\n", s->nb_components);
173*437bfbebSnyanmisaka         ret = MPP_ERR_STREAM;
174*437bfbebSnyanmisaka     }
175*437bfbebSnyanmisaka 
176*437bfbebSnyanmisaka     return ret;
177*437bfbebSnyanmisaka }
178*437bfbebSnyanmisaka 
jpegd_read_len(BitReadCtx_t * gb)179*437bfbebSnyanmisaka static inline RK_U16 jpegd_read_len(BitReadCtx_t *gb)
180*437bfbebSnyanmisaka {
181*437bfbebSnyanmisaka     RK_U8 lh, ll;
182*437bfbebSnyanmisaka     READ_BITS(gb, 8, &lh);
183*437bfbebSnyanmisaka     READ_BITS(gb, 8, &ll);
184*437bfbebSnyanmisaka     return (((RK_U16)lh) << 8) | ((RK_U16)ll);
185*437bfbebSnyanmisaka 
186*437bfbebSnyanmisaka __BITREAD_ERR:
187*437bfbebSnyanmisaka     return 0;
188*437bfbebSnyanmisaka }
189*437bfbebSnyanmisaka 
jpegd_skip_section(JpegdCtx * ctx)190*437bfbebSnyanmisaka static MPP_RET jpegd_skip_section(JpegdCtx *ctx)
191*437bfbebSnyanmisaka {
192*437bfbebSnyanmisaka     BitReadCtx_t *gb = ctx->bit_ctx;
193*437bfbebSnyanmisaka     RK_U16 len = 0;
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka     if (gb->bytes_left_ < 2)
196*437bfbebSnyanmisaka         return MPP_ERR_READ_BIT;
197*437bfbebSnyanmisaka     len = jpegd_read_len(gb);
198*437bfbebSnyanmisaka     if (len < 2 /* invalid marker */ || (RK_U32)len - 2 > gb->bytes_left_) {
199*437bfbebSnyanmisaka         /* too short length or bytes is not enough */
200*437bfbebSnyanmisaka         return MPP_ERR_READ_BIT;
201*437bfbebSnyanmisaka     }
202*437bfbebSnyanmisaka     if (len > 2)
203*437bfbebSnyanmisaka         SKIP_BITS(gb, (len - 2) * 8);
204*437bfbebSnyanmisaka 
205*437bfbebSnyanmisaka     return MPP_OK;
206*437bfbebSnyanmisaka 
207*437bfbebSnyanmisaka __BITREAD_ERR:
208*437bfbebSnyanmisaka     return MPP_NOK;
209*437bfbebSnyanmisaka }
210*437bfbebSnyanmisaka 
jpegd_decode_dht(JpegdCtx * ctx)211*437bfbebSnyanmisaka static MPP_RET jpegd_decode_dht(JpegdCtx *ctx)
212*437bfbebSnyanmisaka {
213*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
214*437bfbebSnyanmisaka     BitReadCtx_t *gb = ctx->bit_ctx;
215*437bfbebSnyanmisaka     JpegdSyntax *syntax = ctx->syntax;
216*437bfbebSnyanmisaka     RK_U32 len, num, value;
217*437bfbebSnyanmisaka     RK_U32 table_type, table_id;
218*437bfbebSnyanmisaka     RK_U32  i, code_max;
219*437bfbebSnyanmisaka 
220*437bfbebSnyanmisaka     len = jpegd_read_len(gb);
221*437bfbebSnyanmisaka     len -= 2; /* Huffman Table Length */
222*437bfbebSnyanmisaka 
223*437bfbebSnyanmisaka     if (len > gb->bytes_left_) {
224*437bfbebSnyanmisaka         mpp_err_f("dht: len %d is too large\n", len);
225*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
226*437bfbebSnyanmisaka     }
227*437bfbebSnyanmisaka     jpegd_dbg_marker("dht: huffman tables length=%d\n", len);
228*437bfbebSnyanmisaka 
229*437bfbebSnyanmisaka     while (len > 0) {
230*437bfbebSnyanmisaka         if (len < MAX_HUFFMAN_CODE_BIT_LENGTH + 1) {
231*437bfbebSnyanmisaka             mpp_err_f("dht: len %d is too small\n", len);
232*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
233*437bfbebSnyanmisaka         }
234*437bfbebSnyanmisaka 
235*437bfbebSnyanmisaka         READ_BITS(gb, 4, &table_type); /* 0 - DC; 1 - AC */
236*437bfbebSnyanmisaka         if (table_type >= HUFFMAN_TABLE_TYPE_BUTT) {
237*437bfbebSnyanmisaka             mpp_err_f("table type %d error\n", table_type);
238*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
239*437bfbebSnyanmisaka         }
240*437bfbebSnyanmisaka 
241*437bfbebSnyanmisaka         READ_BITS(gb, 4, &table_id);
242*437bfbebSnyanmisaka         if (table_id >= HUFFMAN_TABLE_ID_TWO) {
243*437bfbebSnyanmisaka             mpp_err_f("table id %d is unsupported for baseline\n", table_id);
244*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
245*437bfbebSnyanmisaka         }
246*437bfbebSnyanmisaka 
247*437bfbebSnyanmisaka         num = 0;
248*437bfbebSnyanmisaka         if (table_type == HUFFMAN_TABLE_TYPE_DC) {
249*437bfbebSnyanmisaka             DcTable *ptr = &(syntax->dc_table[table_id]);
250*437bfbebSnyanmisaka             for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
251*437bfbebSnyanmisaka                 READ_BITS(gb, 8, &value);
252*437bfbebSnyanmisaka                 ptr->bits[i] = value;
253*437bfbebSnyanmisaka                 num += value;
254*437bfbebSnyanmisaka             }
255*437bfbebSnyanmisaka 
256*437bfbebSnyanmisaka             ptr->actual_length = num;
257*437bfbebSnyanmisaka         } else {
258*437bfbebSnyanmisaka             AcTable *ptr = &(syntax->ac_table[table_id]);
259*437bfbebSnyanmisaka             for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
260*437bfbebSnyanmisaka                 READ_BITS(gb, 8, &value);
261*437bfbebSnyanmisaka                 ptr->bits[i] = value;
262*437bfbebSnyanmisaka                 num += value;
263*437bfbebSnyanmisaka             }
264*437bfbebSnyanmisaka 
265*437bfbebSnyanmisaka             ptr->actual_length = num;
266*437bfbebSnyanmisaka         }
267*437bfbebSnyanmisaka 
268*437bfbebSnyanmisaka         len -= 17;
269*437bfbebSnyanmisaka         if (len < num ||
270*437bfbebSnyanmisaka             (num > MAX_DC_HUFFMAN_TABLE_LENGTH && table_type == HUFFMAN_TABLE_TYPE_DC) ||
271*437bfbebSnyanmisaka             (num > MAX_AC_HUFFMAN_TABLE_LENGTH && table_type == HUFFMAN_TABLE_TYPE_AC)) {
272*437bfbebSnyanmisaka             mpp_err_f("table type %d, code word number %d error\n", table_type, num);
273*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
274*437bfbebSnyanmisaka         }
275*437bfbebSnyanmisaka 
276*437bfbebSnyanmisaka         code_max = 0;
277*437bfbebSnyanmisaka         if (table_type == HUFFMAN_TABLE_TYPE_DC) {
278*437bfbebSnyanmisaka             DcTable *ptr = &(syntax->dc_table[table_id]);
279*437bfbebSnyanmisaka 
280*437bfbebSnyanmisaka             syntax->htbl_entry |= 1 << (table_id * 2);
281*437bfbebSnyanmisaka 
282*437bfbebSnyanmisaka             for (i = 0; i < num; i++) {
283*437bfbebSnyanmisaka                 READ_BITS(gb, 8, &value);
284*437bfbebSnyanmisaka                 ptr->vals[i] = value;
285*437bfbebSnyanmisaka                 if (ptr->vals[i] > code_max)
286*437bfbebSnyanmisaka                     code_max = ptr->vals[i];
287*437bfbebSnyanmisaka             }
288*437bfbebSnyanmisaka         } else {
289*437bfbebSnyanmisaka             AcTable *ptr = &(syntax->ac_table[table_id]);
290*437bfbebSnyanmisaka 
291*437bfbebSnyanmisaka             syntax->htbl_entry |= 1 << ((table_id * 2) + 1);
292*437bfbebSnyanmisaka 
293*437bfbebSnyanmisaka             for (i = 0; i < num; i++) {
294*437bfbebSnyanmisaka                 READ_BITS(gb, 8, &value);
295*437bfbebSnyanmisaka                 ptr->vals[i] = value;
296*437bfbebSnyanmisaka                 if (ptr->vals[i] > code_max)
297*437bfbebSnyanmisaka                     code_max = ptr->vals[i];
298*437bfbebSnyanmisaka             }
299*437bfbebSnyanmisaka         }
300*437bfbebSnyanmisaka         len -= num;
301*437bfbebSnyanmisaka 
302*437bfbebSnyanmisaka         jpegd_dbg_marker("dht: type=%d id=%d code_word_num=%d, code_max=%d, len=%d\n",
303*437bfbebSnyanmisaka                          table_type, table_id, num, code_max, len);
304*437bfbebSnyanmisaka     }
305*437bfbebSnyanmisaka     ret = MPP_OK;
306*437bfbebSnyanmisaka 
307*437bfbebSnyanmisaka __BITREAD_ERR:
308*437bfbebSnyanmisaka     if (ret != MPP_OK)
309*437bfbebSnyanmisaka         jpegd_dbg_syntax("bit read error!\n");
310*437bfbebSnyanmisaka 
311*437bfbebSnyanmisaka     return ret;
312*437bfbebSnyanmisaka }
313*437bfbebSnyanmisaka 
314*437bfbebSnyanmisaka /* quantize tables */
jpegd_decode_dqt(JpegdCtx * ctx)315*437bfbebSnyanmisaka static MPP_RET jpegd_decode_dqt(JpegdCtx *ctx)
316*437bfbebSnyanmisaka {
317*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
318*437bfbebSnyanmisaka     BitReadCtx_t *gb = ctx->bit_ctx;
319*437bfbebSnyanmisaka     JpegdSyntax *syntax = ctx->syntax;
320*437bfbebSnyanmisaka     RK_U32 len;
321*437bfbebSnyanmisaka     int index, i;
322*437bfbebSnyanmisaka     RK_U16 value;
323*437bfbebSnyanmisaka 
324*437bfbebSnyanmisaka     len = jpegd_read_len(gb);
325*437bfbebSnyanmisaka     len -= 2; /* quantize tables length */
326*437bfbebSnyanmisaka 
327*437bfbebSnyanmisaka     if (len > gb->bytes_left_) {
328*437bfbebSnyanmisaka         mpp_err_f("dqt: len %d is too large\n", len);
329*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
330*437bfbebSnyanmisaka     }
331*437bfbebSnyanmisaka 
332*437bfbebSnyanmisaka     while (len >= 65) {
333*437bfbebSnyanmisaka         RK_U16 pr;
334*437bfbebSnyanmisaka         READ_BITS(gb, 4, &pr);
335*437bfbebSnyanmisaka         if (pr > 1) {
336*437bfbebSnyanmisaka             mpp_err_f("dqt: invalid precision\n");
337*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
338*437bfbebSnyanmisaka         }
339*437bfbebSnyanmisaka 
340*437bfbebSnyanmisaka         READ_BITS(gb, 4, &index);
341*437bfbebSnyanmisaka         if (index >= QUANTIZE_TABLE_ID_BUTT) {
342*437bfbebSnyanmisaka             mpp_err_f("dqt: invalid quantize tables ID\n");
343*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
344*437bfbebSnyanmisaka         }
345*437bfbebSnyanmisaka         jpegd_dbg_marker("quantize tables ID=%d\n", index);
346*437bfbebSnyanmisaka 
347*437bfbebSnyanmisaka         /* read quant table */
348*437bfbebSnyanmisaka         for (i = 0; i < QUANTIZE_TABLE_LENGTH; i++) {
349*437bfbebSnyanmisaka             READ_BITS(gb, pr ? 16 : 8, &value);
350*437bfbebSnyanmisaka             syntax->quant_matrixes[index][i] = value;
351*437bfbebSnyanmisaka         }
352*437bfbebSnyanmisaka         syntax->qtbl_entry++;
353*437bfbebSnyanmisaka         if (syntax->qtbl_entry > MAX_COMPONENTS)
354*437bfbebSnyanmisaka             mpp_err_f("%d entries qtbl is not supported\n", syntax->qtbl_entry);
355*437bfbebSnyanmisaka 
356*437bfbebSnyanmisaka         if (jpegd_debug & JPEGD_DBG_TABLE) {
357*437bfbebSnyanmisaka             /* debug code */
358*437bfbebSnyanmisaka             mpp_log("******Start to print quantize table %d******\n", index);
359*437bfbebSnyanmisaka 
360*437bfbebSnyanmisaka             for (i = 0; i < QUANTIZE_TABLE_LENGTH; i += 8) {
361*437bfbebSnyanmisaka                 mpp_log("%2d~%2d 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
362*437bfbebSnyanmisaka                         i, i + 7,
363*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 0],
364*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 1],
365*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 2],
366*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 3],
367*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 4],
368*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 5],
369*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 7],
370*437bfbebSnyanmisaka                         syntax->quant_matrixes[index][i + 7]);
371*437bfbebSnyanmisaka             }
372*437bfbebSnyanmisaka             mpp_log("******Quantize table %d End******\n", index);
373*437bfbebSnyanmisaka         }
374*437bfbebSnyanmisaka 
375*437bfbebSnyanmisaka         // XXX FIXME fine-tune, and perhaps add dc too
376*437bfbebSnyanmisaka         syntax->qscale[index] = MPP_MAX(syntax->quant_matrixes[index][1],
377*437bfbebSnyanmisaka                                         syntax->quant_matrixes[index][8]) >> 1;
378*437bfbebSnyanmisaka 
379*437bfbebSnyanmisaka         jpegd_dbg_marker("qscale[%d]: %d\n", index, syntax->qscale[index]);
380*437bfbebSnyanmisaka         len -= 1 + 64 * (1 + pr);
381*437bfbebSnyanmisaka     }
382*437bfbebSnyanmisaka     ret = MPP_OK;
383*437bfbebSnyanmisaka 
384*437bfbebSnyanmisaka __BITREAD_ERR:
385*437bfbebSnyanmisaka     if (ret != MPP_OK)
386*437bfbebSnyanmisaka         jpegd_dbg_syntax("bit read error!\n");
387*437bfbebSnyanmisaka 
388*437bfbebSnyanmisaka     return ret;
389*437bfbebSnyanmisaka }
390*437bfbebSnyanmisaka 
jpegd_decode_sof(JpegdCtx * ctx)391*437bfbebSnyanmisaka static MPP_RET jpegd_decode_sof(JpegdCtx *ctx)
392*437bfbebSnyanmisaka {
393*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
394*437bfbebSnyanmisaka     BitReadCtx_t *gb = ctx->bit_ctx;
395*437bfbebSnyanmisaka     JpegdSyntax *syntax = ctx->syntax;
396*437bfbebSnyanmisaka     RK_U32 len, bits, i;
397*437bfbebSnyanmisaka     RK_U32 width, height;
398*437bfbebSnyanmisaka     RK_U32 nb_components, value;
399*437bfbebSnyanmisaka 
400*437bfbebSnyanmisaka     len = jpegd_read_len(gb);
401*437bfbebSnyanmisaka     if (len > gb->bytes_left_) {
402*437bfbebSnyanmisaka         mpp_err_f("len %d is too large\n", len);
403*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
404*437bfbebSnyanmisaka     }
405*437bfbebSnyanmisaka 
406*437bfbebSnyanmisaka     READ_BITS(gb, 8, &bits);
407*437bfbebSnyanmisaka     if (bits > 16 || bits < 1) {
408*437bfbebSnyanmisaka         /* usually bits is 8 */
409*437bfbebSnyanmisaka         mpp_err_f("bits %d is invalid\n", bits);
410*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
411*437bfbebSnyanmisaka     }
412*437bfbebSnyanmisaka     syntax->sample_precision = bits;
413*437bfbebSnyanmisaka 
414*437bfbebSnyanmisaka     READ_BITS(gb, 16, &height);
415*437bfbebSnyanmisaka     READ_BITS(gb, 16, &width);
416*437bfbebSnyanmisaka     syntax->height = height;
417*437bfbebSnyanmisaka     syntax->width = width;
418*437bfbebSnyanmisaka     syntax->hor_stride = MPP_ALIGN(width, 16);
419*437bfbebSnyanmisaka     syntax->ver_stride = MPP_ALIGN(height, 16);
420*437bfbebSnyanmisaka 
421*437bfbebSnyanmisaka     jpegd_dbg_marker("sof0: picture: %dx%d, stride: %dx%d\n", width, height,
422*437bfbebSnyanmisaka                      syntax->hor_stride, syntax->ver_stride);
423*437bfbebSnyanmisaka 
424*437bfbebSnyanmisaka     READ_BITS(gb, 8 , &nb_components);
425*437bfbebSnyanmisaka     if ((nb_components != 1) && (nb_components != MAX_COMPONENTS)) {
426*437bfbebSnyanmisaka         mpp_err_f("components number %d error\n", nb_components);
427*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
428*437bfbebSnyanmisaka     }
429*437bfbebSnyanmisaka 
430*437bfbebSnyanmisaka     if (len != (8 + (3 * nb_components)))
431*437bfbebSnyanmisaka         mpp_err_f("decode_sof0: error, len(%d) mismatch nb_components(%d)\n",
432*437bfbebSnyanmisaka                   len, nb_components);
433*437bfbebSnyanmisaka 
434*437bfbebSnyanmisaka     syntax->nb_components = nb_components;
435*437bfbebSnyanmisaka     syntax->h_max = 1;
436*437bfbebSnyanmisaka     syntax->v_max = 1;
437*437bfbebSnyanmisaka     for (i = 0; i < nb_components; i++) {
438*437bfbebSnyanmisaka         /* component id */
439*437bfbebSnyanmisaka         READ_BITS(gb, 8 , &value);
440*437bfbebSnyanmisaka         syntax->component_id[i] = value - 1; /* start from zero */
441*437bfbebSnyanmisaka 
442*437bfbebSnyanmisaka         READ_BITS(gb, 4, &value);
443*437bfbebSnyanmisaka         syntax->h_count[i] = value;  /* Horizontal sampling factor */
444*437bfbebSnyanmisaka 
445*437bfbebSnyanmisaka         READ_BITS(gb, 4, &value);
446*437bfbebSnyanmisaka         syntax->v_count[i] = value; /* Vertical sampling factor */
447*437bfbebSnyanmisaka 
448*437bfbebSnyanmisaka         if (!syntax->h_count[i] || !syntax->v_count[i]) {
449*437bfbebSnyanmisaka             mpp_err_f("Invalid sampling factor in component %d %d:%d\n",
450*437bfbebSnyanmisaka                       i, syntax->h_count[i], syntax->v_count[i]);
451*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
452*437bfbebSnyanmisaka         }
453*437bfbebSnyanmisaka 
454*437bfbebSnyanmisaka         /* compute hmax and vmax (only used in interleaved case) */
455*437bfbebSnyanmisaka         if (syntax->h_count[i] > syntax->h_max)
456*437bfbebSnyanmisaka             syntax->h_max = syntax->h_count[i];
457*437bfbebSnyanmisaka         if (syntax->v_count[i] > syntax->v_max)
458*437bfbebSnyanmisaka             syntax->v_max = syntax->v_count[i];
459*437bfbebSnyanmisaka 
460*437bfbebSnyanmisaka         /* Quantization table destination selector */
461*437bfbebSnyanmisaka         READ_BITS(gb, 8, &value);
462*437bfbebSnyanmisaka         syntax->quant_index[i] = value;
463*437bfbebSnyanmisaka 
464*437bfbebSnyanmisaka         if (syntax->quant_index[i] >= QUANTIZE_TABLE_ID_BUTT) {
465*437bfbebSnyanmisaka             mpp_err_f("quant_index %d is invalid\n", syntax->quant_index[i]);
466*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
467*437bfbebSnyanmisaka         }
468*437bfbebSnyanmisaka 
469*437bfbebSnyanmisaka         jpegd_dbg_marker("component %d %d:%d id: %d quant_id:%d\n",
470*437bfbebSnyanmisaka                          i, syntax->h_count[i], syntax->v_count[i],
471*437bfbebSnyanmisaka                          syntax->component_id[i], syntax->quant_index[i]);
472*437bfbebSnyanmisaka     }
473*437bfbebSnyanmisaka 
474*437bfbebSnyanmisaka     /* judge yuv mode from sampling factor */
475*437bfbebSnyanmisaka     ret = jpeg_judge_yuv_mode(ctx);
476*437bfbebSnyanmisaka 
477*437bfbebSnyanmisaka __BITREAD_ERR:
478*437bfbebSnyanmisaka     if (ret != MPP_OK)
479*437bfbebSnyanmisaka         jpegd_dbg_syntax("bit read error!\n");
480*437bfbebSnyanmisaka 
481*437bfbebSnyanmisaka     return ret;
482*437bfbebSnyanmisaka }
483*437bfbebSnyanmisaka 
jpegd_decode_sos(JpegdCtx * ctx)484*437bfbebSnyanmisaka static MPP_RET jpegd_decode_sos(JpegdCtx *ctx)
485*437bfbebSnyanmisaka {
486*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
487*437bfbebSnyanmisaka     BitReadCtx_t *gb = ctx->bit_ctx;
488*437bfbebSnyanmisaka     JpegdSyntax *syntax = ctx->syntax;
489*437bfbebSnyanmisaka     RK_U32 len, nb_components, value;
490*437bfbebSnyanmisaka     RK_U32 id, i, index;
491*437bfbebSnyanmisaka 
492*437bfbebSnyanmisaka     len = jpegd_read_len(gb);
493*437bfbebSnyanmisaka     if (len > gb->bytes_left_) {
494*437bfbebSnyanmisaka         mpp_err_f("len %d is too large\n", len);
495*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
496*437bfbebSnyanmisaka     }
497*437bfbebSnyanmisaka     syntax->sos_len = len; /* used for calculating stream offset */
498*437bfbebSnyanmisaka 
499*437bfbebSnyanmisaka     READ_BITS(gb, 8, &nb_components);
500*437bfbebSnyanmisaka     if ((nb_components != 1) && (nb_components != MAX_COMPONENTS)) {
501*437bfbebSnyanmisaka         mpp_err_f("decode_sos: nb_components %d unsupported\n", nb_components);
502*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
503*437bfbebSnyanmisaka     }
504*437bfbebSnyanmisaka 
505*437bfbebSnyanmisaka     if (len != 6 + 2 * nb_components) {
506*437bfbebSnyanmisaka         mpp_err_f("decode_sos: invalid len (%d), nb_components:%d\n",
507*437bfbebSnyanmisaka                   len, nb_components);
508*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
509*437bfbebSnyanmisaka     }
510*437bfbebSnyanmisaka     syntax->qtable_cnt = nb_components;
511*437bfbebSnyanmisaka 
512*437bfbebSnyanmisaka     for (i = 0; i < nb_components; i++) {
513*437bfbebSnyanmisaka         READ_BITS(gb, 8, &value);
514*437bfbebSnyanmisaka         id = value - 1;
515*437bfbebSnyanmisaka         jpegd_dbg_marker("sos component: %d\n", id);
516*437bfbebSnyanmisaka 
517*437bfbebSnyanmisaka         /* find component index */
518*437bfbebSnyanmisaka         for (index = 0; index < syntax->nb_components; index++)
519*437bfbebSnyanmisaka             if (id == syntax->component_id[index])
520*437bfbebSnyanmisaka                 break;
521*437bfbebSnyanmisaka 
522*437bfbebSnyanmisaka         if (index == syntax->nb_components) {
523*437bfbebSnyanmisaka             mpp_err_f("decode_sos: index(%d) out of components\n", index);
524*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
525*437bfbebSnyanmisaka         }
526*437bfbebSnyanmisaka 
527*437bfbebSnyanmisaka         READ_BITS(gb, 4, &value);
528*437bfbebSnyanmisaka         syntax->dc_index[i] = value;
529*437bfbebSnyanmisaka 
530*437bfbebSnyanmisaka         READ_BITS(gb, 4, &value);
531*437bfbebSnyanmisaka         syntax->ac_index[i] = value;
532*437bfbebSnyanmisaka 
533*437bfbebSnyanmisaka         jpegd_dbg_marker("component:%d, dc_index:%d, ac_index:%d\n",
534*437bfbebSnyanmisaka                          id, syntax->dc_index[i], syntax->ac_index[i]);
535*437bfbebSnyanmisaka 
536*437bfbebSnyanmisaka         if (syntax->dc_index[i] > HUFFMAN_TABLE_ID_ONE ||
537*437bfbebSnyanmisaka             syntax->ac_index[i] > HUFFMAN_TABLE_ID_ONE) {
538*437bfbebSnyanmisaka             /* for baseline */
539*437bfbebSnyanmisaka             mpp_err_f("Huffman table id error\n");
540*437bfbebSnyanmisaka             return MPP_ERR_STREAM;
541*437bfbebSnyanmisaka         }
542*437bfbebSnyanmisaka     }
543*437bfbebSnyanmisaka 
544*437bfbebSnyanmisaka     READ_BITS(gb, 8, &value);
545*437bfbebSnyanmisaka     syntax->scan_start = value;
546*437bfbebSnyanmisaka 
547*437bfbebSnyanmisaka     READ_BITS(gb, 8, &value);
548*437bfbebSnyanmisaka     syntax->scan_end = value;
549*437bfbebSnyanmisaka 
550*437bfbebSnyanmisaka     READ_BITS(gb, 4, &value);
551*437bfbebSnyanmisaka     syntax->prev_shift = value;
552*437bfbebSnyanmisaka 
553*437bfbebSnyanmisaka     READ_BITS(gb, 4, &value);
554*437bfbebSnyanmisaka     syntax->point_transform = value;
555*437bfbebSnyanmisaka 
556*437bfbebSnyanmisaka     if (syntax->scan_start != 0 || syntax->scan_end != 0x3F ||
557*437bfbebSnyanmisaka         syntax->prev_shift != 0 || syntax->point_transform != 0) {
558*437bfbebSnyanmisaka         /* for baseline */
559*437bfbebSnyanmisaka         mpp_err_f("unsupported sos parameter: scan_start:%d,\n"
560*437bfbebSnyanmisaka                   "\t\tscan_end:%d, prev_shift:%d, point_transform:%d\n",
561*437bfbebSnyanmisaka                   syntax->scan_start, syntax->scan_end,
562*437bfbebSnyanmisaka                   syntax->prev_shift, syntax->point_transform);
563*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
564*437bfbebSnyanmisaka     }
565*437bfbebSnyanmisaka     ret = MPP_OK;
566*437bfbebSnyanmisaka 
567*437bfbebSnyanmisaka __BITREAD_ERR:
568*437bfbebSnyanmisaka     if (ret != MPP_OK)
569*437bfbebSnyanmisaka         jpegd_dbg_syntax("bit read error!\n");
570*437bfbebSnyanmisaka 
571*437bfbebSnyanmisaka     return ret;
572*437bfbebSnyanmisaka }
573*437bfbebSnyanmisaka 
jpegd_decode_dri(JpegdCtx * ctx)574*437bfbebSnyanmisaka static MPP_RET jpegd_decode_dri(JpegdCtx *ctx)
575*437bfbebSnyanmisaka {
576*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
577*437bfbebSnyanmisaka     BitReadCtx_t *gb = ctx->bit_ctx;
578*437bfbebSnyanmisaka     JpegdSyntax *s = ctx->syntax;
579*437bfbebSnyanmisaka     RK_U32 len;
580*437bfbebSnyanmisaka 
581*437bfbebSnyanmisaka     len = jpegd_read_len(gb);
582*437bfbebSnyanmisaka     if (len != DRI_MARKER_LENGTH) {
583*437bfbebSnyanmisaka         mpp_err_f("DRI length %d error\n", len);
584*437bfbebSnyanmisaka         return MPP_ERR_STREAM;
585*437bfbebSnyanmisaka     }
586*437bfbebSnyanmisaka 
587*437bfbebSnyanmisaka     READ_BITS(gb, 16, &s->restart_interval);
588*437bfbebSnyanmisaka     jpegd_dbg_marker("restart interval: %d\n", s->restart_interval);
589*437bfbebSnyanmisaka 
590*437bfbebSnyanmisaka     ret = MPP_OK;
591*437bfbebSnyanmisaka 
592*437bfbebSnyanmisaka __BITREAD_ERR:
593*437bfbebSnyanmisaka     if (ret != MPP_OK)
594*437bfbebSnyanmisaka         jpegd_dbg_syntax("bit read error!\n");
595*437bfbebSnyanmisaka 
596*437bfbebSnyanmisaka     return ret;
597*437bfbebSnyanmisaka }
598*437bfbebSnyanmisaka 
jpegd_setup_default_dht(JpegdCtx * ctx)599*437bfbebSnyanmisaka static MPP_RET jpegd_setup_default_dht(JpegdCtx *ctx)
600*437bfbebSnyanmisaka {
601*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
602*437bfbebSnyanmisaka     JpegdSyntax *s = ctx->syntax;
603*437bfbebSnyanmisaka     AcTable *ac_ptr = NULL;
604*437bfbebSnyanmisaka     DcTable *dc_ptr = NULL;
605*437bfbebSnyanmisaka     const RK_U8 *bits_tmp = NULL;
606*437bfbebSnyanmisaka     const RK_U8 *val_tmp = NULL;
607*437bfbebSnyanmisaka     RK_U32 tmp_len = 0;
608*437bfbebSnyanmisaka     RK_U32 i,  k;
609*437bfbebSnyanmisaka 
610*437bfbebSnyanmisaka     /* Set up the standard Huffman tables (cf. JPEG standard section K.3)
611*437bfbebSnyanmisaka      * IMPORTANT: these are only valid for 8-bit data precision!
612*437bfbebSnyanmisaka      */
613*437bfbebSnyanmisaka     static const RK_U8 bits_dc_luminance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
614*437bfbebSnyanmisaka     {  0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
615*437bfbebSnyanmisaka 
616*437bfbebSnyanmisaka     /* luminance and chrominance all use it */
617*437bfbebSnyanmisaka     static const RK_U8 val_dc[MAX_DC_HUFFMAN_TABLE_LENGTH] =
618*437bfbebSnyanmisaka     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
619*437bfbebSnyanmisaka 
620*437bfbebSnyanmisaka     static const RK_U8 bits_dc_chrominance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
621*437bfbebSnyanmisaka     { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
622*437bfbebSnyanmisaka 
623*437bfbebSnyanmisaka     static const RK_U8 bits_ac_luminance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
624*437bfbebSnyanmisaka     { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
625*437bfbebSnyanmisaka 
626*437bfbebSnyanmisaka     /* 162 Bytes */
627*437bfbebSnyanmisaka     static const RK_U8 val_ac_luminance[MAX_AC_HUFFMAN_TABLE_LENGTH] = {
628*437bfbebSnyanmisaka         0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
629*437bfbebSnyanmisaka         0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
630*437bfbebSnyanmisaka         0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
631*437bfbebSnyanmisaka         0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
632*437bfbebSnyanmisaka         0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
633*437bfbebSnyanmisaka         0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
634*437bfbebSnyanmisaka         0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
635*437bfbebSnyanmisaka         0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
636*437bfbebSnyanmisaka         0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
637*437bfbebSnyanmisaka         0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
638*437bfbebSnyanmisaka         0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
639*437bfbebSnyanmisaka         0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
640*437bfbebSnyanmisaka         0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
641*437bfbebSnyanmisaka         0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
642*437bfbebSnyanmisaka         0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
643*437bfbebSnyanmisaka         0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
644*437bfbebSnyanmisaka         0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
645*437bfbebSnyanmisaka         0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
646*437bfbebSnyanmisaka         0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
647*437bfbebSnyanmisaka         0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
648*437bfbebSnyanmisaka         0xf9, 0xfa
649*437bfbebSnyanmisaka     };
650*437bfbebSnyanmisaka 
651*437bfbebSnyanmisaka     static const RK_U8 bits_ac_chrominance[MAX_HUFFMAN_CODE_BIT_LENGTH] =
652*437bfbebSnyanmisaka     { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
653*437bfbebSnyanmisaka 
654*437bfbebSnyanmisaka     static const RK_U8 val_ac_chrominance[MAX_AC_HUFFMAN_TABLE_LENGTH] = {
655*437bfbebSnyanmisaka         0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
656*437bfbebSnyanmisaka         0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
657*437bfbebSnyanmisaka         0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
658*437bfbebSnyanmisaka         0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
659*437bfbebSnyanmisaka         0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
660*437bfbebSnyanmisaka         0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
661*437bfbebSnyanmisaka         0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
662*437bfbebSnyanmisaka         0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
663*437bfbebSnyanmisaka         0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
664*437bfbebSnyanmisaka         0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
665*437bfbebSnyanmisaka         0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
666*437bfbebSnyanmisaka         0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
667*437bfbebSnyanmisaka         0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
668*437bfbebSnyanmisaka         0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
669*437bfbebSnyanmisaka         0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
670*437bfbebSnyanmisaka         0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
671*437bfbebSnyanmisaka         0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
672*437bfbebSnyanmisaka         0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
673*437bfbebSnyanmisaka         0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
674*437bfbebSnyanmisaka         0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
675*437bfbebSnyanmisaka         0xf9, 0xfa
676*437bfbebSnyanmisaka     };
677*437bfbebSnyanmisaka 
678*437bfbebSnyanmisaka     const RK_U8 *bits_table[4] = {
679*437bfbebSnyanmisaka         bits_ac_luminance,
680*437bfbebSnyanmisaka         bits_ac_chrominance,
681*437bfbebSnyanmisaka         bits_dc_luminance,
682*437bfbebSnyanmisaka         bits_dc_chrominance
683*437bfbebSnyanmisaka     };
684*437bfbebSnyanmisaka 
685*437bfbebSnyanmisaka     const RK_U8 *val_table[4] = {
686*437bfbebSnyanmisaka         val_ac_luminance,
687*437bfbebSnyanmisaka         val_ac_chrominance,
688*437bfbebSnyanmisaka         val_dc,
689*437bfbebSnyanmisaka         val_dc
690*437bfbebSnyanmisaka     };
691*437bfbebSnyanmisaka 
692*437bfbebSnyanmisaka     /* AC Table */
693*437bfbebSnyanmisaka     for (k = 0; k < 2; k++) {
694*437bfbebSnyanmisaka         ac_ptr = &(s->ac_table[k]);
695*437bfbebSnyanmisaka         bits_tmp = bits_table[k];
696*437bfbebSnyanmisaka         val_tmp = val_table[k];
697*437bfbebSnyanmisaka 
698*437bfbebSnyanmisaka         tmp_len = 0;
699*437bfbebSnyanmisaka         for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
700*437bfbebSnyanmisaka             /* read in the values of list BITS */
701*437bfbebSnyanmisaka             tmp_len += ac_ptr->bits[i] = bits_tmp[i];
702*437bfbebSnyanmisaka         }
703*437bfbebSnyanmisaka 
704*437bfbebSnyanmisaka         ac_ptr->actual_length = tmp_len;  /* set the table length */
705*437bfbebSnyanmisaka         for (i = 0; i < tmp_len; i++) {
706*437bfbebSnyanmisaka             /* read in the HUFFVALs */
707*437bfbebSnyanmisaka             ac_ptr->vals[i] = val_tmp[i];
708*437bfbebSnyanmisaka         }
709*437bfbebSnyanmisaka     }
710*437bfbebSnyanmisaka 
711*437bfbebSnyanmisaka     /* DC Table */
712*437bfbebSnyanmisaka     for (k = 0; k < 2; k++) {
713*437bfbebSnyanmisaka         dc_ptr = &(s->dc_table[k]);
714*437bfbebSnyanmisaka         bits_tmp = bits_table[k + 2];
715*437bfbebSnyanmisaka         val_tmp = val_table[k + 2];
716*437bfbebSnyanmisaka 
717*437bfbebSnyanmisaka         tmp_len = 0;
718*437bfbebSnyanmisaka         for (i = 0; i < MAX_HUFFMAN_CODE_BIT_LENGTH; i++) {
719*437bfbebSnyanmisaka             /* read in the values of list BITS */
720*437bfbebSnyanmisaka             tmp_len += dc_ptr->bits[i] = bits_tmp[i];
721*437bfbebSnyanmisaka         }
722*437bfbebSnyanmisaka 
723*437bfbebSnyanmisaka         dc_ptr->actual_length = tmp_len;  /* set the table length */
724*437bfbebSnyanmisaka         for (i = 0; i < tmp_len; i++) {
725*437bfbebSnyanmisaka             /* read in the HUFFVALs */
726*437bfbebSnyanmisaka             dc_ptr->vals[i] = val_tmp[i];
727*437bfbebSnyanmisaka         }
728*437bfbebSnyanmisaka     }
729*437bfbebSnyanmisaka 
730*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
731*437bfbebSnyanmisaka     return MPP_OK;
732*437bfbebSnyanmisaka }
733*437bfbebSnyanmisaka 
jpegd_decode_frame(JpegdCtx * ctx)734*437bfbebSnyanmisaka static MPP_RET jpegd_decode_frame(JpegdCtx *ctx)
735*437bfbebSnyanmisaka {
736*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
737*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
738*437bfbebSnyanmisaka     const RK_U8 *const buf = ctx->buffer;
739*437bfbebSnyanmisaka     RK_U32 strm_len = ctx->streamLength;
740*437bfbebSnyanmisaka     BitReadCtx_t *gb = ctx->bit_ctx;
741*437bfbebSnyanmisaka     JpegdSyntax *syntax = ctx->syntax;
742*437bfbebSnyanmisaka     RK_S32 start_code = 0xffd8;
743*437bfbebSnyanmisaka 
744*437bfbebSnyanmisaka     const RK_U8 *buf_ptr = buf;
745*437bfbebSnyanmisaka     const RK_U8 *const buf_end = buf + strm_len;
746*437bfbebSnyanmisaka 
747*437bfbebSnyanmisaka     syntax->htbl_entry = 0;
748*437bfbebSnyanmisaka     syntax->qtbl_entry = 0;
749*437bfbebSnyanmisaka 
750*437bfbebSnyanmisaka     if (strm_len < 8 || !memchr(buf_ptr, start_code, 8)) {
751*437bfbebSnyanmisaka         // not jpeg
752*437bfbebSnyanmisaka         ret = MPP_ERR_STREAM;
753*437bfbebSnyanmisaka         goto fail;
754*437bfbebSnyanmisaka     }
755*437bfbebSnyanmisaka 
756*437bfbebSnyanmisaka     while (buf_ptr < buf_end) {
757*437bfbebSnyanmisaka         /* find start marker */
758*437bfbebSnyanmisaka         start_code = jpegd_find_marker(&buf_ptr, buf_end);
759*437bfbebSnyanmisaka         if (start_code <= 0) {
760*437bfbebSnyanmisaka             jpegd_dbg_marker("start code not found\n");
761*437bfbebSnyanmisaka             ret = MPP_ERR_STREAM;
762*437bfbebSnyanmisaka             break;
763*437bfbebSnyanmisaka         } else {
764*437bfbebSnyanmisaka             buf_ptr += 2;
765*437bfbebSnyanmisaka         }
766*437bfbebSnyanmisaka 
767*437bfbebSnyanmisaka         jpegd_dbg_marker("marker = 0x%x, avail_size_in_buf = %d\n",
768*437bfbebSnyanmisaka                          start_code, buf_end - buf_ptr);
769*437bfbebSnyanmisaka         ctx->start_code = start_code;
770*437bfbebSnyanmisaka 
771*437bfbebSnyanmisaka         /* setup bit read context */
772*437bfbebSnyanmisaka         mpp_set_bitread_ctx(gb, (RK_U8 *)buf_ptr, buf_end - buf_ptr);
773*437bfbebSnyanmisaka 
774*437bfbebSnyanmisaka         /* process markers */
775*437bfbebSnyanmisaka         if (start_code >= RST0 && start_code <= RST7) {
776*437bfbebSnyanmisaka             /* nothing to do with RSTn */
777*437bfbebSnyanmisaka             jpegd_dbg_syntax("restart marker: %d\n", start_code & 0x0f);
778*437bfbebSnyanmisaka         }
779*437bfbebSnyanmisaka 
780*437bfbebSnyanmisaka         if (start_code > SOF0 && start_code <= SOF15 && start_code != DHT) {
781*437bfbebSnyanmisaka             mpp_err_f("Only baseline DCT is supported, unsupported entropy encoding 0x%x", start_code);
782*437bfbebSnyanmisaka             ret = MPP_ERR_STREAM;
783*437bfbebSnyanmisaka             goto fail;
784*437bfbebSnyanmisaka         }
785*437bfbebSnyanmisaka 
786*437bfbebSnyanmisaka         switch (start_code) {
787*437bfbebSnyanmisaka         case SOI:
788*437bfbebSnyanmisaka             /* nothing to do on SOI */
789*437bfbebSnyanmisaka             syntax->dht_found = 0;
790*437bfbebSnyanmisaka             syntax->eoi_found = 0;
791*437bfbebSnyanmisaka             syntax->sof0_found = 0;
792*437bfbebSnyanmisaka             syntax->qtable_cnt = 0;
793*437bfbebSnyanmisaka             syntax->qtbl_entry = 0;
794*437bfbebSnyanmisaka             syntax->htbl_entry = 0;
795*437bfbebSnyanmisaka             break;
796*437bfbebSnyanmisaka         case DHT:
797*437bfbebSnyanmisaka             if ((ret = jpegd_decode_dht(ctx)) != MPP_OK) {
798*437bfbebSnyanmisaka                 mpp_err_f("huffman table decode error\n");
799*437bfbebSnyanmisaka                 goto fail;
800*437bfbebSnyanmisaka             }
801*437bfbebSnyanmisaka             syntax->dht_found = 1;
802*437bfbebSnyanmisaka             break;
803*437bfbebSnyanmisaka         case DQT:
804*437bfbebSnyanmisaka             if ((ret = jpegd_decode_dqt(ctx)) != MPP_OK) {
805*437bfbebSnyanmisaka                 mpp_err_f("quantize tables decode error\n");
806*437bfbebSnyanmisaka                 goto fail;
807*437bfbebSnyanmisaka             }
808*437bfbebSnyanmisaka             break;
809*437bfbebSnyanmisaka         case SOF0:
810*437bfbebSnyanmisaka             if ((ret = jpegd_decode_sof(ctx)) != MPP_OK) {
811*437bfbebSnyanmisaka                 mpp_err_f("sof0 decode error\n");
812*437bfbebSnyanmisaka                 goto fail;
813*437bfbebSnyanmisaka             }
814*437bfbebSnyanmisaka             if (ctx->syntax->sample_precision != 8) {
815*437bfbebSnyanmisaka                 mpp_err_f("Illegal sample precision %d.\n\
816*437bfbebSnyanmisaka                     For baseline, it should be 8\n", ctx->syntax->sample_precision);
817*437bfbebSnyanmisaka                 goto fail;
818*437bfbebSnyanmisaka             }
819*437bfbebSnyanmisaka 
820*437bfbebSnyanmisaka             syntax->sof0_found = 1;
821*437bfbebSnyanmisaka             break;
822*437bfbebSnyanmisaka         case EOI:
823*437bfbebSnyanmisaka             syntax->eoi_found = 1;
824*437bfbebSnyanmisaka             jpegd_dbg_marker("still exists %d bytes behind EOI marker\n",
825*437bfbebSnyanmisaka                              buf_end - buf_ptr);
826*437bfbebSnyanmisaka             goto done;
827*437bfbebSnyanmisaka             break;
828*437bfbebSnyanmisaka         case SOS:
829*437bfbebSnyanmisaka             if (!syntax->sof0_found) {
830*437bfbebSnyanmisaka                 mpp_err_f("Warning: only support baseline type\n");
831*437bfbebSnyanmisaka                 goto fail;
832*437bfbebSnyanmisaka             }
833*437bfbebSnyanmisaka 
834*437bfbebSnyanmisaka             if ((ret = jpegd_decode_sos(ctx)) != MPP_OK) {
835*437bfbebSnyanmisaka                 mpp_err_f("sos decode error\n");
836*437bfbebSnyanmisaka                 goto fail;
837*437bfbebSnyanmisaka             }
838*437bfbebSnyanmisaka 
839*437bfbebSnyanmisaka             /* stream behind SOS is decoded by hardware */
840*437bfbebSnyanmisaka             syntax->strm_offset = buf_ptr - buf + syntax->sos_len;
841*437bfbebSnyanmisaka             syntax->cur_pos = (RK_U8 *)buf + syntax->strm_offset;
842*437bfbebSnyanmisaka             syntax->pkt_len = ctx->streamLength;
843*437bfbebSnyanmisaka             jpegd_dbg_marker("This packet owns %d bytes with length %zu\n"
844*437bfbebSnyanmisaka                              "\t\thas been decoded %d bytes by software\n"
845*437bfbebSnyanmisaka                              "\t\tbuf_ptr:%p, buf:%p, sos_len:%d\n"
846*437bfbebSnyanmisaka                              "\t\thardware start address:%p",
847*437bfbebSnyanmisaka                              mpp_packet_get_size(ctx->input_packet),
848*437bfbebSnyanmisaka                              syntax->pkt_len,
849*437bfbebSnyanmisaka                              syntax->strm_offset, buf_ptr, buf,
850*437bfbebSnyanmisaka                              syntax->sos_len, syntax->cur_pos);
851*437bfbebSnyanmisaka 
852*437bfbebSnyanmisaka             if (syntax->strm_offset >= ctx->streamLength) {
853*437bfbebSnyanmisaka                 mpp_err_f("stream offset %d is larger than buffer size %d\n",
854*437bfbebSnyanmisaka                           syntax->strm_offset, ctx->streamLength);
855*437bfbebSnyanmisaka                 ret = MPP_ERR_UNKNOW;
856*437bfbebSnyanmisaka                 goto fail;
857*437bfbebSnyanmisaka             }
858*437bfbebSnyanmisaka 
859*437bfbebSnyanmisaka             if ((syntax->strm_offset + 2) < ctx->streamLength &&
860*437bfbebSnyanmisaka                 buf_ptr[syntax->sos_len] == 0xff && buf_ptr[syntax->sos_len + 1] == 0xd8) {
861*437bfbebSnyanmisaka                 jpegd_dbg_marker("Encontered SOI again, parse again!\n");
862*437bfbebSnyanmisaka                 break;
863*437bfbebSnyanmisaka             }
864*437bfbebSnyanmisaka             if (!ctx->scan_all_marker) {
865*437bfbebSnyanmisaka                 jpegd_dbg_marker("just scan parts of markers!\n");
866*437bfbebSnyanmisaka                 goto done;
867*437bfbebSnyanmisaka             }
868*437bfbebSnyanmisaka 
869*437bfbebSnyanmisaka             break;
870*437bfbebSnyanmisaka         case DRI:
871*437bfbebSnyanmisaka             if ((ret = jpegd_decode_dri(ctx)) != MPP_OK) {
872*437bfbebSnyanmisaka                 mpp_err_f("dri decode error\n");
873*437bfbebSnyanmisaka                 goto fail;
874*437bfbebSnyanmisaka             }
875*437bfbebSnyanmisaka             break;
876*437bfbebSnyanmisaka         default:
877*437bfbebSnyanmisaka             jpegd_dbg_marker("unhandled coding type(0x%x) in switch..case..\n",
878*437bfbebSnyanmisaka                              start_code);
879*437bfbebSnyanmisaka             if ((ret = jpegd_skip_section(ctx)) != MPP_OK) {
880*437bfbebSnyanmisaka                 jpegd_dbg_marker("Fail to skip section 0xFF%02x!\n",
881*437bfbebSnyanmisaka                                  start_code);
882*437bfbebSnyanmisaka                 goto fail;
883*437bfbebSnyanmisaka             }
884*437bfbebSnyanmisaka             break;
885*437bfbebSnyanmisaka         }
886*437bfbebSnyanmisaka 
887*437bfbebSnyanmisaka         buf_ptr = ctx->bit_ctx->data_;
888*437bfbebSnyanmisaka     }
889*437bfbebSnyanmisaka 
890*437bfbebSnyanmisaka done:
891*437bfbebSnyanmisaka     if (!syntax->dht_found) {
892*437bfbebSnyanmisaka         jpegd_dbg_marker("sorry, DHT is not found!\n");
893*437bfbebSnyanmisaka         jpegd_setup_default_dht(ctx);
894*437bfbebSnyanmisaka         syntax->htbl_entry = 0x0f;
895*437bfbebSnyanmisaka     }
896*437bfbebSnyanmisaka     if (!syntax->sof0_found) {
897*437bfbebSnyanmisaka         mpp_err_f("sof marker not found!\n");
898*437bfbebSnyanmisaka         ret = MPP_ERR_STREAM;
899*437bfbebSnyanmisaka     }
900*437bfbebSnyanmisaka     if (!syntax->eoi_found) {
901*437bfbebSnyanmisaka         if (MPP_OK != jpegd_find_eoi(&buf_ptr, buf_end)) {
902*437bfbebSnyanmisaka             mpp_err_f("EOI marker not found!\n");
903*437bfbebSnyanmisaka             ret = MPP_ERR_STREAM;
904*437bfbebSnyanmisaka         }
905*437bfbebSnyanmisaka     }
906*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
907*437bfbebSnyanmisaka     return ret;
908*437bfbebSnyanmisaka 
909*437bfbebSnyanmisaka fail:
910*437bfbebSnyanmisaka     ret = MPP_ERR_STREAM;
911*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
912*437bfbebSnyanmisaka     return ret;
913*437bfbebSnyanmisaka }
914*437bfbebSnyanmisaka 
915*437bfbebSnyanmisaka static MPP_RET
jpegd_split_frame(RK_U8 * src,RK_U32 src_size,RK_U8 * dst,RK_U32 dst_size,RK_U32 * copy_length)916*437bfbebSnyanmisaka jpegd_split_frame(RK_U8 *src, RK_U32 src_size,
917*437bfbebSnyanmisaka                   RK_U8 *dst, RK_U32 dst_size, RK_U32 *copy_length)
918*437bfbebSnyanmisaka {
919*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
920*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
921*437bfbebSnyanmisaka     if (NULL == src || NULL == dst || src_size <= 0) {
922*437bfbebSnyanmisaka         mpp_err_f("NULL pointer or wrong src_size(%d)", src_size);
923*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
924*437bfbebSnyanmisaka     }
925*437bfbebSnyanmisaka     RK_U8 *tmp;
926*437bfbebSnyanmisaka     RK_U32 str_size = (src_size + 255) & (~255);
927*437bfbebSnyanmisaka 
928*437bfbebSnyanmisaka     if (src[6] == 0x41 && src[7] == 0x56 && src[8] == 0x49 && src[9] == 0x31) {
929*437bfbebSnyanmisaka         //distinguish 310 from 210 camera
930*437bfbebSnyanmisaka         RK_U32     i;
931*437bfbebSnyanmisaka         RK_U32 copy_len = 0;
932*437bfbebSnyanmisaka         tmp = src;
933*437bfbebSnyanmisaka         jpegd_dbg_parser("distinguish 310 from 210 camera");
934*437bfbebSnyanmisaka 
935*437bfbebSnyanmisaka         for (i = 0; i < src_size - 4; i++) {
936*437bfbebSnyanmisaka             if (tmp[i] == 0xff) {
937*437bfbebSnyanmisaka                 if (tmp[i + 1] == 0x00 && tmp[i + 2] == 0xff && ((tmp[i + 3] & 0xf0) == 0xd0))
938*437bfbebSnyanmisaka                     i += 2;
939*437bfbebSnyanmisaka             }
940*437bfbebSnyanmisaka             *dst++ = tmp[i];
941*437bfbebSnyanmisaka             copy_len++;
942*437bfbebSnyanmisaka         }
943*437bfbebSnyanmisaka         for (; i < src_size; i++) {
944*437bfbebSnyanmisaka             *dst++ = tmp[i];
945*437bfbebSnyanmisaka             copy_len++;
946*437bfbebSnyanmisaka         }
947*437bfbebSnyanmisaka         if (copy_len < src_size)
948*437bfbebSnyanmisaka             memset(dst, 0, src_size - copy_len);
949*437bfbebSnyanmisaka         *copy_length = copy_len;
950*437bfbebSnyanmisaka     } else {
951*437bfbebSnyanmisaka         memcpy(dst, src, src_size);
952*437bfbebSnyanmisaka         memset(dst + src_size, 0, str_size > dst_size ? dst_size - src_size : str_size - src_size);
953*437bfbebSnyanmisaka         *copy_length = src_size;
954*437bfbebSnyanmisaka     }
955*437bfbebSnyanmisaka 
956*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
957*437bfbebSnyanmisaka     return ret;
958*437bfbebSnyanmisaka }
959*437bfbebSnyanmisaka 
jpegd_prepare(void * ctx,MppPacket pkt,HalDecTask * task)960*437bfbebSnyanmisaka static MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task)
961*437bfbebSnyanmisaka {
962*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
963*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
964*437bfbebSnyanmisaka     JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
965*437bfbebSnyanmisaka     if (!JpegCtx->copy_flag) {
966*437bfbebSnyanmisaka         /* no need to copy stream, handle packet from upper application directly*/
967*437bfbebSnyanmisaka         JpegCtx->input_packet = pkt;
968*437bfbebSnyanmisaka     }
969*437bfbebSnyanmisaka 
970*437bfbebSnyanmisaka     MppPacket input_packet = JpegCtx->input_packet;
971*437bfbebSnyanmisaka     RK_U32 copy_length = 0;
972*437bfbebSnyanmisaka     void *base = mpp_packet_get_pos(pkt);
973*437bfbebSnyanmisaka     RK_U8 *pos = base;
974*437bfbebSnyanmisaka     RK_U32 pkt_length = (RK_U32)mpp_packet_get_length(pkt);
975*437bfbebSnyanmisaka     RK_U32 eos = (pkt_length) ? (mpp_packet_get_eos(pkt)) : (1);
976*437bfbebSnyanmisaka 
977*437bfbebSnyanmisaka     JpegCtx->pts = mpp_packet_get_pts(pkt);
978*437bfbebSnyanmisaka 
979*437bfbebSnyanmisaka     task->valid = 0;
980*437bfbebSnyanmisaka     task->flags.eos = eos;
981*437bfbebSnyanmisaka     JpegCtx->eos = eos;
982*437bfbebSnyanmisaka 
983*437bfbebSnyanmisaka     jpegd_dbg_parser("pkt_length %d eos %d\n", pkt_length, eos);
984*437bfbebSnyanmisaka 
985*437bfbebSnyanmisaka     if (!pkt_length) {
986*437bfbebSnyanmisaka         jpegd_dbg_parser("it is end of stream.");
987*437bfbebSnyanmisaka         return ret;
988*437bfbebSnyanmisaka     }
989*437bfbebSnyanmisaka 
990*437bfbebSnyanmisaka     if (pkt_length > JpegCtx->bufferSize) {
991*437bfbebSnyanmisaka         jpegd_dbg_parser("Huge Frame(%d Bytes)! bufferSize:%d",
992*437bfbebSnyanmisaka                          pkt_length, JpegCtx->bufferSize);
993*437bfbebSnyanmisaka         mpp_free(JpegCtx->recv_buffer);
994*437bfbebSnyanmisaka         JpegCtx->recv_buffer = NULL;
995*437bfbebSnyanmisaka 
996*437bfbebSnyanmisaka         JpegCtx->recv_buffer = mpp_calloc(RK_U8, pkt_length + 1024);
997*437bfbebSnyanmisaka         if (NULL == JpegCtx->recv_buffer) {
998*437bfbebSnyanmisaka             mpp_err_f("no memory!");
999*437bfbebSnyanmisaka             return MPP_ERR_NOMEM;
1000*437bfbebSnyanmisaka         }
1001*437bfbebSnyanmisaka 
1002*437bfbebSnyanmisaka         JpegCtx->bufferSize = pkt_length + 1024;
1003*437bfbebSnyanmisaka     }
1004*437bfbebSnyanmisaka 
1005*437bfbebSnyanmisaka     if (JpegCtx->copy_flag)
1006*437bfbebSnyanmisaka         jpegd_split_frame(base, pkt_length, JpegCtx->recv_buffer,
1007*437bfbebSnyanmisaka                           JpegCtx->bufferSize, &copy_length);
1008*437bfbebSnyanmisaka 
1009*437bfbebSnyanmisaka     pos += pkt_length;
1010*437bfbebSnyanmisaka     mpp_packet_set_pos(pkt, pos);
1011*437bfbebSnyanmisaka     if (copy_length != pkt_length) {
1012*437bfbebSnyanmisaka         jpegd_dbg_parser("packet prepare, pkt_length:%d, copy_length:%d\n",
1013*437bfbebSnyanmisaka                          pkt_length, copy_length);
1014*437bfbebSnyanmisaka     }
1015*437bfbebSnyanmisaka 
1016*437bfbebSnyanmisaka     /* debug information */
1017*437bfbebSnyanmisaka     if (jpegd_debug & JPEGD_DBG_IO) {
1018*437bfbebSnyanmisaka         static FILE *jpg_file;
1019*437bfbebSnyanmisaka         static char name[32];
1020*437bfbebSnyanmisaka 
1021*437bfbebSnyanmisaka         snprintf(name, sizeof(name) - 1, "/data/input%02d.jpg",
1022*437bfbebSnyanmisaka                  JpegCtx->input_jpeg_count);
1023*437bfbebSnyanmisaka         jpg_file = fopen(name, "wb+");
1024*437bfbebSnyanmisaka         if (jpg_file) {
1025*437bfbebSnyanmisaka             jpegd_dbg_io("frame_%02d input jpeg(%d Bytes) saving to %s\n",
1026*437bfbebSnyanmisaka                          JpegCtx->input_jpeg_count, pkt_length, name);
1027*437bfbebSnyanmisaka             fwrite(base, pkt_length, 1, jpg_file);
1028*437bfbebSnyanmisaka             fclose(jpg_file);
1029*437bfbebSnyanmisaka             JpegCtx->input_jpeg_count++;
1030*437bfbebSnyanmisaka         }
1031*437bfbebSnyanmisaka     }
1032*437bfbebSnyanmisaka 
1033*437bfbebSnyanmisaka     if (JpegCtx->copy_flag) {
1034*437bfbebSnyanmisaka         mpp_packet_set_data(input_packet, JpegCtx->recv_buffer);
1035*437bfbebSnyanmisaka         mpp_packet_set_size(input_packet, pkt_length);
1036*437bfbebSnyanmisaka         mpp_packet_set_length(input_packet, pkt_length);
1037*437bfbebSnyanmisaka         memcpy(base, JpegCtx->recv_buffer, pkt_length);
1038*437bfbebSnyanmisaka     }
1039*437bfbebSnyanmisaka 
1040*437bfbebSnyanmisaka     JpegCtx->streamLength = pkt_length;
1041*437bfbebSnyanmisaka     task->input_packet = input_packet;
1042*437bfbebSnyanmisaka     task->valid = 1;
1043*437bfbebSnyanmisaka     jpegd_dbg_parser("input_packet:%p, recv_buffer:%p, pkt_length:%d",
1044*437bfbebSnyanmisaka                      input_packet,
1045*437bfbebSnyanmisaka                      JpegCtx->recv_buffer, pkt_length);
1046*437bfbebSnyanmisaka 
1047*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1048*437bfbebSnyanmisaka     return ret;
1049*437bfbebSnyanmisaka }
1050*437bfbebSnyanmisaka 
jpegd_allocate_frame(JpegdCtx * ctx)1051*437bfbebSnyanmisaka static MPP_RET jpegd_allocate_frame(JpegdCtx *ctx)
1052*437bfbebSnyanmisaka {
1053*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1054*437bfbebSnyanmisaka     JpegdSyntax *s = ctx->syntax;
1055*437bfbebSnyanmisaka     MppBufSlots slots = ctx->frame_slots;
1056*437bfbebSnyanmisaka     MppFrame output = ctx->output_frame;
1057*437bfbebSnyanmisaka     RK_S32 slot_idx = ctx->frame_slot_index;
1058*437bfbebSnyanmisaka 
1059*437bfbebSnyanmisaka     if (slot_idx == -1) {
1060*437bfbebSnyanmisaka         RK_U32 value;
1061*437bfbebSnyanmisaka         MppFrameFormat fmt = MPP_FMT_YUV420SP;
1062*437bfbebSnyanmisaka 
1063*437bfbebSnyanmisaka         switch (s->yuv_mode) {
1064*437bfbebSnyanmisaka         case JPEGDEC_YUV420: {
1065*437bfbebSnyanmisaka             fmt = MPP_FMT_YUV420SP;
1066*437bfbebSnyanmisaka         } break;
1067*437bfbebSnyanmisaka         case JPEGDEC_YUV422: {
1068*437bfbebSnyanmisaka             fmt = MPP_FMT_YUV422SP;
1069*437bfbebSnyanmisaka         } break;
1070*437bfbebSnyanmisaka         case JPEGDEC_YUV444: {
1071*437bfbebSnyanmisaka             fmt = MPP_FMT_YUV444SP;
1072*437bfbebSnyanmisaka         } break;
1073*437bfbebSnyanmisaka         case JPEGDEC_YUV400: {
1074*437bfbebSnyanmisaka             fmt = MPP_FMT_YUV400;
1075*437bfbebSnyanmisaka         } break;
1076*437bfbebSnyanmisaka         default : {
1077*437bfbebSnyanmisaka             fmt = MPP_FMT_YUV420SP;
1078*437bfbebSnyanmisaka         } break;
1079*437bfbebSnyanmisaka         }
1080*437bfbebSnyanmisaka 
1081*437bfbebSnyanmisaka         mpp_frame_set_fmt(output, fmt);
1082*437bfbebSnyanmisaka         mpp_frame_set_width(output, s->width);
1083*437bfbebSnyanmisaka         mpp_frame_set_height(output, s->height);
1084*437bfbebSnyanmisaka         mpp_frame_set_hor_stride(output, s->hor_stride);
1085*437bfbebSnyanmisaka         mpp_frame_set_ver_stride(output, s->ver_stride);
1086*437bfbebSnyanmisaka         mpp_frame_set_pts(output, ctx->pts);
1087*437bfbebSnyanmisaka 
1088*437bfbebSnyanmisaka         if (ctx->eos)
1089*437bfbebSnyanmisaka             mpp_frame_set_eos(output, 1);
1090*437bfbebSnyanmisaka 
1091*437bfbebSnyanmisaka         mpp_buf_slot_get_unused(slots, &slot_idx);
1092*437bfbebSnyanmisaka         ctx->frame_slot_index = slot_idx;
1093*437bfbebSnyanmisaka         jpegd_dbg_parser("frame_slot_index:%d\n", slot_idx);
1094*437bfbebSnyanmisaka 
1095*437bfbebSnyanmisaka         value = 2;
1096*437bfbebSnyanmisaka         mpp_slots_set_prop(slots, SLOTS_NUMERATOR, &value);
1097*437bfbebSnyanmisaka         value = 1;
1098*437bfbebSnyanmisaka         mpp_slots_set_prop(slots, SLOTS_DENOMINATOR, &value);
1099*437bfbebSnyanmisaka         if (mpp_buf_slot_set_prop(slots, slot_idx, SLOT_FRAME, output))
1100*437bfbebSnyanmisaka             return MPP_ERR_VALUE;
1101*437bfbebSnyanmisaka         mpp_buf_slot_set_flag(slots, slot_idx, SLOT_CODEC_USE);
1102*437bfbebSnyanmisaka         mpp_buf_slot_set_flag(slots, slot_idx, SLOT_HAL_OUTPUT);
1103*437bfbebSnyanmisaka     }
1104*437bfbebSnyanmisaka 
1105*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1106*437bfbebSnyanmisaka     return MPP_OK;
1107*437bfbebSnyanmisaka }
1108*437bfbebSnyanmisaka 
jpegd_update_frame(JpegdCtx * ctx)1109*437bfbebSnyanmisaka static MPP_RET jpegd_update_frame(JpegdCtx *ctx)
1110*437bfbebSnyanmisaka {
1111*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1112*437bfbebSnyanmisaka 
1113*437bfbebSnyanmisaka     mpp_buf_slot_clr_flag(ctx->frame_slots, ctx->frame_slot_index,
1114*437bfbebSnyanmisaka                           SLOT_CODEC_USE);
1115*437bfbebSnyanmisaka     ctx->frame_slot_index = -1;
1116*437bfbebSnyanmisaka 
1117*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1118*437bfbebSnyanmisaka     return MPP_OK;
1119*437bfbebSnyanmisaka }
1120*437bfbebSnyanmisaka 
jpegd_parse(void * ctx,HalDecTask * task)1121*437bfbebSnyanmisaka static MPP_RET jpegd_parse(void *ctx, HalDecTask *task)
1122*437bfbebSnyanmisaka {
1123*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1124*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
1125*437bfbebSnyanmisaka     JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1126*437bfbebSnyanmisaka     task->valid = 0;
1127*437bfbebSnyanmisaka 
1128*437bfbebSnyanmisaka     JpegCtx->buffer = (RK_U8 *)mpp_packet_get_data(JpegCtx->input_packet);
1129*437bfbebSnyanmisaka 
1130*437bfbebSnyanmisaka     memset(JpegCtx->syntax, 0, sizeof(JpegdSyntax));
1131*437bfbebSnyanmisaka 
1132*437bfbebSnyanmisaka     ret = jpegd_decode_frame(JpegCtx);
1133*437bfbebSnyanmisaka     if (MPP_OK == ret) {
1134*437bfbebSnyanmisaka         if (jpegd_allocate_frame(JpegCtx))
1135*437bfbebSnyanmisaka             return MPP_ERR_VALUE;
1136*437bfbebSnyanmisaka 
1137*437bfbebSnyanmisaka         task->syntax.data = (void *)JpegCtx->syntax;
1138*437bfbebSnyanmisaka         task->syntax.number = sizeof(JpegdSyntax);
1139*437bfbebSnyanmisaka         task->output = JpegCtx->frame_slot_index;
1140*437bfbebSnyanmisaka         task->valid = 1;
1141*437bfbebSnyanmisaka 
1142*437bfbebSnyanmisaka         jpegd_update_frame(JpegCtx);
1143*437bfbebSnyanmisaka     } else
1144*437bfbebSnyanmisaka         task->flags.parse_err = 1;
1145*437bfbebSnyanmisaka 
1146*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1147*437bfbebSnyanmisaka     return ret;
1148*437bfbebSnyanmisaka }
1149*437bfbebSnyanmisaka 
jpegd_deinit(void * ctx)1150*437bfbebSnyanmisaka static MPP_RET jpegd_deinit(void *ctx)
1151*437bfbebSnyanmisaka {
1152*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1153*437bfbebSnyanmisaka     JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1154*437bfbebSnyanmisaka 
1155*437bfbebSnyanmisaka     if (JpegCtx->recv_buffer) {
1156*437bfbebSnyanmisaka         mpp_free(JpegCtx->recv_buffer);
1157*437bfbebSnyanmisaka         JpegCtx->recv_buffer = NULL;
1158*437bfbebSnyanmisaka     }
1159*437bfbebSnyanmisaka 
1160*437bfbebSnyanmisaka     if (JpegCtx->output_frame) {
1161*437bfbebSnyanmisaka         mpp_frame_deinit(&JpegCtx->output_frame);
1162*437bfbebSnyanmisaka     }
1163*437bfbebSnyanmisaka 
1164*437bfbebSnyanmisaka     if (JpegCtx->copy_flag) {
1165*437bfbebSnyanmisaka         if (JpegCtx->input_packet) {
1166*437bfbebSnyanmisaka             mpp_packet_deinit(&JpegCtx->input_packet);
1167*437bfbebSnyanmisaka         }
1168*437bfbebSnyanmisaka     } else {
1169*437bfbebSnyanmisaka         JpegCtx->input_packet = NULL;
1170*437bfbebSnyanmisaka     }
1171*437bfbebSnyanmisaka 
1172*437bfbebSnyanmisaka     if (JpegCtx->bit_ctx) {
1173*437bfbebSnyanmisaka         mpp_free(JpegCtx->bit_ctx);
1174*437bfbebSnyanmisaka         JpegCtx->bit_ctx = NULL;
1175*437bfbebSnyanmisaka     }
1176*437bfbebSnyanmisaka 
1177*437bfbebSnyanmisaka     if (JpegCtx->syntax) {
1178*437bfbebSnyanmisaka         mpp_free(JpegCtx->syntax);
1179*437bfbebSnyanmisaka         JpegCtx->syntax = NULL;
1180*437bfbebSnyanmisaka     }
1181*437bfbebSnyanmisaka 
1182*437bfbebSnyanmisaka     JpegCtx->pts = 0;
1183*437bfbebSnyanmisaka     JpegCtx->eos = 0;
1184*437bfbebSnyanmisaka     JpegCtx->input_jpeg_count = 0;
1185*437bfbebSnyanmisaka 
1186*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1187*437bfbebSnyanmisaka     return 0;
1188*437bfbebSnyanmisaka }
1189*437bfbebSnyanmisaka 
jpegd_init(void * ctx,ParserCfg * parser_cfg)1190*437bfbebSnyanmisaka static MPP_RET jpegd_init(void *ctx, ParserCfg *parser_cfg)
1191*437bfbebSnyanmisaka {
1192*437bfbebSnyanmisaka     JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1193*437bfbebSnyanmisaka     const MppDecHwCap *hw_info = parser_cfg->hw_info;
1194*437bfbebSnyanmisaka 
1195*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1196*437bfbebSnyanmisaka 
1197*437bfbebSnyanmisaka     if (NULL == JpegCtx) {
1198*437bfbebSnyanmisaka         JpegCtx = (JpegdCtx *)mpp_calloc(JpegdCtx, 1);
1199*437bfbebSnyanmisaka         if (NULL == JpegCtx) {
1200*437bfbebSnyanmisaka             mpp_err_f("NULL pointer");
1201*437bfbebSnyanmisaka             return MPP_ERR_NULL_PTR;
1202*437bfbebSnyanmisaka         }
1203*437bfbebSnyanmisaka     }
1204*437bfbebSnyanmisaka 
1205*437bfbebSnyanmisaka     mpp_env_get_u32("jpegd_debug", &jpegd_debug, 0);
1206*437bfbebSnyanmisaka     // mpp only support baseline
1207*437bfbebSnyanmisaka     JpegCtx->scan_all_marker = 0;
1208*437bfbebSnyanmisaka 
1209*437bfbebSnyanmisaka     if (hw_info && hw_info->cap_hw_jpg_fix) {
1210*437bfbebSnyanmisaka         /*
1211*437bfbebSnyanmisaka          * no need to copy stream when decoding jpeg;
1212*437bfbebSnyanmisaka          * just scan parts of markers to reduce CPU's occupancy
1213*437bfbebSnyanmisaka          */
1214*437bfbebSnyanmisaka         JpegCtx->copy_flag = 0;
1215*437bfbebSnyanmisaka     } else {
1216*437bfbebSnyanmisaka         // TODO: do not copy if input provides valid fd and virtual ptr
1217*437bfbebSnyanmisaka         JpegCtx->copy_flag = 1;
1218*437bfbebSnyanmisaka     }
1219*437bfbebSnyanmisaka 
1220*437bfbebSnyanmisaka     JpegCtx->frame_slots = parser_cfg->frame_slots;
1221*437bfbebSnyanmisaka     JpegCtx->packet_slots = parser_cfg->packet_slots;
1222*437bfbebSnyanmisaka     JpegCtx->frame_slot_index = -1;
1223*437bfbebSnyanmisaka     mpp_buf_slot_setup(JpegCtx->frame_slots, 1);
1224*437bfbebSnyanmisaka 
1225*437bfbebSnyanmisaka     JpegCtx->recv_buffer = mpp_calloc(RK_U8, JPEGD_STREAM_BUFF_SIZE);
1226*437bfbebSnyanmisaka     if (NULL == JpegCtx->recv_buffer) {
1227*437bfbebSnyanmisaka         mpp_err_f("no memory!");
1228*437bfbebSnyanmisaka         return MPP_ERR_NOMEM;
1229*437bfbebSnyanmisaka     }
1230*437bfbebSnyanmisaka     JpegCtx->bufferSize = JPEGD_STREAM_BUFF_SIZE;
1231*437bfbebSnyanmisaka     if (JpegCtx->copy_flag) {
1232*437bfbebSnyanmisaka         mpp_packet_init(&JpegCtx->input_packet,
1233*437bfbebSnyanmisaka                         JpegCtx->recv_buffer, JPEGD_STREAM_BUFF_SIZE);
1234*437bfbebSnyanmisaka     } else {
1235*437bfbebSnyanmisaka         JpegCtx->input_packet = NULL;
1236*437bfbebSnyanmisaka     }
1237*437bfbebSnyanmisaka 
1238*437bfbebSnyanmisaka     mpp_frame_init(&JpegCtx->output_frame);
1239*437bfbebSnyanmisaka     if (!JpegCtx->output_frame) {
1240*437bfbebSnyanmisaka         mpp_err_f("Failed to allocate output frame buffer");
1241*437bfbebSnyanmisaka         return MPP_ERR_NOMEM;
1242*437bfbebSnyanmisaka     }
1243*437bfbebSnyanmisaka 
1244*437bfbebSnyanmisaka     JpegCtx->bit_ctx = mpp_calloc(BitReadCtx_t, 1);
1245*437bfbebSnyanmisaka     if (JpegCtx->bit_ctx == NULL) {
1246*437bfbebSnyanmisaka         mpp_err_f("allocate bit_ctx failed\n");
1247*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
1248*437bfbebSnyanmisaka     }
1249*437bfbebSnyanmisaka 
1250*437bfbebSnyanmisaka     JpegCtx->syntax = mpp_calloc(JpegdSyntax, 1);
1251*437bfbebSnyanmisaka     if (JpegCtx->syntax == NULL) {
1252*437bfbebSnyanmisaka         mpp_err_f("allocate syntax failed\n");
1253*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
1254*437bfbebSnyanmisaka     }
1255*437bfbebSnyanmisaka     memset(JpegCtx->syntax, 0, sizeof(JpegdSyntax));
1256*437bfbebSnyanmisaka 
1257*437bfbebSnyanmisaka     JpegCtx->pts = 0;
1258*437bfbebSnyanmisaka     JpegCtx->eos = 0;
1259*437bfbebSnyanmisaka     JpegCtx->input_jpeg_count = 0;
1260*437bfbebSnyanmisaka 
1261*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1262*437bfbebSnyanmisaka     return MPP_OK;
1263*437bfbebSnyanmisaka }
1264*437bfbebSnyanmisaka 
jpegd_flush(void * ctx)1265*437bfbebSnyanmisaka static MPP_RET jpegd_flush(void *ctx)
1266*437bfbebSnyanmisaka {
1267*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1268*437bfbebSnyanmisaka     JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1269*437bfbebSnyanmisaka     (void)JpegCtx;
1270*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1271*437bfbebSnyanmisaka     return MPP_OK;
1272*437bfbebSnyanmisaka }
1273*437bfbebSnyanmisaka 
jpegd_reset(void * ctx)1274*437bfbebSnyanmisaka static MPP_RET jpegd_reset(void *ctx)
1275*437bfbebSnyanmisaka {
1276*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1277*437bfbebSnyanmisaka     JpegdCtx *JpegCtx = (JpegdCtx *)ctx;
1278*437bfbebSnyanmisaka 
1279*437bfbebSnyanmisaka     (void)JpegCtx;
1280*437bfbebSnyanmisaka 
1281*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1282*437bfbebSnyanmisaka     return MPP_OK;
1283*437bfbebSnyanmisaka }
1284*437bfbebSnyanmisaka 
jpegd_control(void * ctx,MpiCmd cmd,void * param)1285*437bfbebSnyanmisaka static MPP_RET jpegd_control(void *ctx, MpiCmd cmd, void *param)
1286*437bfbebSnyanmisaka {
1287*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1288*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
1289*437bfbebSnyanmisaka     (void) ctx;
1290*437bfbebSnyanmisaka     (void) cmd;
1291*437bfbebSnyanmisaka     (void) param;
1292*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1293*437bfbebSnyanmisaka     return ret;
1294*437bfbebSnyanmisaka }
1295*437bfbebSnyanmisaka 
jpegd_callback(void * decoder,void * err_info)1296*437bfbebSnyanmisaka static MPP_RET jpegd_callback(void *decoder, void *err_info)
1297*437bfbebSnyanmisaka {
1298*437bfbebSnyanmisaka     JpegdCtx *JpegCtx = (JpegdCtx *)decoder;
1299*437bfbebSnyanmisaka     DecCbHalDone *ctx = (DecCbHalDone *)err_info;
1300*437bfbebSnyanmisaka     HalDecTask *task_dec = (HalDecTask *)ctx->task;
1301*437bfbebSnyanmisaka     RK_U32 task_err = task_dec->flags.parse_err;
1302*437bfbebSnyanmisaka     RK_U32 hw_dec_err = ctx->hard_err;
1303*437bfbebSnyanmisaka     RK_S32 output = task_dec->output;
1304*437bfbebSnyanmisaka     RK_U32 err_mark = 0;
1305*437bfbebSnyanmisaka     MppFrame frame = NULL;
1306*437bfbebSnyanmisaka 
1307*437bfbebSnyanmisaka     if (output >= 0)
1308*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(JpegCtx->frame_slots, output, SLOT_FRAME_PTR, &frame);
1309*437bfbebSnyanmisaka 
1310*437bfbebSnyanmisaka     if (!frame)
1311*437bfbebSnyanmisaka         goto __RETURN;
1312*437bfbebSnyanmisaka 
1313*437bfbebSnyanmisaka     /* check and mark current frame */
1314*437bfbebSnyanmisaka     if (task_err)
1315*437bfbebSnyanmisaka         err_mark |= MPP_FRAME_ERR_DEC_INVALID;
1316*437bfbebSnyanmisaka     else if (hw_dec_err)
1317*437bfbebSnyanmisaka         err_mark |= MPP_FRAME_ERR_DEC_HW_ERR;
1318*437bfbebSnyanmisaka     if (err_mark)
1319*437bfbebSnyanmisaka         mpp_frame_set_errinfo(frame, err_mark);
1320*437bfbebSnyanmisaka 
1321*437bfbebSnyanmisaka __RETURN:
1322*437bfbebSnyanmisaka     return MPP_OK;
1323*437bfbebSnyanmisaka }
1324*437bfbebSnyanmisaka 
1325*437bfbebSnyanmisaka const ParserApi api_jpegd_parser = {
1326*437bfbebSnyanmisaka     .name = "jpegd_parse",
1327*437bfbebSnyanmisaka     .coding = MPP_VIDEO_CodingMJPEG,
1328*437bfbebSnyanmisaka     .ctx_size = sizeof(JpegdCtx),
1329*437bfbebSnyanmisaka     .flag = 0,
1330*437bfbebSnyanmisaka     .init = jpegd_init,
1331*437bfbebSnyanmisaka     .deinit = jpegd_deinit,
1332*437bfbebSnyanmisaka     .prepare = jpegd_prepare,
1333*437bfbebSnyanmisaka     .parse = jpegd_parse,
1334*437bfbebSnyanmisaka     .reset = jpegd_reset,
1335*437bfbebSnyanmisaka     .flush = jpegd_flush,
1336*437bfbebSnyanmisaka     .control = jpegd_control,
1337*437bfbebSnyanmisaka     .callback = jpegd_callback,
1338*437bfbebSnyanmisaka };
1339*437bfbebSnyanmisaka 
1340*437bfbebSnyanmisaka 
1341