This source file includes following definitions.
- jpeg_scale_quant_table
- jpeg_set_quality
- hantro_jpeg_get_qtable
- hantro_jpeg_header_assemble
- hantro_jpeg_enc_init
- hantro_jpeg_enc_exit
1
2
3
4
5
6
7
8
9 #include <linux/dma-mapping.h>
10 #include <linux/kernel.h>
11 #include <linux/string.h>
12 #include "hantro_jpeg.h"
13 #include "hantro.h"
14
15 #define LUMA_QUANT_OFF 7
16 #define CHROMA_QUANT_OFF 72
17 #define HEIGHT_OFF 141
18 #define WIDTH_OFF 143
19
20 #define HUFF_LUMA_DC_OFF 160
21 #define HUFF_LUMA_AC_OFF 193
22 #define HUFF_CHROMA_DC_OFF 376
23 #define HUFF_CHROMA_AC_OFF 409
24
25
26
27
28 static const unsigned char luma_q_table[] = {
29 0x10, 0x0b, 0x0a, 0x10, 0x7c, 0x8c, 0x97, 0xa1,
30 0x0c, 0x0c, 0x0e, 0x13, 0x7e, 0x9e, 0xa0, 0x9b,
31 0x0e, 0x0d, 0x10, 0x18, 0x8c, 0x9d, 0xa9, 0x9c,
32 0x0e, 0x11, 0x16, 0x1d, 0x97, 0xbb, 0xb4, 0xa2,
33 0x12, 0x16, 0x25, 0x38, 0xa8, 0x6d, 0x67, 0xb1,
34 0x18, 0x23, 0x37, 0x40, 0xb5, 0x68, 0x71, 0xc0,
35 0x31, 0x40, 0x4e, 0x57, 0x67, 0x79, 0x78, 0x65,
36 0x48, 0x5c, 0x5f, 0x62, 0x70, 0x64, 0x67, 0xc7,
37 };
38
39 static const unsigned char chroma_q_table[] = {
40 0x11, 0x12, 0x18, 0x2f, 0x63, 0x63, 0x63, 0x63,
41 0x12, 0x15, 0x1a, 0x42, 0x63, 0x63, 0x63, 0x63,
42 0x18, 0x1a, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63,
43 0x2f, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
44 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
45 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
46 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
47 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
48 };
49
50
51 static const unsigned char luma_dc_table[] = {
52 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
53 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
55 0x08, 0x09, 0x0a, 0x0b,
56 };
57
58 static const unsigned char chroma_dc_table[] = {
59 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
60 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
62 0x08, 0x09, 0x0a, 0x0b,
63 };
64
65 static const unsigned char luma_ac_table[] = {
66 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
67 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
68 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
69 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
70 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
71 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
72 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
73 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
74 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
75 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
76 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
77 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
78 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
79 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
80 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
81 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
82 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
83 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
84 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
85 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
86 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
87 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
88 0xf9, 0xfa,
89 };
90
91 static const unsigned char chroma_ac_table[] = {
92 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
93 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
94 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
95 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
96 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
97 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
98 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
99 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
100 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
101 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
102 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
103 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
104 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
105 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
106 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
107 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
108 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
109 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
110 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
111 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
112 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
113 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
114 0xf9, 0xfa,
115 };
116
117
118
119
120
121 static const unsigned char hantro_jpeg_header[JPEG_HEADER_SIZE] = {
122
123 0xff, 0xd8,
124
125
126 0xff, 0xdb, 0x00, 0x84,
127
128 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137
138 0x01,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147
148
149 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x01,
150 0x40, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01,
151 0x03, 0x11, 0x01,
152
153
154 0xff, 0xc4, 0x00, 0x1f, 0x00,
155
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00,
160
161
162 0xff, 0xc4, 0x00, 0xb5, 0x10,
163
164 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187
188
189 0xff, 0xc4, 0x00, 0x1f, 0x01,
190
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00,
195
196
197 0xff, 0xc4, 0x00, 0xb5, 0x11,
198
199 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222
223
224 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
225 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
226 };
227
228 static void
229 jpeg_scale_quant_table(unsigned char *q_tab,
230 const unsigned char *tab, int scale)
231 {
232 unsigned int temp;
233 int i;
234
235 for (i = 0; i < 64; i++) {
236 temp = DIV_ROUND_CLOSEST((unsigned int)tab[i] * scale, 100);
237 if (temp <= 0)
238 temp = 1;
239 if (temp > 255)
240 temp = 255;
241 q_tab[i] = (unsigned char)temp;
242 }
243 }
244
245 static void jpeg_set_quality(unsigned char *buffer, int quality)
246 {
247 int scale;
248
249
250
251
252
253 if (quality < 50)
254 scale = 5000 / quality;
255 else
256 scale = 200 - 2 * quality;
257
258 jpeg_scale_quant_table(buffer + LUMA_QUANT_OFF,
259 luma_q_table, scale);
260 jpeg_scale_quant_table(buffer + CHROMA_QUANT_OFF,
261 chroma_q_table, scale);
262 }
263
264 unsigned char *
265 hantro_jpeg_get_qtable(struct hantro_jpeg_ctx *ctx, int index)
266 {
267 if (index == 0)
268 return ctx->buffer + LUMA_QUANT_OFF;
269 return ctx->buffer + CHROMA_QUANT_OFF;
270 }
271
272 void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx)
273 {
274 char *buf = ctx->buffer;
275
276 memcpy(buf, hantro_jpeg_header,
277 sizeof(hantro_jpeg_header));
278
279 buf[HEIGHT_OFF + 0] = ctx->height >> 8;
280 buf[HEIGHT_OFF + 1] = ctx->height;
281 buf[WIDTH_OFF + 0] = ctx->width >> 8;
282 buf[WIDTH_OFF + 1] = ctx->width;
283
284 memcpy(buf + HUFF_LUMA_DC_OFF, luma_dc_table, sizeof(luma_dc_table));
285 memcpy(buf + HUFF_LUMA_AC_OFF, luma_ac_table, sizeof(luma_ac_table));
286 memcpy(buf + HUFF_CHROMA_DC_OFF, chroma_dc_table,
287 sizeof(chroma_dc_table));
288 memcpy(buf + HUFF_CHROMA_AC_OFF, chroma_ac_table,
289 sizeof(chroma_ac_table));
290
291 jpeg_set_quality(buf, ctx->quality);
292 }
293
294 int hantro_jpeg_enc_init(struct hantro_ctx *ctx)
295 {
296 ctx->jpeg_enc.bounce_buffer.size =
297 ctx->dst_fmt.plane_fmt[0].sizeimage -
298 ctx->vpu_dst_fmt->header_size;
299
300 ctx->jpeg_enc.bounce_buffer.cpu =
301 dma_alloc_attrs(ctx->dev->dev,
302 ctx->jpeg_enc.bounce_buffer.size,
303 &ctx->jpeg_enc.bounce_buffer.dma,
304 GFP_KERNEL,
305 DMA_ATTR_ALLOC_SINGLE_PAGES);
306 if (!ctx->jpeg_enc.bounce_buffer.cpu)
307 return -ENOMEM;
308
309 return 0;
310 }
311
312 void hantro_jpeg_enc_exit(struct hantro_ctx *ctx)
313 {
314 dma_free_attrs(ctx->dev->dev,
315 ctx->jpeg_enc.bounce_buffer.size,
316 ctx->jpeg_enc.bounce_buffer.cpu,
317 ctx->jpeg_enc.bounce_buffer.dma,
318 DMA_ATTR_ALLOC_SINGLE_PAGES);
319 }