blob: 0aa2b671faa417120217c9ae960e79013171f213 [file] [log] [blame]
Jean-Francois Moine63eb9542008-04-12 09:58:09 -03001#ifndef JPEG_H
2#define JPEG_H 1
3/*
4 * Insert a JPEG header at start of frame
5 *
6 * This module is used by the gspca subdrivers.
7 * A special case is done for Conexant webcams.
8 *
9 * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030027/*
28 * generation options
29 * CONEX_CAM Conexant if present
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030030 */
31
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030032/* JPEG header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030033static const u8 jpeg_head[] = {
Jean-Francois Moine63eb9542008-04-12 09:58:09 -030034 0xff, 0xd8, /* jpeg */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030035
36/* quantization table quality 50% */
Jean-Francois Moine63eb9542008-04-12 09:58:09 -030037 0xff, 0xdb, 0x00, 0x84, /* DQT */
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300380,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030039#define JPEG_QT0_OFFSET 7
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030040 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
41 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
42 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
43 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
44 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
45 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
46 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
47 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300481,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030049#define JPEG_QT1_OFFSET 72
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030050 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
51 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
52 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
53 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
54 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
55 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
56 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
57 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
Jean-Francois Moine63eb9542008-04-12 09:58:09 -030058
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030059/* huffman table */
Jean-Francois Moine63eb9542008-04-12 09:58:09 -030060 0xff, 0xc4, 0x01, 0xa2,
61 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
62 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
64 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03,
65 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
66 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
67 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
68 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03,
69 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
70 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
71 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13,
72 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81,
73 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15,
74 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82,
75 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
76 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36,
77 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
78 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
79 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
80 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
81 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86,
82 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
83 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
84 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
85 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
86 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
87 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
88 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
89 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
90 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
91 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
92 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01,
93 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
94 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
95 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
96 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62,
97 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
98 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28,
99 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
100 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
101 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
102 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
103 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
104 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
105 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
106 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
107 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
108 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
109 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
110 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
111 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2,
112 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
113#ifdef CONEX_CAM
114/* the Conexant frames start with SOF0 */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300115#define JPEG_HDR_SZ 556
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300116#else
117 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
118 0x08, /* data precision */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300119#define JPEG_HEIGHT_OFFSET 561
120 0x01, 0xe0, /* height */
121 0x02, 0x80, /* width */
122 0x03, /* component number */
123 0x01,
124 0x21, /* samples Y */
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300125 0x00, /* quant Y */
126 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
127 0x03, 0x11, 0x01,
128
Jean-Francois Moined43fa322008-06-12 10:58:58 -0300129 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300130 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300131#define JPEG_HDR_SZ 589
132#endif
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300133};
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300134
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300135/* define the JPEG header */
136static void jpeg_define(u8 *jpeg_hdr,
137 int height,
138 int width,
139 int samplesY)
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300140{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300141 memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300142#ifndef CONEX_CAM
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300143 jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
Jean-François Moineded5e902011-01-13 05:27:37 -0300144 jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300145 jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
Jean-François Moineded5e902011-01-13 05:27:37 -0300146 jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300147 jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300148#endif
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300149}
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300150
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300151/* set the JPEG quality */
152static void jpeg_set_qual(u8 *jpeg_hdr,
153 int quality)
154{
155 int i, sc;
156
Mauro Carvalho Chehab32654fb2014-04-07 10:52:43 -0300157 if (quality <= 0)
158 sc = 5000;
159 else if (quality < 50)
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300160 sc = 5000 / quality;
161 else
162 sc = 200 - quality * 2;
163 for (i = 0; i < 64; i++) {
164 jpeg_hdr[JPEG_QT0_OFFSET + i] =
165 (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
166 jpeg_hdr[JPEG_QT1_OFFSET + i] =
167 (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
168 }
Jean-Francois Moine63eb9542008-04-12 09:58:09 -0300169}
170#endif