2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
20 /** \file \ingroup avi
22 * This is external code. Converts between avi and mpeg/jpeg.
30 #include "MEM_guardedalloc.h"
32 #include "IMB_imbuf.h"
37 #include "avi_mjpeg.h"
39 static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize);
40 static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, size_t bufsize);
42 static size_t numbytes;
44 static void add_huff_table(j_decompress_ptr dinfo, JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
47 *htblptr = jpeg_alloc_huff_table((j_common_ptr) dinfo);
49 memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
50 memcpy((*htblptr)->huffval, val, sizeof((*htblptr)->huffval));
52 /* Initialize sent_table false so table will be written to JPEG file. */
53 (*htblptr)->sent_table = false;
56 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
57 /* IMPORTANT: these are only valid for 8-bit data precision! */
59 static void std_huff_tables(j_decompress_ptr dinfo)
61 static const UINT8 bits_dc_luminance[17] =
63 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
65 static const UINT8 val_dc_luminance[] =
67 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
70 static const UINT8 bits_dc_chrominance[17] =
72 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
74 static const UINT8 val_dc_chrominance[] =
76 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
79 static const UINT8 bits_ac_luminance[17] =
81 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d,
83 static const UINT8 val_ac_luminance[] =
85 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
86 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
87 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
88 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
89 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
90 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
91 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
92 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
93 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
94 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
95 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
96 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
97 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
98 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
99 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
100 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
101 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
102 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
103 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
104 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
107 static const UINT8 bits_ac_chrominance[17] =
109 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77,
111 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,
136 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[0],
137 bits_dc_luminance, val_dc_luminance);
138 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[0],
139 bits_ac_luminance, val_ac_luminance);
140 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[1],
141 bits_dc_chrominance, val_dc_chrominance);
142 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[1],
143 bits_ac_chrominance, val_ac_chrominance);
146 static int Decode_JPEG(unsigned char *inBuffer, unsigned char *outBuffer, unsigned int width, unsigned int height, size_t bufsize)
148 struct jpeg_decompress_struct dinfo;
149 struct jpeg_error_mgr jerr;
151 (void)width; /* unused */
155 dinfo.err = jpeg_std_error(&jerr);
156 jpeg_create_decompress(&dinfo);
157 jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize);
158 jpeg_read_header(&dinfo, true);
159 if (dinfo.dc_huff_tbl_ptrs[0] == NULL) {
160 std_huff_tables(&dinfo);
162 dinfo.out_color_space = JCS_RGB;
163 dinfo.dct_method = JDCT_IFAST;
165 jpeg_start_decompress(&dinfo);
167 size_t rowstride = dinfo.output_width * dinfo.output_components;
168 for (size_t y = 0; y < dinfo.output_height; y++) {
169 jpeg_read_scanlines(&dinfo, (JSAMPARRAY) &outBuffer, 1);
170 outBuffer += rowstride;
172 jpeg_finish_decompress(&dinfo);
174 if (dinfo.output_height >= height) return 0;
176 inBuffer += numbytes;
177 jpegmemsrcmgr_build(&dinfo, inBuffer, bufsize - numbytes);
180 jpeg_read_header(&dinfo, true);
181 if (dinfo.dc_huff_tbl_ptrs[0] == NULL) {
182 std_huff_tables(&dinfo);
185 jpeg_start_decompress(&dinfo);
186 rowstride = dinfo.output_width * dinfo.output_components;
187 for (size_t y = 0; y < dinfo.output_height; y++) {
188 jpeg_read_scanlines(&dinfo, (JSAMPARRAY) &outBuffer, 1);
189 outBuffer += rowstride;
191 jpeg_finish_decompress(&dinfo);
192 jpeg_destroy_decompress(&dinfo);
197 static void Compress_JPEG(int quality, unsigned char *outbuffer, const unsigned char *inBuffer, int width, int height, size_t bufsize)
199 struct jpeg_compress_struct cinfo;
200 struct jpeg_error_mgr jerr;
201 unsigned char marker[60];
203 cinfo.err = jpeg_std_error(&jerr);
204 jpeg_create_compress(&cinfo);
205 jpegmemdestmgr_build(&cinfo, outbuffer, bufsize);
207 cinfo.image_width = width;
208 cinfo.image_height = height;
209 cinfo.input_components = 3;
210 cinfo.in_color_space = JCS_RGB;
212 jpeg_set_defaults(&cinfo);
213 jpeg_set_colorspace(&cinfo, JCS_YCbCr);
215 jpeg_set_quality(&cinfo, quality, true);
217 cinfo.dc_huff_tbl_ptrs[0]->sent_table = true;
218 cinfo.dc_huff_tbl_ptrs[1]->sent_table = true;
219 cinfo.ac_huff_tbl_ptrs[0]->sent_table = true;
220 cinfo.ac_huff_tbl_ptrs[1]->sent_table = true;
222 cinfo.comp_info[0].component_id = 0;
223 cinfo.comp_info[0].v_samp_factor = 1;
224 cinfo.comp_info[1].component_id = 1;
225 cinfo.comp_info[2].component_id = 2;
227 cinfo.write_JFIF_header = false;
229 jpeg_start_compress(&cinfo, false);
240 jpeg_write_marker(&cinfo, JPEG_APP0, marker, 60);
246 jpeg_write_marker(&cinfo, JPEG_COM, marker, 60);
248 size_t rowstride = cinfo.image_width * cinfo.input_components;
249 for (size_t y = 0; y < cinfo.image_height; y++) {
250 jpeg_write_scanlines(&cinfo, (JSAMPARRAY) &inBuffer, 1);
251 inBuffer += rowstride;
253 jpeg_finish_compress(&cinfo);
254 jpeg_destroy_compress(&cinfo);
257 static void interlace(unsigned char *to, unsigned char *from, int width, int height)
259 size_t i, rowstride = width * 3;
261 for (i = 0; i < height; i++) {
263 memcpy(&to[i * rowstride], &from[(i / 2 + height / 2) * rowstride], rowstride);
265 memcpy(&to[i * rowstride], &from[(i / 2) * rowstride], rowstride);
269 static void deinterlace(int odd, unsigned char *to, unsigned char *from, int width, int height)
271 size_t i, rowstride = width * 3;
273 for (i = 0; i < height; i++) {
275 memcpy(&to[(i / 2 + height / 2) * rowstride], &from[i * rowstride], rowstride);
277 memcpy(&to[(i / 2) * rowstride], &from[i * rowstride], rowstride);
281 void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
286 (void)stream; /* unused */
288 buf = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_from_mjpeg 1");
293 deint = Decode_JPEG(buffer, buf, movie->header->Width, movie->header->Height, *size);
298 buffer = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_from_mjpeg 2");
300 interlace(buffer, buf, movie->header->Width, movie->header->Height);
310 void *avi_converter_to_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
313 size_t bufsize = *size;
318 buf = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_to_mjpeg 1");
323 if (!movie->interlace) {
324 Compress_JPEG(movie->streams[stream].sh.Quality / 100,
326 movie->header->Width,
327 movie->header->Height,
332 deinterlace(movie->odd_fields, buf, buffer, movie->header->Width, movie->header->Height);
336 buf = imb_alloc_pixels(movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "avi.avi_converter_to_mjpeg 1");
339 Compress_JPEG(movie->streams[stream].sh.Quality / 100,
341 movie->header->Width,
342 movie->header->Height / 2,
346 Compress_JPEG(movie->streams[stream].sh.Quality / 100,
347 buf + *size, buffer + (size_t)(movie->header->Height / 2) * (size_t)movie->header->Width * 3,
348 movie->header->Width,
349 movie->header->Height / 2,
360 /* Compression from memory */
362 static void jpegmemdestmgr_init_destination(j_compress_ptr cinfo)
364 (void)cinfo; /* unused */
367 static boolean jpegmemdestmgr_empty_output_buffer(j_compress_ptr cinfo)
369 (void)cinfo; /* unused */
373 static void jpegmemdestmgr_term_destination(j_compress_ptr cinfo)
375 numbytes -= cinfo->dest->free_in_buffer;
377 MEM_freeN(cinfo->dest);
380 static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, size_t bufsize)
382 cinfo->dest = MEM_mallocN(sizeof(*(cinfo->dest)), "avi.jpegmemdestmgr_build");
384 cinfo->dest->init_destination = jpegmemdestmgr_init_destination;
385 cinfo->dest->empty_output_buffer = jpegmemdestmgr_empty_output_buffer;
386 cinfo->dest->term_destination = jpegmemdestmgr_term_destination;
388 cinfo->dest->next_output_byte = buffer;
389 cinfo->dest->free_in_buffer = bufsize;
394 /* Decompression from memory */
396 static void jpegmemsrcmgr_init_source(j_decompress_ptr dinfo)
401 static boolean jpegmemsrcmgr_fill_input_buffer(j_decompress_ptr dinfo)
403 unsigned char *buf = (unsigned char *) dinfo->src->next_input_byte - 2;
405 /* if we get called, must have run out of data */
406 WARNMS(dinfo, JWRN_JPEG_EOF);
408 buf[0] = (JOCTET) 0xFF;
409 buf[1] = (JOCTET) JPEG_EOI;
411 dinfo->src->next_input_byte = buf;
412 dinfo->src->bytes_in_buffer = 2;
417 static void jpegmemsrcmgr_skip_input_data(j_decompress_ptr dinfo, long skipcnt)
419 if (dinfo->src->bytes_in_buffer < skipcnt)
420 skipcnt = dinfo->src->bytes_in_buffer;
422 dinfo->src->next_input_byte += skipcnt;
423 dinfo->src->bytes_in_buffer -= skipcnt;
426 static void jpegmemsrcmgr_term_source(j_decompress_ptr dinfo)
428 numbytes -= dinfo->src->bytes_in_buffer;
430 MEM_freeN(dinfo->src);
433 static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, size_t bufsize)
435 dinfo->src = MEM_mallocN(sizeof(*(dinfo->src)), "avi.jpegmemsrcmgr_build");
437 dinfo->src->init_source = jpegmemsrcmgr_init_source;
438 dinfo->src->fill_input_buffer = jpegmemsrcmgr_fill_input_buffer;
439 dinfo->src->skip_input_data = jpegmemsrcmgr_skip_input_data;
440 dinfo->src->resync_to_restart = jpeg_resync_to_restart;
441 dinfo->src->term_source = jpegmemsrcmgr_term_source;
443 dinfo->src->bytes_in_buffer = bufsize;
444 dinfo->src->next_input_byte = buffer;