• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Coda multi-standard codec IP - JPEG support functions
4  *
5  * Copyright (C) 2014 Philipp Zabel, Pengutronix
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/swab.h>
10 
11 #include "coda.h"
12 #include "trace.h"
13 
14 #define SOI_MARKER	0xffd8
15 #define EOI_MARKER	0xffd9
16 
17 /*
18  * Typical Huffman tables for 8-bit precision luminance and
19  * chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3
20  */
21 
22 static const unsigned char luma_dc_bits[16] = {
23 	0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
24 	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 };
26 
27 static const unsigned char luma_dc_value[12] = {
28 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
29 	0x08, 0x09, 0x0a, 0x0b,
30 };
31 
32 static const unsigned char chroma_dc_bits[16] = {
33 	0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
34 	0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
35 };
36 
37 static const unsigned char chroma_dc_value[12] = {
38 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
39 	0x08, 0x09, 0x0a, 0x0b,
40 };
41 
42 static const unsigned char luma_ac_bits[16] = {
43 	0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
44 	0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
45 };
46 
47 static const unsigned char luma_ac_value[162 + 2] = {
48 	0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
49 	0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
50 	0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
51 	0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
52 	0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
53 	0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
54 	0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
55 	0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
56 	0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
57 	0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
58 	0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
59 	0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
60 	0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
61 	0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
62 	0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
63 	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
64 	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
65 	0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
66 	0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
67 	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
68 	0xf9, 0xfa, /* padded to 32-bit */
69 };
70 
71 static const unsigned char chroma_ac_bits[16] = {
72 	0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
73 	0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
74 };
75 
76 static const unsigned char chroma_ac_value[162 + 2] = {
77 	0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
78 	0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
79 	0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
80 	0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
81 	0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
82 	0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
83 	0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
84 	0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
85 	0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
86 	0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
87 	0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
88 	0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
89 	0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
90 	0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
91 	0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
92 	0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
93 	0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
94 	0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
95 	0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
96 	0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
97 	0xf9, 0xfa, /* padded to 32-bit */
98 };
99 
100 /*
101  * Quantization tables for luminance and chrominance components in
102  * zig-zag scan order from the Freescale i.MX VPU libraries
103  */
104 
105 static unsigned char luma_q[64] = {
106 	0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x05,
107 	0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b,
108 	0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a, 0x0a,
109 	0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c,
110 	0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c,
111 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
112 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
113 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
114 };
115 
116 static unsigned char chroma_q[64] = {
117 	0x07, 0x07, 0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10,
118 	0x10, 0x18, 0x14, 0x0e, 0x0e, 0x0e, 0x14, 0x14,
119 	0x0e, 0x0e, 0x0e, 0x0e, 0x14, 0x11, 0x0c, 0x0c,
120 	0x0c, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x0c,
121 	0x0c, 0x0c, 0x0c, 0x11, 0x0c, 0x0c, 0x0c, 0x0c,
122 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
123 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
124 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
125 };
126 
127 struct coda_memcpy_desc {
128 	int offset;
129 	const void *src;
130 	size_t len;
131 };
132 
coda_memcpy_parabuf(void * parabuf,const struct coda_memcpy_desc * desc)133 static void coda_memcpy_parabuf(void *parabuf,
134 				const struct coda_memcpy_desc *desc)
135 {
136 	u32 *dst = parabuf + desc->offset;
137 	const u32 *src = desc->src;
138 	int len = desc->len / 4;
139 	int i;
140 
141 	for (i = 0; i < len; i += 2) {
142 		dst[i + 1] = swab32(src[i]);
143 		dst[i] = swab32(src[i + 1]);
144 	}
145 }
146 
coda_jpeg_write_tables(struct coda_ctx * ctx)147 int coda_jpeg_write_tables(struct coda_ctx *ctx)
148 {
149 	int i;
150 	static const struct coda_memcpy_desc huff[8] = {
151 		{ 0,   luma_dc_bits,    sizeof(luma_dc_bits)    },
152 		{ 16,  luma_dc_value,   sizeof(luma_dc_value)   },
153 		{ 32,  luma_ac_bits,    sizeof(luma_ac_bits)    },
154 		{ 48,  luma_ac_value,   sizeof(luma_ac_value)   },
155 		{ 216, chroma_dc_bits,  sizeof(chroma_dc_bits)  },
156 		{ 232, chroma_dc_value, sizeof(chroma_dc_value) },
157 		{ 248, chroma_ac_bits,  sizeof(chroma_ac_bits)  },
158 		{ 264, chroma_ac_value, sizeof(chroma_ac_value) },
159 	};
160 	struct coda_memcpy_desc qmat[3] = {
161 		{ 512, ctx->params.jpeg_qmat_tab[0], 64 },
162 		{ 576, ctx->params.jpeg_qmat_tab[1], 64 },
163 		{ 640, ctx->params.jpeg_qmat_tab[1], 64 },
164 	};
165 
166 	/* Write huffman tables to parameter memory */
167 	for (i = 0; i < ARRAY_SIZE(huff); i++)
168 		coda_memcpy_parabuf(ctx->parabuf.vaddr, huff + i);
169 
170 	/* Write Q-matrix to parameter memory */
171 	for (i = 0; i < ARRAY_SIZE(qmat); i++)
172 		coda_memcpy_parabuf(ctx->parabuf.vaddr, qmat + i);
173 
174 	return 0;
175 }
176 
coda_jpeg_check_buffer(struct coda_ctx * ctx,struct vb2_buffer * vb)177 bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
178 {
179 	void *vaddr = vb2_plane_vaddr(vb, 0);
180 	u16 soi, eoi;
181 	int len, i;
182 
183 	soi = be16_to_cpup((__be16 *)vaddr);
184 	if (soi != SOI_MARKER)
185 		return false;
186 
187 	len = vb2_get_plane_payload(vb, 0);
188 	vaddr += len - 2;
189 	for (i = 0; i < 32; i++) {
190 		eoi = be16_to_cpup((__be16 *)(vaddr - i));
191 		if (eoi == EOI_MARKER) {
192 			if (i > 0)
193 				vb2_set_plane_payload(vb, 0, len - i);
194 			return true;
195 		}
196 	}
197 
198 	return false;
199 }
200 
201 /*
202  * Scale quantization table using nonlinear scaling factor
203  * u8 qtab[64], scale [50,190]
204  */
coda_scale_quant_table(u8 * q_tab,int scale)205 static void coda_scale_quant_table(u8 *q_tab, int scale)
206 {
207 	unsigned int temp;
208 	int i;
209 
210 	for (i = 0; i < 64; i++) {
211 		temp = DIV_ROUND_CLOSEST((unsigned int)q_tab[i] * scale, 100);
212 		if (temp <= 0)
213 			temp = 1;
214 		if (temp > 255)
215 			temp = 255;
216 		q_tab[i] = (unsigned char)temp;
217 	}
218 }
219 
coda_set_jpeg_compression_quality(struct coda_ctx * ctx,int quality)220 void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality)
221 {
222 	unsigned int scale;
223 
224 	ctx->params.jpeg_quality = quality;
225 
226 	/* Clip quality setting to [5,100] interval */
227 	if (quality > 100)
228 		quality = 100;
229 	if (quality < 5)
230 		quality = 5;
231 
232 	/*
233 	 * Non-linear scaling factor:
234 	 * [5,50] -> [1000..100], [51,100] -> [98..0]
235 	 */
236 	if (quality < 50)
237 		scale = 5000 / quality;
238 	else
239 		scale = 200 - 2 * quality;
240 
241 	if (ctx->params.jpeg_qmat_tab[0]) {
242 		memcpy(ctx->params.jpeg_qmat_tab[0], luma_q, 64);
243 		coda_scale_quant_table(ctx->params.jpeg_qmat_tab[0], scale);
244 	}
245 	if (ctx->params.jpeg_qmat_tab[1]) {
246 		memcpy(ctx->params.jpeg_qmat_tab[1], chroma_q, 64);
247 		coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale);
248 	}
249 }
250