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