1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/kernel.h>
17#include <linux/videodev2.h>
18
19#include "mtk_jpeg_parse.h"
20
21#define TEM 0x01
22#define SOF0 0xc0
23#define RST 0xd0
24#define SOI 0xd8
25#define EOI 0xd9
26
27struct mtk_jpeg_stream {
28 u8 *addr;
29 u32 size;
30 u32 curr;
31};
32
33static int read_byte(struct mtk_jpeg_stream *stream)
34{
35 if (stream->curr >= stream->size)
36 return -1;
37 return stream->addr[stream->curr++];
38}
39
40static int read_word_be(struct mtk_jpeg_stream *stream, u32 *word)
41{
42 u32 temp;
43 int byte;
44
45 byte = read_byte(stream);
46 if (byte == -1)
47 return -1;
48 temp = byte << 8;
49 byte = read_byte(stream);
50 if (byte == -1)
51 return -1;
52 *word = (u32)byte | temp;
53
54 return 0;
55}
56
57static void read_skip(struct mtk_jpeg_stream *stream, long len)
58{
59 if (len <= 0)
60 return;
61 while (len--)
62 read_byte(stream);
63}
64
65static bool mtk_jpeg_do_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
66 u32 src_size)
67{
68 bool notfound = true;
69 struct mtk_jpeg_stream stream;
70
71 stream.addr = src_addr_va;
72 stream.size = src_size;
73 stream.curr = 0;
74
75 while (notfound) {
76 int i, length, byte;
77 u32 word;
78
79 byte = read_byte(&stream);
80 if (byte == -1)
81 return false;
82 if (byte != 0xff)
83 continue;
84 do
85 byte = read_byte(&stream);
86 while (byte == 0xff);
87 if (byte == -1)
88 return false;
89 if (byte == 0)
90 continue;
91
92 length = 0;
93 switch (byte) {
94 case SOF0:
95
96 if (read_word_be(&stream, &word))
97 break;
98
99
100 if (read_byte(&stream) == -1)
101 break;
102
103 if (read_word_be(&stream, &word))
104 break;
105 param->pic_h = word;
106
107 if (read_word_be(&stream, &word))
108 break;
109 param->pic_w = word;
110
111 param->comp_num = read_byte(&stream);
112 if (param->comp_num != 1 && param->comp_num != 3)
113 break;
114
115 for (i = 0; i < param->comp_num; i++) {
116 param->comp_id[i] = read_byte(&stream);
117 if (param->comp_id[i] == -1)
118 break;
119
120
121 byte = read_byte(&stream);
122 if (byte == -1)
123 break;
124 param->sampling_w[i] = (byte >> 4) & 0x0F;
125 param->sampling_h[i] = byte & 0x0F;
126
127 param->qtbl_num[i] = read_byte(&stream);
128 if (param->qtbl_num[i] == -1)
129 break;
130 }
131
132 notfound = !(i == param->comp_num);
133 break;
134 case RST ... RST + 7:
135 case SOI:
136 case EOI:
137 case TEM:
138 break;
139 default:
140 if (read_word_be(&stream, &word))
141 break;
142 length = (long)word - 2;
143 read_skip(&stream, length);
144 break;
145 }
146 }
147
148 return !notfound;
149}
150
151bool mtk_jpeg_parse(struct mtk_jpeg_dec_param *param, u8 *src_addr_va,
152 u32 src_size)
153{
154 if (!mtk_jpeg_do_parse(param, src_addr_va, src_size))
155 return false;
156 if (mtk_jpeg_dec_fill_param(param))
157 return false;
158
159 return true;
160}
161