1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef JPEG_H
3 #define JPEG_H 1
4 /*
5  * Insert a JPEG header at start of frame
6  *
7  * This module is used by the gspca subdrivers.
8  * A special case is done for Conexant webcams.
9  *
10  * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
11  */
12 
13 /*
14  * generation options
15  *	CONEX_CAM	Conexant if present
16  */
17 
18 /* JPEG header */
19 static const u8 jpeg_head[] = {
20 	0xff, 0xd8,			/* jpeg */
21 
22 /* quantization table quality 50% */
23 	0xff, 0xdb, 0x00, 0x84,		/* DQT */
24 0,
25 #define JPEG_QT0_OFFSET 7
26 	0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
27 	0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
28 	0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
29 	0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
30 	0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
31 	0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
32 	0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
33 	0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
34 1,
35 #define JPEG_QT1_OFFSET 72
36 	0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
37 	0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
38 	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
39 	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
40 	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
41 	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
42 	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
43 	0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
44 
45 /* huffman table */
46 	0xff, 0xc4, 0x01, 0xa2,
47 	0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
48 	0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 	0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
50 	0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03,
51 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
52 	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
53 	0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
54 	0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03,
55 	0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
56 	0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
57 	0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13,
58 	0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81,
59 	0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15,
60 	0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82,
61 	0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
62 	0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36,
63 	0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
64 	0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
65 	0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
66 	0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
67 	0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86,
68 	0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
69 	0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
70 	0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
71 	0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
72 	0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
73 	0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
74 	0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
75 	0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
76 	0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
77 	0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
78 	0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01,
79 	0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
80 	0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
81 	0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
82 	0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62,
83 	0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
84 	0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28,
85 	0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
86 	0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
87 	0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
88 	0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
89 	0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
90 	0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
91 	0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
92 	0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
93 	0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
94 	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
95 	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
96 	0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
97 	0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2,
98 	0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
99 #ifdef CONEX_CAM
100 /* the Conexant frames start with SOF0 */
101 #define JPEG_HDR_SZ 556
102 #else
103 	0xff, 0xc0, 0x00, 0x11,		/* SOF0 (start of frame 0 */
104 	0x08,				/* data precision */
105 #define JPEG_HEIGHT_OFFSET 561
106 	0x01, 0xe0,			/* height */
107 	0x02, 0x80,			/* width */
108 	0x03,				/* component number */
109 		0x01,
110 			0x21,		/* samples Y */
111 			0x00,		/* quant Y */
112 		0x02, 0x11, 0x01,	/* samples CbCr - quant CbCr */
113 		0x03, 0x11, 0x01,
114 
115 	0xff, 0xda, 0x00, 0x0c,		/* SOS (start of scan) */
116 	0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
117 #define JPEG_HDR_SZ 589
118 #endif
119 };
120 
121 /* define the JPEG header */
jpeg_define(u8 * jpeg_hdr,int height,int width,int samplesY)122 static void jpeg_define(u8 *jpeg_hdr,
123 			int height,
124 			int width,
125 			int samplesY)
126 {
127 	memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
128 #ifndef CONEX_CAM
129 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
130 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height;
131 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
132 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width;
133 	jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
134 #endif
135 }
136 
137 /* set the JPEG quality */
jpeg_set_qual(u8 * jpeg_hdr,int quality)138 static void jpeg_set_qual(u8 *jpeg_hdr,
139 			  int quality)
140 {
141 	int i, sc;
142 
143 	if (quality <= 0)
144 		sc = 5000;
145 	else if (quality < 50)
146 		sc = 5000 / quality;
147 	else
148 		sc = 200 - quality * 2;
149 	for (i = 0; i < 64; i++) {
150 		jpeg_hdr[JPEG_QT0_OFFSET + i] =
151 			(jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
152 		jpeg_hdr[JPEG_QT1_OFFSET + i] =
153 			(jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
154 	}
155 }
156 #endif
157