comparison mjpegenc.c @ 0:986e461dc072 libavcodec

Initial revision
author glantau
date Sun, 22 Jul 2001 14:18:56 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:986e461dc072
1 /*
2 * MJPEG encoder
3 * Copyright (c) 2000 Gerard Lantau.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include "avcodec.h"
22 #include "dsputil.h"
23 #include "mpegvideo.h"
24
25 typedef struct MJpegContext {
26 UINT8 huff_size_dc_luminance[12];
27 UINT16 huff_code_dc_luminance[12];
28 UINT8 huff_size_dc_chrominance[12];
29 UINT16 huff_code_dc_chrominance[12];
30
31 UINT8 huff_size_ac_luminance[256];
32 UINT16 huff_code_ac_luminance[256];
33 UINT8 huff_size_ac_chrominance[256];
34 UINT16 huff_code_ac_chrominance[256];
35 } MJpegContext;
36
37 #define SOF0 0xc0
38 #define SOI 0xd8
39 #define EOI 0xd9
40 #define DQT 0xdb
41 #define DHT 0xc4
42 #define SOS 0xda
43
44 #if 0
45 /* These are the sample quantization tables given in JPEG spec section K.1.
46 * The spec says that the values given produce "good" quality, and
47 * when divided by 2, "very good" quality.
48 */
49 static const unsigned char std_luminance_quant_tbl[64] = {
50 16, 11, 10, 16, 24, 40, 51, 61,
51 12, 12, 14, 19, 26, 58, 60, 55,
52 14, 13, 16, 24, 40, 57, 69, 56,
53 14, 17, 22, 29, 51, 87, 80, 62,
54 18, 22, 37, 56, 68, 109, 103, 77,
55 24, 35, 55, 64, 81, 104, 113, 92,
56 49, 64, 78, 87, 103, 121, 120, 101,
57 72, 92, 95, 98, 112, 100, 103, 99
58 };
59 static const unsigned char std_chrominance_quant_tbl[64] = {
60 17, 18, 24, 47, 99, 99, 99, 99,
61 18, 21, 26, 66, 99, 99, 99, 99,
62 24, 26, 56, 99, 99, 99, 99, 99,
63 47, 66, 99, 99, 99, 99, 99, 99,
64 99, 99, 99, 99, 99, 99, 99, 99,
65 99, 99, 99, 99, 99, 99, 99, 99,
66 99, 99, 99, 99, 99, 99, 99, 99,
67 99, 99, 99, 99, 99, 99, 99, 99
68 };
69 #endif
70
71 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
72 /* IMPORTANT: these are only valid for 8-bit data precision! */
73 static const UINT8 bits_dc_luminance[17] =
74 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
75 static const UINT8 val_dc_luminance[] =
76 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
77
78 static const UINT8 bits_dc_chrominance[17] =
79 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
80 static const UINT8 val_dc_chrominance[] =
81 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
82
83 static const UINT8 bits_ac_luminance[17] =
84 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
85 static const UINT8 val_ac_luminance[] =
86 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
87 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
88 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
89 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
90 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
91 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
92 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
93 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
94 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
95 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
96 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
97 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
98 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
99 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
100 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
101 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
102 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
103 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
104 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
105 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
106 0xf9, 0xfa
107 };
108
109 static const UINT8 bits_ac_chrominance[17] =
110 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
111
112 static const UINT8 val_ac_chrominance[] =
113 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
114 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
115 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
116 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
117 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
118 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
119 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
120 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
121 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
122 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
123 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
124 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
125 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
126 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
127 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
128 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
129 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
130 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
131 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
132 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
133 0xf9, 0xfa
134 };
135
136
137 /* isn't this function nicer than the one in the libjpeg ? */
138 static void build_huffman_codes(UINT8 *huff_size, UINT16 *huff_code,
139 const UINT8 *bits_table, const UINT8 *val_table)
140 {
141 int i, j, k,nb, code, sym;
142
143 code = 0;
144 k = 0;
145 for(i=1;i<=16;i++) {
146 nb = bits_table[i];
147 for(j=0;j<nb;j++) {
148 sym = val_table[k++];
149 huff_size[sym] = i;
150 huff_code[sym] = code;
151 code++;
152 }
153 code <<= 1;
154 }
155 }
156
157 int mjpeg_init(MpegEncContext *s)
158 {
159 MJpegContext *m;
160
161 m = malloc(sizeof(MJpegContext));
162 if (!m)
163 return -1;
164
165 /* build all the huffman tables */
166 build_huffman_codes(m->huff_size_dc_luminance,
167 m->huff_code_dc_luminance,
168 bits_dc_luminance,
169 val_dc_luminance);
170 build_huffman_codes(m->huff_size_dc_chrominance,
171 m->huff_code_dc_chrominance,
172 bits_dc_chrominance,
173 val_dc_chrominance);
174 build_huffman_codes(m->huff_size_ac_luminance,
175 m->huff_code_ac_luminance,
176 bits_ac_luminance,
177 val_ac_luminance);
178 build_huffman_codes(m->huff_size_ac_chrominance,
179 m->huff_code_ac_chrominance,
180 bits_ac_chrominance,
181 val_ac_chrominance);
182
183 s->mjpeg_ctx = m;
184 return 0;
185 }
186
187 void mjpeg_close(MpegEncContext *s)
188 {
189 free(s->mjpeg_ctx);
190 }
191
192 static inline void put_marker(PutBitContext *p, int code)
193 {
194 put_bits(p, 8, 0xff);
195 put_bits(p, 8, code);
196 }
197
198 /* table_class: 0 = DC coef, 1 = AC coefs */
199 static int put_huffman_table(MpegEncContext *s, int table_class, int table_id,
200 const UINT8 *bits_table, const UINT8 *value_table)
201 {
202 PutBitContext *p = &s->pb;
203 int n, i;
204
205 put_bits(p, 4, table_class);
206 put_bits(p, 4, table_id);
207
208 n = 0;
209 for(i=1;i<=16;i++) {
210 n += bits_table[i];
211 put_bits(p, 8, bits_table[i]);
212 }
213
214 for(i=0;i<n;i++)
215 put_bits(p, 8, value_table[i]);
216
217 return n + 17;
218 }
219
220 static void jpeg_table_header(MpegEncContext *s)
221 {
222 PutBitContext *p = &s->pb;
223 int i, size;
224 UINT8 *ptr;
225
226 /* quant matrixes */
227 put_marker(p, DQT);
228 put_bits(p, 16, 2 + 1 * (1 + 64));
229 put_bits(p, 4, 0); /* 8 bit precision */
230 put_bits(p, 4, 0); /* table 0 */
231 for(i=0;i<64;i++) {
232 put_bits(p, 8, s->intra_matrix[i]);
233 }
234 #if 0
235 put_bits(p, 4, 0); /* 8 bit precision */
236 put_bits(p, 4, 1); /* table 1 */
237 for(i=0;i<64;i++) {
238 put_bits(p, 8, s->chroma_intra_matrix[i]);
239 }
240 #endif
241
242 /* huffman table */
243 put_marker(p, DHT);
244 flush_put_bits(p);
245 ptr = p->buf_ptr;
246 put_bits(p, 16, 0); /* patched later */
247 size = 2;
248 size += put_huffman_table(s, 0, 0, bits_dc_luminance, val_dc_luminance);
249 size += put_huffman_table(s, 0, 1, bits_dc_chrominance, val_dc_chrominance);
250
251 size += put_huffman_table(s, 1, 0, bits_ac_luminance, val_ac_luminance);
252 size += put_huffman_table(s, 1, 1, bits_ac_chrominance, val_ac_chrominance);
253 ptr[0] = size >> 8;
254 ptr[1] = size;
255 }
256
257 void mjpeg_picture_header(MpegEncContext *s)
258 {
259 put_marker(&s->pb, SOI);
260
261 jpeg_table_header(s);
262
263 put_marker(&s->pb, SOF0);
264
265 put_bits(&s->pb, 16, 17);
266 put_bits(&s->pb, 8, 8); /* 8 bits/component */
267 put_bits(&s->pb, 16, s->height);
268 put_bits(&s->pb, 16, s->width);
269 put_bits(&s->pb, 8, 3); /* 3 components */
270
271 /* Y component */
272 put_bits(&s->pb, 8, 1); /* component number */
273 put_bits(&s->pb, 4, 2); /* H factor */
274 put_bits(&s->pb, 4, 2); /* V factor */
275 put_bits(&s->pb, 8, 0); /* select matrix */
276
277 /* Cb component */
278 put_bits(&s->pb, 8, 2); /* component number */
279 put_bits(&s->pb, 4, 1); /* H factor */
280 put_bits(&s->pb, 4, 1); /* V factor */
281 put_bits(&s->pb, 8, 0); /* select matrix */
282
283 /* Cr component */
284 put_bits(&s->pb, 8, 3); /* component number */
285 put_bits(&s->pb, 4, 1); /* H factor */
286 put_bits(&s->pb, 4, 1); /* V factor */
287 put_bits(&s->pb, 8, 0); /* select matrix */
288
289 /* scan header */
290 put_marker(&s->pb, SOS);
291 put_bits(&s->pb, 16, 12); /* length */
292 put_bits(&s->pb, 8, 3); /* 3 components */
293
294 /* Y component */
295 put_bits(&s->pb, 8, 1); /* index */
296 put_bits(&s->pb, 4, 0); /* DC huffman table index */
297 put_bits(&s->pb, 4, 0); /* AC huffman table index */
298
299 /* Cb component */
300 put_bits(&s->pb, 8, 2); /* index */
301 put_bits(&s->pb, 4, 1); /* DC huffman table index */
302 put_bits(&s->pb, 4, 1); /* AC huffman table index */
303
304 /* Cr component */
305 put_bits(&s->pb, 8, 3); /* index */
306 put_bits(&s->pb, 4, 1); /* DC huffman table index */
307 put_bits(&s->pb, 4, 1); /* AC huffman table index */
308
309 put_bits(&s->pb, 8, 0); /* Ss (not used) */
310 put_bits(&s->pb, 8, 63); /* Se (not used) */
311 put_bits(&s->pb, 8, 0); /* (not used) */
312 }
313
314 void mjpeg_picture_trailer(MpegEncContext *s)
315 {
316 jflush_put_bits(&s->pb);
317 put_marker(&s->pb, EOI);
318 }
319
320 static inline void encode_dc(MpegEncContext *s, int val,
321 UINT8 *huff_size, UINT16 *huff_code)
322 {
323 int mant, nbits;
324
325 if (val == 0) {
326 jput_bits(&s->pb, huff_size[0], huff_code[0]);
327 } else {
328 mant = val;
329 if (val < 0) {
330 val = -val;
331 mant--;
332 }
333
334 /* compute the log (XXX: optimize) */
335 nbits = 0;
336 while (val != 0) {
337 val = val >> 1;
338 nbits++;
339 }
340
341 jput_bits(&s->pb, huff_size[nbits], huff_code[nbits]);
342
343 jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
344 }
345 }
346
347 static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
348 {
349 int mant, nbits, code, i, j;
350 int component, dc, run, last_index, val;
351 MJpegContext *m = s->mjpeg_ctx;
352 UINT8 *huff_size_ac;
353 UINT16 *huff_code_ac;
354
355 /* DC coef */
356 component = (n <= 3 ? 0 : n - 4 + 1);
357 dc = block[0]; /* overflow is impossible */
358 val = dc - s->last_dc[component];
359 if (n < 4) {
360 encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
361 huff_size_ac = m->huff_size_ac_luminance;
362 huff_code_ac = m->huff_code_ac_luminance;
363 } else {
364 encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
365 huff_size_ac = m->huff_size_ac_chrominance;
366 huff_code_ac = m->huff_code_ac_chrominance;
367 }
368 s->last_dc[component] = dc;
369
370 /* AC coefs */
371
372 run = 0;
373 last_index = s->block_last_index[n];
374 for(i=1;i<=last_index;i++) {
375 j = zigzag_direct[i];
376 val = block[j];
377 if (val == 0) {
378 run++;
379 } else {
380 while (run >= 16) {
381 jput_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]);
382 run -= 16;
383 }
384 mant = val;
385 if (val < 0) {
386 val = -val;
387 mant--;
388 }
389
390 /* compute the log (XXX: optimize) */
391 nbits = 0;
392 while (val != 0) {
393 val = val >> 1;
394 nbits++;
395 }
396 code = (run << 4) | nbits;
397
398 jput_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]);
399
400 jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1));
401 run = 0;
402 }
403 }
404
405 /* output EOB only if not already 64 values */
406 if (last_index < 63 || run != 0)
407 jput_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
408 }
409
410 void mjpeg_encode_mb(MpegEncContext *s,
411 DCTELEM block[6][64])
412 {
413 int i;
414 for(i=0;i<6;i++) {
415 encode_block(s, block[i], i);
416 }
417 }